123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- <?php
- /*
- * This file is part of Packagist.
- *
- * (c) Jordi Boggiano <j.boggiano@seld.be>
- * Nils Adermann <naderman@naderman.de>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Packagist\WebBundle\Package;
- use Symfony\Component\Filesystem\Filesystem;
- use Symfony\Bridge\Doctrine\RegistryInterface;
- use Packagist\WebBundle\Entity\Version;
- /**
- * @author Jordi Boggiano <j.boggiano@seld.be>
- */
- class Dumper
- {
- /**
- * Doctrine
- * @var RegistryInterface
- */
- protected $doctrine;
- /**
- * @var Filesystem
- */
- protected $fs;
- /**
- * @var string
- */
- protected $webDir;
- /**
- * @var string
- */
- protected $cacheDir;
- /**
- * Data cache
- * @var array
- */
- private $files = array();
- /**
- * Constructor
- *
- * @param RegistryInterface $doctrine
- * @param string $webDir web root
- * @param string $cacheDir cache dir
- */
- public function __construct(RegistryInterface $doctrine, Filesystem $filesystem, $webDir, $cacheDir)
- {
- $this->doctrine = $doctrine;
- $this->fs = $filesystem;
- $this->webDir = $webDir;
- $this->cacheDir = $cacheDir . '/composer-packages-build/';
- }
- /**
- * Dump a set of packages to the web root
- *
- * @param array $packages
- * @param Boolean $force
- */
- public function dump(array $packages, $force = false)
- {
- // prepare build dir
- $webDir = realpath($this->webDir);
- $buildDir = realpath($this->cacheDir);
- $this->fs->remove($buildDir);
- $this->fs->mkdir($buildDir);
- if (!$force) {
- foreach (glob($webDir.'/packages*.json') as $file) {
- copy($file, $buildDir.'/'.basename($file));
- }
- }
- $modifiedFiles = array();
- // prepare packages in memory
- foreach ($packages as $package) {
- // clean up all versions of that package
- foreach (glob($buildDir.'/packages*.json') as $file) {
- $key = basename($file);
- $this->loadFile($file);
- if (isset($this->files[$key]['packages'][$package->getName()])) {
- unset($this->files[$key]['packages'][$package->getName()]);
- $modifiedFiles[$key] = true;
- }
- }
- // (re)write versions
- foreach ($package->getVersions() as $version) {
- $file = $buildDir.'/'.$this->getTargetFile($version);
- $modifiedFiles[basename($file)] = true;
- $this->dumpVersion($version, $file);
- }
- $package->setDumpedAt(new \DateTime);
- }
- // prepare root file
- $rootFile = $buildDir.'/packages.json';
- $this->loadFile($rootFile);
- if (!isset($this->files['packages.json']['packages'])) {
- $this->files['packages.json']['packages'] = array();
- }
- // dump files to build dir
- foreach ($modifiedFiles as $file => $dummy) {
- $this->dumpFile($file);
- $this->files['packages.json']['includes'][$file] = array('sha1' => sha1_file($file));
- }
- $this->dumpFile($rootFile);
- // put the new files in production
- foreach ($modifiedFiles as $file => $dummy) {
- rename($file, $webDir.'/'.$file);
- }
- rename($rootFile, $webDir.'/'.basename($rootFile));
- if ($force) {
- // clear files that were not created in this build
- foreach (glob($webDir.'/packages-*.json') as $file) {
- if (!isset($modifiedFiles[basename($file)])) {
- unlink($file);
- }
- }
- }
- // update dump dates
- $this->doctrine->getEntityManager()->flush();
- }
- private function loadFile($file)
- {
- $key = basename($file);
- if (isset($this->files[$key])) {
- return;
- }
- if (file_exists($file)) {
- $this->files[$key] = json_decode(file_get_contents($file), true);
- } else {
- $this->files[$key] = array();
- }
- }
- private function dumpFile($file)
- {
- $key = basename($file);
- // sort all versions and packages to make sha1 consistent
- ksort($this->files[$key]['packages']);
- foreach ($this->files[$key]['packages'] as $package => $versions) {
- ksort($this->files[$key]['packages'][$package]);
- }
- file_put_contents($file, json_encode($this->files[$key]));
- }
- private function dumpVersion(Version $version, $file)
- {
- $this->loadFile($file);
- $this->files[basename($file)]['packages'][$version->getName()][$version->getVersion()] = $version->toArray();
- }
- private function getTargetFile(Version $version)
- {
- if ($version->isDevelopment()) {
- $distribution = 16;
- return 'packages-dev-' . chr(abs(crc32($version->getName())) % $distribution + 97) . '.json';
- }
- $date = $version->getReleasedAt();
- return 'packages-' . ($date->format('Y') === date('Y') ? $date->format('Y-m') : $date->format('Y')) . '.json';
- }
- }
|