public function resolveFeatureBranch(Event $event) { if (empty($this->featureBranchRepositories)) { $this->io->write('No feature branches configured, continuing!'); return; } $package = $this->composer->getPackage(); if ($package->isDev()) { $featureBranchConstraint = new Constraint('=', $this->versionParser->normalize($package->getVersion())); $featureBranchConstraint->setPrettyString($package->getVersion()); $requires = $package->getRequires(); $this->io->write(sprintf("<info>Checking for feature branch '%s'</info>", $featureBranchConstraint->getPrettyString())); foreach ($requires as $key => $require) { if ($this->hasFeatureBranch($require, $featureBranchConstraint)) { $requires[$key] = new Link($require->getSource(), $require->getTarget(), $featureBranchConstraint, 'requires', $featureBranchConstraint->getPrettyString()); } else { $fallbackBranch = $this->getFallbackBranch($require); if ($fallbackBranch !== false) { $fallbackConstraint = new Constraint('=', $this->versionParser->normalize($fallbackBranch)); $fallbackConstraint->setPrettyString($fallbackBranch); $requires[$key] = new Link($require->getSource(), $require->getTarget(), $fallbackConstraint, 'requires', $fallbackConstraint->getPrettyString()); } } $this->io->write(''); } $package->setRequires($requires); } }
/** * @param string $coreVersion Current version of core */ public function __construct($coreVersion) { $this->versionParser = new VersionParser(); try { $this->coreVersion = new VersionConstraint('==', $this->versionParser->normalize($coreVersion)); } catch (UnexpectedValueException $e) { // Non-parsable version, don't fatal. } }
/** * Tests memory package marshalling/serialization semantics * @dataProvider providerVersioningSchemes */ public function testPackageHasExpectedMarshallingSemantics($name, $version) { $versionParser = new VersionParser(); $normVersion = $versionParser->normalize($version); $package = new Package($name, $normVersion, $version); $this->assertEquals(strtolower($name) . '-' . $normVersion, (string) $package); }
/** * @dataProvider getRecommendedRequireVersionPackages */ public function testFindRecommendedRequireVersion($prettyVersion, $isDev, $stability, $expectedVersion, $branchAlias = null) { $pool = $this->createMockPool(); $versionSelector = new VersionSelector($pool); $versionParser = new VersionParser(); $package = $this->getMock('\Composer\Package\PackageInterface'); $package->expects($this->any()) ->method('getPrettyVersion') ->will($this->returnValue($prettyVersion)); $package->expects($this->any()) ->method('getVersion') ->will($this->returnValue($versionParser->normalize($prettyVersion))); $package->expects($this->any()) ->method('isDev') ->will($this->returnValue($isDev)); $package->expects($this->any()) ->method('getStability') ->will($this->returnValue($stability)); $branchAlias = $branchAlias === null ? array() : array('branch-alias' => array($prettyVersion => $branchAlias)); $package->expects($this->any()) ->method('getExtra') ->will($this->returnValue($branchAlias)); $recommended = $versionSelector->findRecommendedRequireVersion($package); // assert that the recommended version is what we expect $this->assertEquals($expectedVersion, $recommended); }
private function guessSvnVersion(array $packageConfig, $path) { SvnUtil::cleanEnv(); // try to fetch current version from svn if (0 === $this->process->execute('svn info --xml', $output, $path)) { $trunkPath = isset($packageConfig['trunk-path']) ? preg_quote($packageConfig['trunk-path'], '#') : 'trunk'; $branchesPath = isset($packageConfig['branches-path']) ? preg_quote($packageConfig['branches-path'], '#') : 'branches'; $tagsPath = isset($packageConfig['tags-path']) ? preg_quote($packageConfig['tags-path'], '#') : 'tags'; $urlPattern = '#<url>.*/(' . $trunkPath . '|(' . $branchesPath . '|' . $tagsPath . ')/(.*))</url>#'; if (preg_match($urlPattern, $output, $matches)) { if (isset($matches[2]) && ($branchesPath === $matches[2] || $tagsPath === $matches[2])) { // we are in a branches path $version = $this->versionParser->normalizeBranch($matches[3]); $prettyVersion = 'dev-' . $matches[3]; if ('9999999-dev' === $version) { $version = $prettyVersion; } return array('version' => $version, 'commit' => '', 'pretty_version' => $prettyVersion); } $prettyVersion = trim($matches[1]); $version = $this->versionParser->normalize($prettyVersion); return array('version' => $version, 'commit' => '', 'pretty_version' => $prettyVersion); } } }
/** * Checks a composer.lock file. * * @param string $lock The path to the composer.lock file * * @return array Result array * * @throws \InvalidArgumentException When the output format is unsupported * @throws \RuntimeException When the lock file does not exist * @throws \RuntimeException When curl does not work or is unavailable */ public function check($lock) { if (is_dir($lock) && file_exists($lock . '/composer.lock')) { $lock = $lock . '/composer.lock'; } elseif (preg_match('/composer\\.json$/', $lock)) { $lock = str_replace('composer.json', 'composer.lock', $lock); } if (!is_file($lock)) { throw new \RuntimeException('Lock file does not exist.'); } $results = array(); $client = new Client(); $vp = new VersionParser(); $data = json_decode(file_get_contents($lock), 1); foreach ($data['packages'] as $package) { $name = $package['name']; $status = 'found'; $localVersion = $vp->normalize($package['version']); $localStatus = $this->parseStatus($localVersion); $stableVersion = 0; $stableStatus = ''; $devVersion = 0; $devStatus = ''; $remoteData = null; try { $response = $client->get("https://packagist.org/packages/{$name}.json"); $body = $response->getBody(); $statusCode = $response->getStatusCode(); if (200 === $statusCode) { $remoteData = json_decode($body, true); } else { $status = 'error'; } } catch (\Exception $e) { $status = 'error'; } if ($remoteData) { foreach ($remoteData['package']['versions'] as $versionName => $versionData) { if ($this->isStable($versionData['version_normalized']) && Comparator::greaterThan($versionData['version_normalized'], $stableVersion)) { $stableVersion = $versionData['version_normalized']; $stableStatus = $this->diffVersion($localVersion, $stableVersion); } } foreach ($remoteData['package']['versions'] as $versionName => $versionData) { if ($this->isTaggedDev($versionData['version_normalized']) && Comparator::greaterThan($versionData['version_normalized'], $devVersion) && Comparator::greaterThan($versionData['version_normalized'], $stableVersion) && ($localVersion === '9999999-dev' || Comparator::greaterThan($versionData['version_normalized'], $localVersion))) { $devVersion = $versionData['version_normalized']; $devStatus = $this->diffVersion($localVersion, $devVersion); } } } else { $stableVersion = 'Not found'; $stableStatus = 'error'; $devVersion = 'Not found'; $devStatus = 'error'; } $results[$name] = array('name' => $name, 'status' => $status, 'localVersion' => $localVersion, 'localStatus' => $localStatus, 'stableVersion' => $stableVersion, 'stableStatus' => $stableStatus, 'devVersion' => $devVersion, 'devStatus' => $devStatus); } return $results; }
private function validateTag($version) { try { return $this->versionParser->normalize($version); } catch (Exception $e) { } return false; }
private function isNormalisible($refName) { try { $this->versionParser->normalize($refName); return true; } catch (UnexpectedValueException $e) { // this shouldnt happen, means branches are in release list return false; } }
/** * @param array $install [name => version, name => version, ...] * @return bool */ public function install(array $install) { $this->addPackages($install); $refresh = []; $versionParser = new VersionParser(); foreach ($install as $name => $version) { $normalized = $versionParser->normalize($version); $refresh[] = new Package($name, $normalized, $version); } $this->composerUpdate(array_keys($install), $refresh); $this->writeConfig(); }
public function testWhatProvides() { $repo = $this->getMockBuilder('Composer\\Repository\\ComposerRepository')->disableOriginalConstructor()->setMethods(array('fetchFile'))->getMock(); $cache = $this->getMockBuilder('Composer\\Cache')->disableOriginalConstructor()->getMock(); $cache->expects($this->any())->method('sha256')->will($this->returnValue(false)); $properties = array('cache' => $cache, 'loader' => new ArrayLoader(), 'providerListing' => array('a' => array('sha256' => 'xxx')), 'providersUrl' => 'https://dummy.test.link/to/%package%/file'); foreach ($properties as $property => $value) { $ref = new \ReflectionProperty($repo, $property); $ref->setAccessible(true); $ref->setValue($repo, $value); } $repo->expects($this->any())->method('fetchFile')->will($this->returnValue(array('packages' => array(array(array('uid' => 1, 'name' => 'a', 'version' => 'dev-master', 'extra' => array('branch-alias' => array('dev-master' => '1.0.x-dev')))), array(array('uid' => 2, 'name' => 'a', 'version' => 'dev-develop', 'extra' => array('branch-alias' => array('dev-develop' => '1.1.x-dev')))), array(array('uid' => 3, 'name' => 'a', 'version' => '0.6')))))); $pool = $this->getMock('Composer\\DependencyResolver\\Pool'); $pool->expects($this->any())->method('isPackageAcceptable')->will($this->returnValue(true)); $versionParser = new VersionParser(); $repo->setRootAliases(array('a' => array($versionParser->normalize('0.6') => array('alias' => 'dev-feature', 'alias_normalized' => $versionParser->normalize('dev-feature')), $versionParser->normalize('1.1.x-dev') => array('alias' => '1.0', 'alias_normalized' => $versionParser->normalize('1.0'))))); $packages = $repo->whatProvides($pool, 'a'); $this->assertCount(7, $packages); $this->assertEquals(array('1', '1-alias', '2', '2-alias', '2-root', '3', '3-root'), array_keys($packages)); $this->assertInstanceOf('Composer\\Package\\AliasPackage', $packages['2-root']); $this->assertSame($packages['2'], $packages['2-root']->getAliasOf()); $this->assertSame($packages['2'], $packages['2-alias']->getAliasOf()); }
/** * @param array $install [name => version, name => version, ...] * @param bool $packagist * @param bool $writeConfig * @param bool $preferSource * @return bool */ public function install(array $install, $packagist = false, $writeConfig = true, $preferSource = false) { $this->addPackages($install); $refresh = []; $versionParser = new VersionParser(); foreach ($install as $name => $version) { try { $normalized = $versionParser->normalize($version); $refresh[] = new Package($name, $normalized, $version); } catch (\UnexpectedValueException $e) { } } $this->composerUpdate(array_keys($install), $refresh, $packagist, $preferSource); if ($writeConfig) { $this->writeConfig(); } }
public static function Construct(IOInterface $io) { $repo = new ArrayRepository(); try { $web_folder = Locator::getWebFolderPath(); $version_file = $web_folder . '/intranet/setup/_init/version.txt'; if (!file_exists($version_file)) { throw new \Exception("No version.txt for core found - assuming framework is not installed"); } $version_data = file($version_file); $core_version = $version_data[1]; $normalizer = new VersionParser(); $core_version_normalized = $normalizer->normalize($core_version); $io->write("Detected core version {$core_version} ({$core_version_normalized})"); $core_package = new Package(FrameworkInstallerV8::PACKAGE_NAME, $core_version_normalized, $core_version); $repo->addPackage($core_package); } catch (\Exception $e) { $io->write($e->getMessage()); // if can't determine location of 'web' folder, not adding the core package therefore letting // composer install it } return $repo; }
protected function initialize() { parent::initialize(); $versionParser = new VersionParser(); // Add each of the override versions as options. // Later we might even replace the extensions instead. foreach ($this->overrides as $override) { // Check that it's a platform package. if (!preg_match(self::PLATFORM_PACKAGE_REGEX, $override['name'])) { throw new \InvalidArgumentException('Invalid platform package name in config.platform: ' . $override['name']); } $version = $versionParser->normalize($override['version']); $package = new CompletePackage($override['name'], $version, $override['version']); $package->setDescription('Package overridden via config.platform'); $package->setExtra(array('config.platform' => true)); parent::addPackage($package); } $prettyVersion = PluginInterface::PLUGIN_API_VERSION; $version = $versionParser->normalize($prettyVersion); $composerPluginApi = new CompletePackage('composer-plugin-api', $version, $prettyVersion); $composerPluginApi->setDescription('The Composer Plugin API'); $this->addPackage($composerPluginApi); try { $prettyVersion = PHP_VERSION; $version = $versionParser->normalize($prettyVersion); } catch (\UnexpectedValueException $e) { $prettyVersion = preg_replace('#^([^~+-]+).*$#', '$1', PHP_VERSION); $version = $versionParser->normalize($prettyVersion); } $php = new CompletePackage('php', $version, $prettyVersion); $php->setDescription('The PHP interpreter'); $this->addPackage($php); if (PHP_INT_SIZE === 8) { $php64 = new CompletePackage('php-64bit', $version, $prettyVersion); $php64->setDescription('The PHP interpreter, 64bit'); $this->addPackage($php64); } $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); } $packageName = $this->buildPackageName($name); $ext = new CompletePackage($packageName, $version, $prettyVersion); $ext->setDescription('The ' . $name . ' PHP extension'); $this->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) { $prettyVersion = null; $description = 'The ' . $name . ' PHP library'; switch ($name) { case 'curl': $curlVersion = curl_version(); $prettyVersion = $curlVersion['version']; break; case 'iconv': $prettyVersion = ICONV_VERSION; break; case 'intl': $name = 'ICU'; if (defined('INTL_ICU_VERSION')) { $prettyVersion = INTL_ICU_VERSION; } else { $reflector = new \ReflectionExtension('intl'); ob_start(); $reflector->info(); $output = ob_get_clean(); preg_match('/^ICU version => (.*)$/m', $output, $matches); $prettyVersion = $matches[1]; } break; case 'libxml': $prettyVersion = LIBXML_DOTTED_VERSION; break; case 'openssl': $prettyVersion = preg_replace_callback('{^(?:OpenSSL\\s*)?([0-9.]+)([a-z]*).*}', function ($match) { if (empty($match[2])) { return $match[1]; } // OpenSSL versions add another letter when they reach Z. // e.g. OpenSSL 0.9.8zh 3 Dec 2015 if (!preg_match('{^z*[a-z]$}', $match[2])) { // 0.9.8abc is garbage return 0; } $len = strlen($match[2]); $patchVersion = ($len - 1) * 26; // All Z $patchVersion += ord($match[2][$len - 1]) - 96; return $match[1] . '.' . $patchVersion; }, OPENSSL_VERSION_TEXT); $description = 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 CompletePackage('lib-' . $name, $version, $prettyVersion); $lib->setDescription($description); $this->addPackage($lib); } if (defined('HHVM_VERSION')) { try { $prettyVersion = HHVM_VERSION; $version = $versionParser->normalize($prettyVersion); } catch (\UnexpectedValueException $e) { $prettyVersion = preg_replace('#^([^~+-]+).*$#', '$1', HHVM_VERSION); $version = $versionParser->normalize($prettyVersion); } $hhvm = new CompletePackage('hhvm', $version, $prettyVersion); $hhvm->setDescription('The HHVM Runtime (64bit)'); $this->addPackage($hhvm); } }
/** * Builds CompletePackages from PEAR package definition data. * * @param ChannelInfo $channelInfo * @param SemverVersionParser $versionParser * @return CompletePackage */ private function buildComposerPackages(ChannelInfo $channelInfo, SemverVersionParser $versionParser) { $result = array(); foreach ($channelInfo->getPackages() as $packageDefinition) { foreach ($packageDefinition->getReleases() as $version => $releaseInfo) { try { $normalizedVersion = $versionParser->normalize($version); } catch (\UnexpectedValueException $e) { $this->io->writeError('Could not load ' . $packageDefinition->getPackageName() . ' ' . $version . ': ' . $e->getMessage(), true, IOInterface::VERBOSE); 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 $urlBits = parse_url($this->url); $scheme = isset($urlBits['scheme']) && 'https' === $urlBits['scheme'] && extension_loaded('openssl') ? 'https' : 'http'; $distUrl = "{$scheme}://{$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 Constraint('==', $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) && ($this->vendorAlias != 'pear-' . $channelInfo->getAlias() || $channelInfo->getName() != $packageDefinition->getChannelName())) { $composerPackageAlias = "{$this->vendorAlias}/{$packageDefinition->getPackageName()}"; $aliasConstraint = new Constraint('==', $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 CompletePackage($composerPackageName, $normalizedVersion, $version); $package->setType('pear-library'); $package->setDescription($packageDefinition->getDescription()); $package->setLicense(array($packageDefinition->getLicense())); $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; }
private function createPackage($version) { $parser = new VersionParser(); return new Package('foo', $parser->normalize($version), $version); }