public function dump(array $packages)
{
$helper = new ArchiveBuilderHelper($this->output, $this->config['archive']);
$basedir = $helper->getDirectory($this->outputDir);
$this->output->writeln(sprintf("<info>Creating local downloads in '%s'</info>", $basedir));
$format = isset($this->config['archive']['format']) ? $this->config['archive']['format'] : 'zip';
$endpoint = isset($this->config['archive']['prefix-url']) ? $this->config['archive']['prefix-url'] : $this->config['homepage'];
$includeArchiveChecksum = isset($this->config['archive']['checksum']) ? (bool) $this->config['archive']['checksum'] : true;
$composerConfig = $this->composer->getConfig();
$factory = new Factory();
/* @var \Composer\Downloader\DownloadManager $downloadManager */
$downloadManager = $this->composer->getDownloadManager();
/* @var \Composer\Package\Archiver\ArchiveManager $archiveManager */
$archiveManager = $factory->createArchiveManager($composerConfig, $downloadManager);
$archiveManager->setOverwriteFiles(false);
shuffle($packages);
$progressBar = null;
$hasStarted = false;
$verbosity = $this->output->getVerbosity();
$renderProgress = $this->input->getOption('stats') && OutputInterface::VERBOSITY_NORMAL == $verbosity;
if ($renderProgress) {
$packageCount = 0;
foreach ($packages as $package) {
if (!$helper->isSkippable($package)) {
++$packageCount;
}
}
$progressBar = new ProgressBar($this->output, $packageCount);
$progressBar->setFormat(' %current%/%max% [%bar%] %percent:3s%% - Installing %packageName% (%packageVersion%)');
}
/* @var \Composer\Package\CompletePackage $package */
foreach ($packages as $package) {
if ($helper->isSkippable($package)) {
continue;
}
if ($renderProgress) {
$progressBar->setMessage($package->getName(), 'packageName');
$progressBar->setMessage($package->getPrettyVersion(), 'packageVersion');
if (!$hasStarted) {
$progressBar->start();
$hasStarted = true;
} else {
$progressBar->display();
}
} else {
$this->output->writeln(sprintf("<info>Dumping '%s'.</info>", $package->getName()));
}
try {
if ($renderProgress) {
$this->output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
}
$intermediatePath = preg_replace('#[^a-z0-9-_/]#i', '-', $package->getName());
$packageName = $archiveManager->getPackageFilename($package);
if ('pear-library' === $package->getType()) {
// PEAR packages are archives already
$filesystem = new Filesystem();
$path = sprintf('%s/%s/%s.%s', realpath($basedir), $intermediatePath, $packageName, pathinfo($package->getDistUrl(), PATHINFO_EXTENSION));
if (!file_exists($path)) {
$downloadDir = sys_get_temp_dir() . '/composer_archiver/' . $packageName;
$filesystem->ensureDirectoryExists($downloadDir);
$downloadManager->download($package, $downloadDir, false);
$filesystem->ensureDirectoryExists(dirname($path));
$filesystem->rename($downloadDir . '/' . pathinfo($package->getDistUrl(), PATHINFO_BASENAME), $path);
$filesystem->removeDirectory($downloadDir);
}
// Set archive format to `file` to tell composer to download it as is
$archiveFormat = 'file';
} else {
$path = $archiveManager->archive($package, $format, sprintf('%s/%s', $basedir, $intermediatePath));
$archiveFormat = $format;
}
$archive = basename($path);
$distUrl = sprintf('%s/%s/%s/%s', $endpoint, $this->config['archive']['directory'], $intermediatePath, $archive);
$package->setDistType($archiveFormat);
$package->setDistUrl($distUrl);
if ($includeArchiveChecksum) {
$package->setDistSha1Checksum(hash_file('sha1', $path));
}
$package->setDistReference($package->getSourceReference());
if ($renderProgress) {
$this->output->setVerbosity($verbosity);
}
} catch (\Exception $exception) {
if ($renderProgress) {
$this->output->setVerbosity($verbosity);
}
if (!$this->skipErrors) {
throw $exception;
}
$this->output->writeln(sprintf("<error>Skipping Exception '%s'.</error>", $exception->getMessage()));
}
if ($renderProgress) {
$progressBar->advance();
}
}
if ($renderProgress) {
$progressBar->finish();
$this->output->writeln('');
}
}
/** * @param InputInterface $input The input instance * @param OutputInterface $output The output instance */ protected function execute(InputInterface $input, OutputInterface $output) { $verbose = $input->getOption('verbose'); $configFile = $input->getArgument('file'); $packagesFilter = $input->getArgument('packages'); $repositoryUrl = $input->getOption('repository-url'); $skipErrors = (bool) $input->getOption('skip-errors'); if ($repositoryUrl !== null && count($packagesFilter) > 0) { throw new \InvalidArgumentException('The arguments "package" and "repository-url" can not be used together.'); } // load auth.json authentication information and pass it to the io interface $io = $this->getIO(); $io->loadConfiguration($this->getConfiguration()); if (preg_match('{^https?://}i', $configFile)) { $rfs = new RemoteFilesystem($io); $contents = $rfs->getContents(parse_url($configFile, PHP_URL_HOST), $configFile, false); $config = JsonFile::parseJson($contents, $configFile); } else { $file = new JsonFile($configFile); if (!$file->exists()) { $output->writeln('<error>File not found: ' . $configFile . '</error>'); return 1; } $config = $file->read(); } // disable packagist by default unset(Config::$defaultRepositories['packagist']); if (!($outputDir = $input->getArgument('output-dir'))) { $outputDir = isset($config['output-dir']) ? $config['output-dir'] : null; } if (null === $outputDir) { throw new \InvalidArgumentException('The output dir must be specified as second argument or be configured inside ' . $input->getArgument('file')); } $composer = $this->getApplication()->getComposer(true, $config); $packageSelection = new PackageSelection($output, $outputDir, $config, $skipErrors); if ($repositoryUrl !== null) { $packageSelection->setRepositoryFilter($repositoryUrl); } else { $packageSelection->setPackagesFilter($packagesFilter); } $packages = $packageSelection->select($composer, $verbose); if (isset($config['archive']['directory'])) { $downloads = new ArchiveBuilder($output, $outputDir, $config, $skipErrors); $downloads->setComposer($composer); $downloads->dump($packages); } if ($packageSelection->hasFilterForPackages()) { // in case of an active package filter we need to load the dumped packages.json and merge the // updated packages in $oldPackages = $packageSelection->load(); $packages += $oldPackages; ksort($packages); } $packagesBuilder = new PackagesBuilder($output, $outputDir, $config, $skipErrors); $packagesBuilder->dump($packages); if ($htmlView = !$input->getOption('no-html-output')) { $htmlView = !isset($config['output-html']) || $config['output-html']; } if ($htmlView) { $web = new WebBuilder($output, $outputDir, $config, $skipErrors); $web->setRootPackage($composer->getPackage()); $web->dump($packages); } }