Page MenuHomePhorge

No OneTemporary

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

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)

Event Timeline