示例#1
0
 /**
  * Builds the archives of the repository.
  *
  * @param array $packages List of packages to dump
  */
 public function dump(array $packages)
 {
     $helper = new ArchiveBuilderHelper($this->output, $this->config['archive']);
     $directory = $helper->getDirectory($this->outputDir);
     $this->output->writeln(sprintf("<info>Creating local downloads in '%s'</info>", $directory));
     $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 = Factory::createConfig();
     $factory = new Factory();
     $io = new ConsoleIO($this->input, $this->output, $this->helperSet);
     $io->loadConfiguration($composerConfig);
     /* @var \Composer\Downloader\DownloadManager $downloadManager */
     $downloadManager = $factory->createDownloadManager($io, $composerConfig);
     /* @var \Composer\Package\Archiver\ArchiveManager $archiveManager */
     $archiveManager = $factory->createArchiveManager($composerConfig, $downloadManager);
     $archiveManager->setOverwriteFiles(false);
     shuffle($packages);
     /* @var \Composer\Package\CompletePackage $package */
     foreach ($packages as $package) {
         if ($helper->isSkippable($package)) {
             continue;
         }
         $this->output->writeln(sprintf("<info>Dumping '%s'.</info>", $package->getName()));
         try {
             if ('pear-library' === $package->getType()) {
                 // PEAR packages are archives already
                 $filesystem = new Filesystem();
                 $packageName = $archiveManager->getPackageFilename($package);
                 $path = realpath($directory) . '/' . $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($directory);
                     $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, $directory);
                 $archiveFormat = $format;
             }
             $archive = basename($path);
             $distUrl = sprintf('%s/%s/%s', $endpoint, $this->config['archive']['directory'], $archive);
             $package->setDistType($archiveFormat);
             $package->setDistUrl($distUrl);
             if ($includeArchiveChecksum) {
                 $package->setDistSha1Checksum(hash_file('sha1', $path));
             }
             $package->setDistReference($package->getSourceReference());
         } catch (\Exception $exception) {
             if (!$this->skipErrors) {
                 throw $exception;
             }
             $this->output->writeln(sprintf("<error>Skipping Exception '%s'.</error>", $exception->getMessage()));
         }
     }
 }
 /**
  * @param PackageInterface $initial
  * @param PackageInterface $target
  */
 protected function updateCode(PackageInterface $initial, PackageInterface $target)
 {
     $initialDownloadPath = $this->getInstallPath($initial);
     $targetDownloadPath = $this->getInstallPath($target);
     if ($targetDownloadPath !== $initialDownloadPath) {
         // if the target and initial dirs intersect, we force a remove + install
         // to avoid the rename wiping the target dir as part of the initial dir cleanup
         if (substr($initialDownloadPath, 0, strlen($targetDownloadPath)) === $targetDownloadPath || substr($targetDownloadPath, 0, strlen($initialDownloadPath)) === $initialDownloadPath) {
             $this->removeCode($initial);
             $this->installCode($target);
             return;
         }
         $this->filesystem->rename($initialDownloadPath, $targetDownloadPath);
     }
     $this->downloadManager->update($initial, $target, $targetDownloadPath);
 }
    /**
     * Dumps runonce file to the target file given in the constructor.
     *
     * @throws \RuntimeException If the combined runonce file exists but is not writable.
     *
     * @return void
     */
    public function dump()
    {
        if (empty($this->files)) {
            return;
        }
        $buffer = <<<'PHP'
<?php

$runonce = function(array $files, $delete = false) {
    foreach ($files as $file) {
        try {
            include $file;
        } catch (\Exception $e) {}

        $relpath = str_replace(TL_ROOT . DIRECTORY_SEPARATOR, '', $file);

        if ($delete && !unlink($file)) {
            throw new \Exception(
                'The file ' . $relpath . ' cannot be deleted. ' .
                'Please remove the file manually and correct the file permission settings on your server.'
            );
        }
    }
};

PHP;
        if (file_exists($this->targetFile)) {
            if (!is_writable($this->targetFile) || !is_file($this->targetFile)) {
                throw new \RuntimeException(sprintf('Runonce file "%s" exists but is not writable.', $this->targetFile));
            }
            $current = str_replace('.php', '_' . substr(md5(mt_rand()), 0, 8) . '.php', $this->targetFile);
            $this->filesystem->rename($this->targetFile, $current);
            $buffer .= "\n\$runonce(array('" . $current . "'), true)\n";
        }
        $buffer .= "\n\$runonce(" . var_export(array_unique($this->files), true) . ");\n";
        $this->filesystem->ensureDirectoryExists(dirname($this->targetFile));
        if (false === file_put_contents($this->targetFile, $buffer)) {
            throw new \RuntimeException(sprintf('Could not write runonce file to "%s"', $this->targetFile));
        }
        $this->files = [];
    }
示例#4
0
 /**
  * Writes includes JSON Files.
  *
  * @param array $packages List of packages to dump
  *
  * @return array Definition of "includes" block for packages.json
  */
 private function dumpPackageIncludeJson(array $packages)
 {
     $repo = array('packages' => array());
     $dumper = new ArrayDumper();
     foreach ($packages as $package) {
         $repo['packages'][$package->getName()][$package->getPrettyVersion()] = $dumper->dump($package);
     }
     // dump to temporary file
     $tempFilename = $this->outputDir . '/$include.json';
     $repoJson = new JsonFile($tempFilename);
     $repoJson->write($repo);
     // rename file accordingly
     $includeFileHash = hash_file('sha1', $tempFilename);
     $includeFileName = str_replace('{sha1}', $includeFileHash, $this->includeFileName);
     $fs = new Filesystem();
     $fs->ensureDirectoryExists(dirname($this->outputDir . '/' . $includeFileName));
     $fs->rename($tempFilename, $this->outputDir . '/' . $includeFileName);
     $this->output->writeln("<info>Wrote packages json {$includeFileName}</info>");
     $includes = array($includeFileName => array('sha1' => $includeFileHash));
     return $includes;
 }
示例#5
0
 /**
  * Create an archive of the specified package.
  *
  * @param  PackageInterface          $package   The package to archive
  * @param  string                    $format    The format of the archive (zip, tar, ...)
  * @param  string                    $targetDir The directory where to build the archive
  * @param  string|null               $fileName  The relative file name to use for the archive, or null to generate
  *                                              the package name. Note that the format will be appended to this name
  * @throws \InvalidArgumentException
  * @throws \RuntimeException
  * @return string                    The path of the created archive
  */
 public function archive(PackageInterface $package, $format, $targetDir, $fileName = null)
 {
     if (empty($format)) {
         throw new \InvalidArgumentException('Format must be specified');
     }
     // Search for the most appropriate archiver
     $usableArchiver = null;
     foreach ($this->archivers as $archiver) {
         if ($archiver->supports($format, $package->getSourceType())) {
             $usableArchiver = $archiver;
             break;
         }
     }
     // Checks the format/source type are supported before downloading the package
     if (null === $usableArchiver) {
         throw new \RuntimeException(sprintf('No archiver found to support %s format', $format));
     }
     $filesystem = new Filesystem();
     if (null === $fileName) {
         $packageName = $this->getPackageFilename($package);
     } else {
         $packageName = $fileName;
     }
     // Archive filename
     $filesystem->ensureDirectoryExists($targetDir);
     $target = realpath($targetDir) . '/' . $packageName . '.' . $format;
     $filesystem->ensureDirectoryExists(dirname($target));
     if (!$this->overwriteFiles && file_exists($target)) {
         return $target;
     }
     if ($package instanceof RootPackageInterface) {
         $sourcePath = realpath('.');
     } else {
         // Directory used to download the sources
         $sourcePath = sys_get_temp_dir() . '/composer_archive' . uniqid();
         $filesystem->ensureDirectoryExists($sourcePath);
         // Download sources
         $this->downloadManager->download($package, $sourcePath);
         // Check exclude from downloaded composer.json
         if (file_exists($composerJsonPath = $sourcePath . '/composer.json')) {
             $jsonFile = new JsonFile($composerJsonPath);
             $jsonData = $jsonFile->read();
             if (!empty($jsonData['archive']['exclude'])) {
                 $package->setArchiveExcludes($jsonData['archive']['exclude']);
             }
         }
     }
     // Create the archive
     $tempTarget = sys_get_temp_dir() . '/composer_archive' . uniqid() . '.' . $format;
     $filesystem->ensureDirectoryExists(dirname($tempTarget));
     $archivePath = $usableArchiver->archive($sourcePath, $tempTarget, $format, $package->getArchiveExcludes());
     $filesystem->rename($archivePath, $target);
     // cleanup temporary download
     if (!$package instanceof RootPackageInterface) {
         $filesystem->removeDirectory($sourcePath);
     }
     $filesystem->remove($tempTarget);
     return $target;
 }
示例#6
0
 /**
  * @param array           $config   Directory where to create the downloads in, prefix-url, etc..
  * @param array           $packages
  * @param InputInterface  $input
  * @param OutputInterface $output
  * @param string          $outputDir
  * @param bool            $skipErrors   If true, any exception while dumping a package will be ignored.
  *
  * @return void
  */
 private function dumpDownloads(array $config, array $packages, InputInterface $input, OutputInterface $output, $outputDir, $skipErrors)
 {
     if (isset($config['archive']['absolute-directory'])) {
         $directory = $config['archive']['absolute-directory'];
     } else {
         $directory = sprintf('%s/%s', $outputDir, $config['archive']['directory']);
     }
     $output->writeln(sprintf("<info>Creating local downloads in '%s'</info>", $directory));
     $format = isset($config['archive']['format']) ? $config['archive']['format'] : 'zip';
     $endpoint = isset($config['archive']['prefix-url']) ? $config['archive']['prefix-url'] : $config['homepage'];
     $skipDev = isset($config['archive']['skip-dev']) ? (bool) $config['archive']['skip-dev'] : false;
     $whitelist = isset($config['archive']['whitelist']) ? (array) $config['archive']['whitelist'] : array();
     $blacklist = isset($config['archive']['blacklist']) ? (array) $config['archive']['blacklist'] : array();
     $includeArchiveChecksum = isset($config['archive']['checksum']) ? (bool) $config['archive']['checksum'] : true;
     $composerConfig = Factory::createConfig();
     $factory = new Factory();
     $io = new ConsoleIO($input, $output, $this->getApplication()->getHelperSet());
     $io->loadConfiguration($composerConfig);
     /* @var \Composer\Downloader\DownloadManager $downloadManager */
     $downloadManager = $factory->createDownloadManager($io, $composerConfig);
     /* @var \Composer\Package\Archiver\ArchiveManager $archiveManager */
     $archiveManager = $factory->createArchiveManager($composerConfig, $downloadManager);
     $archiveManager->setOverwriteFiles(false);
     shuffle($packages);
     /* @var \Composer\Package\CompletePackage $package */
     foreach ($packages as $package) {
         if ('metapackage' === $package->getType()) {
             continue;
         }
         $name = $package->getName();
         if (true === $skipDev && true === $package->isDev()) {
             $output->writeln(sprintf("<info>Skipping '%s' (is dev)</info>", $name));
             continue;
         }
         $names = $package->getNames();
         if ($whitelist && !array_intersect($whitelist, $names)) {
             $output->writeln(sprintf("<info>Skipping '%s' (is not in whitelist)</info>", $name));
             continue;
         }
         if ($blacklist && array_intersect($blacklist, $names)) {
             $output->writeln(sprintf("<info>Skipping '%s' (is in blacklist)</info>", $name));
             continue;
         }
         $output->writeln(sprintf("<info>Dumping '%s'.</info>", $name));
         try {
             if ('pear-library' === $package->getType()) {
                 // PEAR packages are archives already
                 $filesystem = new Filesystem();
                 $packageName = $archiveManager->getPackageFilename($package);
                 $path = realpath($directory) . '/' . $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($directory);
                     $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, $directory);
                 $archiveFormat = $format;
             }
             $archive = basename($path);
             $distUrl = sprintf('%s/%s/%s', $endpoint, $config['archive']['directory'], $archive);
             $package->setDistType($archiveFormat);
             $package->setDistUrl($distUrl);
             if ($includeArchiveChecksum) {
                 $package->setDistSha1Checksum(hash_file('sha1', $path));
             }
             $package->setDistReference($package->getSourceReference());
         } catch (\Exception $exception) {
             if (!$skipErrors) {
                 throw $exception;
             }
             $output->writeln(sprintf("<error>Skipping Exception '%s'.</error>", $exception->getMessage()));
         }
     }
 }
示例#7
0
 /**
  * {@inheritdoc}
  */
 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('');
     }
 }