/** * @param array $mapping */ protected function extractMapping(array $mapping) { foreach ($mapping as &$level) { $level = Level::fromString($level); } $this->mapping = $mapping; }
/** * @param \Symfony\Component\Console\Output\OutputInterface $output * @param \PHPSemVerChecker\Report\Report $report * @param string $context */ protected function outputTable(OutputInterface $output, Report $report, $context) { $table = new Table($output); $table->setHeaders(['Level', 'Location', 'Target', 'Reason', 'Code']); foreach (Level::asList('desc') as $level) { $reportForLevel = $report[$context][$level]; /** @var \PHPSemVerChecker\Operation\Operation $operation */ foreach ($reportForLevel as $operation) { $table->addRow([Level::toString($level), $this->getLocation($operation), $operation->getTarget(), $operation->getReason(), $operation->getCode()]); } } $table->render(); }
public function getOutput() { $output = []; $output['level'] = Level::toString($this->report->getSuggestedLevel()); $output['changes'] = []; $contexts = ['class', 'function', 'interface', 'trait']; $differences = $this->report->getDifferences(); foreach ($contexts as $context) { foreach (Level::asList('desc') as $level) { $reportForLevel = $differences[$context][$level]; /** @var \PHPSemVerChecker\Operation\Operation $operation */ foreach ($reportForLevel as $operation) { $output['changes'][$context][] = ['level' => Level::toString($level), 'location' => $operation->getLocation(), 'line' => $operation->getLine(), 'target' => $operation->getTarget(), 'reason' => $operation->getReason(), 'code' => $operation->getCode()]; } } } return $output; }
/** * @return int */ public function getSuggestedLevel() { foreach (Level::asList('desc') as $level) { foreach ($this->differences as $context => $levels) { if (!empty($levels[$level])) { return $level; } } } return Level::NONE; }
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'); }