protected function initialize() { parent::initialize(); $versionParser = new VersionParser(); try { $prettyVersion = PHP_VERSION; $version = $versionParser->normalize($prettyVersion); } catch (\UnexpectedValueException $e) { $prettyVersion = preg_replace('#^(.+?)(-.+)?$#', '$1', PHP_VERSION); $version = $versionParser->normalize($prettyVersion); } $php = new MemoryPackage('php', $version, $prettyVersion); $php->setDescription('The PHP interpreter'); parent::addPackage($php); foreach (get_loaded_extensions() as $name) { if (in_array($name, array('standard', 'Core'))) { continue; } $reflExt = new \ReflectionExtension($name); try { $prettyVersion = $reflExt->getVersion(); $version = $versionParser->normalize($prettyVersion); } catch (\UnexpectedValueException $e) { $prettyVersion = '0'; $version = $versionParser->normalize($prettyVersion); } $ext = new MemoryPackage('ext-' . $name, $version, $prettyVersion); $ext->setDescription('The ' . $name . ' PHP extension'); parent::addPackage($ext); } }
/** * Tests memory package versioning semantics * @dataProvider providerVersioningSchemes */ public function testMemoryPackageHasExpectedVersioningSemantics($name, $version) { $versionParser = new VersionParser(); $normVersion = $versionParser->normalize($version); $package = new MemoryPackage($name, $normVersion, $version); $this->assertEquals($version, $package->getPrettyVersion()); $this->assertEquals($normVersion, $package->getVersion()); }
public function testIncludePathsAreAppendedInAutoloadFile() { $package = new MemoryPackage('a', '1.0', '1.0'); $packages = array(); $a = new MemoryPackage("a/a", "1.0", "1.0"); $a->setIncludePaths(array("lib/")); $packages[] = $a; $this->repository->expects($this->once())->method("getPackages")->will($this->returnValue($packages)); mkdir($this->vendorDir . "/composer", 0777, true); $this->generator->dump($this->repository, $package, $this->im, $this->vendorDir . "/composer"); $oldIncludePath = get_include_path(); require $this->vendorDir . "/autoload.php"; $this->assertEquals($oldIncludePath . PATH_SEPARATOR . $this->vendorDir . "/a/a/lib", get_include_path()); set_include_path($oldIncludePath); }
protected function initialize() { parent::initialize(); $versionParser = new VersionParser(); try { $prettyVersion = PHP_VERSION; $version = $versionParser->normalize($prettyVersion); } catch (\UnexpectedValueException $e) { $prettyVersion = preg_replace('#^(.+?)(-.+)?$#', '$1', PHP_VERSION); $version = $versionParser->normalize($prettyVersion); } $php = new MemoryPackage('php', $version, $prettyVersion); $php->setDescription('The PHP interpreter'); parent::addPackage($php); $loadedExtensions = get_loaded_extensions(); // Extensions scanning foreach ($loadedExtensions as $name) { if (in_array($name, array('standard', 'Core'))) { continue; } $reflExt = new \ReflectionExtension($name); try { $prettyVersion = $reflExt->getVersion(); $version = $versionParser->normalize($prettyVersion); } catch (\UnexpectedValueException $e) { $prettyVersion = '0'; $version = $versionParser->normalize($prettyVersion); } $ext = new MemoryPackage('ext-' . $name, $version, $prettyVersion); $ext->setDescription('The ' . $name . ' PHP extension'); parent::addPackage($ext); } // Another quick loop, just for possible libraries // Doing it this way to know that functions or constants exist before // relying on them. foreach ($loadedExtensions as $name) { switch ($name) { case 'curl': $curlVersion = curl_version(); $prettyVersion = $curlVersion['version']; break; case 'iconv': $prettyVersion = ICONV_VERSION; break; case 'libxml': $prettyVersion = LIBXML_DOTTED_VERSION; break; case 'openssl': $prettyVersion = preg_replace_callback('{^(?:OpenSSL\\s*)?([0-9.]+)([a-z]?).*}', function ($match) { return $match[1] . (empty($match[2]) ? '' : '.' . (ord($match[2]) - 96)); }, OPENSSL_VERSION_TEXT); break; case 'pcre': $prettyVersion = preg_replace('{^(\\S+).*}', '$1', PCRE_VERSION); break; case 'uuid': $prettyVersion = phpversion('uuid'); break; case 'xsl': $prettyVersion = LIBXSLT_DOTTED_VERSION; break; default: // None handled extensions have no special cases, skip continue 2; } try { $version = $versionParser->normalize($prettyVersion); } catch (\UnexpectedValueException $e) { continue; } $lib = new MemoryPackage('lib-' . $name, $version, $prettyVersion); $lib->setDescription('The ' . $name . ' PHP library'); parent::addPackage($lib); } }
public function load(array $config) { if (!isset($config['name'])) { throw new \UnexpectedValueException('Unknown package has no name defined (' . json_encode($config) . ').'); } if (!isset($config['version'])) { throw new \UnexpectedValueException('Package ' . $config['name'] . ' has no version defined.'); } // handle already normalized versions if (isset($config['version_normalized'])) { $version = $config['version_normalized']; } else { $version = $this->versionParser->normalize($config['version']); } $package = new Package\MemoryPackage($config['name'], $version, $config['version']); $package->setType(isset($config['type']) ? strtolower($config['type']) : 'library'); if (isset($config['target-dir'])) { $package->setTargetDir($config['target-dir']); } if (isset($config['extra']) && is_array($config['extra'])) { $package->setExtra($config['extra']); } if (isset($config['bin'])) { if (!is_array($config['bin'])) { throw new \UnexpectedValueException('Package ' . $config['name'] . '\'s bin key should be an array, ' . gettype($config['bin']) . ' given.'); } foreach ($config['bin'] as $key => $bin) { $config['bin'][$key] = ltrim($bin, '/'); } $package->setBinaries($config['bin']); } if (isset($config['scripts']) && is_array($config['scripts'])) { foreach ($config['scripts'] as $event => $listeners) { $config['scripts'][$event] = (array) $listeners; } $package->setScripts($config['scripts']); } if (!empty($config['description']) && is_string($config['description'])) { $package->setDescription($config['description']); } if (!empty($config['homepage']) && is_string($config['homepage'])) { $package->setHomepage($config['homepage']); } if (!empty($config['keywords']) && is_array($config['keywords'])) { $package->setKeywords($config['keywords']); } if (!empty($config['license'])) { $package->setLicense(is_array($config['license']) ? $config['license'] : array($config['license'])); } if (!empty($config['time'])) { try { $date = new \DateTime($config['time']); $date->setTimezone(new \DateTimeZone('UTC')); $package->setReleaseDate($date); } catch (\Exception $e) { } } if (!empty($config['authors']) && is_array($config['authors'])) { $package->setAuthors($config['authors']); } if (isset($config['installation-source'])) { $package->setInstallationSource($config['installation-source']); } if (isset($config['source'])) { if (!isset($config['source']['type']) || !isset($config['source']['url'])) { throw new \UnexpectedValueException(sprintf("package source should be specified as {\"type\": ..., \"url\": ...},\n%s given", json_encode($config['source']))); } $package->setSourceType($config['source']['type']); $package->setSourceUrl($config['source']['url']); $package->setSourceReference($config['source']['reference']); } if (isset($config['dist'])) { if (!isset($config['dist']['type']) || !isset($config['dist']['url'])) { throw new \UnexpectedValueException(sprintf("package dist should be specified as " . "{\"type\": ..., \"url\": ..., \"reference\": ..., \"shasum\": ...},\n%s given", json_encode($config['dist']))); } $package->setDistType($config['dist']['type']); $package->setDistUrl($config['dist']['url']); $package->setDistReference(isset($config['dist']['reference']) ? $config['dist']['reference'] : null); $package->setDistSha1Checksum(isset($config['dist']['shasum']) ? $config['dist']['shasum'] : null); } // check for a branch alias (dev-master => 1.0.x-dev for example) if this is a named branch if ('dev-' === substr($package->getPrettyVersion(), 0, 4) && isset($config['extra']['branch-alias']) && is_array($config['extra']['branch-alias'])) { foreach ($config['extra']['branch-alias'] as $sourceBranch => $targetBranch) { // ensure it is an alias to a -dev package if ('-dev' !== substr($targetBranch, -4)) { continue; } // normalize without -dev and ensure it's a numeric branch that is parseable $validatedTargetBranch = $this->versionParser->normalizeBranch(substr($targetBranch, 0, -4)); if ('-dev' !== substr($validatedTargetBranch, -4)) { continue; } // ensure that it is the current branch aliasing itself if (strtolower($package->getPrettyVersion()) !== strtolower($sourceBranch)) { continue; } $package->setAlias($validatedTargetBranch); $package->setPrettyAlias(preg_replace('{(\\.9{7})+}', '.x', $validatedTargetBranch)); break; } } foreach (Package\BasePackage::$supportedLinkTypes as $type => $opts) { if (isset($config[$type])) { $method = 'set' . ucfirst($opts['method']); $package->{$method}($this->loadLinksFromConfig($package, $opts['description'], $config[$type])); } } if (isset($config['suggest']) && is_array($config['suggest'])) { foreach ($config['suggest'] as $target => $reason) { if ('self.version' === trim($reason)) { $config['suggest'][$target] = $package->getPrettyVersion(); } } $package->setSuggests($config['suggest']); } if (isset($config['autoload'])) { $package->setAutoload($config['autoload']); } if (isset($config['include-path'])) { $package->setIncludePaths($config['include-path']); } if (isset($config['support'])) { $package->setSupport($config['support']); } return $package; }
/** * testNoVendorName */ public function testNoVendorName() { $installer = new Installer($this->io, $this->composer); $package = new MemoryPackage('sfPhpunitPlugin', '1.0.0', '1.0.0'); $package->setType('symfony1-plugin'); $result = $installer->getInstallPath($package); $this->assertEquals('plugins/sfPhpunitPlugin/', $result); }
public function testIncludePathsArePrependedInAutoloadFile() { $package = new MemoryPackage('a', '1.0', '1.0'); $packages = array(); $a = new MemoryPackage("a/a", "1.0", "1.0"); $a->setIncludePaths(array("lib/")); $packages[] = $a; $this->repository->expects($this->once())->method("getPackages")->will($this->returnValue($packages)); mkdir($this->vendorDir . "/composer", 0777, true); $this->generator->dump($this->config, $this->repository, $package, $this->im, "composer", false, '_11'); $oldIncludePath = get_include_path(); // suppress the class loader to avoid fatals if the class is redefined file_put_contents($this->vendorDir . '/composer/ClassLoader.php', ''); require $this->vendorDir . "/autoload.php"; $this->assertEquals($this->vendorDir . "/a/a/lib" . PATH_SEPARATOR . $oldIncludePath, get_include_path()); set_include_path($oldIncludePath); }
public function testOverrideVendorsAutoloading() { $package = new MemoryPackage('a', '1.0', '1.0'); $package->setAutoload(array('psr-0' => array('A\\B' => '/home/deveuser/local-packages/a-a/lib'))); $packages = array(); $packages[] = $a = new MemoryPackage('a/a', '1.0', '1.0'); $packages[] = $b = new MemoryPackage('b/b', '1.0', '1.0'); $a->setAutoload(array('psr-0' => array('A' => 'src/', 'A\\B' => 'lib/'))); $b->setAutoload(array('psr-0' => array('B\\Sub\\Name' => 'src/'))); $this->repository->expects($this->once())->method('getPackages')->will($this->returnValue($packages)); mkdir($this->vendorDir . '/.composer', 0777, true); $this->generator->dump($this->repository, $package, $this->im, $this->vendorDir . '/.composer'); $this->assertAutoloadFiles('override_vendors', $this->vendorDir . '/.composer'); }
public function load($config) { if (!isset($config['name'])) { throw new \UnexpectedValueException('Unknown package has no name defined (' . json_encode($config) . ').'); } if (!isset($config['version'])) { throw new \UnexpectedValueException('Package ' . $config['name'] . ' has no version defined.'); } // handle already normalized versions if (isset($config['version_normalized'])) { $version = $config['version_normalized']; } else { $version = $this->versionParser->normalize($config['version']); } $package = new Package\MemoryPackage($config['name'], $version, $config['version']); $package->setType(isset($config['type']) ? strtolower($config['type']) : 'library'); if (isset($config['target-dir'])) { $package->setTargetDir($config['target-dir']); } if (isset($config['extra']) && is_array($config['extra'])) { $package->setExtra($config['extra']); } if (isset($config['bin']) && is_array($config['bin'])) { foreach ($config['bin'] as $key => $bin) { $config['bin'][$key] = ltrim($bin, '/'); } $package->setBinaries($config['bin']); } if (isset($config['scripts']) && is_array($config['scripts'])) { foreach ($config['scripts'] as $event => $listeners) { $config['scripts'][$event] = (array) $listeners; } $package->setScripts($config['scripts']); } if (!empty($config['description']) && is_string($config['description'])) { $package->setDescription($config['description']); } if (!empty($config['homepage']) && is_string($config['homepage'])) { $package->setHomepage($config['homepage']); } if (!empty($config['keywords'])) { $package->setKeywords(is_array($config['keywords']) ? $config['keywords'] : array($config['keywords'])); } if (!empty($config['license'])) { $package->setLicense(is_array($config['license']) ? $config['license'] : array($config['license'])); } if (!empty($config['time'])) { try { $package->setReleaseDate(new \DateTime($config['time'])); } catch (\Exception $e) { } } if (!empty($config['authors']) && is_array($config['authors'])) { $package->setAuthors($config['authors']); } if (isset($config['installation-source'])) { $package->setInstallationSource($config['installation-source']); } if (isset($config['source'])) { if (!isset($config['source']['type']) || !isset($config['source']['url'])) { throw new \UnexpectedValueException(sprintf("package source should be specified as {\"type\": ..., \"url\": ...},\n%s given", json_encode($config['source']))); } $package->setSourceType($config['source']['type']); $package->setSourceUrl($config['source']['url']); $package->setSourceReference($config['source']['reference']); } elseif ($package->isDev()) { throw new \UnexpectedValueException('Dev package ' . $package . ' must have a source specified'); } if (isset($config['dist'])) { if (!isset($config['dist']['type']) || !isset($config['dist']['url'])) { throw new \UnexpectedValueException(sprintf("package dist should be specified as " . "{\"type\": ..., \"url\": ..., \"reference\": ..., \"shasum\": ...},\n%s given", json_encode($config['dist']))); } $package->setDistType($config['dist']['type']); $package->setDistUrl($config['dist']['url']); $package->setDistReference(isset($config['dist']['reference']) ? $config['dist']['reference'] : null); $package->setDistSha1Checksum(isset($config['dist']['shasum']) ? $config['dist']['shasum'] : null); } foreach ($this->supportedLinkTypes as $type => $description) { if (isset($config[$type])) { $method = 'set' . ucfirst($description); $package->{$method}($this->loadLinksFromConfig($package, $description, $config[$type])); } } if (isset($config['autoload'])) { $package->setAutoload($config['autoload']); } return $package; }
/** * Builds MemoryPackages from PEAR package definition data. * * @param ChannelInfo $channelInfo * @return MemoryPackage */ private function buildComposerPackages(ChannelInfo $channelInfo, VersionParser $versionParser) { $result = array(); foreach ($channelInfo->getPackages() as $packageDefinition) { foreach ($packageDefinition->getReleases() as $version => $releaseInfo) { try { $normalizedVersion = $versionParser->normalize($version); } catch (\UnexpectedValueException $e) { if ($this->io->isVerbose()) { $this->io->write('Could not load ' . $packageDefinition->getPackageName() . ' ' . $version . ': ' . $e->getMessage()); } continue; } $composerPackageName = $this->buildComposerPackageName($packageDefinition->getChannelName(), $packageDefinition->getPackageName()); // distribution url must be read from /r/{packageName}/{version}.xml::/r/g:text() // but this location is 'de-facto' standard $distUrl = "http://{$packageDefinition->getChannelName()}/get/{$packageDefinition->getPackageName()}-{$version}.tgz"; $requires = array(); $suggests = array(); $conflicts = array(); $replaces = array(); // alias package only when its channel matches repository channel, // cause we've know only repository channel alias if ($channelInfo->getName() == $packageDefinition->getChannelName()) { $composerPackageAlias = $this->buildComposerPackageName($channelInfo->getAlias(), $packageDefinition->getPackageName()); $aliasConstraint = new VersionConstraint('==', $normalizedVersion); $replaces[] = new Link($composerPackageName, $composerPackageAlias, $aliasConstraint, 'replaces', (string) $aliasConstraint); } // alias package with user-specified prefix. it makes private pear channels looks like composer's. if (!empty($this->vendorAlias)) { $composerPackageAlias = "{$this->vendorAlias}/{$packageDefinition->getPackageName()}"; $aliasConstraint = new VersionConstraint('==', $normalizedVersion); $replaces[] = new Link($composerPackageName, $composerPackageAlias, $aliasConstraint, 'replaces', (string) $aliasConstraint); } foreach ($releaseInfo->getDependencyInfo()->getRequires() as $dependencyConstraint) { $dependencyPackageName = $this->buildComposerPackageName($dependencyConstraint->getChannelName(), $dependencyConstraint->getPackageName()); $constraint = $versionParser->parseConstraints($dependencyConstraint->getConstraint()); $link = new Link($composerPackageName, $dependencyPackageName, $constraint, $dependencyConstraint->getType(), $dependencyConstraint->getConstraint()); switch ($dependencyConstraint->getType()) { case 'required': $requires[] = $link; break; case 'conflicts': $conflicts[] = $link; break; case 'replaces': $replaces[] = $link; break; } } foreach ($releaseInfo->getDependencyInfo()->getOptionals() as $group => $dependencyConstraints) { foreach ($dependencyConstraints as $dependencyConstraint) { $dependencyPackageName = $this->buildComposerPackageName($dependencyConstraint->getChannelName(), $dependencyConstraint->getPackageName()); $suggests[$group . '-' . $dependencyPackageName] = $dependencyConstraint->getConstraint(); } } $package = new MemoryPackage($composerPackageName, $normalizedVersion, $version); $package->setType('pear-library'); $package->setDescription($packageDefinition->getDescription()); $package->setDistType('file'); $package->setDistUrl($distUrl); $package->setAutoload(array('classmap' => array(''))); $package->setIncludePaths(array('/')); $package->setRequires($requires); $package->setConflicts($conflicts); $package->setSuggests($suggests); $package->setReplaces($replaces); $result[] = $package; } } return $result; }
public function testShouldCreatePackages() { $reader = $this->getMockBuilder('\\Composer\\Repository\\PearRepository')->disableOriginalConstructor()->getMock(); $ref = new \ReflectionMethod($reader, 'buildComposerPackages'); $ref->setAccessible(true); $channelInfo = new ChannelInfo('test.loc', 'test', array(new PackageInfo('test.loc', 'sample', 'license', 'shortDescription', 'description', array('1.0.0.1' => new ReleaseInfo('stable', new DependencyInfo(array(new DependencyConstraint('required', '> 5.2.0.0', 'php', ''), new DependencyConstraint('conflicts', '== 2.5.6.0', 'pear.php.net', 'broken')), array('*' => array(new DependencyConstraint('optional', '*', 'ext', 'xml'))))))))); $packages = $ref->invoke($reader, $channelInfo, new VersionParser()); $expectedPackage = new MemoryPackage('pear-test.loc/sample', '1.0.0.1', '1.0.0.1'); $expectedPackage->setType('pear-library'); $expectedPackage->setDistType('file'); $expectedPackage->setDescription('description'); $expectedPackage->setDistUrl("http://test.loc/get/sample-1.0.0.1.tgz"); $expectedPackage->setAutoload(array('classmap' => array(''))); $expectedPackage->setIncludePaths(array('/')); $expectedPackage->setRequires(array(new Link('pear-test.loc/sample', 'php', $this->createConstraint('>', '5.2.0.0'), 'required', '> 5.2.0.0'))); $expectedPackage->setConflicts(array(new Link('pear-test.loc/sample', 'pear-pear.php.net/broken', $this->createConstraint('==', '2.5.6.0'), 'conflicts', '== 2.5.6.0'))); $expectedPackage->setSuggests(array('*-ext-xml' => '*')); $expectedPackage->setReplaces(array(new Link('pear-test.loc/sample', 'pear-test/sample', new VersionConstraint('==', '1.0.0.1'), 'replaces', '== 1.0.0.1'))); $this->assertCount(1, $packages); $this->assertEquals($expectedPackage, $packages[0], 0, 1); }