/** * Returns revision log for url. * * @param string $repository_url Repository url. * * @return RevisionLog */ public function getRevisionLog($repository_url) { $bugtraq_logregex = $this->_repositoryConnector->withCache('1 year')->getProperty('bugtraq:logregex', $repository_url); $revision_log = new RevisionLog($repository_url, $this->_repositoryConnector, $this->_cacheManager, $this->_io); $revision_log->registerPlugin(new SummaryRevisionLogPlugin()); $revision_log->registerPlugin(new PathsRevisionLogPlugin()); $revision_log->registerPlugin(new BugsRevisionLogPlugin(new LogMessageParser($bugtraq_logregex))); $revision_log->registerPlugin(new MergesRevisionLogPlugin()); $revision_log->refresh(); return $revision_log; }
/** * {@inheritdoc} * * @throws \RuntimeException When url was given instead of path. */ protected function initialize(InputInterface $input, OutputInterface $output) { $this->_rawPath = null; $output->getFormatter()->setStyle('debug', new OutputFormatterStyle('white', 'magenta')); parent::initialize($input, $output); // Only apply check for commands, that accept working copy path. if ($input->hasArgument('path')) { if (!$this->pathAcceptsUrl && $this->repositoryConnector->isUrl($this->getRawPath())) { throw new \RuntimeException('The "path" argument must be a working copy path and not URL.'); } } }
public function testGetFreshMergedRevisionsWithChanges() { $this->_expectCommand("svn --non-interactive propget svn:mergeinfo '/path/to/working-copy' --revision BASE", '/projects/project-name/trunk:10,15' . PHP_EOL); $this->_expectCommand("svn --non-interactive propget svn:mergeinfo '/path/to/working-copy'", '/projects/project-name/trunk:10,15,18,33' . PHP_EOL . '/projects/project-name/branches/branch-name:4' . PHP_EOL); $this->_revisionListParser->expandRanges(Argument::cetera())->willReturnArgument(0); $this->assertSame(array('/projects/project-name/trunk' => array('18', '33'), '/projects/project-name/branches/branch-name' => array('4')), $this->_repositoryConnector->getFreshMergedRevisions('/path/to/working-copy')); }
/** * Detects if given project_path is known project root. * * @param string $path Path. * * @return boolean */ protected function isRef($path) { // Not a folder. if (substr($path, -1, 1) !== '/') { return false; } return $this->_repositoryConnector->isRefRoot($path); }
/** * Return working copy path. * * @return string * @throws \RuntimeException When url was given instead of path. */ protected function getPath() { $path = $this->io->getArgument('path'); if (!$this->repositoryConnector->isUrl($path)) { $path = realpath($path); } elseif (!$this->pathAcceptsUrl) { throw new \RuntimeException('The "path" argument must be a working copy path and not URL.'); } return $path; }
/** * Finds revisions by sub-match. * * @param integer $project_id Project ID. * @param string $path Path. * @param integer|null $max_revision Max revision. * * @return array */ protected function findBySubMatch($project_id, $path, $max_revision = null) { $path_id = $this->getPathId($path); if ($path_id === false) { return array(); } $sql = 'SELECT Revision, CopyPathId FROM CommitPaths WHERE PathId = :path_id AND CopyPathId IS NOT NULL ORDER BY Revision DESC LIMIT 1'; $copy_data = $this->database->fetchOne($sql, array('path_id' => $path_id)); if ($this->_repositoryConnector->isRefRoot($path)) { $where_clause = array('RefId = :ref_id'); $bind_params = array('ref_id' => $this->getRefId($project_id, $this->_repositoryConnector->getRefByPath($path))); // Revisions, made after copy revision. if ($copy_data) { $where_clause[] = 'Revision >= :min_revision'; $bind_params['min_revision'] = $copy_data['Revision']; } // Revisions made before copy revision. if (isset($max_revision)) { $where_clause[] = 'Revision < :max_revision'; $bind_params['max_revision'] = $max_revision; } $sql = 'SELECT DISTINCT Revision FROM CommitRefs WHERE (' . implode(') AND (', $where_clause) . ')'; $results = $this->database->fetchCol($sql, $bind_params); } else { $where_clause = array('cpr.ProjectId = :project_id', 'p.Path LIKE :path'); $bind_params = array('project_id' => $project_id, 'path' => $path . '%'); // Revisions, made after copy revision. if ($copy_data) { $where_clause[] = 'cpr.Revision >= :min_revision'; $bind_params['min_revision'] = $copy_data['Revision']; } // Revisions made before copy revision. if (isset($max_revision)) { $where_clause[] = 'cpr.Revision < :max_revision'; $bind_params['max_revision'] = $max_revision; } $sql = 'SELECT DISTINCT cpr.Revision FROM CommitProjects cpr JOIN CommitPaths cpa ON cpa.Revision = cpr.Revision JOIN Paths p ON p.Id = cpa.PathId WHERE (' . implode(') AND (', $where_clause) . ')'; $results = $this->database->fetchCol($sql, $bind_params); } if (!$copy_data) { return $results; } return array_merge($results, $this->findBySubMatch($project_id, $this->getPathFromId($copy_data['CopyPathId']), $copy_data['Revision'])); }
/** * Queries missing revision data. * * @param integer $from_revision From revision. * @param integer $to_revision To revision. * * @return void */ private function _queryRevisionData($from_revision, $to_revision) { $range_start = $from_revision; // The "io" isn't set during autocomplete. if (isset($this->_io)) { // Create progress bar for repository plugins, where data amount is known upfront. $progress_bar = $this->_io->createProgressBar(ceil(($to_revision - $from_revision) / 200) + 1); $progress_bar->setMessage(' * Reading missing revisions:'); $progress_bar->setFormat('%message% %current%/%max% [%bar%] <info>%percent:3s%%</info> %elapsed:6s%/%estimated:-6s% <info>%memory:-10s%</info>'); $progress_bar->start(); } $log_command_arguments = $this->_getLogCommandArguments(); $is_verbose = isset($this->_io) && $this->_io->isVerbose(); while ($range_start <= $to_revision) { $range_end = min($range_start + 199, $to_revision); $command = $this->_repositoryConnector->getCommand('log', sprintf($log_command_arguments, $range_start, $range_end, $this->_repositoryRootUrl)); $command->setCacheDuration('10 years'); $svn_log = $command->run(); $this->_parseLog($svn_log); $range_start = $range_end + 1; if (isset($progress_bar)) { $progress_bar->advance(); } } if (isset($progress_bar)) { // Remove progress bar of repository plugins. $progress_bar->clear(); unset($progress_bar); // Create progress bar for database plugins, where data amount isn't known upfront. $progress_bar = $this->_io->createProgressBar(); $progress_bar->setMessage(' * Reading missing revisions:'); $progress_bar->setFormat('%message% %current% [%bar%] %elapsed:6s% <info>%memory:-10s%</info>'); $progress_bar->start(); foreach ($this->getDatabaseCollectorPlugins() as $plugin) { $plugin->process($from_revision, $to_revision, $progress_bar); } } else { foreach ($this->getDatabaseCollectorPlugins() as $plugin) { $plugin->process($from_revision, $to_revision); } } if (isset($progress_bar)) { $progress_bar->finish(); $this->_io->writeln(''); } if ($is_verbose) { $this->_displayPluginActivityStatistics(); } }
/** * Queries missing revision data. * * @param integer $from_revision From revision. * @param integer $to_revision To revision. * * @return void */ private function _queryRevisionData($from_revision, $to_revision) { $range_start = $from_revision; $project_url = $this->_repositoryConnector->getProjectUrl($this->_repositoryUrl); $progress_bar = $this->_io->createProgressBar(ceil(($to_revision - $from_revision) / 1000)); $progress_bar->setFormat(' * Reading missing revisions: %current%/%max% [%bar%] %percent:3s%%'); $progress_bar->start(); while ($range_start < $to_revision) { $range_end = min($range_start + 1000, $to_revision); $command = $this->_repositoryConnector->getCommand('log', '-r ' . $range_start . ':' . $range_end . ' --xml --verbose --use-merge-history {' . $project_url . '}'); $this->_parseLog($command->run()); $range_start = $range_end + 1; $progress_bar->advance(); } $progress_bar->finish(); $this->_io->writeln(''); }
public function testGetProperty() { $this->_expectCommand("svn --non-interactive propget prop-name 'the/path'", 'OK'); $this->assertEquals('OK', $this->_repositoryConnector->getProperty('prop-name', 'the/path')); }
/** * Returns previously recoded conflicts. * * @param string $wc_path Working copy path. * * @return array */ public function getNewConflicts($wc_path) { return $this->repositoryConnector->getWorkingCopyConflicts($wc_path); }