Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4

[*.{yml,yaml,json,xml}]
indent_size = 2[*.md]
trim_trailing_whitespace = false
22 changes: 22 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Set default behavior
* text=auto

# Enforce LF endings for scripts and configs (Crucial for CLI tools running on Linux/Docker)
*.php text eol=lf
*.json text eol=lf
*.yml text eol=lf
*.xml text eol=lf
*.sh text eol=lf

# ── EXPORT IGNORE (Keeps production installations tiny) ───────
/tests/ export-ignore
/.github/ export-ignore
/.idea/ export-ignore
/.vscode/ export-ignore
/phpunit.xml.dist export-ignore
/phpstan.neon export-ignore
/rector.php export-ignore
/.php-cs-fixer.php export-ignore
/infection.json5 export-ignore
/.gitignore export-ignore
/.editorconfig export-ignore
68 changes: 48 additions & 20 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,25 +1,53 @@
# CakePHP 3
# ── COMPOSER ──────────────────────────────────────────────────
/vendor/
#(Uncomment if you want to ignore lock file for the library)
composer.lock

/vendor/*
/config/app.php

/tmp/cache/models/*
!/tmp/cache/models/empty
/tmp/cache/persistent/*
!/tmp/cache/persistent/empty
/tmp/cache/views/*
!/tmp/cache/views/empty
/tmp/sessions/*
!/tmp/sessions/empty
/tmp/tests/*
!/tmp/tests/empty
# ── TESTING & COVERAGE ────────────────────────────────────────
/.phpunit.cache/
.phpunit.result.cache
/coverage/
/coverage-html/
coverage.xml
clover.xml
phpunit.xml
!phpunit.xml.dist
infection.log

/logs/*
!/logs/empty
# ── STATIC ANALYSIS & REFACTORING CACHES ──────────────────────
.php-cs-fixer.cache
/.phpstan.cache/
/.rector/
phpstan-results.json

# CakePHP 2
# ── PROFILING & DEBUGGING (Xdebug) ────────────────────────────
cachegrind.out.*
xdebug.log
error_log
php_errors.log

/app/tmp/*
/app/Config/core.php
/app/Config/database.php
/vendors/*
# ── BUILD ARTIFACTS (If you compile the CLI) ──────────────────
/build/
/dist/
*.phar

# ── ENVIRONMENT & DOCKER ──────────────────────────────────────
.env
.env.*.local
docker-compose.override.yml
docker-compose.local.yml

# ── OS & IDEs ─────────────────────────────────────────────────
.DS_Store
.AppleDouble
.LSOverride
Icon
._*
Thumbs.db
ehthumbs.db
/.idea/
/.vscode/
*.swp
*.swo
*~
29 changes: 29 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

use PhpCsFixer\Config;
use PhpCsFixer\Finder;

return (new Config())
->setRiskyAllowed(true)
->setRules([
'@auto' => true,
'@auto:risky' => true
])
// 💡 by default, Fixer looks for `*.php` files excluding `./vendor/` - here, you can groom this config
->setFinder(
(new Finder())
// 💡 root folder to check
->in(__DIR__)
// 💡 additional files, eg bin entry file
// ->append([__DIR__.'/bin-entry-file'])
// 💡 folders to exclude, if any
// ->exclude([/* ... */])
// 💡 path patterns to exclude, if any
// ->notPath([/* ... */])
// 💡 extra configs
// ->ignoreDotFiles(false) // true by default in v3, false in v4 or future mode
// ->ignoreVCS(true) // true by default
)
;
59 changes: 58 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,86 @@
"description": "Interactive CLI component runtime for PHP microservice and hexagonal architectures.",
"type": "library",
"license": "MIT",
"keywords":[
"cli",
"hexagonal-architecture",
"microservices",
"io",
"terminal"
],
"authors":[
{
"name": "Alfacode Team",
"email": "shamavurasheed@gmail.com",
"role": "Developer"
}
],
"autoload": {
"psr-4": {
"AlfacodeTeam\\PhpIoCli\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"AlfacodeTeam\\PhpIoCli\\Tests\\": "tests/"
}
},
"require": {
"php": "^8.2",
"psr/log": "^3.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.50",
"infection/infection": "^0.29",
"mockery/mockery": "^1.6",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan-mockery": "^1.1",
"phpstan/phpstan-phpunit": "^1.3",
"phpunit/phpunit": "^10.5 || ^11.0",
"rector/rector": "^1.0",
"symfony/console": "^6.0 || ^7.0"
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"sort-packages": true,
"allow-plugins": {
"infection/extension-installer": true,
"phpstan/extension-installer": true
}
},
"scripts": {
"test": "phpunit",
"test:coverage": "phpunit --coverage-html coverage",
"format": "php-cs-fixer fix --allow-risky=yes",
"lint": "php-cs-fixer fix --dry-run --allow-risky=yes",
"analyse": "phpstan analyse --memory-limit=256M",
"refactor": "rector process",
"mutation": "infection --threads=max",
"check":[
"@lint",
"@analyse",
"@test"
]
},
"scripts-descriptions": {
"test": "Run unit tests",
"test:coverage": "Run unit tests with HTML coverage report",
"format": "Automatically format PHP code using PHP-CS-Fixer",
"lint": "Check coding standards without modifying files",
"analyse": "Run static analysis with PHPStan",
"refactor": "Run Rector to automatically upgrade code and apply design patterns",
"mutation": "Run mutation testing with Infection to verify test suite quality",
"check": "Run all checks (linting, static analysis, and tests)"
},
"extra": {
"_comment": "── php-io-cli: command auto-discovery ──────────────────────────────────────",
"_comment2": "Applications that depend on this library should add their own 'extra.php-io-cli'",
"_comment3": "block in THEIR composer.json (not this file). Example:",
"_example": {
"extra": {
"php-io-cli": {
"commands": [
"commands":[
"App\\Commands\\ServeCommand",
"App\\Commands\\MakeModelCommand",
"App\\Commands\\MigrateCommand"
Expand Down
7 changes: 3 additions & 4 deletions examples/01-inputs.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env php
<?php

/**
* php-io-cli — Example: All Interactive Input Components
*
Expand Down Expand Up @@ -27,9 +28,7 @@
$name = (new TextInput('What is your name?'))
->placeholder('e.g. Alice')
->default('World')
->validate(function (string $value): ?string {
return mb_strlen($value) >= 2 ? null : 'Name must be at least 2 characters.';
})
->validate(fn(string $value): ?string => mb_strlen($value) >= 2 ? null : 'Name must be at least 2 characters.')
->run();

Colors::line(" → Name: {$name}", Colors::GREEN);
Expand All @@ -52,7 +51,7 @@
->showStrength()
->run();

Colors::line(" → Password length: " . mb_strlen((string)$secret) . " chars", Colors::GREEN);
Colors::line(" → Password length: " . mb_strlen((string) $secret) . " chars", Colors::GREEN);

// ── 4. Confirm ────────────────────────────────────────────────────

Expand Down
7 changes: 4 additions & 3 deletions examples/02-display.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env php
<?php

/**
* php-io-cli — Example: Display Components
*
Expand Down Expand Up @@ -45,10 +46,10 @@
Table::make()
->headers(['Service', 'Status', 'Latency', 'Requests'])
->rows([
['api-gateway', Colors::wrap('healthy', Colors::GREEN), '12 ms', '15,204'],
['api-gateway', Colors::wrap('healthy', Colors::GREEN), '12 ms', '15,204'],
['auth-service', Colors::wrap('degraded', Colors::YELLOW), '340 ms', '3,891'],
['payment-worker', Colors::wrap('down', Colors::RED), '—', '0'],
['cache-service', Colors::wrap('healthy', Colors::GREEN), '2 ms', '52,001'],
['payment-worker', Colors::wrap('down', Colors::RED), '—', '0'],
['cache-service', Colors::wrap('healthy', Colors::GREEN), '2 ms', '52,001'],
])
->align([3 => 'right'])
->render();
Expand Down
9 changes: 5 additions & 4 deletions examples/03-application.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env php
<?php

/**
* php-io-cli — Example: Full CLI Application with Commands
*
Expand Down Expand Up @@ -37,9 +38,9 @@ protected function configure(): void
$this->description = 'Deploy the application to an environment';

$this->addArgument('environment', 'Target environment', required: true);
$this->addOption('tag', 't', 'Git tag to deploy', acceptsValue: true, default: 'latest');
$this->addOption('tag', 't', 'Git tag to deploy', acceptsValue: true, default: 'latest');
$this->addOption('dry-run', 'd', 'Simulate without side-effects');
$this->addOption('force', 'f', 'Skip confirmation prompt');
$this->addOption('force', 'f', 'Skip confirmation prompt');
}

protected function handle(): int
Expand Down Expand Up @@ -107,7 +108,7 @@ protected function configure(): void
$this->description = 'Run pending database migrations';

$this->addOption('rollback', 'r', 'Rollback the last batch');
$this->addOption('steps', 's', 'Number of steps to roll back', acceptsValue: true, default: '1');
$this->addOption('steps', 's', 'Number of steps to roll back', acceptsValue: true, default: '1');
}

protected function handle(): int
Expand Down Expand Up @@ -190,7 +191,7 @@ protected function handle(): int
$this->table()
->headers(['File', 'Status'])
->rows(array_map(
fn (string $f) => ["src/{$name}/{$f}.php", Colors::wrap('created', Colors::GREEN)],
fn(string $f) => ["src/{$name}/{$f}.php", Colors::wrap('created', Colors::GREEN)],
$features
))
->render();
Expand Down
5 changes: 3 additions & 2 deletions examples/04-shell.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env php
<?php

/**
* php-io-cli — Example: Shell::run + SpinnerComponent integration
*
Expand Down Expand Up @@ -29,8 +30,8 @@
$gitVersion = Shell::capture('git --version');

echo PHP_EOL;
Colors::line(" PHP: " . explode("\n", (string)$phpVersion)[0], Colors::GREEN);
Colors::line(" Git: " . (string)$gitVersion, Colors::GREEN);
Colors::line(" PHP: " . explode("\n", (string) $phpVersion)[0], Colors::GREEN);
Colors::line(" Git: " . (string) $gitVersion, Colors::GREEN);
echo PHP_EOL;

// ── Example 2: Shell::run with SpinnerComponent ────────────────────
Expand Down
17 changes: 17 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
cacheDirectory=".phpunit.cache">
<testsuites>
<testsuite name="PhpIoCli Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory>src</directory>
</include>
</source>
</phpunit>
15 changes: 15 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;

return RectorConfig::configure()
->withPaths([
__DIR__ . '/examples',
__DIR__ . '/src',
__DIR__ . '/tests',
])
// uncomment to reach your current PHP version
// ->withPhpSets()
->withTypeCoverageLevel(0);
Loading
Loading