/** * Get content for version * * Get the contents of the current resource in the specified version. * * @param string $version * @return string */ public function getVersionedContent($version) { if (!in_array($version, $this->getVersions(), true)) { throw new vcsNoSuchVersionException($this->path, $version); } if (($content = vcsCache::get($this->path, $version, 'content')) === false) { // Execute command $content = svn_cat($this->root . $this->path, $version); vcsCache::cache($this->path, $version, 'content', $content); } return $content; }
/** * Get diff * * Get the diff between the current version and the given version. * Optionally you may specify another version then the current one as the * diff base as the second parameter. * * @param string $version * @param string $current * @return vcsResource */ public function getDiff($version, $current = null) { if (!in_array($version, $this->getVersions(), true)) { throw new vcsNoSuchVersionException($this->path, $version); } $diff = vcsCache::get($this->path, $version, 'diff'); if ($diff === false) { // Refetch the basic content information, and cache it. $process = new vcsHgCliProcess(); $process->workingDirectory($this->root); $process->argument('diff'); if ($current !== null) { $process->argument('-r' . $current); } $process->argument('-r' . $version); $process->argument(new pbsPathArgument('.' . $this->path)); $process->execute(); // Parse resulting unified diff $parser = new vcsUnifiedDiffParser(); $diff = $parser->parseString($process->stdoutOutput); vcsCache::cache($this->path, $version, 'diff', $diff); } return $diff; }
/** * Get blame information for resource * * The method should return author and revision information for each line, * describing who when last changed the current resource. The returned * array should look like: * <code> * array( * T_LINE_NUMBER => array( * 'author' => T_STRING, * 'version' => T_STRING, * ), * ... * ); * </code> * * If some file in the repository has no blame information associated, like * binary files, the method should return false. * * Optionally a version may be specified which defines a later version of * the resource for which the blame information should be returned. * * @param mixed $version * @return mixed */ public function blame($version = null) { $version = $version === null ? $this->getVersionString() : $version; if (!in_array($version, $this->getVersions(), true)) { throw new vcsNoSuchVersionException($this->path, $version); } $blame = vcsCache::get($this->path, $version, 'blame'); if ($blame === false) { $shortHashCache = array(); // Refetch the basic blamermation, and cache it. $process = new vcsBzrCliProcess(); $process->workingDirectory($this->root); // Execute command $process->argument('xmlannotate'); if ($version !== null) { $process->argument('-r' . $version); } $process->argument(new pbsPathArgument('.' . $this->path)); $return = $process->execute(); $blame = array(); libxml_use_internal_errors(true); try { $xmlDoc = new SimpleXMLElement($process->stdoutOutput); // Convert returned lines into diff structures foreach ($xmlDoc->entry as $line) { $blame[] = new vcsBlameStruct($line, $line['revno'], $line['author'], strtotime($line['date'])); } } catch (Exception $e) { return false; } vcsCache::cache($this->path, $version, 'blame', $blame); } return $blame; }
/** * Get content for version * * Get the contents of the current resource in the specified version. * * @param string $version * @return string */ public function getVersionedContent($version) { if (!in_array($version, $this->getVersions(), true)) { throw new vcsNoSuchVersionException($this->path, $version); } if (($content = vcsCache::get($this->path, $version, 'content')) === false) { // Refetch the basic content information, and cache it. $process = new vcsSvnCliProcess(); $process->argument('-r' . $version); // Execute command $return = $process->argument('cat')->argument(new pbsPathArgument($this->root . $this->path))->execute(); vcsCache::cache($this->path, $version, 'content', $content = $process->stdoutOutput); } return $content; }
/** * Get diff * * Get the diff between the current version and the given version. * Optionally you may specify another version then the current one as the * diff base as the second parameter. * * @param string $version * @param string $current * @return vcsResource */ public function getDiff($version, $current = null) { $current = $current === null ? $this->getVersionString() : $current; if (($diff = vcsCache::get($this->path, $version, 'diff')) !== false) { return $diff; } // Refetch the basic content information, and cache it. $process = new vcsCvsCliProcess(); // WTF: Why is there a non zero exit code? $process->nonZeroExitCodeException = false; // Configure process instance $process->workingDirectory($this->root)->redirect(vcsCvsCliProcess::STDERR, vcsCvsCliProcess::STDOUT)->argument('diff')->argument('-u')->argument('-r')->argument($version)->argument('-r')->argument($current)->argument('.' . $this->path)->execute(); $parser = new vcsUnifiedDiffParser(); $diff = $parser->parseString($process->stdoutOutput); vcsCache::cache($this->path, $version, 'diff', $diff); return $diff; }
/** * This method takes a coverage report and then rebuilds the raw coverage * data based on the report data and the change history of the covered files. * * @param PHP_ChangeCoverage_Report $report The coverage report data. * * @return PHP_CodeCoverage */ protected function rebuildCoverageData(PHP_ChangeCoverage_Report $report) { $codeCoverage = new PHP_CodeCoverage(); $factory = new PHP_ChangeCoverage_ChangeSet_Factory(); vcsCache::initialize($this->tempDirectory); $this->writeLine(); $this->writeLine('Collecting commits and meta data, this may take a moment.'); $this->writeLine(); $xdebug = new PHP_ChangeCoverage_Xdebug(); if ($this->unmodifiedAsCovered) { $xdebug->setUnmodifiedAsCovered(); } foreach ($report->getFiles() as $file) { $changeSet = $factory->create($file); $changeSet->setStartDate($this->modifiedSince); foreach ($xdebug->generateData($changeSet->calculate()) as $data) { $codeCoverage->append($data, md5(microtime())); } } return $codeCoverage; }
/** * Get resource log * * Get the full log for the current resource up tu the current revision * * @return array(vcsLogEntry) */ protected function getResourceLog() { if (($log = vcsCache::get($this->path, $this->currentVersion, 'log')) !== false) { return $log; } $version = $this->currentVersion !== null ? $this->currentVersion : 'HEAD'; $process = new vcsCvsCliProcess(); $process->workingDirectory($this->root)->redirect(vcsCvsCliProcess::STDERR, vcsCvsCliProcess::STDOUT)->argument('log')->argument('-r:' . $version)->argument('.' . $this->path)->execute(); $log = array(); $regexp = '((?# Get revision number ) revision\\s+(?P<revision>[\\d\\.]+)(\\r\\n|\\r|\\n) (?# Get commit date ) date:\\s+(?P<date>[^;]+);\\s+ (?# Get commit author ) author:\\s+(?P<author>[^;]+);\\s+ (?# Skip everything else ) [^\\n\\r]+;(\\r\\n|\\r|\\n) (branches:\\s+[^\\n\\r]+;(\\r\\n|\\r|\\n))? (?# Get commit message ) (?P<message>[\\r\\n\\t]*|.*)$)xs'; // Remove closing equal characters $output = rtrim(substr(rtrim($process->stdoutOutput), 0, -77)); // Split all log entries $rawLogs = explode('----------------------------', $output); $rawLogs = array_map('trim', $rawLogs); foreach ($rawLogs as $rawLog) { if (preg_match($regexp, $rawLog, $match) === 0) { continue; } $date = strtotime($match['date']); $revision = $match['revision']; $logEntry = new vcsLogEntry($revision, $match['author'], $match['message'], $date); $log[$revision] = $logEntry; } $log = array_reverse($log); $last = end($log); $this->currentVersion = $last->version; vcsCache::cache($this->path, $this->currentVersion, 'log', $log); return $log; }
/** * Returns the complete log for this resource. * * @return array */ protected function getResourceLog() { $log = vcsCache::get($this->path, $this->currentVersion, 'log'); if ($log === false) { // Refetch the basic logrmation, and cache it. $process = new vcsHgCliProcess(); $process->workingDirectory($this->root); // Fetch for specified version, if set if ($this->currentVersion !== null) { $process->argument('-r ' . $this->currentVersion); } // Execute log command $process->argument('log'); $process->argument('--template')->argument('{node}\\t{author|email}\\t{date|isodate}\\t{desc|urlescape}\\n'); $process->argument(new pbsPathArgument('.' . $this->path)); $process->execute(); // Parse commit log $lines = explode("\n", $process->stdoutOutput); if (!$lines) { return array(); } $lineCount = count($lines); $log = array(); $lastCommit = null; foreach ($lines as $line) { if (!$line) { continue; } list($node, $author, $date, $desc) = explode("\t", $line, 4); $atPosition = strpos($author, '@'); if ($atPosition) { $author = substr($author, 0, $atPosition); } $log[$node] = new vcsLogEntry($node, $author, urldecode($desc), strtotime($date)); } $log = array_reverse($log); $last = end($log); $this->currentVersion = (string) $last->version; // Cache extracted data vcsCache::cache($this->path, $this->currentVersion, 'log', $log); } return $log; }
/** * Get diff * * Get the diff between the current version and the given version. * Optionally you may specify another version then the current one as the * diff base as the second parameter. * * @param string $version * @param string $current * @return vcsResource */ public function getDiff($version, $current = null) { $current = $current === null ? $this->getVersionString() : $current; if (($diff = vcsCache::get($this->path, $version, 'diff')) === false) { // Refetch the basic content information, and cache it. $process = new vcsSvnCliProcess(); $process->argument('-r' . $version . ':' . $current); // Execute command $return = $process->argument('diff')->argument(new pbsPathArgument($this->root . $this->path))->execute(); $parser = new vcsUnifiedDiffParser(); $diff = $parser->parseString($process->stdoutOutput); vcsCache::cache($this->path, $version, 'diff', $diff); } foreach ($diff as $fileDiff) { $fileDiff->from = substr($fileDiff->from, strlen($this->root)); $fileDiff->to = substr($fileDiff->to, strlen($this->root)); } return $diff; }
/** * Initialize cache * * Initialize cache with its settings. You need to provide a path to a * location where the cache may store its contents. * * Optionally you may pass a different cache size limit, which defaults to * 1MB in bytes, and a cleanup rate. The clean up rate defines how much of * the cache contents will be left on the device, when the cache size limit * has been exceeded. The default rate of .8 with a cache size of 1 * MBdefines, that everything except the most recently used 800 kB will be * purged. * * @param string $path * @param int $size * @param float $cleanupRate * @return void */ public static function initialize($path, $size = 1048576, $cleanupRate = 0.8) { self::$path = (string) $path; self::$size = (int) $size; self::$cleanupRate = (double) $cleanupRate; // Determine meta data handler to use for caching the cache metadata. if (false && extension_loaded('sqlite3')) { // SQLite metadata cache handler disabled for now, since it has // lock issues. self::$metaDataHandler = new vcsCacheSqliteMetaData(self::$path); } else { self::$metaDataHandler = new vcsCacheFileSystemMetaData(self::$path); } }