diff --git a/README.md b/README.md index 1b38b8b..9d50026 100644 --- a/README.md +++ b/README.md @@ -37,14 +37,18 @@ Note that PHP for Windows does not include CA certificates, so you'll need to in ## Usage -`vendor/bin/libyear < path to project > [-q|--quiet] [-v|--verbose]` +`vendor/bin/libyear [-q|--quiet] [-v|--verbose]` -(or `php path/to/libyear.phar < path to project > [-q|--quiet] [-v|--verbose]` for the PHAR version) +(or `php path/to/libyear.phar [-q|--quiet] [-v|--verbose]` for the PHAR version) Arguments: -- `path to project`: required, directory containing `composer.json` and `composer.lock` files -- `-q`, `--quiet`: optional, quiet mode will only output libraries which are not up-to-date (that is, where "Libyears Behind" > 0) -- `-v`, `--verbose`: optional, verbose mode will output processing details like when a library isn't found in a repository +- `path`: required, directory containing `composer.json` and `composer.lock` files + +Options: +- `-h`, `--help`: show help text and exit without checking dependencies +- `-q`, `--quiet`: quiet mode will only output libraries which are not up-to-date (that is, where "Libyears Behind" > 0) +- `-u`, `--update`: update mode will write the latest version info to your `composer.json` file (note that you'll still need to run `composer update` to actually update your local dependencies) +- `-v`, `--verbose`: verbose mode will output processing details like when a library isn't found in a repository ## Contributing diff --git a/composer.json b/composer.json index 2c5c351..4ca3f39 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "ecoapm/libyear", - "version": "2.2.1", + "version": "2.3.0", "description": "A simple measure of software dependency freshness", "homepage": "https://libyear.com", "readme": "README.md", diff --git a/src/App.php b/src/App.php index d377940..bd6172d 100644 --- a/src/App.php +++ b/src/App.php @@ -29,37 +29,25 @@ public function __construct(Calculator $calculator, ComposerFile $composer, $out */ public function run(array $args): void { + if (in_array('-h', $args) || in_array('--help', $args)) + { + $this->showHelp(); + return; + } + $quiet_mode = in_array('-q', $args) || in_array('--quiet', $args); $update_mode = in_array('-u', $args) || in_array('--update', $args); $verbose_mode = in_array('-v', $args) || in_array('--verbose', $args); - $other_args = array_filter(array_slice($args, 1), fn ($a) => !in_array($a, ['-q', '--quiet', '-u', '--update', '-v', '--verbose'])); - $dir = $other_args ? array_values($other_args)[0] : '.'; + $known_options = ['-q', '--quiet', '-u', '--update', '-v', '--verbose']; + $other_args = array_filter(array_slice($args, 1), fn ($a) => !in_array($a, $known_options)); + $dir = !empty($other_args) ? array_values($other_args)[0] : '.'; $real_dir = realpath($dir); fwrite($this->output, "Gathering information for $real_dir...\n"); $dependencies = $this->getDependencies($dir, $quiet_mode, $verbose_mode); - - $table = new Table( - ['Package', 'Current Version', 'Released', 'Newest Version', 'Released', 'Libyears Behind'], - array_map( - fn (Dependency $dependency): array => [ - $dependency->name, - $dependency->current_version->version_number, - isset($dependency->current_version->released) ? $dependency->current_version->released->format('Y-m-d') : "", - isset($dependency->newest_version->version_number) ? $dependency->newest_version->version_number : "", - isset($dependency->newest_version->released) ? $dependency->newest_version->released->format('Y-m-d') : "", - $dependency->getLibyearsBehind() !== null ? number_format($dependency->getLibyearsBehind(), 2) : "" - ], - $dependencies - ) - ); - if (!empty($dependencies)) { - $rows = $table->getDisplayLines(); - foreach ($rows as $row) { - fwrite($this->output, $row . "\n"); - } + $this->showTable($dependencies); } $total = Calculator::getTotalLibyearsBehind($dependencies); @@ -86,4 +74,49 @@ private function getDependencies(string $dir, bool $quiet_mode, bool $verbose_mo ? array_filter($dependencies, fn (Dependency $dependency): bool => $dependency->getLibyearsBehind() > 0) : $dependencies; } + + private function showTable(array $dependencies): void + { + $table = new Table( + ['Package', 'Current Version', 'Released', 'Newest Version', 'Released', 'Libyears Behind'], + array_map( + fn (Dependency $dependency): array => [ + $dependency->name, + $dependency->current_version->version_number, + isset($dependency->current_version->released) ? $dependency->current_version->released->format('Y-m-d') : "", + isset($dependency->newest_version->version_number) ? $dependency->newest_version->version_number : "", + isset($dependency->newest_version->released) ? $dependency->newest_version->released->format('Y-m-d') : "", + $dependency->getLibyearsBehind() !== null ? number_format($dependency->getLibyearsBehind(), 2) : "" + ], + $dependencies + ) + ); + + $rows = $table->getDisplayLines(); + foreach ($rows as $row) { + fwrite($this->output, $row . "\n"); + } + } + + private function showHelp(): void + { + $output = 'libyear: a simple measure of dependency freshness' . PHP_EOL + . PHP_EOL + . 'Calculates the total number of years behind their respective newest versions for all' + . ' dependencies listed in composer.json.' . PHP_EOL + . PHP_EOL + . 'Usage: libyear [-q|--quiet] [-u|--update] [-v|--verbose]' . PHP_EOL + . PHP_EOL + . 'Arguments:' . PHP_EOL + . '- path (required) the directory containing composer.json and composer.lock files' . PHP_EOL + . PHP_EOL + . 'Options:' . PHP_EOL + . '--help (-h) show this message and exit' . PHP_EOL + . '--quiet (-q) only display outdated dependencies' . PHP_EOL + . '--update (-u) update composer.json with newest versions' . PHP_EOL + . '--verbose (-v) display network debug information' . PHP_EOL + . PHP_EOL; + + fwrite($this->output, $output); + } } diff --git a/tests/AppTest.php b/tests/AppTest.php index fec0e46..f8f4428 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -32,7 +32,24 @@ private static function calculator(): Calculator ]); } - public function testShowsAllDependenciesByDefaut() + public function testCanDisplayHelpText() + { + //arrange + $composer = Mockery::mock(ComposerFile::class); + $output = fopen('php://memory', 'a+'); + $app = new App(self::calculator(), $composer, $output); + + //act + $app->run(['libyear', '--help']); + + //assert + fseek($output, 0); + $console = stream_get_contents($output); + $this->assertStringContainsString('Arguments:', $console); + $this->assertStringContainsString('Options:', $console); + } + + public function testShowsAllDependenciesByDefault() { //arrange $composer = Mockery::mock(ComposerFile::class);