示例#1
0
 public function execute()
 {
     global $wgUser;
     // Before doing anything at all, let's check permissions
     if (!$wgUser->isAllowed('codereview-use')) {
         $this->dieUsage('You don\'t have permission to update code', 'permissiondenied');
     }
     $params = $this->extractRequestParams();
     $repo = CodeRepository::newFromName($params['repo']);
     if (!$repo) {
         $this->dieUsage("Invalid repo ``{$params['repo']}''", 'invalidrepo');
     }
     $svn = SubversionAdaptor::newFromRepo($repo->getPath());
     $lastStoredRev = $repo->getLastStoredRev();
     if ($lastStoredRev >= $params['rev']) {
         // Nothing to do, we're up to date.
         // Return an empty result
         $this->getResult()->addValue(null, $this->getModuleName(), array());
         return;
     }
     // FIXME: this could be a lot?
     $log = $svn->getLog('', $lastStoredRev + 1, $params['rev']);
     if (!$log) {
         // FIXME: When and how often does this happen?
         // Should we use dieUsage() here instead?
         ApiBase::dieDebug(__METHOD__, 'Something awry...');
     }
     $result = array();
     $revs = array();
     foreach ($log as $data) {
         $codeRev = CodeRevision::newFromSvn($repo, $data);
         $codeRev->save();
         $result[] = array('id' => $codeRev->getId(), 'author' => $codeRev->getAuthor(), 'timestamp' => wfTimestamp(TS_ISO_8601, $codeRev->getTimestamp()), 'message' => $codeRev->getMessage());
         $revs[] = $codeRev;
     }
     // Cache the diffs if there are a only a few.
     // Mainly for WMF post-commit ping hook...
     if (count($revs) <= 2) {
         foreach ($revs as $codeRev) {
             $repo->setDiffCache($codeRev);
             // trigger caching
         }
     }
     $this->getResult()->setIndexedTagName($result, 'rev');
     $this->getResult()->addValue(null, $this->getModuleName(), $result);
 }
 function getContent()
 {
     if (is_null($this->mRepository)) {
         return wfMsgHtml('codebrowse-not-found', $this->mRepoName);
     }
     $this->svn = SubversionAdaptor::newFromRepo($this->mRepository->getPath());
     $contents = $this->svn->getDirList($this->mBasePath);
     if (!is_array($contents)) {
         return wfMsgHtml('codebrowse-not-found', $this->mPath);
     }
     // FIXME
     if (count($contents) == 1 && $contents[0]['type'] == 'file') {
         return $this->showFile();
     } else {
         if (substr($this->mPath, -1) !== '/') {
             $this->mPath .= '/';
             $this->mBasePath .= '/';
         }
         return $this->listDir($contents);
     }
 }
示例#3
0
 function __construct($repo, $proxy, $timeout = 30)
 {
     parent::__construct($repo);
     $this->mProxy = $proxy;
     $this->mTimeout = $timeout;
 }
示例#4
0
 /**
  * Import a repository in the local database.
  * @param $repoName String Local name of repository
  * @param $start Int Revision to begin the import from (Default: null, means last stored revision);
  */
 private function importRepo($repoName, $start = null, $cacheSize = 0)
 {
     global $wgCodeReviewImportBatchSize;
     static $adaptorReported = false;
     $repo = CodeRepository::newFromName($repoName);
     if (!$repo) {
         $this->error("Invalid repo {$repoName}");
         return;
     }
     $svn = SubversionAdaptor::newFromRepo($repo->getPath());
     if (!$adaptorReported) {
         $this->output("Using " . get_class($svn) . " adaptor\n");
         $adaptorReported = true;
     }
     $this->output("IMPORT FROM REPO: {$repoName}\n");
     $lastStoredRev = $repo->getLastStoredRev();
     $this->output("Last stored revision: {$lastStoredRev}\n");
     $chunkSize = $wgCodeReviewImportBatchSize;
     $startTime = microtime(true);
     $revCount = 0;
     $start = $start !== null ? intval($start) : $lastStoredRev + 1;
     /*
      * FIXME: when importing only a part of a repository, the given path
      * might not have been created with revision 1. For example, the
      * mediawiki '/trunk/phase3' got created with r1284.
      */
     if ($start > $lastStoredRev + 1) {
         $this->error("Invalid starting point. r{$start} is beyond last stored revision: r" . ($lastStoredRev + 1));
         return;
     }
     $this->output("Syncing from r{$start} to HEAD...\n");
     if (!$svn->canConnect()) {
         $this->error("Unable to connect to repository.");
         return;
     }
     while (true) {
         $log = $svn->getLog('', $start, $start + $chunkSize - 1);
         if (empty($log)) {
             # Repo seems to give a blank when max rev is invalid, which
             # stops new revisions from being added. Try to avoid this
             # by trying less at a time from the last point.
             if ($chunkSize <= 1) {
                 break;
                 // done!
             }
             $chunkSize = max(1, floor($chunkSize / 4));
             continue;
         } else {
             $start += $chunkSize;
         }
         if (!is_array($log)) {
             var_dump($log);
             // @TODO: cleanup :)
             $this->error('Log entry is not an array! See content above.', true);
         }
         foreach ($log as $data) {
             $revCount++;
             $delta = microtime(true) - $startTime;
             $revSpeed = $revCount / $delta;
             $codeRev = CodeRevision::newFromSvn($repo, $data);
             $codeRev->save();
             $this->output(sprintf("%d %s %s (%0.1f revs/sec)\n", $codeRev->getId(), wfTimestamp(TS_DB, $codeRev->getTimestamp()), $codeRev->getAuthor(), $revSpeed));
         }
         wfWaitForSlaves();
     }
     if ($cacheSize !== 0) {
         $dbw = wfGetDB(DB_MASTER);
         $options = array('ORDER BY' => 'cr_id DESC');
         if ($cacheSize == "all") {
             $this->output("Pre-caching all uncached diffs...\n");
         } else {
             if ($cacheSize == 1) {
                 $this->output("Pre-caching the latest diff...\n");
             } else {
                 $this->output("Pre-caching the latest {$cacheSize} diffs...\n");
             }
             $options['LIMIT'] = $cacheSize;
         }
         // Get all rows for this repository that don't already have a diff filled in.
         // This is LIMITed according to the $cacheSize setting, above, so only the
         // rows that we plan to pre-cache are returned.
         // TODO: This was optimised in order to skip rows that already have a diff,
         //		 which is mostly what is required, but there may be situations where
         //		 you want to re-calculate diffs (e.g. if $wgCodeReviewMaxDiffPaths
         //		 changes).  If these situations arise we will either want to revert
         //		 this behaviour, or add a --force flag or something.
         $res = $dbw->select('code_rev', 'cr_id', array('cr_repo_id' => $repo->getId(), 'cr_diff IS NULL OR cr_diff = ""'), __METHOD__, $options);
         foreach ($res as $row) {
             $repo->getRevision($row->cr_id);
             $diff = $repo->getDiff($row->cr_id);
             // trigger caching
             $msg = "Diff r{$row->cr_id} ";
             if (is_integer($diff)) {
                 $msg .= "Skipped: " . CodeRepository::getDiffErrorMessage($diff);
             } else {
                 $msg .= "done";
             }
             $this->output($msg . "\n");
         }
     } else {
         $this->output("Pre-caching skipped.\n");
     }
     $this->output("Done!\n");
 }
示例#5
0
 /**
  * Set diff cache (for import operations)
  * @param $codeRev CodeRevision
  */
 public function setDiffCache(CodeRevision $codeRev)
 {
     global $wgMemc;
     wfProfileIn(__METHOD__);
     $rev1 = $codeRev->getId() - 1;
     $rev2 = $codeRev->getId();
     $svn = SubversionAdaptor::newFromRepo($this->path);
     $data = $svn->getDiff('', $rev1, $rev2);
     // Store to cache
     $key = wfMemcKey('svn', md5($this->path), 'diff', $rev1, $rev2);
     $wgMemc->set($key, $data, 3600 * 24 * 3);
     // Permanent DB storage
     $storedData = $data;
     $flags = Revision::compressRevisionText($storedData);
     $dbw = wfGetDB(DB_MASTER);
     $dbw->update('code_rev', array('cr_diff' => $storedData, 'cr_flags' => $flags), array('cr_repo_id' => $this->id, 'cr_id' => $codeRev->getId()), __METHOD__);
     wfProfileOut(__METHOD__);
 }