/** * Get best version to install * * @param OutputInterface $output * @return string * @throws InvalidArgumentException */ protected function getBestVersion(OutputInterface $output) { $this->log($output, 'Determining best version to install'); // Find all versions for the given recipe $available = Composer::getLibraryVersions($this->getCommandRunner($output), $this->getRecipe()); // Choose based on available and preference $versions = $this->getVersion()->getComposerVersions(); foreach ($versions as $version) { if (in_array($version, $available)) { return $version; } } throw new InvalidArgumentException("Could not install project from version " . $this->version->getValue()); }
/** * Compare versions. * * (4.0.0 > 4.0.0-alpha1, 4.0.0 < 4.0.1) * * @param Version $other * @return int negative for smaller version, 0 for equal, positive for later version */ public function compareTo(Version $other) { $diff = $this->getMajor() - $other->getMajor(); if ($diff) { return $diff; } $diff = $this->getMinor() - $other->getMinor(); if ($diff) { return $diff; } $diff = $this->getPatch() - $other->getPatch(); if ($diff) { return $diff; } // Compare stability $diff = $this->compareStabliity($this->getStability(), $other->getStability()); if ($diff) { return $diff; } // Fall back to stability type (e.g. alpha1 vs alpha2) $diff = $this->getStabilityVersion() - $other->getStabilityVersion(); return $diff; }
/** * Commit changes to git * * @param OutputInterface $output * @param Library $library * @param Version $version * @param string $path */ public function commitChanges(OutputInterface $output, Library $library, Version $version, $path) { $repo = $library->getRepository(); $versionName = $version->getValue(); $repo->run("add", array($path)); $status = $repo->run("status"); if (stripos($status, 'Changes to be committed:')) { $repo->run("commit", array("-m", "Added {$versionName} changelog")); } }
/** * ComposerConstraint constructor. * @param string $constraint * @param Version $parentVersion * @param string $name Name of dependency */ public function __construct($constraint, $parentVersion = null, $name = null) { $this->setValue($constraint); if ($constraint === 'self.version') { if (!$parentVersion instanceof Version) { throw new InvalidArgumentException("{$name} dependency self.version given with missing parent version"); } $this->isSelfVersion = true; $this->minVersion = $parentVersion; $this->maxVersion = $parentVersion; return; } // Check if matches explicit version (4.0.0, no semver flags) if (Version::parse($constraint)) { $this->minVersion = new Version($constraint); $this->maxVersion = new Version($constraint); return; } // Parse type $parsed = static::parse($constraint); if (!$parsed) { throw new InvalidArgumentException("Composer constraint {$constraint} for {$name} is not semver-compatible. " . "E.g. ^4.0, self.version, or a fixed version"); } // From version ignores modifier, includes alpha1 tag. :) if (empty($parsed['stability'])) { $fromStability = ''; } else { $fromStabilityVersion = isset($parsed['stabilityVersion']) ? $parsed['stabilityVersion'] : ''; $fromStability = '-' . $parsed['stability'] . $fromStabilityVersion; } $from = sprintf("%d.%d.%d%s", $parsed['major'], isset($parsed['minor']) ? $parsed['minor'] : '0', isset($parsed['patch']) ? $parsed['patch'] : '0', $fromStability); // Semver to if ($parsed['type'] === '^') { $to = $parsed['major'] . '.99999.99999'; } elseif (isset($parsed['patch']) && strlen($parsed['patch'])) { // ~x.y.z $to = $parsed['major'] . '.' . $parsed['minor'] . '.99999'; } elseif (isset($parsed['minor']) && strlen($parsed['minor'])) { // ~x.y $to = $parsed['major'] . '.99999.99999'; } else { // ~y $to = '99999.99999.99999'; } $this->minVersion = new Version($from); $this->maxVersion = new Version($to); }
/** * Determine if the current branch should be changed * * @param string $currentBranch Note, this can be empty * @param Version $version * @return bool Whether the branch should be changed */ protected function canCheckout($currentBranch, Version $version) { // Get expected major and minor branches $minorBranch = $version->getMajor() . "." . $version->getMinor(); // Already on ideal branch if ($currentBranch === $minorBranch) { return false; } // Branch if doing beta / rc / stable release if ($version->isStable() || in_array($version->getStability(), ['beta', 'rc'])) { return true; } return false; }
/** * Get command to suggest to publish this release * * @param Version $version * @param Project $project * @return string Command name */ protected function getPublishCommand($version, $project) { $command = 'cow release:publish ' . $version->getValue() . ' ' . $project->getName(); switch ($this->output->getVerbosity()) { case Output::VERBOSITY_DEBUG: $command .= ' -vvv'; break; case Output::VERBOSITY_VERY_VERBOSE: $command .= ' -vv'; break; case Output::VERBOSITY_VERBOSE: $command .= ' -v'; break; } return $command; }
/** * @dataProvider dependencyProvider() * @param string $version * @param string $stability * @param string $constraint */ public function testGetConstraint($version, $stability, $constraint) { $versionObj = new Version($version); $this->assertEquals($constraint, $versionObj->getConstraint($stability)); }
/** * Get changelog path * * @param Version $version * @return string */ public function getChangelogPath(Version $version) { $cowData = $this->getCowData(); // If generating via markdown committed to source control if (empty($cowData['changelog-path'])) { return null; } $path = Format::formatString($cowData['changelog-path'], ['stability' => $version->getStability(), 'stabilityVersion' => $version->getStabilityVersion(), 'major' => $version->getMajor(), 'minor' => $version->getMinor(), 'patch' => $version->getPatch(), 'version' => $version->getValue(), 'versionStable' => $version->getValueStable()]); // Collapse duplicate // return str_replace('//', '/', $path); }
/** * Update the version of a selected library * * @param OutputInterface $output * @param InputInterface $input * @param LibraryRelease $selectedVersion */ protected function reviewLibraryVersion(OutputInterface $output, InputInterface $input, LibraryRelease $selectedVersion) { $question = new Question("Please enter a new version to release for <info>" . $selectedVersion->getLibrary()->getName() . "</info>: ", $selectedVersion->getVersion()); $newVersionName = $this->getQuestionHelper()->ask($input, $output, $question); // If version is valid, update and return if (Version::parse($newVersionName)) { // Warn if upgrade-only and selected version isn't an existing tag if ($selectedVersion->getLibrary()->isUpgradeOnly()) { $tags = $selectedVersion->getLibrary()->getTags(); if (!array_key_exists($newVersionName, $tags)) { $this->log($output, "This library is marked as upgrade-only; {$newVersionName} is not an existing tag", 'error'); $this->reviewLibraryVersion($output, $input, $selectedVersion); return; } } // Update release version $newVersion = new Version($newVersionName); $this->modifyLibraryReleaseVersion($selectedVersion, $newVersion); // Save modified plan to cache immediately $this->getProject()->saveCachedPlan($this->getReleasePlan()); return; } // If error, repeat $this->log($output, "Invalid version {$newVersionName}; Please enter a tag in w.x.y(-[rc|alpha|beta][z]) format", "error"); $this->reviewLibraryVersion($output, $input, $selectedVersion); }