Skip to content

Commit

Permalink
Display spinner when downloading and remove vendor directory when no …
Browse files Browse the repository at this point in the history
…remote
  • Loading branch information
pyrech committed Feb 27, 2024
1 parent 65b9d9d commit e5b6e61
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 7 deletions.
1 change: 0 additions & 1 deletion doc/going-further/extending-castor/remote-imports.md
Expand Up @@ -85,7 +85,6 @@ import('package://organization/package', source: [
> standard `composer.json` to your repository and import your newly created
> package by using the `composer://` scheme and the `vcs` argument.
<<<<<<< HEAD
## Import only a specific file

No matter where does the package come from (Composer package, git repository,
Expand Down
2 changes: 1 addition & 1 deletion src/Console/ApplicationFactory.php
Expand Up @@ -50,7 +50,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 RemoteImportSubscriber($importer));

Expand Down
18 changes: 15 additions & 3 deletions src/Remote/Composer.php
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand All @@ -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());
Expand Down
11 changes: 9 additions & 2 deletions src/Remote/EventSubscriber/RemoteImportSubscriber.php
Expand Up @@ -2,6 +2,7 @@

namespace Castor\Remote\EventSubscriber;

use Castor\Event\AfterApplicationInitializationEvent;
use Castor\Event\BeforeApplicationInitializationEvent;
use Castor\Remote\Importer;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
Expand All @@ -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();
}
}
13 changes: 13 additions & 0 deletions src/Remote/Importer.php
Expand Up @@ -8,6 +8,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 */
Expand All @@ -16,6 +17,7 @@ class Importer
public function __construct(
private readonly LoggerInterface $logger,
private readonly Composer $composer,
private readonly Filesystem $filesystem,
) {
}

Expand Down Expand Up @@ -73,6 +75,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,
Expand Down
@@ -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!
===================
Expand Down
2 changes: 2 additions & 0 deletions tests/TaskTestCase.php
Expand Up @@ -25,6 +25,8 @@ public function runTask(array $args, ?string $cwd = null, bool $needRemote = fal

if (!$needRemote) {
$extraEnv['CASTOR_NO_REMOTE'] = 1;
} else {
unlink(__DIR__ . '/../.castor/vendor/castor-requirements.json');
}

if ($coverage) {
Expand Down

0 comments on commit e5b6e61

Please sign in to comment.