diff --git a/src/Composer/Composer.php b/src/Composer/Composer.php index 39d995db2..6a9b40805 100644 --- a/src/Composer/Composer.php +++ b/src/Composer/Composer.php @@ -14,6 +14,7 @@ namespace Composer; use Composer\Repository\ComposerRepository; use Composer\Repository\PlatformRepository; +use Composer\Repository\GitRepository; /** * @author Jordi Boggiano @@ -72,22 +73,27 @@ class Composer return $this->repositories; } - public function createRepository($type, $url) + public function createRepository($type, $spec) { - $url = rtrim($url, '/'); + if (is_string($spec)) { + $spec = array('url' => $spec); + } + $spec['url'] = rtrim($spec['url'], '/'); switch ($type) { case 'git-bare': - case 'git-package': case 'git-multi': throw new \Exception($type.' repositories not supported yet'); break; + case 'git': + return new GitRepository($spec['url']); + case 'platform': return new PlatformRepository; case 'composer': - return new ComposerRepository($url); + return new ComposerRepository($spec['url']); } } } \ No newline at end of file diff --git a/src/Composer/Repository/GitRepository.php b/src/Composer/Repository/GitRepository.php new file mode 100644 index 000000000..696b1fc6d --- /dev/null +++ b/src/Composer/Repository/GitRepository.php @@ -0,0 +1,99 @@ + + * 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\Package\MemoryPackage; +use Composer\Package\BasePackage; +use Composer\Package\Link; +use Composer\Package\LinkConstraint\VersionConstraint; + +/** + * @author Jordi Boggiano + */ +class GitRepository extends ArrayRepository +{ + protected $packages; + + public function __construct($url) + { + $this->url = $url; + } + + protected function initialize() + { + parent::initialize(); + + if (preg_match('#^(?:https?|git(?:\+ssh)?|ssh)://#', $this->url)) { + // check if the repo is on github.com, read the composer.json file & branch/tags out of it + // otherwise, maybe we have to clone the repo to figure out what's in it + throw new \Exception('Not implemented yet'); + } elseif (file_exists($this->url)) { + if (!file_exists($this->url.'/composer.json')) { + throw new \InvalidArgumentException('The repository at url '.$this->url.' does not contain a composer.json file.'); + } + $config = json_decode(file_get_contents($this->url.'/composer.json'), true); + if (!$config) { + throw new \UnexpectedValueException('Config file could not be parsed: '.$this->url.'/composer.json. Probably a JSON syntax error.'); + } + } else { + throw new \InvalidArgumentException('Could not find repository at url '.$this->url); + } + + $this->createPackage($config); + } + + // TODO code re-use + protected function createPackage($data) + { + $version = BasePackage::parseVersion($data['version']); + + $package = new MemoryPackage($data['name'], $version['version'], $version['type']); + $package->setSourceType('git'); + $package->setSourceUrl($this->url); + + if (isset($data['license'])) { + $package->setLicense($data['license']); + } + + $links = array( + 'require', + 'conflict', + 'provide', + 'replace', + 'recommend', + 'suggest', + ); + foreach ($links as $link) { + if (isset($data[$link])) { + $method = 'set'.$link.'s'; + $package->{$method}($this->createLinks($data['name'], $link.'s', $data[$link])); + } + } + $this->addPackage($package); + } + + // TODO code re-use + protected function createLinks($name, $description, $linkSpecs) + { + $links = array(); + foreach ($linkSpecs as $dep => $ver) { + preg_match('#^([>=<~]*)([\d.]+.*)$#', $ver, $match); + if (!$match[1]) { + $match[1] = '='; + } + $constraint = new VersionConstraint($match[1], $match[2]); + $links[] = new Link($name, $dep, $constraint, $description); + } + return $links; + } +} \ No newline at end of file