From 811d7004285c0da74cc3d1def5aa681e95148b57 Mon Sep 17 00:00:00 2001 From: Matthias Althaus Date: Thu, 12 May 2022 12:33:20 +0200 Subject: [PATCH] Added outdated command (fixes #47341) --- CHANGELOG.md | 8 ++++ README.md | 1 + bin/composertoolsinstaller | 1 + src/Command/AbstractToolCommand.php | 12 ++++-- src/Command/OutdatedCommand.php | 59 +++++++++++++++++++++++++++++ src/Command/UpdateAllCommand.php | 15 ++++++-- src/Tools/ToolPath.php | 13 +++++++ 7 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 src/Command/OutdatedCommand.php diff --git a/CHANGELOG.md b/CHANGELOG.md index d73efec..96c8a76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file, in reverse ## [Unreleased] +### Added + +- Added `outdated` command. #47341 + +### Fixed + +- Fixed `update-all` command not finding any tools. + ## 1.4 - 2022-04-12 ### Changed diff --git a/README.md b/README.md index b9f9ae9..7979f34 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ For each tool a standalone folder named by the package without the vendor will b * **install $name**: Installs a new tool. `$name` must be a tool's composer or registered shortcut name. * **update $name**: Updates an installed tool. `$name` must be a tool's name without vendor or registered shortcut name. * **update-all**: Updates all installed tools. +* **outdated**: Lists all tools and checks if they are up-to-date. * **extend $name $extension**: Installs a tool extension. `$name` must be a tool's composer or registered shortcut name. `$extension` must be the composer name of the extension. ## How to build cotor diff --git a/bin/composertoolsinstaller b/bin/composertoolsinstaller index bd4c655..c961622 100755 --- a/bin/composertoolsinstaller +++ b/bin/composertoolsinstaller @@ -15,4 +15,5 @@ $application->add(new Command\InstallCommand($filesystem)); $application->add(new Command\ExtendCommand($filesystem)); $application->add(new Command\UpdateCommand()); $application->add(new Command\UpdateAllCommand()); +$application->add(new Command\OutdatedCommand()); $application->run(); diff --git a/src/Command/AbstractToolCommand.php b/src/Command/AbstractToolCommand.php index c41d653..49cda8d 100644 --- a/src/Command/AbstractToolCommand.php +++ b/src/Command/AbstractToolCommand.php @@ -33,7 +33,7 @@ protected function getPackage(string $name): Package /** * @throws ProcessFailedException */ - protected function runComposerWithPackage(string $command, string $targetDir, Package $package, bool $useVersion): void + protected function runComposerWithPackage(string $command, string $targetDir, Package $package, bool $useVersion): string { $name = $package->getComposerName(); if ($useVersion) { @@ -42,23 +42,29 @@ protected function runComposerWithPackage(string $command, string $targetDir, Pa $process = new Process(['composer', $command, sprintf('--working-dir=%s', $targetDir), $name]); $process->mustRun(); + + return $process->getOutput(); } /** * @throws ProcessFailedException */ - protected function runComposer(string $command, string $targetDir): void + protected function runComposer(string $command, string $targetDir): string { $process = new Process(['composer', $command, sprintf('--working-dir=%s', $targetDir)]); $process->mustRun(); + + return $process->getOutput(); } /** * @throws ProcessFailedException */ - protected function runComposerWithArguments(string $command, string $targetDir, string ...$arguments): void + protected function runComposerWithArguments(string $command, string $targetDir, string ...$arguments): string { $process = new Process(array_merge(['composer', $command, sprintf('--working-dir=%s', $targetDir)], $arguments)); $process->mustRun(); + + return $process->getOutput(); } } diff --git a/src/Command/OutdatedCommand.php b/src/Command/OutdatedCommand.php new file mode 100644 index 0000000..c77f102 --- /dev/null +++ b/src/Command/OutdatedCommand.php @@ -0,0 +1,59 @@ +setDescription('Check if tools are outdated or not') + ->setHelp('This command allows you to check if tools are outdated or not') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + + $toolsDir = getcwd() . '/tools'; + if (!is_dir($toolsDir)) { + $io->error('There is no tools directory! Did you miss to install something first?'); + + return Command::INVALID; + } + + $targetDirs = ToolPath::glob($toolsDir); + + if ([] === $targetDirs) { + $io->warning('Could not find any tools! Did you miss to run `install`?'); + } + + foreach ($targetDirs as $targetDir) { + try { + if ('' === $out = $this->runComposerWithArguments('outdated', $targetDir, '--direct')) { + $io->writeln(sprintf(' %s is up-to-date.', ToolPath::path2name($targetDir))); + } elseif (preg_match('#^1(?:.+?)/(?:.+?)\s(?P.+?)\s.\s(?P.+?)\s#', $out, $matches)) { + $io->writeln(sprintf(' %s is outdated: %s => %s', ToolPath::path2name($targetDir), $matches['current'], $matches['new'])); + } else { + $io->writeln(sprintf(' %s is outdated: %s', ToolPath::path2name($targetDir), trim($out))); + } + } catch (ProcessFailedException) { + $io->writeln(sprintf(' Failed to check if %s is outdated.', ToolPath::path2name($targetDir))); + } + } + + return Command::SUCCESS; + } +} diff --git a/src/Command/UpdateAllCommand.php b/src/Command/UpdateAllCommand.php index 2908e63..bd52967 100644 --- a/src/Command/UpdateAllCommand.php +++ b/src/Command/UpdateAllCommand.php @@ -4,6 +4,7 @@ namespace IServ\ComposerToolsInstaller\Command; +use IServ\ComposerToolsInstaller\Tools\ToolPath; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -33,12 +34,18 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::INVALID; } - foreach (glob($toolsDir . '/*', GLOB_ONLYDIR) as $targetDir) { + $targetDirs = ToolPath::glob($toolsDir); + + if ([] === $targetDirs) { + $io->warning('Could not find any tools! Did you miss to run `install`?'); + } + + foreach ($targetDirs as $targetDir) { try { $this->runComposer('update', $targetDir); - $io->writeln(sprintf(' %s updated successfully.', substr(strrchr($targetDir, '/'), 1))); - } catch (ProcessFailedException $e) { - $io->writeln(sprintf(' Failed to update %s.', substr(strrchr($targetDir, '/'), 1))); + $io->writeln(sprintf(' %s updated successfully.', ToolPath::path2name($targetDir))); + } catch (ProcessFailedException) { + $io->writeln(sprintf(' Failed to update %s.', ToolPath::path2name($targetDir))); } } diff --git a/src/Tools/ToolPath.php b/src/Tools/ToolPath.php index b64e778..5212b01 100644 --- a/src/Tools/ToolPath.php +++ b/src/Tools/ToolPath.php @@ -19,4 +19,17 @@ public static function createExecutable(string $toolsDir, string $name): string { return sprintf('%s/%s', $toolsDir, $name); } + + /** @return array */ + public static function glob(string $toolsDir): array + { + $targetDirs = glob($toolsDir . '/.*', GLOB_ONLYDIR); + + return array_filter($targetDirs, static fn (string $dir): bool => !str_ends_with($dir, '/.') && !str_ends_with($dir, '/..')); + } + + public static function path2name(string $tooldir): string + { + return substr(strrchr($tooldir, '/'), 2); // 2 = Remove slash and dot + } }