diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 9234f46f8..72a4699a1 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -281,6 +281,7 @@ class Factory $rm->setRepositoryClass('git', 'Composer\Repository\VcsRepository'); $rm->setRepositoryClass('svn', 'Composer\Repository\VcsRepository'); $rm->setRepositoryClass('hg', 'Composer\Repository\VcsRepository'); + $rm->setRepositoryClass('artifact', 'Composer\Repository\ArtifactRepository'); return $rm; } diff --git a/src/Composer/Repository/ArtifactRepository.php b/src/Composer/Repository/ArtifactRepository.php new file mode 100644 index 000000000..4cf2b4b52 --- /dev/null +++ b/src/Composer/Repository/ArtifactRepository.php @@ -0,0 +1,78 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Repository; + +/** + * @author Serge Smertin + */ +use Composer\IO\IOInterface; +use Composer\Config; +use Composer\Json\JsonFile; +use Composer\Package\Loader\LoaderInterface; +use Composer\Package\Version\VersionParser; +use Composer\Package\Loader\ArrayLoader; + +class ArtifactRepository extends ArrayRepository +{ + protected $path; + + /** @var LoaderInterface */ + protected $loader; + + public function __construct(array $repoConfig, IOInterface $io, Config $config, array $drivers = null) + { + $this->path = $repoConfig['url']; + } + + protected function initialize() + { + parent::initialize(); + $this->versionParser = new VersionParser; + if (!$this->loader) { + $this->loader = new ArrayLoader($this->versionParser); + } + + $this->getDirectoryPackages($this->path); + } + + private function getDirectoryPackages($path) + { + foreach(new \RecursiveDirectoryIterator($path) as $file) { + /* @var $file \SplFileInfo */ + if(!$file->isFile()) { + continue; + } + + $package = $this->getComposerInformation($file); + if(!$package) { + // @todo add log + continue; + } + + $package = $this->loader->load($package); + + $this->addPackage($package); + } + } + + private function getComposerInformation(\SplFileInfo $file) + { + $config = "zip://{$file->getPathname()}#composer.json"; + $json = @file_get_contents($config); + if(!$json) { + return false; + } + + return JsonFile::parseJson($json, $config); + } +} diff --git a/tests/Composer/Test/Repository/ArtifactRepositoryTest.php b/tests/Composer/Test/Repository/ArtifactRepositoryTest.php new file mode 100644 index 000000000..af412420e --- /dev/null +++ b/tests/Composer/Test/Repository/ArtifactRepositoryTest.php @@ -0,0 +1,36 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Repository; + +use Composer\Test\TestCase; +use Composer\IO\NullIO; +use Composer\Config; +use Composer\Package\Package; + +class ArtifactRepositoryTest extends TestCase +{ + public function testExtractsConfigsFromZipArchives() { + $expectedPackages = array( + 'vendor0/package0-0.0.1', + 'vendor1/package2-4.3.2', + ); + + $coordinates = array('type' => 'artifact', 'url' => __DIR__ . '/Fixtures/artifacts'); + $repo = new ArtifactRepository($coordinates, new NullIO(), new Config()); + + $foundPackages = array_map(function(Package $package) { + return "{$package->getPrettyName()}-{$package->getPrettyVersion()}"; + }, $repo->getPackages()); + + $this->assertEquals($expectedPackages, $foundPackages); + } +} diff --git a/tests/Composer/Test/Repository/Fixtures/artifacts/package0.zip b/tests/Composer/Test/Repository/Fixtures/artifacts/package0.zip new file mode 100644 index 000000000..855c6a64d Binary files /dev/null and b/tests/Composer/Test/Repository/Fixtures/artifacts/package0.zip differ diff --git a/tests/Composer/Test/Repository/Fixtures/artifacts/package2.zip b/tests/Composer/Test/Repository/Fixtures/artifacts/package2.zip new file mode 100644 index 000000000..671058059 Binary files /dev/null and b/tests/Composer/Test/Repository/Fixtures/artifacts/package2.zip differ