Something went wrong. Try again.
@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
Something went wrong. Try again.
16 kB · 665 lines
PHP
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666<?php
final class DiffusionCommitGraphView extends DiffusionView {
private $history; private $commits; private $isHead; private $isTail; private $parents; private $filterParents; private $noDataString;
private $commitMap; private $buildableMap; private $revisionMap;
private $showAuditors;
/** * @param array<DiffusionPathChange> $history */ public function setHistory(array $history) { assert_instances_of($history, DiffusionPathChange::class); $this->history = $history; return $this; }
public function getHistory() { return $this->history; }
/** * @param array<PhabricatorRepositoryCommit> $commits */ public function setCommits(array $commits) { assert_instances_of($commits, PhabricatorRepositoryCommit::class); $this->commits = $commits; return $this; }
public function getCommits() { return $this->commits; }
public function setShowAuditors($show_auditors) { $this->showAuditors = $show_auditors; return $this; }
public function getShowAuditors() { return $this->showAuditors; }
public function setParents(array $parents) { $this->parents = $parents; return $this; }
public function getParents() { return $this->parents; }
public function setIsHead($is_head) { $this->isHead = $is_head; return $this; }
public function getIsHead() { return $this->isHead; }
public function setIsTail($is_tail) { $this->isTail = $is_tail; return $this; }
public function getIsTail() { return $this->isTail; }
public function setFilterParents($filter_parents) { $this->filterParents = $filter_parents; return $this; }
public function getFilterParents() { return $this->filterParents; }
public function setNoDataString($no_data_string) { $this->noDataString = $no_data_string; return $this; }
private function getRepository() { $drequest = $this->getDiffusionRequest();
if (!$drequest) { return null; }
return $drequest->getRepository(); }
public function newObjectItemListView() { $list_view = new PHUIObjectItemListView();
$item_views = $this->newObjectItemViews(); foreach ($item_views as $item_view) { $list_view->addItem($item_view); }
return $list_view; }
private function newObjectItemViews() { $viewer = $this->getViewer();
require_celerity_resource('diffusion-css');
$show_builds = $this->shouldShowBuilds(); $show_revisions = $this->shouldShowRevisions(); $show_auditors = $this->shouldShowAuditors();
$phids = array();
if ($show_revisions) { $revision_map = $this->getRevisionMap(); foreach ($revision_map as $revisions) { foreach ($revisions as $revision) { $phids[] = $revision->getPHID(); } } }
$commits = $this->getCommitMap();
foreach ($commits as $commit) { $author_phid = $commit->getAuthorDisplayPHID(); if ($author_phid !== null) { $phids[] = $author_phid; } }
if ($show_auditors) { foreach ($commits as $commit) { $audits = $commit->getAudits(); foreach ($audits as $auditor) { $phids[] = $auditor->getAuditorPHID(); } } }
$handles = $viewer->loadHandles($phids);
$views = array();
$items = $this->newHistoryItems(); foreach ($items as $hash => $item) { $content = array();
$commit = $item['commit'];
$commit_description = $this->getCommitDescription($commit); $commit_link = $this->getCommitURI($hash);
$short_hash = $this->getCommitObjectName($hash); $is_disabled = $this->getCommitIsDisabled($commit);
$item_view = id(new PHUIObjectItemView()) ->setViewer($viewer) ->setHeader($commit_description) ->setObjectName($short_hash) ->setHref($commit_link) ->setDisabled($is_disabled);
$this->addBrowseAction($item_view, $hash);
if ($show_builds) { $this->addBuildAction($item_view, $hash); }
// hide Audit entry on /diffusion/commit/query/all if Audit is disabled if (id(new PhabricatorAuditApplication())->isInstalled()) { $this->addAuditAction($item_view, $hash); }
if ($show_auditors) { $auditor_list = $item_view->newMapView(); if ($commit) { $auditors = $this->newAuditorList($commit, $handles); $auditor_list->newItem() ->setName(pht('Auditors')) ->setValue($auditors); } }
$property_list = $item_view->newMapView();
if ($commit) { $author_view = $this->getCommitAuthorView($commit); if ($author_view) { $property_list->newItem() ->setName(pht('Author')) ->setValue($author_view); } }
if ($show_revisions) { if ($commit) { $revisions = $this->getRevisions($commit); if ($revisions) { $list_view = $handles->newSublist(mpull($revisions, 'getPHID')) ->newListView();
$property_list->newItem() ->setName(pht('Revisions')) ->setValue($list_view); } } }
$views[$hash] = $item_view; }
return $views; }
/** * @return array<PHUIObjectItemListView> */ private function newObjectItemRows() { $viewer = $this->getViewer();
$items = $this->newHistoryItems(); $views = $this->newObjectItemViews();
$last_date = null; $rows = array(); foreach ($items as $hash => $item) { $item_epoch = $item['epoch']; $item_date = phabricator_date($item_epoch, $viewer); if ($item_date !== $last_date) { $last_date = $item_date; $header = $item_date; } else { $header = null; }
$item_view = $views[$hash];
$list_view = id(new PHUIObjectItemListView()) ->setViewer($viewer) ->setFlush(true) ->addItem($item_view);
if ($header !== null) { $list_view->setHeader($header); }
$rows[] = $list_view; }
return $rows; }
public function render() { $rows = $this->newObjectItemRows();
$graph = $this->newGraphView(); foreach ($rows as $idx => $row) { $cells = array();
if ($graph) { $cells[] = phutil_tag( 'td', array( 'class' => 'diffusion-commit-graph-path-cell', ), $graph[$idx]); }
$cells[] = phutil_tag( 'td', array( 'class' => 'diffusion-commit-graph-content-cell', ), $row);
$rows[$idx] = phutil_tag('tr', array(), $cells); }
if ($rows) { $table = phutil_tag( 'table', array( 'class' => 'diffusion-commit-graph-table', ), $rows); } else { $table = id(new PHUIObjectItemListView()) ->setNoDataString($this->noDataString); }
return $table; }
private function newGraphView() { if (!$this->getParents()) { return null; }
$parents = $this->getParents();
// If we're filtering parents, remove relationships which point to // commits that are not part of the visible graph. Otherwise, we get // a big tree of nonsense when viewing release branches like "stable" // versus "master". if ($this->getFilterParents()) { foreach ($parents as $key => $nodes) { foreach ($nodes as $nkey => $node) { if (empty($parents[$node])) { unset($parents[$key][$nkey]); } } } }
return id(new PHUIDiffGraphView()) ->setIsHead($this->getIsHead()) ->setIsTail($this->getIsTail()) ->renderGraph($parents); }
private function shouldShowBuilds() { $viewer = $this->getViewer();
$show_builds = PhabricatorApplication::isClassInstalledForViewer( PhabricatorHarbormasterApplication::class, $this->getUser());
return $show_builds; }
private function shouldShowRevisions() { $viewer = $this->getViewer();
$show_revisions = PhabricatorApplication::isClassInstalledForViewer( PhabricatorDifferentialApplication::class, $viewer);
return $show_revisions; }
private function shouldShowAuditors() { return $this->getShowAuditors(); }
private function newHistoryItems() { $items = array();
$history = $this->getHistory(); if ($history !== null) { foreach ($history as $history_item) { $commit_hash = $history_item->getCommitIdentifier();
$items[$commit_hash] = array( 'epoch' => $history_item->getEpoch(), 'hash' => $commit_hash, 'commit' => $this->getCommit($commit_hash), ); } } else { $commits = $this->getCommitMap(); foreach ($commits as $commit) { $commit_hash = $commit->getCommitIdentifier();
$items[$commit_hash] = array( 'epoch' => $commit->getEpoch(), 'hash' => $commit_hash, 'commit' => $commit, ); } }
return $items; }
private function getCommitDescription($commit) { if (!$commit) { return phutil_tag('em', array(), pht("Discovering\xE2\x80\xA6")); }
// We can show details once the message and change have been imported. $partial_import = PhabricatorRepositoryCommit::IMPORTED_MESSAGE | PhabricatorRepositoryCommit::IMPORTED_CHANGE; if (!$commit->isPartiallyImported($partial_import)) { return phutil_tag('em', array(), pht("Importing\xE2\x80\xA6")); }
return $commit->getCommitData()->getSummary(); }
private function getCommitURI($hash) { $repository = $this->getRepository();
if ($repository) { return $repository->getCommitURI($hash); }
$commit = $this->getCommit($hash); if ($commit) { return $commit->getURI(); }
return null; }
private function getCommitObjectName($hash) { $repository = $this->getRepository();
if ($repository) { return $repository->formatCommitName( $hash, $is_local = true); }
$commit = $this->getCommit($hash); if ($commit) { return $commit->getDisplayName(); }
return null; }
private function getCommitIsDisabled($commit) { if (!$commit) { return true; }
if ($commit->isUnreachable()) { return true; }
return false; }
private function getCommitAuthorView($commit) { if (!$commit) { return null; }
$viewer = $this->getViewer();
$author_phid = $commit->getAuthorDisplayPHID(); if ($author_phid) { return $viewer->loadHandles(array($author_phid)) ->newListView(); }
return $commit->newCommitAuthorView($viewer); }
private function getCommit($hash) { $commit_map = $this->getCommitMap(); return idx($commit_map, $hash); }
private function getCommitMap() { if ($this->commitMap === null) { $commit_list = $this->newCommitList(); $this->commitMap = mpull($commit_list, null, 'getCommitIdentifier'); }
return $this->commitMap; }
private function addBrowseAction(PHUIObjectItemView $item, $hash) { $repository = $this->getRepository();
if (!$repository) { return; }
$drequest = $this->getDiffusionRequest(); $path = $drequest->getPath();
$uri = $drequest->generateURI( array( 'action' => 'browse', 'path' => $path, 'commit' => $hash, ));
$menu_item = $item->newMenuItem() ->setName(pht('Browse Repository')) ->setURI($uri);
$menu_item->newIcon() ->setIcon('fa-folder-open-o') ->setColor('bluegrey'); }
private function addBuildAction(PHUIObjectItemView $item, $hash) { $is_disabled = true;
$buildable = null;
$commit = $this->getCommit($hash); if ($commit) { $buildable = $this->getBuildable($commit); }
if ($buildable) { $icon = $buildable->getStatusIcon(); $color = $buildable->getStatusColor(); $name = $buildable->getStatusDisplayName(); $uri = $buildable->getURI(); } else { $icon = 'fa-times'; $color = 'grey'; $name = pht('No Builds'); $uri = null; }
$menu_item = $item->newMenuItem() ->setName($name) ->setURI($uri) ->setDisabled(($uri === null));
$menu_item->newIcon() ->setIcon($icon) ->setColor($color); }
private function addAuditAction(PHUIObjectItemView $item_view, $hash) { $commit = $this->getCommit($hash);
if ($commit) { $status = $commit->getAuditStatusObject();
$text = $status->getName(); $icon = $status->getIcon();
$is_disabled = $status->isNoAudit(); if ($is_disabled) { $uri = null; $color = 'grey'; } else { $color = $status->getColor(); $uri = $commit->getURI(); } } else { $text = pht('No Audit'); $color = 'grey'; $icon = 'fa-times'; $uri = null;
$is_disabled = true; }
$menu_item = $item_view->newMenuItem() ->setName($text) ->setURI($uri) ->setBackgroundColor($color) ->setDisabled($is_disabled);
$menu_item->newIcon() ->setIcon($icon) ->setColor($color); }
private function getBuildable(PhabricatorRepositoryCommit $commit) { $buildable_map = $this->getBuildableMap(); return idx($buildable_map, $commit->getPHID()); }
private function getBuildableMap() { if ($this->buildableMap === null) { $commits = $this->getCommitMap(); $buildables = $this->loadBuildables($commits); $this->buildableMap = $buildables; }
return $this->buildableMap; }
private function getRevisions(PhabricatorRepositoryCommit $commit) { $revision_map = $this->getRevisionMap(); return idx($revision_map, $commit->getPHID(), array()); }
private function getRevisionMap() { if ($this->revisionMap === null) { $this->revisionMap = $this->newRevisionMap(); }
return $this->revisionMap; }
private function newRevisionMap() { $viewer = $this->getViewer(); $commits = $this->getCommitMap();
return DiffusionCommitRevisionQuery::loadRevisionMapForCommits( $viewer, $commits); }
private function newCommitList() { $commits = $this->getCommits(); if ($commits !== null) { return $commits; }
$repository = $this->getRepository(); if (!$repository) { return array(); }
$history = $this->getHistory(); if ($history === null) { return array(); }
$identifiers = array(); foreach ($history as $item) { $identifiers[] = $item->getCommitIdentifier(); }
if (!$identifiers) { return array(); }
$viewer = $this->getViewer();
$commits = id(new DiffusionCommitQuery()) ->setViewer($viewer) ->withRepository($repository) ->withIdentifiers($identifiers) ->needCommitData(true) ->needIdentities(true) ->execute();
return $commits; }
private function newAuditorList( PhabricatorRepositoryCommit $commit, $handles) {
$auditors = $commit->getAudits(); if (!$auditors) { return phutil_tag('em', array(), pht('None')); }
$auditor_phids = mpull($auditors, 'getAuditorPHID'); $auditor_list = $handles->newSublist($auditor_phids) ->newListView();
return $auditor_list; }
}