protected function buildPropertyView(DiffusionRequest $drequest, PhabricatorActionListView $actions)
 {
     $viewer = $this->getRequest()->getUser();
     $view = id(new PHUIPropertyListView())->setUser($viewer)->setActionList($actions);
     $stable_commit = $drequest->getStableCommit();
     $callsign = $drequest->getRepository()->getCallsign();
     $view->addProperty(pht('Commit'), phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'commit', 'commit' => $stable_commit))), $drequest->getRepository()->formatCommitName($stable_commit)));
     return $view;
 }
 protected function newBlameFuture(DiffusionRequest $request, $path)
 {
     $repository = $request->getRepository();
     $commit = $request->getCommit();
     // NOTE: We're using "--debug" to make "--changeset" give us the full
     // commit hashes.
     return $repository->getLocalCommandFuture('annotate --debug --changeset --rev %s -- %s', $commit, $path);
 }
 private function newFile(DiffusionRequest $drequest, $content)
 {
     $path = $drequest->getPath();
     $name = basename($path);
     $repository = $drequest->getRepository();
     $repository_phid = $repository->getPHID();
     $file = PhabricatorFile::buildFromFileDataOrHash($content, array('name' => $name, 'ttl' => time() + phutil_units('48 hours in seconds'), 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE));
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $file->attachToObject($repository_phid);
     unset($unguarded);
     return $file;
 }
 protected function buildPropertyView(DiffusionRequest $drequest, PhabricatorActionListView $actions)
 {
     $viewer = $this->getRequest()->getUser();
     $view = id(new PHUIPropertyListView())->setUser($viewer)->setActionList($actions);
     $stable_commit = $drequest->getStableCommit();
     $callsign = $drequest->getRepository()->getCallsign();
     $view->addProperty(pht('Commit'), phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'commit', 'commit' => $stable_commit))), $drequest->getRepository()->formatCommitName($stable_commit)));
     if ($drequest->getSymbolicType() == 'tag') {
         $symbolic = $drequest->getSymbolicCommit();
         $view->addProperty(pht('Tag'), $symbolic);
         $tags = $this->callConduitWithDiffusionRequest('diffusion.tagsquery', array('names' => array($symbolic), 'needMessages' => true));
         $tags = DiffusionRepositoryTag::newFromConduit($tags);
         $tags = mpull($tags, null, 'getName');
         $tag = idx($tags, $symbolic);
         if ($tag && strlen($tag->getMessage())) {
             $view->addSectionHeader(pht('Tag Content'));
             $view->addTextContent($this->markupText($tag->getMessage()));
         }
     }
     return $view;
 }
 protected function buildPropertyView(DiffusionRequest $drequest, PhabricatorActionListView $actions)
 {
     $viewer = $this->getViewer();
     $view = id(new PHUIPropertyListView())->setUser($viewer)->setActionList($actions);
     $stable_commit = $drequest->getStableCommit();
     $callsign = $drequest->getRepository()->getCallsign();
     $view->addProperty(pht('Commit'), phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'commit', 'commit' => $stable_commit))), $drequest->getRepository()->formatCommitName($stable_commit)));
     if ($drequest->getSymbolicType() == 'tag') {
         $symbolic = $drequest->getSymbolicCommit();
         $view->addProperty(pht('Tag'), $symbolic);
         $tags = $this->callConduitWithDiffusionRequest('diffusion.tagsquery', array('names' => array($symbolic), 'needMessages' => true));
         $tags = DiffusionRepositoryTag::newFromConduit($tags);
         $tags = mpull($tags, null, 'getName');
         $tag = idx($tags, $symbolic);
         if ($tag && strlen($tag->getMessage())) {
             $view->addSectionHeader(pht('Tag Content'));
             $view->addTextContent($this->markupText($tag->getMessage()));
         }
     }
     $repository = $drequest->getRepository();
     $owners = 'PhabricatorOwnersApplication';
     if (PhabricatorApplication::isClassInstalled($owners)) {
         $package_query = id(new PhabricatorOwnersPackageQuery())->setViewer($viewer)->withControl($repository->getPHID(), array($drequest->getPath()));
         $package_query->execute();
         $packages = $package_query->getControllingPackagesForPath($repository->getPHID(), $drequest->getPath());
         if ($packages) {
             $ownership = id(new PHUIStatusListView())->setUser($viewer);
             foreach ($packages as $package) {
                 $icon = 'fa-list-alt';
                 $color = 'grey';
                 $item = id(new PHUIStatusItemView())->setIcon($icon, $color)->setTarget($viewer->renderHandle($package->getPHID()));
                 $ownership->addItem($item);
             }
         } else {
             $ownership = phutil_tag('em', array(), pht('None'));
         }
         $view->addProperty(pht('Packages'), $ownership);
     }
     return $view;
 }
 protected static function newQueryObject($base_class, DiffusionRequest $request)
 {
     $repository = $request->getRepository();
     $map = array(PhabricatorRepositoryType::REPOSITORY_TYPE_GIT => 'Git', PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL => 'Mercurial', PhabricatorRepositoryType::REPOSITORY_TYPE_SVN => 'Svn');
     $name = idx($map, $repository->getVersionControlSystem());
     if (!$name) {
         throw new Exception("Unsupported VCS!");
     }
     $class = str_replace('Diffusion', 'Diffusion' . $name, $base_class);
     $obj = new $class();
     $obj->request = $request;
     return $obj;
 }
 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);
     } 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;
 }
 public static final function newFromDiffusionRequest(DiffusionRequest $request)
 {
     $repository = $request->getRepository();
     switch ($repository->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
             $class = 'DiffusionGitBranchQuery';
             break;
         default:
             throw new Exception("Unsupported VCS!");
     }
     PhutilSymbolLoader::loadClass($class);
     $query = new $class();
     $query->request = $request;
     return $query;
 }
 public static final function newFromDiffusionRequest(DiffusionRequest $request)
 {
     $repository = $request->getRepository();
     switch ($repository->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
             $query = new DiffusionGitBranchQuery();
             break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
             $query = new DiffusionMercurialBranchQuery();
             break;
         default:
             throw new Exception("Unsupported VCS!");
     }
     $query->request = $request;
     return $query;
 }
 public static final function newFromDiffusionRequest(DiffusionRequest $request)
 {
     $repository = $request->getRepository();
     switch ($repository->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
             // TODO: Verify local-path?
             $class = 'DiffusionGitBrowseQuery';
             break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
             $class = 'DiffusionMercurialBrowseQuery';
             break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
             $class = 'DiffusionSvnBrowseQuery';
             break;
         default:
             throw new Exception("Unsupported VCS!");
     }
     PhutilSymbolLoader::loadClass($class);
     $query = new $class();
     $query->request = $request;
     return $query;
 }
 private function buildDisplayRows(array $text_list, array $rev_list, array $blame_dict, $needs_blame, DiffusionRequest $drequest, DiffusionFileContentQuery $file_query, $selected)
 {
     if ($blame_dict) {
         $epoch_list = ipull(ifilter($blame_dict, 'epoch'), 'epoch');
         $epoch_min = min($epoch_list);
         $epoch_max = max($epoch_list);
         $epoch_range = $epoch_max - $epoch_min + 1;
     }
     $line_arr = array();
     $line_str = $drequest->getLine();
     $ranges = explode(',', $line_str);
     foreach ($ranges as $range) {
         if (strpos($range, '-') !== false) {
             list($min, $max) = explode('-', $range, 2);
             $line_arr[] = array('min' => min($min, $max), 'max' => max($min, $max));
         } else {
             if (strlen($range)) {
                 $line_arr[] = array('min' => $range, 'max' => $range);
             }
         }
     }
     $display = array();
     $line_number = 1;
     $last_rev = null;
     $color = null;
     foreach ($text_list as $k => $line) {
         $display_line = array('color' => null, 'epoch' => null, 'commit' => null, 'author' => null, 'target' => null, 'highlighted' => null, 'line' => $line_number, 'data' => $line);
         if ($needs_blame) {
             // If the line's rev is same as the line above, show empty content
             // with same color; otherwise generate blame info. The newer a change
             // is, the more saturated the color.
             // TODO: SVN doesn't always give us blame for the last line, if empty?
             // Bug with our stuff or with SVN?
             $rev = idx($rev_list, $k, $last_rev);
             if ($last_rev == $rev) {
                 $display_line['color'] = $color;
             } else {
                 $blame = $blame_dict[$rev];
                 if (!isset($blame['epoch'])) {
                     $color = '#ffd';
                     // Render as warning.
                 } else {
                     $color_ratio = ($blame['epoch'] - $epoch_min) / $epoch_range;
                     $color_value = 0xf6 * (1.0 - $color_ratio);
                     $color = sprintf('#%02x%02x%02x', $color_value, 0xf6, $color_value);
                 }
                 $display_line['epoch'] = idx($blame, 'epoch');
                 $display_line['color'] = $color;
                 $display_line['commit'] = $rev;
                 if (isset($blame['handle'])) {
                     $author_link = $blame['handle']->renderLink();
                 } else {
                     $author_link = phutil_render_tag('span', array(), phutil_escape_html($blame['author']));
                 }
                 $display_line['author'] = $author_link;
                 $last_rev = $rev;
             }
         }
         if ($line_arr) {
             if ($line_number == $line_arr[0]['min']) {
                 $display_line['target'] = true;
             }
             foreach ($line_arr as $range) {
                 if ($line_number >= $range['min'] && $line_number <= $range['max']) {
                     $display_line['highlighted'] = true;
                 }
             }
         }
         $display[] = $display_line;
         ++$line_number;
     }
     $commits = array_filter(ipull($display, 'commit'));
     if ($commits) {
         $commits = id(new PhabricatorAuditCommitQuery())->withIdentifiers($drequest->getRepository()->getID(), $commits)->needCommitData(true)->execute();
         $commits = mpull($commits, null, 'getCommitIdentifier');
     }
     $revision_ids = id(new DifferentialRevision())->loadIDsByCommitPHIDs(mpull($commits, 'getPHID'));
     $revisions = array();
     if ($revision_ids) {
         $revisions = id(new DifferentialRevision())->loadAllWhere('id IN (%Ld)', $revision_ids);
     }
     $request = $this->getRequest();
     $user = $request->getUser();
     Javelin::initBehavior('phabricator-oncopy', array());
     $rows = array();
     foreach ($display as $line) {
         $line_href = $drequest->generateURI(array('action' => 'browse', 'line' => $line['line'], 'stable' => true));
         $blame = array();
         if ($line['color']) {
             $color = $line['color'];
             $before_link = null;
             $commit_link = null;
             $revision_link = null;
             if (idx($line, 'commit')) {
                 $commit = $line['commit'];
                 $summary = 'Unknown';
                 if (idx($commits, $commit)) {
                     $summary = $commits[$commit]->getCommitData()->getSummary();
                 }
                 $tooltip = phabricator_date($line['epoch'], $user) . " · " . $summary;
                 Javelin::initBehavior('phabricator-tooltips', array());
                 require_celerity_resource('aphront-tooltip-css');
                 $commit_link = javelin_render_tag('a', array('href' => $drequest->generateURI(array('action' => 'commit', 'commit' => $line['commit'])), 'sigil' => 'has-tooltip', 'meta' => array('tip' => $tooltip, 'align' => 'E', 'size' => 600)), phutil_escape_html(phutil_utf8_shorten($line['commit'], 9, '')));
                 $revision_id = null;
                 if (idx($commits, $commit)) {
                     $revision_id = idx($revision_ids, $commits[$commit]->getPHID());
                 }
                 if ($revision_id) {
                     $revision = idx($revisions, $revision_id);
                     if (!$revision) {
                         $tooltip = '(Invalid revision)';
                     } else {
                         $tooltip = phabricator_date($revision->getDateModified(), $user) . " · " . $revision->getTitle();
                     }
                     $revision_link = javelin_render_tag('a', array('href' => '/D' . $revision_id, 'sigil' => 'has-tooltip', 'meta' => array('tip' => $tooltip, 'align' => 'E', 'size' => 600)), 'D' . $revision_id);
                 }
                 $uri = $line_href->alter('before', $commit);
                 $before_link = javelin_render_tag('a', array('href' => $uri->setQueryParam('view', 'blame'), 'sigil' => 'has-tooltip', 'meta' => array('tip' => 'Skip Past This Commit', 'align' => 'E', 'size' => 300)), "«");
             }
             $blame[] = phutil_render_tag('th', array('class' => 'diffusion-blame-link', 'style' => 'background: ' . $color), $before_link);
             $blame[] = phutil_render_tag('th', array('class' => 'diffusion-rev-link', 'style' => 'background: ' . $color), $commit_link);
             $blame[] = phutil_render_tag('th', array('class' => 'diffusion-rev-link', 'style' => 'background: ' . $color), $revision_link);
             $blame[] = phutil_render_tag('th', array('class' => 'diffusion-author-link', 'style' => 'background: ' . $color), idx($line, 'author'));
         }
         $line_link = phutil_render_tag('a', array('href' => $line_href), phutil_escape_html($line['line']));
         $blame[] = javelin_render_tag('th', array('class' => 'diffusion-line-link', 'sigil' => 'diffusion-line-link', 'style' => isset($color) ? 'background: ' . $color : null), $line_link);
         Javelin::initBehavior('diffusion-line-linker');
         $blame = implode('', $blame);
         if ($line['target']) {
             Javelin::initBehavior('diffusion-jump-to', array('target' => 'scroll_target'));
             $anchor_text = '<a id="scroll_target"></a>';
         } else {
             $anchor_text = null;
         }
         $line_text = phutil_render_tag('td', array(), $anchor_text . "​" . $line['data']);
         $rows[] = phutil_render_tag('tr', array('class' => $line['highlighted'] ? 'highlighted' : null), $blame . $line_text);
     }
     return $rows;
 }
 protected function buildPropertyView(DiffusionRequest $drequest, PhabricatorRepositoryBranch $branch, $total, PhabricatorActionListView $actions)
 {
     $viewer = $this->getRequest()->getUser();
     $view = id(new PHUIPropertyListView())->setUser($viewer)->setActionList($actions);
     $lint_commit = $branch->getLintCommit();
     $view->addProperty(pht('Lint Commit'), phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'commit', 'commit' => $lint_commit))), $drequest->getRepository()->formatCommitName($lint_commit)));
     $view->addProperty(pht('Total Messages'), pht('%s', new PhutilNumber($total)));
     return $view;
 }
Beispiel #13
0
 public static final function loadHistoryForCommitIdentifiers(array $identifiers, DiffusionRequest $drequest)
 {
     if (!$identifiers) {
         return array();
     }
     $repository = $drequest->getRepository();
     $commits = self::loadCommitsByIdentifiers($identifiers, $drequest);
     if (!$commits) {
         return array();
     }
     $path = $drequest->getPath();
     $conn_r = $repository->establishConnection('r');
     $path_normal = DiffusionPathIDQuery::normalizePath($path);
     $paths = queryfx_all($conn_r, 'SELECT id, path FROM %T WHERE pathHash IN (%Ls)', PhabricatorRepository::TABLE_PATH, array(md5($path_normal)));
     $paths = ipull($paths, 'id', 'path');
     $path_id = idx($paths, $path_normal);
     $commit_ids = array_filter(mpull($commits, 'getID'));
     $path_changes = array();
     if ($path_id && $commit_ids) {
         $path_changes = queryfx_all($conn_r, 'SELECT * FROM %T WHERE commitID IN (%Ld) AND pathID = %d', PhabricatorRepository::TABLE_PATHCHANGE, $commit_ids, $path_id);
         $path_changes = ipull($path_changes, null, 'commitID');
     }
     $history = array();
     foreach ($identifiers as $identifier) {
         $item = new DiffusionPathChange();
         $item->setCommitIdentifier($identifier);
         $commit = idx($commits, $identifier);
         if ($commit) {
             $item->setCommit($commit);
             try {
                 $item->setCommitData($commit->getCommitData());
             } catch (Exception $ex) {
                 // Ignore, commit just doesn't have data.
             }
             $change = idx($path_changes, $commit->getID());
             if ($change) {
                 $item->setChangeType($change['changeType']);
                 $item->setFileType($change['fileType']);
             }
         }
         $history[] = $item;
     }
     return $history;
 }
 protected function newBlameFuture(DiffusionRequest $request, $path)
 {
     $repository = $request->getRepository();
     $commit = $request->getCommit();
     return $repository->getRemoteCommandFuture('blame --force %s', $repository->getSubversionPathURI($path, $commit));
 }
 protected function newBlameFuture(DiffusionRequest $request, $path)
 {
     $repository = $request->getRepository();
     $commit = $request->getCommit();
     return $repository->getLocalCommandFuture('--no-pager blame -s -l %s -- %s', $commit, $path);
 }
 protected function renderPathLinks(DiffusionRequest $drequest, $action)
 {
     $path = $drequest->getPath();
     $path_parts = array_filter(explode('/', trim($path, '/')));
     $divider = phutil_tag('span', array('class' => 'phui-header-divider'), '/');
     $links = array();
     if ($path_parts) {
         $links[] = phutil_tag('a', array('href' => $drequest->generateURI(array('action' => $action, 'path' => ''))), 'r' . $drequest->getRepository()->getCallsign());
         $links[] = $divider;
         $accum = '';
         $last_key = last_key($path_parts);
         foreach ($path_parts as $key => $part) {
             $accum .= '/' . $part;
             if ($key === $last_key) {
                 $links[] = $part;
             } else {
                 $links[] = phutil_tag('a', array('href' => $drequest->generateURI(array('action' => $action, 'path' => $accum . '/'))), $part);
                 $links[] = $divider;
             }
         }
     } else {
         $links[] = 'r' . $drequest->getRepository()->getCallsign();
         $links[] = $divider;
     }
     return $links;
 }
 private function buildRefs(DiffusionRequest $request)
 {
     // Not turning this into a proper Query class since it's pretty simple,
     // one-off, and Git-specific.
     $type_git = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
     $repository = $request->getRepository();
     if ($repository->getVersionControlSystem() != $type_git) {
         return null;
     }
     list($stdout) = $repository->execxLocalCommand('log --format=%s -n 1 %s --', '%d', $request->getCommit());
     // %d, gives a weird output format
     // similar to (remote/one, remote/two, remote/three)
     $refs = trim($stdout, "() \n");
     if (!$refs) {
         return null;
     }
     $refs = explode(',', $refs);
     $refs = array_map('trim', $refs);
     $ref_links = array();
     foreach ($refs as $ref) {
         $ref_links[] = phutil_render_tag('a', array('href' => $request->generateURI(array('action' => 'browse', 'branch' => $ref))), phutil_escape_html($ref));
     }
     $ref_links = implode(', ', $ref_links);
     return $ref_links;
 }
 protected function renderCommitHashTag(DiffusionRequest $drequest)
 {
     $stable_commit = $drequest->getStableCommit();
     $commit = phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'commit', 'commit' => $stable_commit))), $drequest->getRepository()->formatCommitName($stable_commit, true));
     $tag = id(new PHUITagView())->setName($commit)->setShade('indigo')->setType(PHUITagView::TYPE_SHADE);
     return $tag;
 }
 private function enrichCurtain(PHUICurtainView $curtain, DiffusionRequest $drequest, $show_blame, $show_color)
 {
     $viewer = $this->getViewer();
     $base_uri = $this->getRequest()->getRequestURI();
     $curtain->addAction(id(new PhabricatorActionView())->setName(pht('Show Last Change'))->setHref($drequest->generateURI(array('action' => 'change')))->setIcon('fa-backward'));
     if ($show_blame) {
         $blame_text = pht('Disable Blame');
         $blame_icon = 'fa-exclamation-circle lightgreytext';
         $blame_value = 0;
     } else {
         $blame_text = pht('Enable Blame');
         $blame_icon = 'fa-exclamation-circle';
         $blame_value = 1;
     }
     $curtain->addAction(id(new PhabricatorActionView())->setName($blame_text)->setHref($base_uri->alter('blame', $blame_value))->setIcon($blame_icon)->setUser($viewer)->setRenderAsForm($viewer->isLoggedIn()));
     if ($show_color) {
         $highlight_text = pht('Disable Highlighting');
         $highlight_icon = 'fa-star-o grey';
         $highlight_value = 0;
     } else {
         $highlight_text = pht('Enable Highlighting');
         $highlight_icon = 'fa-star';
         $highlight_value = 1;
     }
     $curtain->addAction(id(new PhabricatorActionView())->setName($highlight_text)->setHref($base_uri->alter('color', $highlight_value))->setIcon($highlight_icon)->setUser($viewer)->setRenderAsForm($viewer->isLoggedIn()));
     $href = null;
     if ($this->getRequest()->getStr('lint') !== null) {
         $lint_text = pht('Hide %d Lint Message(s)', count($this->lintMessages));
         $href = $base_uri->alter('lint', null);
     } else {
         if ($this->lintCommit === null) {
             $lint_text = pht('Lint not Available');
         } else {
             $lint_text = pht('Show %d Lint Message(s)', count($this->lintMessages));
             $href = $this->getDiffusionRequest()->generateURI(array('action' => 'browse', 'commit' => $this->lintCommit))->alter('lint', '');
         }
     }
     $curtain->addAction(id(new PhabricatorActionView())->setName($lint_text)->setHref($href)->setIcon('fa-exclamation-triangle')->setDisabled(!$href));
     $repository = $drequest->getRepository();
     $owners = 'PhabricatorOwnersApplication';
     if (PhabricatorApplication::isClassInstalled($owners)) {
         $package_query = id(new PhabricatorOwnersPackageQuery())->setViewer($viewer)->withStatuses(array(PhabricatorOwnersPackage::STATUS_ACTIVE))->withControl($repository->getPHID(), array($drequest->getPath()));
         $package_query->execute();
         $packages = $package_query->getControllingPackagesForPath($repository->getPHID(), $drequest->getPath());
         if ($packages) {
             $ownership = id(new PHUIStatusListView())->setUser($viewer);
             foreach ($packages as $package) {
                 $icon = 'fa-list-alt';
                 $color = 'grey';
                 $item = id(new PHUIStatusItemView())->setIcon($icon, $color)->setTarget($viewer->renderHandle($package->getPHID()));
                 $ownership->addItem($item);
             }
         } else {
             $ownership = phutil_tag('em', array(), pht('None'));
         }
         $curtain->newPanel()->setHeaderText(pht('Owners'))->appendChild($ownership);
     }
     return $curtain;
 }
 private function buildTagListTable(DiffusionRequest $drequest)
 {
     $viewer = $this->getRequest()->getUser();
     $repository = $drequest->getRepository();
     switch ($repository->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
             // no tags in SVN
             return null;
     }
     $tag_limit = 15;
     $tags = array();
     $tags = DiffusionRepositoryTag::newFromConduit($this->callConduitWithDiffusionRequest('diffusion.tagsquery', array('commit' => null, 'limit' => $tag_limit + 1)));
     if (!$tags) {
         return null;
     }
     $more_tags = count($tags) > $tag_limit;
     $tags = array_slice($tags, 0, $tag_limit);
     $commits = id(new DiffusionCommitQuery())->setViewer($viewer)->withIdentifiers(mpull($tags, 'getCommitIdentifier'))->withRepository($repository)->needCommitData(true)->execute();
     $view = id(new DiffusionTagListView())->setUser($viewer)->setDiffusionRequest($drequest)->setTags($tags)->setCommits($commits);
     $phids = $view->getRequiredHandlePHIDs();
     $handles = $this->loadViewerHandles($phids);
     $view->setHandles($handles);
     $panel = new PHUIObjectBoxView();
     $header = new PHUIHeaderView();
     $header->setHeader(pht('Tags'));
     if ($more_tags) {
         $header->setSubHeader(pht('Showing the %d most recent tags.', $tag_limit));
     }
     $icon = id(new PHUIIconView())->setIconFont('fa-tag');
     $button = new PHUIButtonView();
     $button->setText(pht('Show All Tags'));
     $button->setTag('a');
     $button->setIcon($icon);
     $button->setHref($drequest->generateURI(array('action' => 'tags')));
     $header->addActionLink($button);
     $panel->setHeader($header);
     $panel->setTable($view);
     return $panel;
 }
 private function buildDisplayRows(array $text_list, array $rev_list, array $blame_dict, $needs_blame, DiffusionRequest $drequest, $show_blame, $show_color)
 {
     $handles = array();
     if ($blame_dict) {
         $epoch_list = ipull(ifilter($blame_dict, 'epoch'), 'epoch');
         $epoch_min = min($epoch_list);
         $epoch_max = max($epoch_list);
         $epoch_range = $epoch_max - $epoch_min + 1;
         $author_phids = ipull(ifilter($blame_dict, 'authorPHID'), 'authorPHID');
         $handles = $this->loadViewerHandles($author_phids);
     }
     $line_arr = array();
     $line_str = $drequest->getLine();
     $ranges = explode(',', $line_str);
     foreach ($ranges as $range) {
         if (strpos($range, '-') !== false) {
             list($min, $max) = explode('-', $range, 2);
             $line_arr[] = array('min' => min($min, $max), 'max' => max($min, $max));
         } else {
             if (strlen($range)) {
                 $line_arr[] = array('min' => $range, 'max' => $range);
             }
         }
     }
     $display = array();
     $line_number = 1;
     $last_rev = null;
     $color = null;
     foreach ($text_list as $k => $line) {
         $display_line = array('epoch' => null, 'commit' => null, 'author' => null, 'target' => null, 'highlighted' => null, 'line' => $line_number, 'data' => $line);
         if ($show_blame) {
             // If the line's rev is same as the line above, show empty content
             // with same color; otherwise generate blame info. The newer a change
             // is, the more saturated the color.
             $rev = idx($rev_list, $k, $last_rev);
             if ($last_rev == $rev) {
                 $display_line['color'] = $color;
             } else {
                 $blame = $blame_dict[$rev];
                 if (!isset($blame['epoch'])) {
                     $color = '#ffd';
                     // Render as warning.
                 } else {
                     $color_ratio = ($blame['epoch'] - $epoch_min) / $epoch_range;
                     $color_value = 0xe6 * (1.0 - $color_ratio);
                     $color = sprintf('#%02x%02x%02x', $color_value, 0xf6, $color_value);
                 }
                 $display_line['epoch'] = idx($blame, 'epoch');
                 $display_line['color'] = $color;
                 $display_line['commit'] = $rev;
                 $author_phid = idx($blame, 'authorPHID');
                 if ($author_phid && $handles[$author_phid]) {
                     $author_link = $handles[$author_phid]->renderLink();
                 } else {
                     $author_link = $blame['author'];
                 }
                 $display_line['author'] = $author_link;
                 $last_rev = $rev;
             }
         }
         if ($line_arr) {
             if ($line_number == $line_arr[0]['min']) {
                 $display_line['target'] = true;
             }
             foreach ($line_arr as $range) {
                 if ($line_number >= $range['min'] && $line_number <= $range['max']) {
                     $display_line['highlighted'] = true;
                 }
             }
         }
         $display[] = $display_line;
         ++$line_number;
     }
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $commits = array_filter(ipull($display, 'commit'));
     if ($commits) {
         $commits = id(new DiffusionCommitQuery())->setViewer($viewer)->withRepository($drequest->getRepository())->withIdentifiers($commits)->execute();
         $commits = mpull($commits, null, 'getCommitIdentifier');
     }
     $revision_ids = id(new DifferentialRevision())->loadIDsByCommitPHIDs(mpull($commits, 'getPHID'));
     $revisions = array();
     if ($revision_ids) {
         $revisions = id(new DifferentialRevisionQuery())->setViewer($viewer)->withIDs($revision_ids)->execute();
     }
     $phids = array();
     foreach ($commits as $commit) {
         if ($commit->getAuthorPHID()) {
             $phids[] = $commit->getAuthorPHID();
         }
     }
     foreach ($revisions as $revision) {
         if ($revision->getAuthorPHID()) {
             $phids[] = $revision->getAuthorPHID();
         }
     }
     $handles = $this->loadViewerHandles($phids);
     Javelin::initBehavior('phabricator-oncopy', array());
     $engine = null;
     $inlines = array();
     if ($this->getRequest()->getStr('lint') !== null && $this->lintMessages) {
         $engine = new PhabricatorMarkupEngine();
         $engine->setViewer($viewer);
         foreach ($this->lintMessages as $message) {
             $inline = id(new PhabricatorAuditInlineComment())->setSyntheticAuthor(ArcanistLintSeverity::getStringForSeverity($message['severity']) . ' ' . $message['code'] . ' (' . $message['name'] . ')')->setLineNumber($message['line'])->setContent($message['description']);
             $inlines[$message['line']][] = $inline;
             $engine->addObject($inline, PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY);
         }
         $engine->process();
         require_celerity_resource('differential-changeset-view-css');
     }
     $rows = $this->renderInlines(idx($inlines, 0, array()), $show_blame, (bool) $this->coverage, $engine);
     foreach ($display as $line) {
         $line_href = $drequest->generateURI(array('action' => 'browse', 'line' => $line['line'], 'stable' => true));
         $blame = array();
         $style = null;
         if (array_key_exists('color', $line)) {
             if ($line['color']) {
                 $style = 'background: ' . $line['color'] . ';';
             }
             $before_link = null;
             $commit_link = null;
             $revision_link = null;
             if (idx($line, 'commit')) {
                 $commit = $line['commit'];
                 if (idx($commits, $commit)) {
                     $tooltip = $this->renderCommitTooltip($commits[$commit], $handles, $line['author']);
                 } else {
                     $tooltip = null;
                 }
                 Javelin::initBehavior('phabricator-tooltips', array());
                 require_celerity_resource('aphront-tooltip-css');
                 $commit_link = javelin_tag('a', array('href' => $drequest->generateURI(array('action' => 'commit', 'commit' => $line['commit'])), 'sigil' => 'has-tooltip', 'meta' => array('tip' => $tooltip, 'align' => 'E', 'size' => 600)), id(new PhutilUTF8StringTruncator())->setMaximumGlyphs(9)->setTerminator('')->truncateString($line['commit']));
                 $revision_id = null;
                 if (idx($commits, $commit)) {
                     $revision_id = idx($revision_ids, $commits[$commit]->getPHID());
                 }
                 if ($revision_id) {
                     $revision = idx($revisions, $revision_id);
                     if ($revision) {
                         $tooltip = $this->renderRevisionTooltip($revision, $handles);
                         $revision_link = javelin_tag('a', array('href' => '/D' . $revision->getID(), 'sigil' => 'has-tooltip', 'meta' => array('tip' => $tooltip, 'align' => 'E', 'size' => 600)), 'D' . $revision->getID());
                     }
                 }
                 $uri = $line_href->alter('before', $commit);
                 $before_link = javelin_tag('a', array('href' => $uri->setQueryParam('view', 'blame'), 'sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Skip Past This Commit'), 'align' => 'E', 'size' => 300)), "«");
             }
             $blame[] = phutil_tag('th', array('class' => 'diffusion-blame-link'), $before_link);
             $object_links = array();
             $object_links[] = $commit_link;
             if ($revision_link) {
                 $object_links[] = phutil_tag('span', array(), '/');
                 $object_links[] = $revision_link;
             }
             $blame[] = phutil_tag('th', array('class' => 'diffusion-rev-link'), $object_links);
         }
         $line_link = phutil_tag('a', array('href' => $line_href, 'style' => $style), $line['line']);
         $blame[] = javelin_tag('th', array('class' => 'diffusion-line-link', 'sigil' => 'phabricator-source-line', 'style' => $style), $line_link);
         Javelin::initBehavior('phabricator-line-linker');
         if ($line['target']) {
             Javelin::initBehavior('diffusion-jump-to', array('target' => 'scroll_target'));
             $anchor_text = phutil_tag('a', array('id' => 'scroll_target'), '');
         } else {
             $anchor_text = null;
         }
         $blame[] = phutil_tag('td', array(), array($anchor_text, "​", phutil_safe_html(str_replace("\t", '  ', $line['data']))));
         if ($this->coverage) {
             require_celerity_resource('differential-changeset-view-css');
             $cov_index = $line['line'] - 1;
             if (isset($this->coverage[$cov_index])) {
                 $cov_class = $this->coverage[$cov_index];
             } else {
                 $cov_class = 'N';
             }
             $blame[] = phutil_tag('td', array('class' => 'cov cov-' . $cov_class), '');
         }
         $rows[] = phutil_tag('tr', array('class' => $line['highlighted'] ? 'phabricator-source-highlight' : null), $blame);
         $cur_inlines = $this->renderInlines(idx($inlines, $line['line'], array()), $show_blame, $this->coverage, $engine);
         foreach ($cur_inlines as $cur_inline) {
             $rows[] = $cur_inline;
         }
     }
     return $rows;
 }
 private function buildRawDiffResponse(DiffusionRequest $drequest)
 {
     $raw_diff = $this->callConduitWithDiffusionRequest('diffusion.rawdiffquery', array('commit' => $drequest->getCommit(), 'path' => $drequest->getPath()));
     $file = PhabricatorFile::buildFromFileDataOrHash($raw_diff, array('name' => $drequest->getCommit() . '.diff', 'ttl' => 60 * 60 * 24, 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE));
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $file->attachToObject($drequest->getRepository()->getPHID());
     unset($unguarded);
     return $file->getRedirectResponse();
 }
 private function buildTagListTable(DiffusionRequest $drequest)
 {
     $viewer = $this->getRequest()->getUser();
     $tag_limit = 15;
     $tags = array();
     try {
         $tags = DiffusionRepositoryTag::newFromConduit($this->callConduitWithDiffusionRequest('diffusion.tagsquery', array('commit' => null, 'limit' => $tag_limit + 1)));
     } catch (ConduitException $e) {
         if ($e->getMessage() != 'ERR-UNSUPPORTED-VCS') {
             throw $e;
         }
     }
     if (!$tags) {
         return null;
     }
     $more_tags = count($tags) > $tag_limit;
     $tags = array_slice($tags, 0, $tag_limit);
     $commits = id(new DiffusionCommitQuery())->setViewer($viewer)->withIdentifiers(mpull($tags, 'getCommitIdentifier'))->withRepository($drequest->getRepository())->needCommitData(true)->execute();
     $view = id(new DiffusionTagListView())->setUser($viewer)->setDiffusionRequest($drequest)->setTags($tags)->setCommits($commits);
     $phids = $view->getRequiredHandlePHIDs();
     $handles = $this->loadViewerHandles($phids);
     $view->setHandles($handles);
     $panel = new PHUIObjectBoxView();
     $header = new PHUIHeaderView();
     $header->setHeader(pht('Tags'));
     if ($more_tags) {
         $header->setSubHeader(pht('Showing the %d most recent tags.', $tag_limit));
     }
     $icon = id(new PHUIIconView())->setIconFont('fa-tag');
     $button = new PHUIButtonView();
     $button->setText(pht('Show All Tags'));
     $button->setTag('a');
     $button->setIcon($icon);
     $button->setHref($drequest->generateURI(array('action' => 'tags')));
     $header->addActionLink($button);
     $panel->setHeader($header);
     $panel->appendChild($view);
     return $panel;
 }