From 033a61692a43ae7d085a6448ae52a4afdae767f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFck=20Piera?= Date: Tue, 27 Feb 2024 10:02:14 +0100 Subject: [PATCH] Display spinner when downloading and remove vendor directory when no remote --- src/Console/ApplicationFactory.php | 2 +- src/Remote/Composer.php | 18 +++++++++++++++--- src/Remote/Importer.php | 13 +++++++++++++ src/Remote/Listener/RemoteImportListener.php | 11 +++++++++-- .../RemoteImportRemoteTasksTest.php.output.txt | 9 +++++++++ tests/TaskTestCase.php | 2 ++ 6 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/Console/ApplicationFactory.php b/src/Console/ApplicationFactory.php index 96f9974c..867638ad 100644 --- a/src/Console/ApplicationFactory.php +++ b/src/Console/ApplicationFactory.php @@ -52,7 +52,7 @@ public static function create(): SymfonyApplication $cache = new FilesystemAdapter(directory: $cacheDir); $logger = new Logger('castor', [], [new ProcessProcessor()]); $fs = new Filesystem(); - $importer = new Importer($logger, new Composer($logger)); + $importer = new Importer($logger, new Composer($logger), $fs); $eventDispatcher = new EventDispatcher(logger: $logger); $eventDispatcher->addSubscriber(new UpdateCastorListener( $cache, diff --git a/src/Remote/Composer.php b/src/Remote/Composer.php index dcd55b03..077a151d 100644 --- a/src/Remote/Composer.php +++ b/src/Remote/Composer.php @@ -2,9 +2,11 @@ namespace Castor\Remote; +use Castor\GlobalHelper; use Castor\PathHelper; use Castor\Remote\Exception\ComposerError; use Psr\Log\LoggerInterface; +use Symfony\Component\Console\Helper\ProgressIndicator; use Symfony\Component\Process\Process; class Composer @@ -66,14 +68,24 @@ public function require(string $package, string $version): void $requirements = []; } - $this->run('require', $package . ':' . $version); + $progressIndicator = new ProgressIndicator(GlobalHelper::getOutput(), null, 100, ['⠏', '⠛', '⠹', '⢸', '⣰', '⣤', '⣆', '⡇']); + $progressIndicator->start(sprintf('Downloading remote package "%s"', $package)); + + $this->run(['require', $package . ':' . $version], callback: function () use ($progressIndicator) { + $progressIndicator->advance(); + }); + + $progressIndicator->finish(sprintf('Imported package "%s"', $package)); $requirements[$package] = $version; $this->writeJsonFile(PathHelper::getRoot() . self::PATH_CASTOR_REQUIREMENTS, $requirements); } - private function run(string ...$args): void + /** + * @param string[] $args + */ + private function run(array $args, callable $callback): void { $this->logger->debug('Running Composer command.', [ 'args' => implode(' ', $args), @@ -85,7 +97,7 @@ private function run(string ...$args): void $process->setEnv([ 'COMPOSER_VENDOR_DIR' => $dir, ]); - $process->run(); + $process->run($callback); if (!$process->isSuccessful()) { throw new ComposerError('The Composer process failed: ' . $process->getErrorOutput()); diff --git a/src/Remote/Importer.php b/src/Remote/Importer.php index 29f2d74f..599a5dfc 100644 --- a/src/Remote/Importer.php +++ b/src/Remote/Importer.php @@ -9,6 +9,7 @@ use Castor\Remote\Exception\ImportError; use Castor\Remote\Exception\InvalidImportFormat; use Psr\Log\LoggerInterface; +use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Process\ExecutableFinder; /** @internal */ @@ -17,6 +18,7 @@ class Importer public function __construct( private readonly LoggerInterface $logger, private readonly Composer $composer, + private readonly Filesystem $filesystem, ) { } @@ -77,6 +79,17 @@ public function reset(): void ]); } + public function cleanIfNoRemotes(): void + { + $json = $this->composer->getConfiguration(); + + if (\count($json['require'] ?? []) > 0) { + return; + } + + $this->filesystem->remove(PathHelper::getRoot() . Composer::VENDOR_DIR); + } + /** * @param ?array{ * url?: string, diff --git a/src/Remote/Listener/RemoteImportListener.php b/src/Remote/Listener/RemoteImportListener.php index 75fc6087..ff9893c4 100644 --- a/src/Remote/Listener/RemoteImportListener.php +++ b/src/Remote/Listener/RemoteImportListener.php @@ -2,6 +2,7 @@ namespace Castor\Remote\Listener; +use Castor\Event\AfterApplicationInitializationEvent; use Castor\Event\BeforeApplicationInitializationEvent; use Castor\Remote\Importer; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -16,12 +17,18 @@ public function __construct( public static function getSubscribedEvents(): array { return [ - BeforeApplicationInitializationEvent::class => 'onInitialize', + BeforeApplicationInitializationEvent::class => 'beforeInitialize', + AfterApplicationInitializationEvent::class => 'afterInitialize', ]; } - public function onInitialize(BeforeApplicationInitializationEvent $event): void + public function beforeInitialize(BeforeApplicationInitializationEvent $event): void { $this->importer->reset(); } + + public function afterInitialize(AfterApplicationInitializationEvent $event): void + { + $this->importer->cleanIfNoRemotes(); + } } diff --git a/tests/Examples/Remote/RemoteImportRemoteTasksTest.php.output.txt b/tests/Examples/Remote/RemoteImportRemoteTasksTest.php.output.txt index 41083c96..959db5dd 100644 --- a/tests/Examples/Remote/RemoteImportRemoteTasksTest.php.output.txt +++ b/tests/Examples/Remote/RemoteImportRemoteTasksTest.php.output.txt @@ -1,3 +1,12 @@ + Downloading remote package "pyrech/castor-example" + Imported package "pyrech/castor-example" + + Downloading remote package "pyrech/castor-example-package-not-published" + Imported package "pyrech/castor-example-package-not-published" + + Downloading remote package "pyrech/foobar" + Imported package "pyrech/foobar" + Hello from example! =================== diff --git a/tests/TaskTestCase.php b/tests/TaskTestCase.php index 9bd7a45a..0030a229 100644 --- a/tests/TaskTestCase.php +++ b/tests/TaskTestCase.php @@ -25,6 +25,8 @@ public function runTask(array $args, ?string $cwd = null, bool $needRemote = fal if (!$needRemote) { $extraEnv['CASTOR_NO_REMOTE'] = 1; + } elseif (file_exists($castorRequirementsFile = __DIR__ . '/../.castor/vendor/castor-requirements.json')) { + unlink($castorRequirementsFile); } if ($coverage) {