public function execute(InputInterface $input, OutputInterface $output) { $dir = $input->getOption("dir"); $dir = realpath(getcwd() . "/" . ($dir ?: "")); if (!is_dir($dir) || !is_writeable($dir)) { $output->writeln("<error>Given directory does not exists or is not writeable</error>"); return; } $fs = new Filesystem(new Adapter($dir)); $files = $fs->listContents("", true); $updates = []; $errors = 0; foreach ($files as $file) { if ($file['type'] === 'dir') { continue; } $content = $fs->read($file['path']); $content = preg_replace_callback(static::SEMVER_REGEX, function ($matches) use(&$updates, &$errors, $input) { list($prefix, $ver) = array_slice($matches, 1); try { $semver = new version($ver); } catch (\Exception $e) { $errors++; return $prefix . $ver; } if ($input->getOption("major")) { $semver->inc("major"); } elseif ($input->getOption("minor")) { $semver->inc("minor"); } elseif ($input->getOption("patch")) { $semver->inc("patch"); } else { $semver->inc("patch"); } if (!isset($updates[$ver])) { $updates[$ver] = ["count" => 0, "ver" => $semver->getVersion()]; } $updates[$ver]['count']++; return $prefix . $semver->getVersion(); }, $content); $fs->update($file['path'], $content); } foreach ($updates as $update => $count) { $output->writeln("<info>{$count['count']} files have been updated from {$update} to {$count['ver']}</info>"); } }
function testIncrementVersions() { $compare = array(array("1.2.3", "major", "2.0.0"), array("1.2.3", "minor", "1.3.0"), array("1.2.3", "patch", "1.2.4"), array("1.2.3", "build", "1.2.3-1"), array("1.2.3-4", "build", "1.2.3-5"), array("1.2.3tag", "major", "2.0.0"), array("1.2.3-tag", "major", "2.0.0"), array("1.2.3tag", "build", "1.2.3-1"), array("1.2.3-tag", "build", "1.2.3-1"), array("1.2.3-4-tag", "build", "1.2.3-5"), array("1.2.3-4tag", "build", "1.2.3-5"), array("1.2.3", "fake", null), array("fake", "major", null)); foreach ($compare as $set) { $s = $set[0]; if ($set[2] === null) { $this->expectException(); } $v = new SemVer\version($s); $this->assertEqual($v->inc($set[1])->getVersion(), $set[2], "%s > inc({$set['0']}, {$set['1']}) === {$set['2']}"); } }
protected function execute(InputInterface $input, OutputInterface $output) { $type = $input->getArgument('type'); //Check the type is valid if (!in_array($type, array('major', 'minor', 'patch', 'build'))) { $output->writeln('<error>You must specify the release type (major, minor, patch or build)</error>'); } //Fetch the current version from git $process = new Process('git describe --tags --abbrev=0'); $process->run(); if (!$process->isSuccessful()) { $output->writeln('<error>Git repository invalid or doesn\'t contain any tags'); return; } $oldVersion = new version($process->getOutput()); //Incriment the new version $newVersion = $oldVersion->inc($type); //Incriment the version $output->writeln('<info>Tagging new version ' . $newVersion->getVersion() . ' from version ' . $oldVersion->getVersion() . '</info>'); //Tag the version $process = new Process('git tag ' . $newVersion->getVersion()); $process->run(); if (!$process->isSuccessful()) { $output->writeln('<error>Failed to create new tag. Is your source up to date?</error>'); return; } //Push the tags $output->writeln('<info>Pushing tags to Origin...</info>'); $process = new Process('git push origin --tags'); $process->run(); if ($process->isSuccessful()) { $output->writeln('<info>Success!</info>'); } else { $output->writeln('<error>Failed to push new tag to origin!</error>'); } }
protected function execute(InputInterface $input, OutputInterface $output) { $startTime = microtime(true); $targetDirectory = getcwd(); $tag = $this->config->get('tag'); $against = $this->config->get('against') ?: 'HEAD'; $includeBefore = $this->config->get('include-before'); $excludeBefore = $this->config->get('exclude-before'); $includeAfter = $this->config->get('include-after'); $excludeAfter = $this->config->get('exclude-after'); $client = new Client(); $repository = $client->getRepository($targetDirectory); if ($tag === null) { $tag = $this->findLatestTag($repository); } else { $tag = $this->findTag($repository, $tag); } if ($tag === null) { $output->writeln('<error>No tags to suggest against</error>'); return; } $output->writeln('<info>Testing ' . $against . ' against tag: ' . $tag . '</info>'); $finder = new Finder(); $sourceFilter = new SourceFilter(); $beforeScanner = new Scanner(); $afterScanner = new Scanner(); $modifiedFiles = $repository->getModifiedFiles($tag, $against); $modifiedFiles = array_filter($modifiedFiles, function ($modifiedFile) { return substr($modifiedFile, -4) === '.php'; }); $initialBranch = $repository->getCurrentBranch(); if (!$this->config->get('allow-detached') && !$initialBranch) { $output->writeln('<error>You are on a detached HEAD, aborting.</error>'); $output->writeln('<info>If you still wish to run against a detached HEAD, use --allow-detached.</info>'); return -1; } // Start with the against commit $repository->checkout($against . ' --'); $sourceAfter = $finder->findFromString($targetDirectory, $includeAfter, $excludeAfter); $sourceAfterMatchedCount = count($sourceAfter); $sourceAfter = $sourceFilter->filter($sourceAfter, $modifiedFiles); $progress = new ProgressBar($output, count($sourceAfter)); foreach ($sourceAfter as $file) { $afterScanner->scan($file); $progress->advance(); } $progress->clear(); // Finish with the tag commit $repository->checkout($tag . ' --'); $sourceBefore = $finder->findFromString($targetDirectory, $includeBefore, $excludeBefore); $sourceBeforeMatchedCount = count($sourceBefore); $sourceBefore = $sourceFilter->filter($sourceBefore, $modifiedFiles); $progress = new ProgressBar($output, count($sourceBefore)); foreach ($sourceBefore as $file) { $beforeScanner->scan($file); $progress->advance(); } $progress->clear(); // Reset repository to initial branch if ($initialBranch) { $repository->checkout($initialBranch); } $registryBefore = $beforeScanner->getRegistry(); $registryAfter = $afterScanner->getRegistry(); $analyzer = new Analyzer(); $report = $analyzer->analyze($registryBefore, $registryAfter); $tag = new SemanticVersion($tag); $newTag = new SemanticVersion($tag); $suggestedLevel = $report->getSuggestedLevel(); if ($suggestedLevel !== Level::NONE) { if ($newTag->getPrerelease()) { $newTag->inc('prerelease'); } else { if ($newTag->getMajor() < 1 && $suggestedLevel === Level::MAJOR) { $newTag->inc('minor'); } else { $newTag->inc(strtolower(Level::toString($suggestedLevel))); } } } $output->writeln(''); $output->writeln('<info>Initial semantic version: ' . $tag . '</info>'); $output->writeln('<info>Suggested semantic version: ' . $newTag . '</info>'); if ($this->config->get('details')) { $reporter = new Reporter($report); $reporter->output($output); } $duration = microtime(true) - $startTime; $output->writeln(''); $output->writeln('[Scanned files] Before: ' . count($sourceBefore) . ' (' . $sourceBeforeMatchedCount . ' unfiltered), After: ' . count($sourceAfter) . ' (' . $sourceAfterMatchedCount . ' unfiltered)'); $output->writeln('Time: ' . round($duration, 3) . ' seconds, Memory: ' . round(memory_get_peak_usage() / 1024 / 1024, 3) . ' MB'); }
private function getNextVersionName($type) { $manifest = $this->getManifest(); $lastRelease = new version($manifest['versions'][0]); return $lastRelease->inc($type); }
/** * Increment the version number * @param string $what One of 'major', 'minor', 'patch' or 'build' * @return Version * @throws SemVerException When an invalid increment value is given */ public function inc($what) { return new static(parent::inc($what)->__toString()); }