Install a package as a specific version

@param		string	$packageName	Name of the package to install
@param		string	$constraint		Version constraint string - see https://getcomposer.org/doc/articles/versions.md
@return	boolean	Indicates success or frailure
328137
public static function installPackage($packageName, $constraint = 'dev-master')
	{
		if (self::_requirePackage($packageName, $constraint))
		{
			self::_resetComposer();
			return self::_updatePackage($packageName);
		}
		return false;
	}
1357401
def versions(name, constraint = Semverse::DEFAULT_CONSTRAINT)
      constraint = Semverse::Constraint.coerce(constraint)

      if constraint == Semverse::DEFAULT_CONSTRAINT
        @artifacts_by_name[name]
      else
        @artifacts_by_name[name].select do |artifact|
          constraint.satisfies?(artifact.version)
        end
      end
    end
1224120
public function isVersioningNecessary($con = null)
    {
        if ($this->alreadyInSave) {
            return false;
        }

        if ($this->enforceVersion) {
            return true;
        }

        if (ChildIndexEngineIndexQuery::isVersioningEnabled() && ($this->isNew() || $this->isModified()) || $this->isDeleted()) {
            return true;
        }

        return false;
    }
680527
public function visitDateTimeFormatConstraint(StringValue\DateTimeFormatConstraint $constraint)
    {
        if (!$this->formatValidationEnabled()) {
            return $this->createResult();
        }

        $value = $this->currentValue();
        if (!$value instanceof Value\StringValue) {
            return $this->createResult();
        }

        $formats = array(
            DateTime::ISO8601,
            'Y-m-d\TH:i:s\Z',
            'Y-m-d\TH:i:sP',
        );
        foreach ($formats as $format) {
            if (false !== DateTime::createFromFormat($format, $value->value())) {
                return $this->createResult();
            }
        }

        return $this->createSingleIssueResult($constraint);
    }
811303
protected function satisfyVersion(Link $require, $normalizedVersion)
    {
        $constraintSame = $this->versionParser->parseConstraints($normalizedVersion);
        $sameVersion = (bool) $require->getConstraint()->matches($constraintSame);

        $consNormalizedVersion = FilterUtil::getVersionConstraint($normalizedVersion, $this->versionParser);
        $constraint = FilterUtil::getVersionConstraint($consNormalizedVersion->getPrettyString(), $this->versionParser);

        return (bool) $require->getConstraint()->matches($constraint) || $sameVersion;
    }
561484
private function parseConstraint($constraint)
    {
        if (preg_match('{^([^,\s]+?)@(' . implode('|', self::$stabilities) . ')$}i', $constraint, $match)) {
            $constraint = $match[1];
            if ($match[2] !== 'stable') {
                $stabilityModifier = $match[2];
            }
        }

        if (preg_match('{^v?[xX*](\.[xX*])*$}i', $constraint)) {
            return array(new EmptyConstraint());
        }

        $versionRegex = 'v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.(\d++))?' . self::$modifierRegex . '(?:\+[^\s]+)?';

        // Tilde Range
        //
        // Like wildcard constraints, unsuffixed tilde constraints say that they must be greater than the previous
        // version, to ensure that unstable instances of the current version are allowed. However, if a stability
        // suffix is added to the constraint, then a >= match on the current version is used instead.
        if (preg_match('{^~>?' . $versionRegex . '$}i', $constraint, $matches)) {
            if (substr($constraint, 0, 2) === '~>') {
                throw new \UnexpectedValueException(
                    'Could not parse version constraint ' . $constraint . ': ' .
                    'Invalid operator "~>", you probably meant to use the "~" operator'
                );
            }

            // Work out which position in the version we are operating at
            if (isset($matches[4]) && '' !== $matches[4] && null !== $matches[4]) {
                $position = 4;
            } elseif (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
                $position = 3;
            } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
                $position = 2;
            } else {
                $position = 1;
            }

            // Calculate the stability suffix
            $stabilitySuffix = '';
            if (empty($matches[5]) && empty($matches[7])) {
                $stabilitySuffix .= '-dev';
            }

            $lowVersion = $this->normalize(substr($constraint . $stabilitySuffix, 1));
            $lowerBound = new Constraint('>=', $lowVersion);

            // For upper bound, we increment the position of one more significance,
            // but highPosition = 0 would be illegal
            $highPosition = max(1, $position - 1);
            $highVersion = $this->manipulateVersionString($matches, $highPosition, 1) . '-dev';
            $upperBound = new Constraint('<', $highVersion);

            return array(
                $lowerBound,
                $upperBound,
            );
        }

        // Caret Range
        //
        // Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple.
        // In other words, this allows patch and minor updates for versions 1.0.0 and above, patch updates for
        // versions 0.X >=0.1.0, and no updates for versions 0.0.X
        if (preg_match('{^\^' . $versionRegex . '($)}i', $constraint, $matches)) {
            // Work out which position in the version we are operating at
            if ('0' !== $matches[1] || '' === $matches[2] || null === $matches[2]) {
                $position = 1;
            } elseif ('0' !== $matches[2] || '' === $matches[3] || null === $matches[3]) {
                $position = 2;
            } else {
                $position = 3;
            }

            // Calculate the stability suffix
            $stabilitySuffix = '';
            if (empty($matches[5]) && empty($matches[7])) {
                $stabilitySuffix .= '-dev';
            }

            $lowVersion = $this->normalize(substr($constraint . $stabilitySuffix, 1));
            $lowerBound = new Constraint('>=', $lowVersion);

            // For upper bound, we increment the position of one more significance,
            // but highPosition = 0 would be illegal
            $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
            $upperBound = new Constraint('<', $highVersion);

            return array(
                $lowerBound,
                $upperBound,
            );
        }

        // X Range
        //
        // Any of X, x, or * may be used to "stand in" for one of the numeric values in the [major, minor, patch] tuple.
        // A partial version range is treated as an X-Range, so the special character is in fact optional.
        if (preg_match('{^v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.[xX*])++$}', $constraint, $matches)) {
            if (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
                $position = 3;
            } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
                $position = 2;
            } else {
                $position = 1;
            }

            $lowVersion = $this->manipulateVersionString($matches, $position) . '-dev';
            $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';

            if ($lowVersion === '0.0.0.0-dev') {
                return array(new Constraint('<', $highVersion));
            }

            return array(
                new Constraint('>=', $lowVersion),
                new Constraint('<', $highVersion),
            );
        }

        // Hyphen Range
        //
        // Specifies an inclusive set. If a partial version is provided as the first version in the inclusive range,
        // then the missing pieces are replaced with zeroes. If a partial version is provided as the second version in
        // the inclusive range, then all versions that start with the supplied parts of the tuple are accepted, but
        // nothing that would be greater than the provided tuple parts.
        if (preg_match('{^(?P<from>' . $versionRegex . ') +- +(?P<to>' . $versionRegex . ')($)}i', $constraint, $matches)) {
            // Calculate the stability suffix
            $lowStabilitySuffix = '';
            if (empty($matches[6]) && empty($matches[8])) {
                $lowStabilitySuffix = '-dev';
            }

            $lowVersion = $this->normalize($matches['from']);
            $lowerBound = new Constraint('>=', $lowVersion . $lowStabilitySuffix);

            $empty = function ($x) {
                return ($x === 0 || $x === '0') ? false : empty($x);
            };

            if ((!$empty($matches[11]) && !$empty($matches[12])) || !empty($matches[14]) || !empty($matches[16])) {
                $highVersion = $this->normalize($matches['to']);
                $upperBound = new Constraint('<=', $highVersion);
            } else {
                $highMatch = array('', $matches[10], $matches[11], $matches[12], $matches[13]);
                $highVersion = $this->manipulateVersionString($highMatch, $empty($matches[11]) ? 1 : 2, 1) . '-dev';
                $upperBound = new Constraint('<', $highVersion);
            }

            return array(
                $lowerBound,
                $upperBound,
            );
        }

        // Basic Comparators
        if (preg_match('{^(<>|!=|>=?|<=?|==?)?\s*(.*)}', $constraint, $matches)) {
            try {
                $version = $this->normalize($matches[2]);

                if (!empty($stabilityModifier) && $this->parseStability($version) === 'stable') {
                    $version .= '-' . $stabilityModifier;
                } elseif ('<' === $matches[1] || '>=' === $matches[1]) {
                    if (!preg_match('/-' . self::$modifierRegex . '$/', strtolower($matches[2]))) {
                        if (substr($matches[2], 0, 4) !== 'dev-') {
                            $version .= '-dev';
                        }
                    }
                }

                return array(new Constraint($matches[1] ?: '=', $version));
            } catch (\Exception $e) {
            }
        }

        $message = 'Could not parse version constraint ' . $constraint;
        if (isset($e)) {
            $message .= ': ' . $e->getMessage();
        }

        throw new \UnexpectedValueException($message);
    }
410761
public static function isMatch($constraint, Version $version, &$failures = array())
    {
        foreach (explode(',', $constraint) as $constraintExpression) {
            $c = self::fromString($constraintExpression);
            if (!$c->match($version)) {
                $failures[]= "Constraint '$constraintExpression' failed";
            }
        }
        return count($failures) === 0;
    }
399982
public static function create(Package $package, $version)
    {
        $result = new static();
        $result->package = $package;
        $result->version = (string) $version;
        $result->createdOn = new DateTime();
        $result->updatedOn = new DateTime();

        return $result;
    }
255345
public function setVersion(string $version): bool
    {
        $supportedVersions = $this->getSupportedVersions();

        if (in_array($version, $supportedVersions, true)) {
            $this->_version = $version;

            return true;
        } else {
            throw new NotSupportedException("Version `$version` is not supported in " . __CLASS__ . "! Supported versions: " . implode(' - ', $supportedVersions));
        }
    }
1303735
public function validate($value, Constraint $constraint)
    {
        $result = $this->repository->hasOtherNodeWithSameParentAndOrder(
            $value->getParentId(),
            $value->getOrder(),
            $value->getNodeId(),
            $value->getSiteId()
        );

        if (true === $result) {
            $this->context->buildViolation($constraint->message)->addViolation();
        }
    }
510238
public function findByHandleAndVersion($packageHandle, $packageVersion)
    {
        $result = null;
        $packageHandle = (string) $packageHandle;
        if ($packageHandle !== '') {
            $packageVersion = (string) $packageVersion;
            if ($packageVersion !== '') {
                $list = $this->createQueryBuilder('v')
                    ->innerJoin(Package::class, 'p', Expr\Join::WITH, 'v.package = p.id')
                    ->where('p.handle = :handle')->setParameter('handle', $packageHandle)
                    ->andWhere('v.version = :version')->setParameter('version', $packageVersion)
                    ->setMaxResults(1)
                    ->getQuery()->execute();
                if (!empty($list)) {
                    $result = $list[0];
                }
            }
        }

        return $result;
    }
365110
public function requirePackage($package_name, $package_version, $options = ['dev' => FALSE]) {

    /** @var \Robo\Task\Composer\RequireDependency $task */
    $task = $this->taskComposerRequire()
      ->printOutput(TRUE)
      ->printMetadata(TRUE)
      ->dir($this->getConfigValue('repo.root'))
      ->interactive($this->input()->isInteractive())
      ->setVerbosityThreshold(VerbosityThresholdInterface::VERBOSITY_VERBOSE);
    if ($options['dev']) {
      $task->dev(TRUE);
    }
    if ($package_version) {
      $task->dependency($package_name, $package_version);
    }
    else {
      $task->dependency($package_name);
    }
    $result = $task->run();

    if (!$result->wasSuccessful()) {
      $this->logger->error("An error occurred while requiring {$package_name}.");
      $this->say("This is likely due to an incompatibility with your existing packages or memory exhaustion. See full error output above.");
      $confirm = $this->confirm("Should BLT attempt to update all of your Composer packages in order to find a compatible version?");
      if ($confirm) {
        $command = "composer require '{$package_name}:{$package_version}' --no-update ";
        if ($options['dev']) {
          $command .= "--dev ";
        }
        $command .= "&& composer update";
        $task = $this->taskExec($command)
          ->printOutput(TRUE)
          ->printMetadata(TRUE)
          ->dir($this->getConfigValue('repo.root'))
          ->interactive($this->input()->isInteractive())
          ->setVerbosityThreshold(VerbosityThresholdInterface::VERBOSITY_VERBOSE);
        ;
        $result = $task->run();
        if (!$result->wasSuccessful()) {
          throw new BltException("Unable to install {$package_name} package.");
        }
      }
      else {
        // @todo Revert previous file changes.
        throw new BltException("Unable to install {$package_name} package.");
      }
    }

    return $result;
  }
111326
private function findUpgradeNotes($packageName, $fromVersion)
    {
        if (preg_match('/^([0-9]\.[0-9]+\.?[0-9]*)/', $fromVersion, $m)) {
            $fromVersionMajor = $m[1];
        } else {
            $fromVersionMajor = $fromVersion;
        }

        $upgradeFile = $this->_vendorDir . '/' . $packageName . '/UPGRADE.md';
        if (!is_file($upgradeFile) || !is_readable($upgradeFile)) {
            return false;
        }
        $lines = preg_split('~\R~', file_get_contents($upgradeFile));
        $relevantLines = [];
        $consuming = false;
        // whether an exact match on $fromVersion has been encountered
        $foundExactMatch = false;
        foreach($lines as $line) {
            if (preg_match('/^Upgrade from Yii ([0-9]\.[0-9]+\.?[0-9\.]*)/i', $line, $matches)) {
                if ($matches[1] === $fromVersion) {
                    $foundExactMatch = true;
                }
                if (version_compare($matches[1], $fromVersion, '<') && ($foundExactMatch || version_compare($matches[1], $fromVersionMajor, '<'))) {
                    break;
                }
                $consuming = true;
            }
            if ($consuming) {
                $relevantLines[] = $line;
            }
        }
        return $relevantLines;
    }
752161
public function findPackageByName($vendor, $packageName = '')
    {
        if ($packageName === '') {
            if (strpos($vendor, '/') === false) {
                throw new Exception('Invalid package name');
            }
            list($vendor, $packageName) = explode('/', $vendor);
        }

        return $this->makeRequest("/packages/{$vendor}/{$packageName}.json");
    }
91890
protected function matchesCakeVersion($matcher, $version)
    {
        if (class_exists('Composer\Semver\Constraint\MultiConstraint')) {
            $multiClass = 'Composer\Semver\Constraint\MultiConstraint';
            $constraintClass = 'Composer\Semver\Constraint\Constraint';
        } else {
            $multiClass = 'Composer\Package\LinkConstraint\MultiConstraint';
            $constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint';
        }

        $repositoryManager = $this->composer->getRepositoryManager();
        if ($repositoryManager) {
            $repos = $repositoryManager->getLocalRepository();
            if (!$repos) {
                return false;
            }
            $cake3 = new $multiClass(array(
                new $constraintClass($matcher, $version),
                new $constraintClass('!=', '9999999-dev'),
            ));
            $pool = new Pool('dev');
            $pool->addRepository($repos);
            $packages = $pool->whatProvides('cakephp/cakephp');
            foreach ($packages as $package) {
                $installed = new $constraintClass('=', $package->getVersion());
                if ($cake3->matches($installed)) {
                    return true;
                }
            }
        }
        return false;
    }
565490
public function add($key, Constraint\ConstraintInterface $constraint)
    {
        if (empty($this->constraints[$key])) {
            $this->constraints[$key] = [];
        }
        $this->constraints[$key][] = $constraint;

        return $this;
    }
376100
public function getComponentVersion( $componentName )
    {
        $root = $this->xml->deps->packages->package;

        foreach ( $root as $package )
        {
            if ( (string) $package['name'] == $componentName )
            {
                return (string) $package['version'];
            }
        }
        return false;
    }