Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2895071
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
38 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/applications/diffusion/controller/DiffusionLastModifiedController.php b/src/applications/diffusion/controller/DiffusionLastModifiedController.php
index 3487733c8b..b23abf1903 100644
--- a/src/applications/diffusion/controller/DiffusionLastModifiedController.php
+++ b/src/applications/diffusion/controller/DiffusionLastModifiedController.php
@@ -1,166 +1,163 @@
<?php
final class DiffusionLastModifiedController extends DiffusionController {
public function shouldAllowPublic() {
return true;
}
protected function processDiffusionRequest(AphrontRequest $request) {
$drequest = $this->getDiffusionRequest();
$viewer = $request->getUser();
$paths = $request->getStr('paths');
try {
$paths = phutil_json_decode($paths);
} catch (PhutilJSONParserException $ex) {
return new Aphront400Response();
}
$modified_map = $this->callConduitWithDiffusionRequest(
'diffusion.lastmodifiedquery',
array(
'paths' => array_fill_keys($paths, $drequest->getCommit()),
));
if ($modified_map) {
$commit_map = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withRepository($drequest->getRepository())
->withIdentifiers(array_values($modified_map))
->needCommitData(true)
->execute();
$commit_map = mpull($commit_map, null, 'getCommitIdentifier');
} else {
$commit_map = array();
}
$commits = array();
foreach ($paths as $path) {
$modified_at = idx($modified_map, $path);
if ($modified_at) {
$commit = idx($commit_map, $modified_at);
if ($commit) {
$commits[$path] = $commit;
}
}
}
$phids = array();
foreach ($commits as $commit) {
$data = $commit->getCommitData();
$phids[] = $data->getCommitDetail('authorPHID');
$phids[] = $data->getCommitDetail('committerPHID');
}
$phids = array_filter($phids);
$handles = $this->loadViewerHandles($phids);
$branch = $drequest->loadBranch();
if ($branch && $commits) {
$lint_query = id(new DiffusionLintCountQuery())
->withBranchIDs(array($branch->getID()))
->withPaths(array_keys($commits));
if ($drequest->getLint()) {
$lint_query->withCodes(array($drequest->getLint()));
}
$lint = $lint_query->execute();
} else {
$lint = array();
}
$output = array();
foreach ($commits as $path => $commit) {
$prequest = clone $drequest;
$prequest->setPath($path);
$output[$path] = $this->renderColumns(
$prequest,
$handles,
$commit,
idx($lint, $path));
}
return id(new AphrontAjaxResponse())->setContent($output);
}
private function renderColumns(
DiffusionRequest $drequest,
array $handles,
PhabricatorRepositoryCommit $commit = null,
$lint = null) {
assert_instances_of($handles, 'PhabricatorObjectHandle');
$viewer = $this->getRequest()->getUser();
if ($commit) {
$epoch = $commit->getEpoch();
$modified = DiffusionView::linkCommit(
$drequest->getRepository(),
$commit->getCommitIdentifier());
- $date = phabricator_date($epoch, $viewer);
- $time = phabricator_time($epoch, $viewer);
+ $date = phabricator_datetime($epoch, $viewer);
} else {
$modified = '';
$date = '';
- $time = '';
}
$data = $commit->getCommitData();
if ($data) {
$author_phid = $data->getCommitDetail('authorPHID');
if ($author_phid && isset($handles[$author_phid])) {
$author = $handles[$author_phid]->renderLink();
} else {
$author = DiffusionView::renderName($data->getAuthorName());
}
$committer = $data->getCommitDetail('committer');
if ($committer) {
$committer_phid = $data->getCommitDetail('committerPHID');
if ($committer_phid && isset($handles[$committer_phid])) {
$committer = $handles[$committer_phid]->renderLink();
} else {
$committer = DiffusionView::renderName($committer);
}
if ($author != $committer) {
$author = hsprintf('%s/%s', $author, $committer);
}
}
$details = AphrontTableView::renderSingleDisplayLine($data->getSummary());
} else {
$author = '';
$details = '';
}
$return = array(
'commit' => $modified,
'date' => $date,
- 'time' => $time,
'author' => $author,
'details' => $details,
);
if ($lint !== null) {
$return['lint'] = phutil_tag(
'a',
array(
'href' => $drequest->generateURI(array(
'action' => 'lint',
'lint' => null,
)),
),
number_format($lint));
}
// The client treats these results as markup, so make sure they have been
// escaped correctly.
foreach ($return as $key => $value) {
$return[$key] = hsprintf('%s', $value);
}
return $return;
}
}
diff --git a/src/applications/diffusion/view/DiffusionBranchTableView.php b/src/applications/diffusion/view/DiffusionBranchTableView.php
index d053d5bb33..0f4594e576 100644
--- a/src/applications/diffusion/view/DiffusionBranchTableView.php
+++ b/src/applications/diffusion/view/DiffusionBranchTableView.php
@@ -1,156 +1,165 @@
<?php
final class DiffusionBranchTableView extends DiffusionView {
private $branches;
private $commits = array();
public function setBranches(array $branches) {
assert_instances_of($branches, 'DiffusionRepositoryRef');
$this->branches = $branches;
return $this;
}
public function setCommits(array $commits) {
assert_instances_of($commits, 'PhabricatorRepositoryCommit');
$this->commits = mpull($commits, null, 'getCommitIdentifier');
return $this;
}
public function render() {
$drequest = $this->getDiffusionRequest();
$current_branch = $drequest->getBranch();
$repository = $drequest->getRepository();
+ $commits = $this->commits;
+ $viewer = $this->getUser();
+
+ $buildables = $this->loadBuildables($commits);
+ $have_builds = false;
$can_close_branches = ($repository->isHg());
Javelin::initBehavior('phabricator-tooltips');
$doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: Autoclose');
$rows = array();
$rowc = array();
foreach ($this->branches as $branch) {
- $commit = idx($this->commits, $branch->getCommitIdentifier());
+ $commit = idx($commits, $branch->getCommitIdentifier());
if ($commit) {
$details = $commit->getSummary();
- $datetime = phabricator_datetime($commit->getEpoch(), $this->user);
+ $datetime = phabricator_datetime($commit->getEpoch(), $viewer);
+ $buildable = idx($buildables, $commit->getPHID());
+ if ($buildable) {
+ $build_status = $this->renderBuildable($buildable);
+ $have_builds = true;
+ } else {
+ $build_status = null;
+ }
} else {
$datetime = null;
$details = null;
+ $build_status = null;
}
switch ($repository->shouldSkipAutocloseBranch($branch->getShortName())) {
case PhabricatorRepository::BECAUSE_REPOSITORY_IMPORTING:
$icon = 'fa-times bluegrey';
$tip = pht('Repository Importing');
break;
case PhabricatorRepository::BECAUSE_AUTOCLOSE_DISABLED:
$icon = 'fa-times bluegrey';
$tip = pht('Repository Autoclose Disabled');
break;
case PhabricatorRepository::BECAUSE_BRANCH_UNTRACKED:
$icon = 'fa-times bluegrey';
$tip = pht('Branch Untracked');
break;
case PhabricatorRepository::BECAUSE_BRANCH_NOT_AUTOCLOSE:
$icon = 'fa-times bluegrey';
$tip = pht('Branch Autoclose Disabled');
break;
case null:
$icon = 'fa-check bluegrey';
$tip = pht('Autoclose Enabled');
break;
default:
$icon = 'fa-question';
$tip = pht('Status Unknown');
break;
}
$status_icon = id(new PHUIIconView())
->setIconFont($icon)
->addSigil('has-tooltip')
->setHref($doc_href)
->setMetadata(
array(
'tip' => $tip,
'size' => 200,
));
$fields = $branch->getRawFields();
$closed = idx($fields, 'closed');
if ($closed) {
$status = pht('Closed');
} else {
$status = pht('Open');
}
$rows[] = array(
- phutil_tag(
- 'a',
- array(
- 'href' => $drequest->generateURI(
- array(
- 'action' => 'history',
- 'branch' => $branch->getShortName(),
- )),
- ),
- pht('History')),
+ $this->linkBranchHistory($branch->getShortName()),
phutil_tag(
'a',
array(
'href' => $drequest->generateURI(
array(
'action' => 'browse',
'branch' => $branch->getShortName(),
)),
),
$branch->getShortName()),
self::linkCommit(
$drequest->getRepository(),
$branch->getCommitIdentifier()),
+ $build_status,
$status,
+ AphrontTableView::renderSingleDisplayLine($details),
$status_icon,
$datetime,
- AphrontTableView::renderSingleDisplayLine($details),
);
if ($branch->getShortName() == $current_branch) {
$rowc[] = 'highlighted';
} else {
$rowc[] = null;
}
}
$view = new AphrontTableView($rows);
$view->setHeaders(
array(
- pht('History'),
+ null,
pht('Branch'),
pht('Head'),
+ null,
pht('State'),
- pht(''),
- pht('Modified'),
pht('Details'),
+ null,
+ pht('Committed'),
));
$view->setColumnClasses(
array(
'',
'pri',
'',
+ 'icon',
'',
+ 'wide',
'',
'',
- 'wide',
));
$view->setColumnVisibility(
array(
true,
true,
true,
+ $have_builds,
$can_close_branches,
));
$view->setRowClasses($rowc);
return $view->render();
}
+
}
diff --git a/src/applications/diffusion/view/DiffusionBrowseTableView.php b/src/applications/diffusion/view/DiffusionBrowseTableView.php
index a8eb745fe4..71cc659897 100644
--- a/src/applications/diffusion/view/DiffusionBrowseTableView.php
+++ b/src/applications/diffusion/view/DiffusionBrowseTableView.php
@@ -1,155 +1,156 @@
<?php
final class DiffusionBrowseTableView extends DiffusionView {
private $paths;
private $handles = array();
public function setPaths(array $paths) {
assert_instances_of($paths, 'DiffusionRepositoryPath');
$this->paths = $paths;
return $this;
}
public function setHandles(array $handles) {
assert_instances_of($handles, 'PhabricatorObjectHandle');
$this->handles = $handles;
return $this;
}
public function render() {
$request = $this->getDiffusionRequest();
$repository = $request->getRepository();
$base_path = trim($request->getPath(), '/');
if ($base_path) {
$base_path = $base_path.'/';
}
$need_pull = array();
$rows = array();
$show_edit = false;
foreach ($this->paths as $path) {
+ $history_link = $this->linkHistory($path->getPath());
+
$dir_slash = null;
$file_type = $path->getFileType();
if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
$browse_text = $path->getPath().'/';
$dir_slash = '/';
$browse_link = phutil_tag('strong', array(), $this->linkBrowse(
$base_path.$path->getPath().$dir_slash,
array(
'type' => $file_type,
'name' => $browse_text,
)));
} else if ($file_type == DifferentialChangeType::FILE_SUBMODULE) {
$browse_text = $path->getPath().'/';
$browse_link = phutil_tag('strong', array(), $this->linkBrowse(
null,
array(
'type' => $file_type,
'name' => $browse_text,
'hash' => $path->getHash(),
'external' => $path->getExternalURI(),
)));
} else {
$browse_text = $path->getPath();
$browse_link = $this->linkBrowse(
$base_path.$path->getPath(),
array(
'type' => $file_type,
'name' => $browse_text,
));
}
$dict = array(
'lint' => celerity_generate_unique_node_id(),
'commit' => celerity_generate_unique_node_id(),
'date' => celerity_generate_unique_node_id(),
- 'time' => celerity_generate_unique_node_id(),
'author' => celerity_generate_unique_node_id(),
'details' => celerity_generate_unique_node_id(),
);
$need_pull[$base_path.$path->getPath().$dir_slash] = $dict;
foreach ($dict as $k => $uniq) {
$dict[$k] = phutil_tag('span', array('id' => $uniq), '');
}
$rows[] = array(
+ $history_link,
$browse_link,
idx($dict, 'lint'),
$dict['commit'],
$dict['author'],
$dict['details'],
$dict['date'],
- $dict['time'],
);
}
if ($need_pull) {
Javelin::initBehavior(
'diffusion-pull-lastmodified',
array(
'uri' => (string)$request->generateURI(
array(
'action' => 'lastmodified',
'stable' => true,
)),
'map' => $need_pull,
));
}
$branch = $this->getDiffusionRequest()->loadBranch();
$show_lint = ($branch && $branch->getLintCommit());
$lint = $request->getLint();
$view = new AphrontTableView($rows);
$view->setHeaders(
array(
+ null,
pht('Path'),
($lint ? $lint : pht('Lint')),
pht('Modified'),
pht('Author/Committer'),
pht('Details'),
- pht('Date'),
- pht('Time'),
+ pht('Committed'),
));
$view->setColumnClasses(
array(
+ 'nudgeright',
+ '',
+ '',
'',
- 'n',
- 'n',
'',
'wide',
'',
- 'right',
));
$view->setColumnVisibility(
array(
true,
- $show_lint,
true,
+ $show_lint,
true,
true,
true,
true,
));
$view->setDeviceVisibility(
array(
true,
- false,
true,
false,
true,
false,
+ true,
false,
));
return $view->render();
}
}
diff --git a/src/applications/diffusion/view/DiffusionHistoryTableView.php b/src/applications/diffusion/view/DiffusionHistoryTableView.php
index 80989efdf2..314bfb435c 100644
--- a/src/applications/diffusion/view/DiffusionHistoryTableView.php
+++ b/src/applications/diffusion/view/DiffusionHistoryTableView.php
@@ -1,422 +1,368 @@
<?php
final class DiffusionHistoryTableView extends DiffusionView {
private $history;
private $revisions = array();
private $handles = array();
private $isHead;
private $parents;
- private $buildCache;
public function setHistory(array $history) {
assert_instances_of($history, 'DiffusionPathChange');
$this->history = $history;
- $this->buildCache = null;
return $this;
}
public function loadRevisions() {
$commit_phids = array();
foreach ($this->history as $item) {
if ($item->getCommit()) {
$commit_phids[] = $item->getCommit()->getPHID();
}
}
// TODO: Get rid of this.
$this->revisions = id(new DifferentialRevision())
->loadIDsByCommitPHIDs($commit_phids);
return $this;
}
public function setHandles(array $handles) {
assert_instances_of($handles, 'PhabricatorObjectHandle');
$this->handles = $handles;
return $this;
}
private function getRequiredHandlePHIDs() {
$phids = array();
foreach ($this->history as $item) {
$data = $item->getCommitData();
if ($data) {
if ($data->getCommitDetail('authorPHID')) {
$phids[$data->getCommitDetail('authorPHID')] = true;
}
if ($data->getCommitDetail('committerPHID')) {
$phids[$data->getCommitDetail('committerPHID')] = true;
}
}
}
return array_keys($phids);
}
public function setParents(array $parents) {
$this->parents = $parents;
return $this;
}
public function setIsHead($is_head) {
$this->isHead = $is_head;
return $this;
}
- public function loadBuildablesOnDemand() {
- if ($this->buildCache !== null) {
- return $this->buildCache;
- }
-
- $commits_to_builds = array();
-
- $commits = mpull($this->history, 'getCommit');
-
- $commit_phids = mpull($commits, 'getPHID');
-
- $buildables = id(new HarbormasterBuildableQuery())
- ->setViewer($this->getUser())
- ->withBuildablePHIDs($commit_phids)
- ->withManualBuildables(false)
- ->execute();
-
- $this->buildCache = mpull($buildables, null, 'getBuildablePHID');
-
- return $this->buildCache;
- }
-
public function render() {
$drequest = $this->getDiffusionRequest();
$viewer = $this->getUser();
+ $buildables = $this->loadBuildables(mpull($this->history, 'getCommit'));
+ $has_any_build = false;
+
$show_revisions = PhabricatorApplication::isClassInstalledForViewer(
'PhabricatorDifferentialApplication',
$viewer);
$handles = $viewer->loadHandles($this->getRequiredHandlePHIDs());
$graph = null;
if ($this->parents) {
$graph = $this->renderGraph();
}
$show_builds = PhabricatorApplication::isClassInstalledForViewer(
'PhabricatorHarbormasterApplication',
$this->getUser());
$rows = array();
$ii = 0;
foreach ($this->history as $history) {
$epoch = $history->getEpoch();
if ($epoch) {
- $date = phabricator_date($epoch, $this->user);
- $time = phabricator_time($epoch, $this->user);
+ $committed = phabricator_datetime($epoch, $viewer);
} else {
- $date = null;
- $time = null;
+ $committed = null;
}
$data = $history->getCommitData();
$author_phid = $committer = $committer_phid = null;
if ($data) {
$author_phid = $data->getCommitDetail('authorPHID');
$committer_phid = $data->getCommitDetail('committerPHID');
$committer = $data->getCommitDetail('committer');
}
if ($author_phid && isset($handles[$author_phid])) {
$author = $handles[$author_phid]->renderLink();
} else {
$author = self::renderName($history->getAuthorName());
}
$different_committer = false;
if ($committer_phid) {
$different_committer = ($committer_phid != $author_phid);
} else if ($committer != '') {
$different_committer = ($committer != $history->getAuthorName());
}
if ($different_committer) {
if ($committer_phid && isset($handles[$committer_phid])) {
$committer = $handles[$committer_phid]->renderLink();
} else {
$committer = self::renderName($committer);
}
$author = hsprintf('%s/%s', $author, $committer);
}
// We can show details once the message and change have been imported.
$partial_import = PhabricatorRepositoryCommit::IMPORTED_MESSAGE |
PhabricatorRepositoryCommit::IMPORTED_CHANGE;
$commit = $history->getCommit();
if ($commit && $commit->isPartiallyImported($partial_import) && $data) {
$summary = AphrontTableView::renderSingleDisplayLine(
$history->getSummary());
} else {
$summary = phutil_tag('em', array(), pht("Importing\xE2\x80\xA6"));
}
$build = null;
if ($show_builds) {
- $buildable_lookup = $this->loadBuildablesOnDemand();
- $buildable = idx($buildable_lookup, $commit->getPHID());
+ $buildable = idx($buildables, $commit->getPHID());
if ($buildable !== null) {
- $icon = HarbormasterBuildable::getBuildableStatusIcon(
- $buildable->getBuildableStatus());
- $color = HarbormasterBuildable::getBuildableStatusColor(
- $buildable->getBuildableStatus());
- $name = HarbormasterBuildable::getBuildableStatusName(
- $buildable->getBuildableStatus());
-
- $icon_view = id(new PHUIIconView())
- ->setIconFont($icon.' '.$color);
-
- $tooltip_view = javelin_tag(
- 'span',
- array(
- 'sigil' => 'has-tooltip',
- 'meta' => array('tip' => $name),
- ),
- $icon_view);
-
- Javelin::initBehavior('phabricator-tooltips');
-
- $href_view = phutil_tag(
- 'a',
- array('href' => '/'.$buildable->getMonogram()),
- $tooltip_view);
-
- $build = $href_view;
-
+ $build = $this->renderBuildable($buildable);
$has_any_build = true;
}
}
$browse = $this->linkBrowse(
$history->getPath(),
array(
'commit' => $history->getCommitIdentifier(),
'branch' => $drequest->getBranch(),
'type' => $history->getFileType(),
));
$rows[] = array(
$graph ? $graph[$ii++] : null,
$browse,
self::linkCommit(
$drequest->getRepository(),
$history->getCommitIdentifier()),
$build,
($commit ?
self::linkRevision(idx($this->revisions, $commit->getPHID())) :
null),
$author,
$summary,
- $date,
- $time,
+ $committed,
);
}
$view = new AphrontTableView($rows);
$view->setHeaders(
array(
null,
null,
pht('Commit'),
null,
- pht('Revision'),
+ null,
pht('Author/Committer'),
pht('Details'),
- pht('Date'),
- pht('Time'),
+ pht('Committed'),
));
$view->setColumnClasses(
array(
'threads',
'nudgeright',
- 'n',
+ '',
'icon',
- 'n',
+ '',
'',
'wide',
'',
- 'right',
));
$view->setColumnVisibility(
array(
$graph ? true : false,
true,
true,
- true,
+ $has_any_build,
$show_revisions,
));
$view->setDeviceVisibility(
array(
$graph ? true : false,
true,
true,
true,
true,
false,
true,
false,
- false,
));
return $view->render();
}
/**
* Draw a merge/branch graph from the parent revision data. We're basically
* building up a bunch of strings like this:
*
* ^
* |^
* o|
* |o
* o
*
* ...which form an ASCII representation of the graph we eventually want to
* draw.
*
* NOTE: The actual implementation is black magic.
*/
private function renderGraph() {
// This keeps our accumulated information about each line of the
// merge/branch graph.
$graph = array();
// This holds the next commit we're looking for in each column of the
// graph.
$threads = array();
// This is the largest number of columns any row has, i.e. the width of
// the graph.
$count = 0;
foreach ($this->history as $key => $history) {
$joins = array();
$splits = array();
$parent_list = $this->parents[$history->getCommitIdentifier()];
// Look for some thread which has this commit as the next commit. If
// we find one, this commit goes on that thread. Otherwise, this commit
// goes on a new thread.
$line = '';
$found = false;
$pos = count($threads);
for ($n = 0; $n < $count; $n++) {
if (empty($threads[$n])) {
$line .= ' ';
continue;
}
if ($threads[$n] == $history->getCommitIdentifier()) {
if ($found) {
$line .= ' ';
$joins[] = $n;
unset($threads[$n]);
} else {
$line .= 'o';
$found = true;
$pos = $n;
}
} else {
// We render a "|" for any threads which have a commit that we haven't
// seen yet, this is later drawn as a vertical line.
$line .= '|';
}
}
// If we didn't find the thread this commit goes on, start a new thread.
// We use "o" to mark the commit for the rendering engine, or "^" to
// indicate that there's nothing after it so the line from the commit
// upward should not be drawn.
if (!$found) {
if ($this->isHead) {
$line .= '^';
} else {
$line .= 'o';
foreach ($graph as $k => $meta) {
// Go back across all the lines we've already drawn and add a
// "|" to the end, since this is connected to some future commit
// we don't know about.
for ($jj = strlen($meta['line']); $jj <= $count; $jj++) {
$graph[$k]['line'] .= '|';
}
}
}
}
// Update the next commit on this thread to the commit's first parent.
// This might have the effect of making a new thread.
$threads[$pos] = head($parent_list);
// If we made a new thread, increase the thread count.
$count = max($pos + 1, $count);
// Now, deal with splits (merges). I picked this terms opposite to the
// underlying repository term to confuse you.
foreach (array_slice($parent_list, 1) as $parent) {
$found = false;
// Try to find the other parent(s) in our existing threads. If we find
// them, split to that thread.
foreach ($threads as $idx => $thread_commit) {
if ($thread_commit == $parent) {
$found = true;
$splits[] = $idx;
}
}
// If we didn't find the parent, we don't know about it yet. Find the
// first free thread and add it as the "next" commit in that thread.
// This might create a new thread.
if (!$found) {
for ($n = 0; $n < $count; $n++) {
if (empty($threads[$n])) {
break;
}
}
$threads[$n] = $parent;
$splits[] = $n;
$count = max($n + 1, $count);
}
}
$graph[] = array(
'line' => $line,
'split' => $splits,
'join' => $joins,
);
}
// Render into tags for the behavior.
foreach ($graph as $k => $meta) {
$graph[$k] = javelin_tag(
'div',
array(
'sigil' => 'commit-graph',
'meta' => $meta,
),
'');
}
Javelin::initBehavior(
'diffusion-commit-graph',
array(
'count' => $count,
));
return $graph;
}
}
diff --git a/src/applications/diffusion/view/DiffusionTagListView.php b/src/applications/diffusion/view/DiffusionTagListView.php
index 668453f88e..3b27284f5e 100644
--- a/src/applications/diffusion/view/DiffusionTagListView.php
+++ b/src/applications/diffusion/view/DiffusionTagListView.php
@@ -1,110 +1,138 @@
<?php
final class DiffusionTagListView extends DiffusionView {
private $tags;
private $commits = array();
private $handles = array();
public function setTags($tags) {
$this->tags = $tags;
return $this;
}
public function setCommits(array $commits) {
$this->commits = mpull($commits, null, 'getCommitIdentifier');
return $this;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function getRequiredHandlePHIDs() {
return array_filter(mpull($this->commits, 'getAuthorPHID'));
}
public function render() {
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
+ $buildables = $this->loadBuildables($this->commits);
+ $has_builds = false;
$rows = array();
foreach ($this->tags as $tag) {
$commit = idx($this->commits, $tag->getCommitIdentifier());
$tag_link = phutil_tag(
'a',
array(
'href' => $drequest->generateURI(
array(
'action' => 'browse',
'commit' => $tag->getName(),
)),
),
$tag->getName());
$commit_link = phutil_tag(
'a',
array(
'href' => $drequest->generateURI(
array(
'action' => 'commit',
'commit' => $tag->getCommitIdentifier(),
)),
),
$repository->formatCommitName(
$tag->getCommitIdentifier()));
$author = null;
if ($commit && $commit->getAuthorPHID()) {
$author = $this->handles[$commit->getAuthorPHID()]->renderLink();
} else if ($commit && $commit->getCommitData()) {
$author = self::renderName($commit->getCommitData()->getAuthorName());
} else {
$author = self::renderName($tag->getAuthor());
}
$description = null;
if ($tag->getType() == 'git/tag') {
// In Git, a tag may be a "real" tag, or just a reference to a commit.
// If it's a real tag, use the message on the tag, since this may be
// unique data which isn't otherwise available.
$description = $tag->getDescription();
} else {
if ($commit) {
$description = $commit->getSummary();
} else {
$description = $tag->getDescription();
}
}
+ $build = null;
+ if ($commit) {
+ $buildable = idx($buildables, $commit->getPHID());
+ if ($buildable) {
+ $build = $this->renderBuildable($buildable);
+ $has_builds = true;
+ }
+ }
+
+ $history = $this->linkTagHistory($tag->getName());
+
$rows[] = array(
+ $history,
$tag_link,
$commit_link,
- $description,
+ $build,
$author,
+ $description,
phabricator_datetime($tag->getEpoch(), $this->user),
);
}
- $table = new AphrontTableView($rows);
- $table->setHeaders(
- array(
- pht('Tag'),
- pht('Commit'),
- pht('Description'),
- pht('Author'),
- pht('Created'),
- ));
- $table->setColumnClasses(
- array(
- 'pri',
- '',
- 'wide',
- ));
+ $table = id(new AphrontTableView($rows))
+ ->setHeaders(
+ array(
+ null,
+ pht('Tag'),
+ pht('Commit'),
+ null,
+ pht('Author'),
+ pht('Description'),
+ pht('Created'),
+ ))
+ ->setColumnClasses(
+ array(
+ 'nudgeright',
+ 'pri',
+ '',
+ '',
+ '',
+ 'wide',
+ ))
+ ->setColumnVisibility(
+ array(
+ true,
+ true,
+ true,
+ $has_builds,
+ ));
+
return $table->render();
}
}
diff --git a/src/applications/diffusion/view/DiffusionView.php b/src/applications/diffusion/view/DiffusionView.php
index b7b3599a2d..83fdc1f7e5 100644
--- a/src/applications/diffusion/view/DiffusionView.php
+++ b/src/applications/diffusion/view/DiffusionView.php
@@ -1,173 +1,251 @@
<?php
abstract class DiffusionView extends AphrontView {
private $diffusionRequest;
final public function setDiffusionRequest(DiffusionRequest $request) {
$this->diffusionRequest = $request;
return $this;
}
final public function getDiffusionRequest() {
return $this->diffusionRequest;
}
final public function linkHistory($path) {
$href = $this->getDiffusionRequest()->generateURI(
array(
'action' => 'history',
'path' => $path,
));
+ return $this->renderHistoryLink($href);
+ }
+
+ final public function linkBranchHistory($branch) {
+ $href = $this->getDiffusionRequest()->generateURI(
+ array(
+ 'action' => 'history',
+ 'branch' => $branch,
+ ));
+
+ return $this->renderHistoryLink($href);
+ }
+
+ final public function linkTagHistory($tag) {
+ $href = $this->getDiffusionRequest()->generateURI(
+ array(
+ 'action' => 'history',
+ 'commit' => $tag,
+ ));
+
+ return $this->renderHistoryLink($href);
+ }
+
+ private function renderHistoryLink($href) {
return javelin_tag(
'a',
array(
'href' => $href,
'class' => 'diffusion-link-icon',
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => pht('History'),
'align' => 'E',
),
),
- id(new PHUIIconView())->setIconFont('fa-list-ul blue'));
+ id(new PHUIIconView())->setIconFont('fa-history bluegrey'));
}
final public function linkBrowse($path, array $details = array()) {
require_celerity_resource('diffusion-icons-css');
Javelin::initBehavior('phabricator-tooltips');
$file_type = idx($details, 'type');
unset($details['type']);
$display_name = idx($details, 'name');
unset($details['name']);
if (strlen($display_name)) {
$display_name = phutil_tag(
'span',
array(
'class' => 'diffusion-browse-name',
),
$display_name);
}
if (isset($details['external'])) {
$href = id(new PhutilURI('/diffusion/external/'))
->setQueryParams(
array(
'uri' => idx($details, 'external'),
'id' => idx($details, 'hash'),
));
$tip = pht('Browse External');
} else {
$href = $this->getDiffusionRequest()->generateURI(
$details + array(
'action' => 'browse',
'path' => $path,
));
$tip = pht('Browse');
}
$icon = DifferentialChangeType::getIconForFileType($file_type);
$icon_view = id(new PHUIIconView())->setIconFont("{$icon} blue");
// If we're rendering a file or directory name, don't show the tooltip.
if ($display_name !== null) {
$sigil = null;
$meta = null;
} else {
$sigil = 'has-tooltip';
$meta = array(
'tip' => $tip,
'align' => 'E',
);
}
return javelin_tag(
'a',
array(
'href' => $href,
'class' => 'diffusion-link-icon',
'sigil' => $sigil,
'meta' => $meta,
),
array(
$icon_view,
$display_name,
));
}
final public static function nameCommit(
PhabricatorRepository $repository,
$commit) {
switch ($repository->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$commit_name = substr($commit, 0, 12);
break;
default:
$commit_name = $commit;
break;
}
$callsign = $repository->getCallsign();
return "r{$callsign}{$commit_name}";
}
final public static function linkCommit(
PhabricatorRepository $repository,
$commit,
$summary = '') {
$commit_name = self::nameCommit($repository, $commit);
$callsign = $repository->getCallsign();
if (strlen($summary)) {
$commit_name .= ': '.$summary;
}
return phutil_tag(
'a',
array(
'href' => "/r{$callsign}{$commit}",
),
$commit_name);
}
final public static function linkRevision($id) {
if (!$id) {
return null;
}
return phutil_tag(
'a',
array(
'href' => "/D{$id}",
),
"D{$id}");
}
final public static function renderName($name) {
$email = new PhutilEmailAddress($name);
if ($email->getDisplayName() && $email->getDomainName()) {
Javelin::initBehavior('phabricator-tooltips', array());
require_celerity_resource('aphront-tooltip-css');
return javelin_tag(
'span',
array(
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $email->getAddress(),
'align' => 'E',
'size' => 'auto',
),
),
$email->getDisplayName());
}
return hsprintf('%s', $name);
}
+ final protected function renderBuildable(HarbormasterBuildable $buildable) {
+ $status = $buildable->getBuildableStatus();
+
+ $icon = HarbormasterBuildable::getBuildableStatusIcon($status);
+ $color = HarbormasterBuildable::getBuildableStatusColor($status);
+ $name = HarbormasterBuildable::getBuildableStatusName($status);
+
+ $icon_view = id(new PHUIIconView())
+ ->setIconFont($icon.' '.$color);
+
+ $tooltip_view = javelin_tag(
+ 'span',
+ array(
+ 'sigil' => 'has-tooltip',
+ 'meta' => array('tip' => $name),
+ ),
+ $icon_view);
+
+ Javelin::initBehavior('phabricator-tooltips');
+
+ return phutil_tag(
+ 'a',
+ array('href' => '/'.$buildable->getMonogram()),
+ $tooltip_view);
+ }
+
+ final protected function loadBuildables(array $commits) {
+ assert_instances_of($commits, 'PhabricatorRepositoryCommit');
+
+ if (!$commits) {
+ return array();
+ }
+
+ $viewer = $this->getUser();
+
+ $harbormaster_app = 'PhabricatorHarbormasterApplication';
+ $have_harbormaster = PhabricatorApplication::isClassInstalledForViewer(
+ $harbormaster_app,
+ $viewer);
+
+ if ($have_harbormaster) {
+ $buildables = id(new HarbormasterBuildableQuery())
+ ->setViewer($viewer)
+ ->withBuildablePHIDs(mpull($commits, 'getPHID'))
+ ->withManualBuildables(false)
+ ->execute();
+ $buildables = mpull($buildables, null, 'getBuildablePHID');
+ } else {
+ $buildables = array();
+ }
+
+ return $buildables;
+ }
+
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Jan 19 2025, 20:54 (6 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1128644
Default Alt Text
(38 KB)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment