protected function loadPage() { $table = new DifferentialDiff(); $conn_r = $table->establishConnection('r'); $data = queryfx_all($conn_r, 'SELECT * FROM %T %Q %Q %Q', $table->getTableName(), $this->buildWhereClause($conn_r), $this->buildOrderClause($conn_r), $this->buildLimitClause($conn_r)); return $table->loadAllFromArray($data); }
public function renderDiffPropertyViewValue(DifferentialDiff $diff) { $host = $diff->getSourceMachine(); if (!$host) { return null; } return $host; }
public function renderDiffPropertyViewValue(DifferentialDiff $diff) { $colors = array(DifferentialUnitStatus::UNIT_NONE => 'grey', DifferentialUnitStatus::UNIT_OKAY => 'green', DifferentialUnitStatus::UNIT_WARN => 'yellow', DifferentialUnitStatus::UNIT_FAIL => 'red', DifferentialUnitStatus::UNIT_SKIP => 'blue', DifferentialUnitStatus::UNIT_AUTO_SKIP => 'blue'); $icon_color = idx($colors, $diff->getUnitStatus(), 'grey'); $message = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($diff->getUnitStatus()); $status = id(new PHUIStatusListView())->addItem(id(new PHUIStatusItemView())->setIcon(PHUIStatusItemView::ICON_STAR, $icon_color)->setTarget($message)); return $status; }
public function renderDiffPropertyViewValue(DifferentialDiff $diff) { $path = $diff->getSourcePath(); if (!$path) { return null; } return $path; }
private function getDefaultRefName(PhabricatorRepository $repository, DifferentialDiff $diff) { $onto = $diff->loadTargetBranch(); if ($onto !== null) { return $onto; } return $repository->getDefaultBranch(); }
private function loadDiffs(array $revisions) { if (!$revisions) { return array(); } $diff_teml = new DifferentialDiff(); $diffs = $diff_teml->loadAllWhere('revisionID in (%Ld)', array_keys($revisions)); return $diffs; }
public function addDiff(DifferentialDiff $diff, $comments) { if ($diff->getRevisionID() && $diff->getRevisionID() != $this->getRevision()->getID()) { $diff_id = (int) $diff->getID(); $targ_id = (int) $this->getRevision()->getID(); $real_id = (int) $diff->getRevisionID(); throw new Exception("Can not attach diff #{$diff_id} to Revision D{$targ_id}, it is " . "already attached to D{$real_id}."); } $this->diff = $diff; $this->comments = $comments; return $this; }
protected function renderHarbormasterStatus(DifferentialDiff $diff, array $messages) { $colors = array(DifferentialLintStatus::LINT_NONE => 'grey', DifferentialLintStatus::LINT_OKAY => 'green', DifferentialLintStatus::LINT_WARN => 'yellow', DifferentialLintStatus::LINT_FAIL => 'red', DifferentialLintStatus::LINT_SKIP => 'blue', DifferentialLintStatus::LINT_AUTO_SKIP => 'blue'); $icon_color = idx($colors, $diff->getLintStatus(), 'grey'); $message = DifferentialRevisionUpdateHistoryView::getDiffLintMessage($diff); $excuse = $diff->getProperty('arc:lint-excuse'); if (strlen($excuse)) { $excuse = array(phutil_tag('strong', array(), pht('Excuse:')), ' ', phutil_escape_html_newlines($excuse)); } $status = id(new PHUIStatusListView())->addItem(id(new PHUIStatusItemView())->setIcon(PHUIStatusItemView::ICON_STAR, $icon_color)->setTarget($message)->setNote($excuse)); return $status; }
public function testGenerateHarbormasterAutotargets() { $viewer = $this->generateNewTestUser(); $raw_diff = <<<EODIFF diff --git a/fruit b/fruit new file mode 100644 index 0000000..1c0f49d --- /dev/null +++ b/fruit @@ -0,0 +1,2 @@ +apal +banan EODIFF; $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($raw_diff); $diff = DifferentialDiff::newFromRawChanges($viewer, $changes)->setLintStatus(DifferentialLintStatus::LINT_AUTO_SKIP)->setUnitStatus(DifferentialUnitStatus::UNIT_AUTO_SKIP)->attachRevision(null)->save(); $params = array('objectPHID' => $diff->getPHID(), 'targetKeys' => array(HarbormasterArcLintBuildStepImplementation::STEPKEY, HarbormasterArcUnitBuildStepImplementation::STEPKEY)); // Creation of autotargets should work from an empty state. $result = id(new ConduitCall('harbormaster.queryautotargets', $params))->setUser($viewer)->execute(); $targets = idx($result, 'targetMap'); foreach ($params['targetKeys'] as $target_key) { $this->assertTrue((bool) $result['targetMap'][$target_key]); } // Querying the same autotargets again should produce the same results, // not make new ones. $retry = id(new ConduitCall('harbormaster.queryautotargets', $params))->setUser($viewer)->execute(); $this->assertEqual($result, $retry); }
private function buildChangesetParser($type, $data, $file) { $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($data); $diff = DifferentialDiff::newFromRawChanges($changes); if (count($diff->getChangesets()) !== 1) { throw new Exception("Expected one changeset: {$file}"); } $changeset = head($diff->getChangesets()); $engine = new PhabricatorMarkupEngine(); $engine->setViewer(new PhabricatorUser()); $cparser = new DifferentialChangesetParser(); $cparser->setDisableCache(true); $cparser->setChangeset($changeset); $cparser->setMarkupEngine($engine); if ($type == 'one') { $cparser->setRenderer(new DifferentialChangesetOneUpTestRenderer()); } else { if ($type == 'two') { $cparser->setRenderer(new DifferentialChangesetTwoUpTestRenderer()); } else { throw new Exception("Unknown renderer type '{$type}'!"); } } return $cparser; }
public function testDetectSlowCopiedCode() { // This tests that the detector has a reasonable runtime when a diff // contains a very large number of identical lines. See T5041. $parser = new ArcanistDiffParser(); $line = str_repeat('x', 60); $oline = '-' . $line . "\n"; $nline = '+' . $line . "\n"; $n = 1000; $oblock = str_repeat($oline, $n); $nblock = str_repeat($nline, $n); $raw_diff = <<<EODIFF diff --git a/dst b/dst new file mode 100644 index 0000000..1234567 --- /dev/null +++ b/dst @@ -0,0 +1,{$n} @@ {$nblock} diff --git a/src b/src deleted file mode 100644 index 123457..0000000 --- a/src +++ /dev/null @@ -1,{$n} +0,0 @@ {$oblock} EODIFF; $diff = DifferentialDiff::newFromRawChanges($parser->parseDiff($raw_diff)); $this->assertTrue(true); }
protected function execute(ConduitAPIRequest $request) { $viewer = $request->getUser(); $raw_diff = $request->getValue('diff'); $repository_phid = $request->getValue('repositoryPHID'); if ($repository_phid) { $repository = id(new PhabricatorRepositoryQuery())->setViewer($viewer)->withPHIDs(array($repository_phid))->executeOne(); if (!$repository) { throw new Exception(pht('No such repository "%s"!', $repository_phid)); } } else { $repository = null; } $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($raw_diff); $diff = DifferentialDiff::newFromRawChanges($changes); $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP); $diff->setUnitStatus(DifferentialUnitStatus::UNIT_SKIP); $diff->setAuthorPHID($viewer->getPHID()); $diff->setCreationMethod('web'); if ($repository) { $diff->setRepositoryPHID($repository->getPHID()); } id(new DifferentialDiffEditor())->setActor($viewer)->setContentSource(PhabricatorContentSource::newFromConduitRequest($request))->saveDiff($diff); return $this->buildDiffInfoDictionary($diff); }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); if (!$drequest->getRawCommit()) { $effective_commit = $this->getEffectiveCommit(); if (!$effective_commit) { return null; } // TODO: This side effect is kind of skethcy. $drequest->setCommit($effective_commit); } else { $effective_commit = $drequest->getCommit(); } $options = array('-M', '-C', '--no-ext-diff', '--no-color', '--src-prefix=a/', '--dst-prefix=b/', '-U65535'); $options = implode(' ', $options); list($raw_diff) = execx("(cd %s && git diff {$options} %s^ %s -- %s)", $repository->getDetail('local-path'), $effective_commit, $effective_commit, $drequest->getPath()); $parser = new ArcanistDiffParser(); $parser->setDetectBinaryFiles(true); $changes = $parser->parseDiff($raw_diff); $diff = DifferentialDiff::newFromRawChanges($changes); $changesets = $diff->getChangesets(); $changeset = reset($changesets); $this->renderingReference = $drequest->getBranchURIComponent($drequest->getBranch()) . $drequest->getPath() . ';' . $drequest->getCommit(); return $changeset; }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); $effective_commit = $this->getEffectiveCommit(); if (!$effective_commit) { return null; } // TODO: This side effect is kind of skethcy. $drequest->setCommit($effective_commit); $query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest); $raw_diff = $query->loadRawDiff(); $parser = new ArcanistDiffParser(); $try_encoding = $repository->getDetail('encoding'); if ($try_encoding) { $parser->setTryEncoding($try_encoding); } $parser->setDetectBinaryFiles(true); $changes = $parser->parseDiff($raw_diff); $diff = DifferentialDiff::newFromRawChanges($changes); $changesets = $diff->getChangesets(); $changeset = reset($changesets); $this->renderingReference = $drequest->generateURI(array('action' => 'rendering-ref')); return $changeset; }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); $effective_commit = $this->getEffectiveCommit(); if (!$effective_commit) { return null; } // TODO: This side effect is kind of skethcy. $drequest->setCommit($effective_commit); $path = $drequest->getPath(); list($raw_diff) = $repository->execxLocalCommand('diff -U %d --git --change %s -- %s', 65535, $effective_commit, $path); $parser = new ArcanistDiffParser(); $try_encoding = $repository->getDetail('encoding'); if ($try_encoding) { $parser->setTryEncoding($try_encoding); } $parser->setDetectBinaryFiles(true); $changes = $parser->parseDiff($raw_diff); $diff = DifferentialDiff::newFromRawChanges($changes); $changesets = $diff->getChangesets(); $changeset = reset($changesets); $this->renderingReference = $drequest->getBranchURIComponent($drequest->getBranch()) . $drequest->getPath() . ';' . $drequest->getCommit(); return $changeset; }
protected function execute(ConduitAPIRequest $request) { $viewer = $request->getUser(); $raw_diff = $request->getValue('diff'); $repository_phid = $request->getValue('repositoryPHID'); if ($repository_phid) { $repository = id(new PhabricatorRepositoryQuery())->setViewer($viewer)->withPHIDs(array($repository_phid))->executeOne(); if (!$repository) { throw new Exception(pht('No such repository "%s"!', $repository_phid)); } } $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($raw_diff); $diff = DifferentialDiff::newFromRawChanges($viewer, $changes); // We're bounded by doing INSERTs for all the hunks and changesets, so // estimate the number of inserts we'll require. $size = 0; foreach ($diff->getChangesets() as $changeset) { $hunks = $changeset->getHunks(); $size += 1 + count($hunks); } $raw_limit = 10000; if ($size > $raw_limit) { throw new Exception(pht('The raw diff you have submitted is too large to parse (it affects ' . 'more than %s paths and hunks). Differential should only be used ' . 'for changes which are small enough to receive detailed human ' . 'review. See "Differential User Guide: Large Changes" in the ' . 'documentation for more information.', new PhutilNumber($raw_limit))); } $diff_data_dict = array('creationMethod' => 'web', 'authorPHID' => $viewer->getPHID(), 'repositoryPHID' => $repository_phid, 'lintStatus' => DifferentialLintStatus::LINT_SKIP, 'unitStatus' => DifferentialUnitStatus::UNIT_SKIP); $xactions = array(id(new DifferentialDiffTransaction())->setTransactionType(DifferentialDiffTransaction::TYPE_DIFF_CREATE)->setNewValue($diff_data_dict)); if ($request->getValue('viewPolicy')) { $xactions[] = id(new DifferentialDiffTransaction())->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)->setNewValue($request->getValue('viewPolicy')); } id(new DifferentialDiffEditor())->setActor($viewer)->setContentSource($request->newContentSource())->setContinueOnNoEffect(true)->setLookupRepository(false)->applyTransactions($diff, $xactions); return $this->buildDiffInfoDictionary($diff); }
private function buildChangesetParsers($type, $data, $file) { $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($data); $diff = DifferentialDiff::newFromRawChanges(PhabricatorUser::getOmnipotentUser(), $changes); $changesets = $diff->getChangesets(); $engine = new PhabricatorMarkupEngine(); $engine->setViewer(new PhabricatorUser()); $parsers = array(); foreach ($changesets as $changeset) { $cparser = new DifferentialChangesetParser(); $cparser->setUser(new PhabricatorUser()); $cparser->setDisableCache(true); $cparser->setChangeset($changeset); $cparser->setMarkupEngine($engine); if ($type == 'one') { $cparser->setRenderer(new DifferentialChangesetOneUpTestRenderer()); } else { if ($type == 'two') { $cparser->setRenderer(new DifferentialChangesetTwoUpTestRenderer()); } else { throw new Exception(pht('Unknown renderer type "%s"!', $type)); } } $parsers[] = $cparser; } return $parsers; }
public function processRequest() { $request = $this->getRequest(); if ($request->isFormPost()) { $parser = new ArcanistDiffParser(); $diff = null; try { $diff = PhabricatorFile::readUploadedFileData($_FILES['diff-file']); } catch (Exception $ex) { $diff = $request->getStr('diff'); } $changes = $parser->parseDiff($diff); $diff = DifferentialDiff::newFromRawChanges($changes); $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP); $diff->setUnitStatus(DifferentialLintStatus::LINT_SKIP); $diff->setAuthorPHID($request->getUser()->getPHID()); $diff->setCreationMethod('web'); $diff->save(); return id(new AphrontRedirectResponse())->setURI('/differential/diff/' . $diff->getID() . '/'); } $form = new AphrontFormView(); $arcanist_href = PhabricatorEnv::getDoclink('article/Arcanist_User_Guide.html'); $arcanist_link = phutil_render_tag('a', array('href' => $arcanist_href, 'target' => '_blank'), 'Arcanist'); $form->setAction('/differential/diff/create/')->setEncType('multipart/form-data')->setUser($request->getUser())->appendChild('<p class="aphront-form-instructions">The best way to create a ' . "Differential diff is by using {$arcanist_link}, but you " . 'can also just paste a diff (e.g., from <tt>svn diff</tt> or ' . '<tt>git diff</tt>) into this box or upload it as a file if you ' . 'really want.</p>')->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Raw Diff')->setName('diff')->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL))->appendChild(id(new AphrontFormFileControl())->setLabel('Raw Diff from file')->setName('diff-file'))->appendChild(id(new AphrontFormSubmitControl())->setValue("Create Diff »")); $panel = new AphrontPanelView(); $panel->setHeader('Create New Diff'); $panel->appendChild($form); $panel->setWidth(AphrontPanelView::WIDTH_FORM); return $this->buildStandardPageResponse($panel, array('title' => 'Create Diff', 'tab' => 'create')); }
private function getBranchDescription(DifferentialDiff $diff) { $branch = $diff->getBranch(); $bookmark = $diff->getBookmark(); if (strlen($branch) && strlen($bookmark)) { return pht('%s (bookmark) on %s (branch)', $bookmark, $branch); } else { if (strlen($bookmark)) { return pht('%s (bookmark)', $bookmark); } else { if (strlen($branch)) { return $branch; } else { return null; } } } }
public function saveDiff(DifferentialDiff $diff) { $actor = $this->requireActor(); // Generate a PHID first, so the transcript will point at the object if // we deicde to preserve it. $phid = $diff->generatePHID(); $diff->setPHID($phid); $adapter = id(new HeraldDifferentialDiffAdapter())->setDiff($diff); $adapter->setContentSource($this->getContentSource()); $adapter->setIsNewObject(true); $engine = new HeraldEngine(); $rules = $engine->loadRulesForAdapter($adapter); $rules = mpull($rules, null, 'getID'); $effects = $engine->applyRules($rules, $adapter); $blocking_effect = null; foreach ($effects as $effect) { if ($effect->getAction() == HeraldAdapter::ACTION_BLOCK) { $blocking_effect = $effect; break; } } if ($blocking_effect) { $rule = idx($rules, $effect->getRuleID()); if ($rule && strlen($rule->getName())) { $rule_name = $rule->getName(); } else { $rule_name = pht('Unnamed Herald Rule'); } $message = $effect->getTarget(); if (!strlen($message)) { $message = pht('(None.)'); } throw new DifferentialDiffCreationRejectException(pht("Creation of this diff was rejected by Herald rule %s.\n" . " Rule: %s\n" . "Reason: %s", 'H' . $effect->getRuleID(), $rule_name, $message)); } $diff->save(); // NOTE: We only save the transcript if we didn't block the diff. // Otherwise, we might save some of the diff's content in the transcript // table, which would defeat the purpose of allowing rules to block // storage of key material. $engine->applyEffects($effects, $adapter, $rules); $xscript = $engine->getTranscript(); }
private function createHunksFromFile($name) { $data = Filesystem::readFile(dirname(__FILE__) . '/data/' . $name); $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($data); if (count($changes) !== 1) { throw new Exception("Expected 1 changeset for '{$name}'!"); } $diff = DifferentialDiff::newFromRawChanges($changes); return head($diff->getChangesets())->getHunks(); }
public function renderDiffPropertyViewValue(DifferentialDiff $diff) { // TODO: This load is slightly inefficient, but most of this is moving // to Harbormaster and this simplifies the transition. Eat 1-2 extra // queries for now. $keys = $this->getDiffPropertyKeys(); $properties = id(new DifferentialDiffProperty())->loadAllWhere('diffID = %d AND name IN (%Ls)', $diff->getID(), $keys); $properties = mpull($properties, 'getData', 'getName'); foreach ($keys as $key) { $diff->attachProperty($key, idx($properties, $key)); } $target_phids = $diff->getBuildTargetPHIDs(); if ($target_phids) { $messages = $this->loadHarbormasterTargetMessages($target_phids); } else { $messages = array(); } if (!$messages) { // No Harbormaster messages, so look for legacy messages and make them // look like modern messages. $legacy_messages = $diff->getProperty($this->getLegacyProperty()); if ($legacy_messages) { // Show the top 100 legacy lint messages. Previously, we showed some // by default and let the user toggle the rest. With modern messages, // we can send the user to the Harbormaster detail page. Just show // "a lot" of messages in legacy cases to try to strike a balance // between implementation simplicitly and compatibility. $legacy_messages = array_slice($legacy_messages, 0, 100); foreach ($legacy_messages as $message) { try { $modern = $this->newModernMessage($message); $messages[] = $modern; } catch (Exception $ex) { // Ignore any poorly formatted messages. } } } } $status = $this->renderHarbormasterStatus($diff, $messages); if ($messages) { $path_map = mpull($diff->loadChangesets(), 'getID', 'getFilename'); foreach ($path_map as $path => $id) { $href = '#C' . $id . 'NL'; // TODO: When the diff is not the right-hand-size diff, we should // ideally adjust this URI to be absolute. $path_map[$path] = $href; } $view = $this->newHarbormasterMessageView($messages); if ($view) { $view->setPathURIMap($path_map); } } else { $view = null; } if ($view) { $view = phutil_tag('div', array('class' => 'differential-harbormaster-table-view'), $view); } return array($status, $view); }
protected function execute(ConduitAPIRequest $request) { $raw_diff = $request->getValue('diff'); $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($raw_diff); $diff = DifferentialDiff::newFromRawChanges($changes); $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP); $diff->setUnitStatus(DifferentialLintStatus::LINT_SKIP); $diff->setAuthorPHID($request->getUser()->getPHID()); $diff->setCreationMethod('web'); $diff->save(); return $this->buildDiffInfoDictionary($diff); }
private function getBranchDescription(DifferentialDiff $diff) { $branch = $diff->getBranch(); $bookmark = $diff->getBookmark(); if (strlen($branch) && strlen($bookmark)) { return pht('%s (bookmark) on %s (branch)', $bookmark, $branch); } else { if (strlen($bookmark)) { return pht('%s (bookmark)', $bookmark); } else { if (strlen($branch)) { $onto = $diff->loadTargetBranch(); if (strlen($onto) && $onto !== $branch) { return pht('%s (branched from %s)', $branch, $onto); } else { return $branch; } } else { return null; } } } }
public static function createDiffDict(DifferentialDiff $diff) { $dict = array('id' => $diff->getID(), 'parent' => $diff->getParentRevisionID(), 'revisionID' => $diff->getRevisionID(), 'sourceControlBaseRevision' => $diff->getSourceControlBaseRevision(), 'sourceControlPath' => $diff->getSourceControlPath(), 'changes' => array(), 'properties' => array()); foreach ($diff->getChangesets() as $changeset) { $hunks = array(); foreach ($changeset->getHunks() as $hunk) { $hunks[] = array('oldOffset' => $hunk->getOldOffset(), 'newOffset' => $hunk->getNewOffset(), 'oldLength' => $hunk->getOldLen(), 'newLength' => $hunk->getNewLen(), 'addLines' => null, 'delLines' => null, 'isMissingOldNewline' => null, 'isMissingNewNewline' => null, 'corpus' => $hunk->getChanges()); } $change = array('metadata' => $changeset->getMetadata(), 'oldPath' => $changeset->getOldFile(), 'currentPath' => $changeset->getFileName(), 'awayPaths' => $changeset->getAwayPaths(), 'oldProperties' => $changeset->getOldProperties(), 'newProperties' => $changeset->getNewProperties(), 'type' => $changeset->getChangeType(), 'fileType' => $changeset->getFileType(), 'commitHash' => null, 'hunks' => $hunks); $dict['changes'][] = $change; } $properties = id(new DifferentialDiffProperty())->loadAllWhere('diffID = %d', $diff->getID()); foreach ($properties as $property) { $dict['properties'][$property->getName()] = $property->getData(); } return $dict; }
public function buildPatch() { $diff = new DifferentialDiff(); $diff->attachChangesets($this->getChangesets()); $raw_changes = $diff->buildChangesList(); $changes = array(); foreach ($raw_changes as $changedict) { $changes[] = ArcanistDiffChange::newFromDictionary($changedict); } $viewer = $this->getViewer(); $loader = id(new PhabricatorFileBundleLoader())->setViewer($viewer); $bundle = ArcanistBundle::newFromChanges($changes); $bundle->setLoadFileDataCallback(array($loader, 'loadFileData')); $format = $this->getFormat(); switch ($format) { case 'git': return $bundle->toGitPatch(); break; case 'unified': default: return $bundle->toUnifiedDiff(); break; } }
public function handleRequest(AphrontRequest $request) { $response = $this->loadDiffusionContext(); if ($response) { return $response; } $viewer = $this->getViewer(); $drequest = $this->getDiffusionRequest(); $content = array(); $data = $this->callConduitWithDiffusionRequest('diffusion.diffquery', array('commit' => $drequest->getCommit(), 'path' => $drequest->getPath())); $drequest->updateSymbolicCommit($data['effectiveCommit']); $raw_changes = ArcanistDiffChange::newFromConduit($data['changes']); $diff = DifferentialDiff::newEphemeralFromRawChanges($raw_changes); $changesets = $diff->getChangesets(); $changeset = reset($changesets); if (!$changeset) { // TODO: Refine this. return new Aphront404Response(); } $repository = $drequest->getRepository(); $changesets = array(0 => $changeset); $changeset_view = new DifferentialChangesetListView(); $changeset_view->setTitle(pht('Change')); $changeset_view->setChangesets($changesets); $changeset_view->setVisibleChangesets($changesets); $changeset_view->setRenderingReferences(array(0 => $drequest->generateURI(array('action' => 'rendering-ref')))); $raw_params = array('action' => 'browse', 'params' => array('view' => 'raw')); $right_uri = $drequest->generateURI($raw_params); $raw_params['params']['before'] = $drequest->getStableCommit(); $left_uri = $drequest->generateURI($raw_params); $changeset_view->setRawFileURIs($left_uri, $right_uri); $changeset_view->setRenderURI($repository->getPathURI('diff/')); $changeset_view->setWhitespace(DifferentialChangesetParser::WHITESPACE_SHOW_ALL); $changeset_view->setUser($viewer); // TODO: This is pretty awkward, unify the CSS between Diffusion and // Differential better. require_celerity_resource('differential-core-view-css'); $content[] = $changeset_view->render(); $crumbs = $this->buildCrumbs(array('branch' => true, 'path' => true, 'view' => 'change')); $links = $this->renderPathLinks($drequest, $mode = 'browse'); $header = id(new PHUIHeaderView())->setHeader($links)->setUser($viewer)->setPolicyObject($drequest->getRepository()); $actions = $this->buildActionView($drequest); $properties = $this->buildPropertyView($drequest, $actions); $object_box = id(new PHUIObjectBoxView())->setHeader($header)->addPropertyList($properties); return $this->newPage()->setTitle(array(basename($drequest->getPath()), $repository->getDisplayName()))->setCrumbs($crumbs)->appendChild(array($object_box, $content)); }
protected function renderHarbormasterStatus(DifferentialDiff $diff, array $messages) { $colors = array(DifferentialUnitStatus::UNIT_NONE => 'grey', DifferentialUnitStatus::UNIT_OKAY => 'green', DifferentialUnitStatus::UNIT_WARN => 'yellow', DifferentialUnitStatus::UNIT_FAIL => 'red', DifferentialUnitStatus::UNIT_SKIP => 'blue', DifferentialUnitStatus::UNIT_AUTO_SKIP => 'blue'); $icon_color = idx($colors, $diff->getUnitStatus(), 'grey'); $message = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($diff); $note = array(); $groups = mgroup($messages, 'getResult'); $groups = array_select_keys($groups, array(ArcanistUnitTestResult::RESULT_FAIL, ArcanistUnitTestResult::RESULT_BROKEN, ArcanistUnitTestResult::RESULT_UNSOUND, ArcanistUnitTestResult::RESULT_SKIP, ArcanistUnitTestResult::RESULT_PASS)) + $groups; foreach ($groups as $result => $group) { $count = phutil_count($group); switch ($result) { case ArcanistUnitTestResult::RESULT_PASS: $note[] = pht('%s Passed Test(s)', $count); break; case ArcanistUnitTestResult::RESULT_FAIL: $note[] = pht('%s Failed Test(s)', $count); break; case ArcanistUnitTestResult::RESULT_SKIP: $note[] = pht('%s Skipped Test(s)', $count); break; case ArcanistUnitTestResult::RESULT_BROKEN: $note[] = pht('%s Broken Test(s)', $count); break; case ArcanistUnitTestResult::RESULT_UNSOUND: $note[] = pht('%s Unsound Test(s)', $count); break; default: $note[] = pht('%s Other Test(s)', $count); break; } } $buildable = $diff->getBuildable(); if ($buildable) { $full_results = '/harbormaster/unit/' . $buildable->getID() . '/'; $note[] = phutil_tag('a', array('href' => $full_results), pht('View Full Results')); } $excuse = $diff->getProperty('arc:unit-excuse'); if (strlen($excuse)) { $excuse = array(phutil_tag('strong', array(), pht('Excuse:')), ' ', phutil_escape_html_newlines($excuse)); $note[] = $excuse; } $note = phutil_implode_html(" · ", $note); $status = id(new PHUIStatusListView())->addItem(id(new PHUIStatusItemView())->setIcon(PHUIStatusItemView::ICON_STAR, $icon_color)->setTarget($message)->setNote($note)); return $status; }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); if (!$drequest->getRawCommit()) { $effective_commit = $this->getEffectiveCommit(); if (!$effective_commit) { return null; } // TODO: This side effect is kind of skethcy. $drequest->setCommit($effective_commit); } else { $effective_commit = $drequest->getCommit(); } $options = array('-M', '-C', '--no-ext-diff', '--no-color', '--src-prefix=a/', '--dst-prefix=b/', '-U65535'); $options = implode(' ', $options); try { list($raw_diff) = $repository->execxLocalCommand('diff %C %s^ %s -- %s', $options, $effective_commit, $effective_commit, $drequest->getPath()); } catch (CommandException $ex) { // Check if this is the root commit by seeing if it has parents. list($parents) = $repository->execxLocalCommand('log --format=%s %s --', '%P', $effective_commit); if (!strlen(trim($parents))) { // No parents means we're looking at the root revision. Diff against // the empty tree hash instead, since there is no parent so "^" does // not work. See ArcanistGitAPI for more discussion. list($raw_diff) = $repository->execxLocalCommand('diff %C %s %s -- %s', $options, ArcanistGitAPI::GIT_MAGIC_ROOT_COMMIT, $effective_commit, $drequest->getPath()); } else { throw $ex; } } $parser = new ArcanistDiffParser(); $try_encoding = $repository->getDetail('encoding'); if ($try_encoding) { $parser->setTryEncoding($try_encoding); } $parser->setDetectBinaryFiles(true); $changes = $parser->parseDiff($raw_diff); $diff = DifferentialDiff::newFromRawChanges($changes); $changesets = $diff->getChangesets(); $changeset = reset($changesets); $this->renderingReference = $drequest->getBranchURIComponent($drequest->getBranch()) . $drequest->getPath() . ';' . $drequest->getCommit(); return $changeset; }
private function loadHunk($name) { $root = dirname(__FILE__) . '/hunk/'; $data = Filesystem::readFile($root . $name); $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($data); $viewer = PhabricatorUser::getOmnipotentUser(); $diff = DifferentialDiff::newFromRawChanges($viewer, $changes); $changesets = $diff->getChangesets(); if (count($changesets) !== 1) { throw new Exception(pht('Expected exactly one changeset from "%s".', $name)); } $changeset = head($changesets); $hunks = $changeset->getHunks(); if (count($hunks) !== 1) { throw new Exception(pht('Expected exactly one hunk from "%s".', $name)); } $hunk = head($hunks); return $hunk; }