diff --git a/src/FileFetcher.php b/src/FileFetcher.php index 4435306..34e8472 100644 --- a/src/FileFetcher.php +++ b/src/FileFetcher.php @@ -7,6 +7,7 @@ namespace DrupalComposer\DrupalScaffold; +use Composer\IO\IOInterface; use Composer\Util\Filesystem; use Composer\Util\RemoteFilesystem; @@ -17,23 +18,52 @@ class FileFetcher { */ protected $remoteFilesystem; + /** + * @var \Composer\IO\IOInterface + */ + protected $io; + + /** + * @var bool + * + * A boolean indicating if progress should be displayed. + */ + protected $progress; + protected $source; protected $filenames; protected $fs; - public function __construct(RemoteFilesystem $remoteFilesystem, $source, $filenames = []) { + public function __construct(RemoteFilesystem $remoteFilesystem, $source, IOInterface $io, $progress = TRUE) { $this->remoteFilesystem = $remoteFilesystem; + $this->io = $io; $this->source = $source; - $this->filenames = $filenames; $this->fs = new Filesystem(); + $this->progress = $progress; } - public function fetch($version, $destination) { - array_walk($this->filenames, function ($filename) use ($version, $destination) { - $url = $this->getUri($filename, $version); - $this->fs->ensureDirectoryExists($destination . '/' . dirname($filename)); - $this->remoteFilesystem->copy($url, $url, $destination . '/' . $filename); - }); + public function fetch($version, $destination, $override) { + foreach ($this->filenames as $sourceFilename => $filename) { + $target = "$destination/$filename"; + if ($override || !file_exists($target)) { + $url = $this->getUri($sourceFilename, $version); + $this->fs->ensureDirectoryExists($destination . '/' . dirname($filename)); + if ($this->progress) { + $this->io->writeError(" - $filename ($url): ", FALSE); + $this->remoteFilesystem->copy($url, $url, $target, $this->progress); + // Used to put a new line because the remote file system does not put + // one. + $this->io->writeError(''); + } + else { + $this->remoteFilesystem->copy($url, $url, $target, $this->progress); + } + } + } + } + + public function setFilenames(array $filenames) { + $this->filenames = $filenames; } protected function getUri($filename, $version) { diff --git a/src/Handler.php b/src/Handler.php index 7130732..681a54e 100644 --- a/src/Handler.php +++ b/src/Handler.php @@ -33,6 +33,13 @@ class Handler { */ protected $io; + /** + * @var bool + * + * A boolean indicating if progress should be displayed. + */ + protected $progress; + /** * @var \Composer\Package\PackageInterface */ @@ -47,6 +54,7 @@ class Handler { public function __construct(Composer $composer, IOInterface $io) { $this->composer = $composer; $this->io = $io; + $this->progress = TRUE; } /** @@ -66,6 +74,20 @@ protected function getCorePackage($operation) { return NULL; } + /** + * Get the command options. + * + * @param \Composer\Plugin\CommandEvent $event + */ + public function onCmdBeginsEvent(\Composer\Plugin\CommandEvent $event) { + if ($event->getInput()->hasOption('no-progress')) { + $this->progress = !($event->getInput()->getOption('no-progress')); + } + else { + $this->progress = TRUE; + } + } + /** * Marks scaffolding to be processed after an install or update command. * @@ -114,11 +136,12 @@ public function downloadScaffold() { $remoteFs = new RemoteFilesystem($this->io); - $fetcher = new PrestissimoFileFetcher($remoteFs, $options['source'], $files, $this->io, $this->composer->getConfig()); - $fetcher->fetch($version, $webroot); + $fetcher = new PrestissimoFileFetcher($remoteFs, $options['source'], $this->io, $this->progress, $this->composer->getConfig()); + $fetcher->setFilenames(array_combine($files, $files)); + $fetcher->fetch($version, $webroot, true); - $initialFileFetcher = new InitialFileFetcher($remoteFs, $options['source'], $this->getInitial()); - $initialFileFetcher->fetch($version, $webroot); + $fetcher->setFilenames($this->getInitial()); + $fetcher->fetch($version, $webroot, false); // Call post-scaffold scripts. $dispatcher->dispatch(self::POST_DRUPAL_SCAFFOLD_CMD); diff --git a/src/InitialFileFetcher.php b/src/InitialFileFetcher.php deleted file mode 100644 index 4b46c70..0000000 --- a/src/InitialFileFetcher.php +++ /dev/null @@ -1,23 +0,0 @@ -filenames, function ($filename, $sourceFilename) use ($version, $destination) { - $target = "$destination/$filename"; - if (!file_exists($target)) { - $url = $this->getUri($sourceFilename, $version); - $this->fs->ensureDirectoryExists($destination . '/' . dirname($filename)); - $this->remoteFilesystem->copy($url, $url, $target); - } - }); - } - -} diff --git a/src/Plugin.php b/src/Plugin.php index 73fd2a0..58a06cd 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -11,6 +11,8 @@ use Composer\Installer\PackageEvent; use Composer\Installer\PackageEvents; use Composer\IO\IOInterface; +use Composer\Plugin\CommandEvent; +use Composer\Plugin\PluginEvents; use Composer\Plugin\PluginInterface; use Composer\Script\ScriptEvents; @@ -45,9 +47,19 @@ public static function getSubscribedEvents() { //PackageEvents::POST_PACKAGE_UNINSTALL => 'postPackage', //ScriptEvents::POST_INSTALL_CMD => 'postCmd', ScriptEvents::POST_UPDATE_CMD => 'postCmd', + PluginEvents::COMMAND => 'cmdBegins', ); } + /** + * Command begins event callback. + * + * @param \Composer\Plugin\CommandEvent $event + */ + public function cmdBegins(\Composer\Plugin\CommandEvent $event) { + $this->handler->onCmdBeginsEvent($event); + } + /** * Post package event behaviour. * diff --git a/src/PrestissimoFileFetcher.php b/src/PrestissimoFileFetcher.php index a99aa1d..5f6d10e 100644 --- a/src/PrestissimoFileFetcher.php +++ b/src/PrestissimoFileFetcher.php @@ -14,37 +14,35 @@ class PrestissimoFileFetcher extends FileFetcher { - /** - * @var \Composer\IO\IOInterface - */ - protected $io; - /** * @var \Composer\Config */ protected $config; - public function __construct(\Composer\Util\RemoteFilesystem $remoteFilesystem, $source, array $filenames = [], IOInterface $io, Config $config) { - parent::__construct($remoteFilesystem, $source, $filenames); - $this->io = $io; + public function __construct(\Composer\Util\RemoteFilesystem $remoteFilesystem, $source, IOInterface $io, $progress = TRUE, Config $config) { + parent::__construct($remoteFilesystem, $source, $io, $progress); $this->config = $config; } - public function fetch($version, $destination) { + public function fetch($version, $destination, $override) { if (class_exists(CurlMulti::class)) { - $this->fetchWithPrestissimo($version, $destination); + $this->fetchWithPrestissimo($version, $destination, $override); return; } - parent::fetch($version, $destination); + parent::fetch($version, $destination, $override); } - protected function fetchWithPrestissimo($version, $destination) { + protected function fetchWithPrestissimo($version, $destination, $override) { $requests = []; - array_walk($this->filenames, function ($filename) use ($version, $destination, &$requests) { - $url = $this->getUri($filename, $version); - $this->fs->ensureDirectoryExists($destination . '/' . dirname($filename)); - $requests[] = new CopyRequest($url, $destination . '/' . $filename, false, $this->io, $this->config); - }); + + foreach ($this->filenames as $sourceFilename => $filename) { + $target = "$destination/$filename"; + if ($override || !file_exists($target)) { + $url = $this->getUri($sourceFilename, $version); + $this->fs->ensureDirectoryExists($destination . '/' . dirname($filename)); + $requests[] = new CopyRequest($url, $target, false, $this->io, $this->config); + } + } $successCnt = $failureCnt = 0; $totalCnt = count($requests); @@ -57,8 +55,10 @@ protected function fetchWithPrestissimo($version, $destination) { $result = $multi->getFinishedResults(); $successCnt += $result['successCnt']; $failureCnt += $result['failureCnt']; - foreach ($result['urls'] as $url) { - $this->io->writeError(" $successCnt/$totalCnt:\t$url", true, \Composer\IO\IOInterface::VERBOSE); + if ($this->progress) { + foreach ($result['urls'] as $url) { + $this->io->writeError(" - Downloading $successCnt/$totalCnt: $url", true); + } } } while ($multi->remain()); } diff --git a/tests/FetcherTest.php b/tests/FetcherTest.php index 0aa5972..8fdc77e 100644 --- a/tests/FetcherTest.php +++ b/tests/FetcherTest.php @@ -63,15 +63,22 @@ protected function ensureDirectoryExistsAndClear($directory) { } public function testFetch() { - $fetcher = new FileFetcher(new RemoteFilesystem(new NullIO()), 'http://cgit.drupalcode.org/drupal/plain/{path}?h={version}', ['.htaccess', 'sites/default/default.settings.php']); - $fetcher->fetch('8.1.1', $this->tmpDir); + $fetcher = new FileFetcher(new RemoteFilesystem(new NullIO()), 'http://cgit.drupalcode.org/drupal/plain/{path}?h={version}', new NullIO()); + $fetcher->setFilenames([ + '.htaccess' => '.htaccess', + 'sites/default/default.settings.php' => 'sites/default/default.settings.php', + ]); + $fetcher->fetch('8.1.1', $this->tmpDir, true); $this->assertFileExists($this->tmpDir . '/.htaccess'); $this->assertFileExists($this->tmpDir . '/sites/default/default.settings.php'); } public function testInitialFetch() { - $fetcher = new InitialFileFetcher(new RemoteFilesystem(new NullIO()), 'http://cgit.drupalcode.org/drupal/plain/{path}?h={version}', ['sites/default/default.settings.php' => 'sites/default/settings.php']); - $fetcher->fetch('8.1.1', $this->tmpDir); + $fetcher = new FileFetcher(new RemoteFilesystem(new NullIO()), 'http://cgit.drupalcode.org/drupal/plain/{path}?h={version}', new NullIO()); + $fetcher->setFilenames([ + 'sites/default/default.settings.php' => 'sites/default/settings.php', + ]); + $fetcher->fetch('8.1.1', $this->tmpDir, false); $this->assertFileExists($this->tmpDir . '/sites/default/settings.php'); } }