示例#1
0
 public final 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);
     $color = DifferentialChangeType::getIconColorForFileType($file_type);
     $icon_view = id(new PHUIIconView())->setIcon($icon . ' ' . $color);
     // 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));
 }
 public final function linkChange($change_type, $file_type, $path = null, $commit_identifier = null)
 {
     $text = DifferentialChangeType::getFullNameForChangeType($change_type);
     if ($change_type == DifferentialChangeType::TYPE_CHILD) {
         // TODO: Don't link COPY_AWAY without a direct change.
         return $text;
     }
     if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
         return $text;
     }
     $drequest = $this->getDiffusionRequest();
     if ($commit_identifier) {
         $commit = ';' . $commit_identifier;
     } else {
         if ($drequest->getRawCommit()) {
             $commit = ';' . $drequest->getCommitURIComponent($drequest->getRawCommit());
         } else {
             $commit = null;
         }
     }
     $repository = $drequest->getRepository();
     $callsign = $repository->getCallsign();
     $branch = $drequest->getBranchURIComponent($drequest->getBranch());
     $path = $branch . ($path ? $path : $drequest->getPath());
     return phutil_render_tag('a', array('href' => "/diffusion/{$callsign}/change/{$path}{$commit}"), $text);
 }
 public final function linkChange($change_type, $file_type, $path = null, $commit_identifier = null)
 {
     $text = DifferentialChangeType::getFullNameForChangeType($change_type);
     if ($change_type == DifferentialChangeType::TYPE_CHILD) {
         // TODO: Don't link COPY_AWAY without a direct change.
         return $text;
     }
     if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
         return $text;
     }
     $href = $this->getDiffusionRequest()->generateURI(array('action' => 'change', 'path' => $path, 'commit' => $commit_identifier));
     return phutil_tag('a', array('href' => $href), $text);
 }
 public function render()
 {
     $rows = array();
     // TODO: Experiment with path stack rendering.
     // TODO: Copy Away and Move Away are rendered junkily still.
     foreach ($this->pathChanges as $change) {
         $change_verb = DifferentialChangeType::getFullNameForChangeType($change->getChangeType());
         $path = $change->getPath();
         if ($change->getFileType() == DifferentialChangeType::FILE_DIRECTORY) {
             $path_column = phutil_escape_html($path) . '/';
         } else {
             $hash = substr(md5($path), 0, 8);
             $path_column = phutil_render_tag('a', array('href' => '#' . $hash), phutil_escape_html($path));
         }
         $rows[] = array($this->linkHistory($change->getPath()), $this->linkBrowse($change->getPath()), $this->linkChange($change->getChangeType(), $change->getFileType(), $change->getPath()), $path_column);
     }
     $view = new AphrontTableView($rows);
     $view->setHeaders(array('History', 'Browse', 'Change', 'Path'));
     $view->setColumnClasses(array('', '', '', 'wide'));
     $view->setNoDataString('This change has not been fully parsed yet.');
     return $view->render();
 }
 public function render()
 {
     require_celerity_resource('differential-core-view-css');
     require_celerity_resource('differential-table-of-contents-css');
     $rows = array();
     $changesets = $this->changesets;
     foreach ($changesets as $changeset) {
         $file = $changeset->getFilename();
         $display_file = $changeset->getDisplayFilename();
         $type = $changeset->getChangeType();
         $ftype = $changeset->getFileType();
         if (DifferentialChangeType::isOldLocationChangeType($type)) {
             $link = phutil_escape_html($display_file);
             $away = $changeset->getAwayPaths();
             if (count($away) > 1) {
                 $meta = array();
                 if ($type == DifferentialChangeType::TYPE_MULTICOPY) {
                     $meta[] = 'Deleted after being copied to multiple locations:';
                 } else {
                     $meta[] = 'Copied to multiple locations:';
                 }
                 foreach ($away as $path) {
                     $meta[] = $path;
                 }
                 $meta = implode('<br />', $meta);
             } else {
                 if ($type == DifferentialChangeType::TYPE_MOVE_AWAY) {
                     $meta = 'Moved to ' . reset($away);
                 } else {
                     $meta = 'Copied to ' . reset($away);
                 }
             }
         } else {
             if ($this->standaloneViewLink) {
                 $id = $changeset->getID();
                 if ($id) {
                     $vs_id = idx($this->vsMap, $id);
                 } else {
                     $vs_id = null;
                 }
                 $ref = $vs_id ? $id . '/' . $vs_id : $id;
                 $detail_uri = new PhutilURI($this->renderURI);
                 $detail_uri->setQueryParams(array('ref' => $ref, 'whitespace' => $this->whitespace, 'revision_id' => $this->revisionID));
                 $link = phutil_render_tag('a', array('href' => $detail_uri, 'target' => '_blank'), phutil_escape_html($display_file));
             } else {
                 $link = phutil_render_tag('a', array('href' => '#' . $changeset->getAnchorName()), phutil_escape_html($display_file));
             }
             if ($type == DifferentialChangeType::TYPE_MOVE_HERE) {
                 $meta = 'Moved from ' . phutil_escape_html($changeset->getOldFile());
             } else {
                 if ($type == DifferentialChangeType::TYPE_COPY_HERE) {
                     $meta = 'Copied from ' . phutil_escape_html($changeset->getOldFile());
                 } else {
                     $meta = null;
                 }
             }
         }
         $line_count = $changeset->getAffectedLineCount();
         if ($line_count == 0) {
             $lines = null;
         } else {
             if ($line_count == 1) {
                 $lines = ' (1 line)';
             } else {
                 $lines = ' (' . $line_count . ' lines)';
             }
         }
         $char = DifferentialChangeType::getSummaryCharacterForChangeType($type);
         $chartitle = DifferentialChangeType::getFullNameForChangeType($type);
         $desc = DifferentialChangeType::getShortNameForFileType($ftype);
         if ($desc) {
             $desc = '(' . $desc . ')';
         }
         $pchar = $changeset->getOldProperties() === $changeset->getNewProperties() ? null : '<span title="Properties Changed">M</span>';
         $rows[] = '<tr>' . '<td class="differential-toc-char" title=' . $chartitle . '>' . $char . '</td>' . '<td class="differential-toc-prop">' . $pchar . '</td>' . '<td class="differential-toc-ftype">' . $desc . '</td>' . '<td class="differential-toc-file">' . $link . $lines . '</td>' . '</tr>';
         if ($meta) {
             $rows[] = '<tr>' . '<td colspan="3"></td>' . '<td class="differential-toc-meta">' . $meta . '</td>' . '</tr>';
         }
     }
     return '<div class="differential-toc differential-panel">' . '<h1>Table of Contents</h1>' . '<table>' . implode("\n", $rows) . '</table>' . '</div>';
 }
 public function render()
 {
     $this->requireResource('differential-core-view-css');
     $this->requireResource('differential-table-of-contents-css');
     $rows = array();
     $coverage = array();
     if ($this->unitTestData) {
         $coverage_by_file = array();
         foreach ($this->unitTestData as $result) {
             $test_coverage = idx($result, 'coverage');
             if (!$test_coverage) {
                 continue;
             }
             foreach ($test_coverage as $file => $results) {
                 $coverage_by_file[$file][] = $results;
             }
         }
         foreach ($coverage_by_file as $file => $coverages) {
             $coverage[$file] = ArcanistUnitTestResult::mergeCoverage($coverages);
         }
     }
     $changesets = $this->changesets;
     $paths = array();
     foreach ($changesets as $id => $changeset) {
         $type = $changeset->getChangeType();
         $ftype = $changeset->getFileType();
         $ref = idx($this->references, $id);
         $display_file = $changeset->getDisplayFilename();
         $meta = null;
         if (DifferentialChangeType::isOldLocationChangeType($type)) {
             $away = $changeset->getAwayPaths();
             if (count($away) > 1) {
                 $meta = array();
                 if ($type == DifferentialChangeType::TYPE_MULTICOPY) {
                     $meta[] = pht('Deleted after being copied to multiple locations:');
                 } else {
                     $meta[] = pht('Copied to multiple locations:');
                 }
                 foreach ($away as $path) {
                     $meta[] = $path;
                 }
                 $meta = phutil_implode_html(phutil_tag('br'), $meta);
             } else {
                 if ($type == DifferentialChangeType::TYPE_MOVE_AWAY) {
                     $display_file = $this->renderRename($display_file, reset($away), "→");
                 } else {
                     $meta = pht('Copied to %s', reset($away));
                 }
             }
         } else {
             if ($type == DifferentialChangeType::TYPE_MOVE_HERE) {
                 $old_file = $changeset->getOldFile();
                 $display_file = $this->renderRename($display_file, $old_file, "←");
             } else {
                 if ($type == DifferentialChangeType::TYPE_COPY_HERE) {
                     $meta = pht('Copied from %s', $changeset->getOldFile());
                 }
             }
         }
         $link = $this->renderChangesetLink($changeset, $ref, $display_file);
         $line_count = $changeset->getAffectedLineCount();
         if ($line_count == 0) {
             $lines = '';
         } else {
             $lines = ' ' . pht('(%d line(s))', $line_count);
         }
         $char = DifferentialChangeType::getSummaryCharacterForChangeType($type);
         $chartitle = DifferentialChangeType::getFullNameForChangeType($type);
         $desc = DifferentialChangeType::getShortNameForFileType($ftype);
         if ($desc) {
             $desc = '(' . $desc . ')';
         }
         $pchar = $changeset->getOldProperties() === $changeset->getNewProperties() ? '' : phutil_tag('span', array('title' => pht('Properties Changed')), 'M');
         $fname = $changeset->getFilename();
         $cov = $this->renderCoverage($coverage, $fname);
         if ($cov === null) {
             $mcov = $cov = phutil_tag('em', array(), '-');
         } else {
             $mcov = phutil_tag('div', array('id' => 'differential-mcoverage-' . md5($fname), 'class' => 'differential-mcoverage-loading'), isset($this->visibleChangesets[$id]) ? pht('Loading...') : pht('?'));
         }
         if ($meta) {
             $meta = phutil_tag('div', array('class' => 'differential-toc-meta'), $meta);
         }
         if ($this->diff && $this->repository) {
             $paths[] = $changeset->getAbsoluteRepositoryPath($this->repository, $this->diff);
         }
         $rows[] = array($char, $pchar, $desc, array($link, $lines, $meta), $cov, $mcov);
     }
     $editor_link = null;
     if ($paths && $this->user) {
         $editor_link = $this->user->loadEditorLink($paths, 1, $this->repository->getCallsign());
         if ($editor_link) {
             $editor_link = phutil_tag('a', array('href' => $editor_link, 'class' => 'button differential-toc-edit-all'), pht('Open All in Editor'));
         }
     }
     $reveal_link = javelin_tag('a', array('sigil' => 'differential-reveal-all', 'mustcapture' => true, 'class' => 'button differential-toc-reveal-all'), pht('Show All Context'));
     $buttons = phutil_tag('div', array('class' => 'differential-toc-buttons grouped'), array($editor_link, $reveal_link));
     $table = id(new AphrontTableView($rows));
     $table->setHeaders(array('', '', '', pht('Path'), pht('Coverage (All)'), pht('Coverage (Touched)')));
     $table->setColumnClasses(array('differential-toc-char center', 'differential-toc-prop center', 'differential-toc-ftype center', 'differential-toc-file wide', 'differential-toc-cov', 'differential-toc-cov'));
     $table->setDeviceVisibility(array(true, true, true, true, false, false));
     $anchor = id(new PhabricatorAnchorView())->setAnchorName('toc')->setNavigationMarker(true);
     return id(new PHUIObjectBoxView())->setHeaderText(pht('Table of Contents'))->appendChild($anchor)->appendChild($table)->appendChild($buttons);
 }
 public function render()
 {
     require_celerity_resource('differential-core-view-css');
     require_celerity_resource('differential-table-of-contents-css');
     $rows = array();
     $coverage = array();
     if ($this->unitTestData) {
         $coverage_by_file = array();
         foreach ($this->unitTestData as $result) {
             $test_coverage = idx($result, 'coverage');
             if (!$test_coverage) {
                 continue;
             }
             foreach ($test_coverage as $file => $results) {
                 $coverage_by_file[$file][] = $results;
             }
         }
         foreach ($coverage_by_file as $file => $coverages) {
             $coverage[$file] = ArcanistUnitTestResult::mergeCoverage($coverages);
         }
     }
     $changesets = $this->changesets;
     $paths = array();
     foreach ($changesets as $id => $changeset) {
         $type = $changeset->getChangeType();
         $ftype = $changeset->getFileType();
         $ref = idx($this->references, $id);
         $link = $this->renderChangesetLink($changeset, $ref);
         if (DifferentialChangeType::isOldLocationChangeType($type)) {
             $away = $changeset->getAwayPaths();
             if (count($away) > 1) {
                 $meta = array();
                 if ($type == DifferentialChangeType::TYPE_MULTICOPY) {
                     $meta[] = 'Deleted after being copied to multiple locations:';
                 } else {
                     $meta[] = 'Copied to multiple locations:';
                 }
                 foreach ($away as $path) {
                     $meta[] = phutil_escape_html($path);
                 }
                 $meta = implode('<br />', $meta);
             } else {
                 if ($type == DifferentialChangeType::TYPE_MOVE_AWAY) {
                     $meta = 'Moved to ' . phutil_escape_html(reset($away));
                 } else {
                     $meta = 'Copied to ' . phutil_escape_html(reset($away));
                 }
             }
         } else {
             if ($type == DifferentialChangeType::TYPE_MOVE_HERE) {
                 $meta = 'Moved from ' . phutil_escape_html($changeset->getOldFile());
             } else {
                 if ($type == DifferentialChangeType::TYPE_COPY_HERE) {
                     $meta = 'Copied from ' . phutil_escape_html($changeset->getOldFile());
                 } else {
                     $meta = null;
                 }
             }
         }
         $line_count = $changeset->getAffectedLineCount();
         if ($line_count == 0) {
             $lines = null;
         } else {
             $lines = ' ' . pht('(%d line(s))', $line_count);
         }
         $char = DifferentialChangeType::getSummaryCharacterForChangeType($type);
         $chartitle = DifferentialChangeType::getFullNameForChangeType($type);
         $desc = DifferentialChangeType::getShortNameForFileType($ftype);
         if ($desc) {
             $desc = '(' . $desc . ')';
         }
         $pchar = $changeset->getOldProperties() === $changeset->getNewProperties() ? null : '<span title="Properties Changed">M</span>';
         $fname = $changeset->getFilename();
         $cov = $this->renderCoverage($coverage, $fname);
         if ($cov === null) {
             $mcov = $cov = '<em>-</em>';
         } else {
             $mcov = phutil_render_tag('div', array('id' => 'differential-mcoverage-' . md5($fname), 'class' => 'differential-mcoverage-loading'), isset($this->visibleChangesets[$id]) ? 'Loading...' : '?');
         }
         $rows[] = '<tr>' . phutil_render_tag('td', array('class' => 'differential-toc-char', 'title' => $chartitle), $char) . '<td class="differential-toc-prop">' . $pchar . '</td>' . '<td class="differential-toc-ftype">' . $desc . '</td>' . '<td class="differential-toc-file">' . $link . $lines . '</td>' . '<td class="differential-toc-cov">' . $cov . '</td>' . '<td class="differential-toc-mcov">' . $mcov . '</td>' . '</tr>';
         if ($meta) {
             $rows[] = '<tr>' . '<td colspan="3"></td>' . '<td class="differential-toc-meta">' . $meta . '</td>' . '</tr>';
         }
         if ($this->diff && $this->repository) {
             $paths[] = $changeset->getAbsoluteRepositoryPath($this->repository, $this->diff);
         }
     }
     $editor_link = null;
     if ($paths && $this->user) {
         $editor_link = $this->user->loadEditorLink(implode(' ', $paths), 1, $this->repository->getCallsign());
         if ($editor_link) {
             $editor_link = phutil_render_tag('a', array('href' => $editor_link, 'class' => 'button differential-toc-edit-all'), 'Open All in Editor');
         }
     }
     $reveal_link = javelin_render_tag('a', array('sigil' => 'differential-reveal-all', 'mustcapture' => true, 'class' => 'button differential-toc-reveal-all'), 'Show All Context');
     return '<div id="differential-review-toc" ' . 'class="differential-toc differential-panel">' . $editor_link . $reveal_link . '<h1>Table of Contents</h1>' . '<table>' . '<tr>' . '<th></th>' . '<th></th>' . '<th></th>' . '<th>Path</th>' . '<th class="differential-toc-cov">Coverage (All)</th>' . '<th class="differential-toc-mcov">Coverage (Touched)</th>' . '</tr>' . implode("\n", $rows) . '</table>' . '</div>';
 }
 private function writeBrowse(PhabricatorRepository $repository, PhabricatorRepositoryCommit $commit, array $effects, array $path_map)
 {
     $conn_w = $repository->establishConnection('w');
     $sql = array();
     foreach ($effects as $effect) {
         $type = $effect['changeType'];
         if (!$effect['rawDirect']) {
             if ($type == DifferentialChangeType::TYPE_COPY_AWAY) {
                 // Don't write COPY_AWAY to the filesystem table if it isn't a direct
                 // event.
                 continue;
             }
             if ($type == DifferentialChangeType::TYPE_CHILD) {
                 // Don't write CHILD to the filesystem table. Although doing these
                 // writes has the nice property of letting you see when a directory's
                 // contents were last changed, it explodes the table tremendously
                 // and makes Diffusion far slower.
                 continue;
             }
         }
         if ($effect['rawPath'] == '/') {
             // Don't write any events on '/' to the filesystem table; in
             // particular, it doesn't have a meaningful parentID.
             continue;
         }
         $existed = !DifferentialChangeType::isDeleteChangeType($type);
         $sql[] = qsprintf($conn_w, '(%d, %d, %d, %d, %d, %d)', $repository->getID(), $path_map[$this->getParentPath($effect['rawPath'])], $commit->getCommitIdentifier(), $path_map[$effect['rawPath']], $existed ? 1 : 0, $effect['fileType']);
     }
     queryfx($conn_w, 'DELETE FROM %T WHERE repositoryID = %d AND svnCommit = %d', PhabricatorRepository::TABLE_FILESYSTEM, $repository->getID(), $commit->getCommitIdentifier());
     foreach (array_chunk($sql, 512) as $sql_chunk) {
         queryfx($conn_w, 'INSERT INTO %T
       (repositoryID, parentID, svnCommit, pathID, existed, fileType)
       VALUES %Q', PhabricatorRepository::TABLE_FILESYSTEM, implode(', ', $sql_chunk));
     }
 }
 private function renderChangesetMetadata()
 {
     $changeset = $this->getChangeset();
     $type = $changeset->getChangeType();
     $meta = array();
     if (DifferentialChangeType::isOldLocationChangeType($type)) {
         $away = $changeset->getAwayPaths();
         if (count($away) > 1) {
             if ($type == DifferentialChangeType::TYPE_MULTICOPY) {
                 $meta[] = pht('Deleted after being copied to multiple locations:');
             } else {
                 $meta[] = pht('Copied to multiple locations:');
             }
             foreach ($away as $path) {
                 $meta[] = $path;
             }
         } else {
             if ($type == DifferentialChangeType::TYPE_MOVE_AWAY) {
                 // This case is handled when we render the path.
             } else {
                 $meta[] = pht('Copied to %s', head($away));
             }
         }
     } else {
         if ($type == DifferentialChangeType::TYPE_COPY_HERE) {
             $meta[] = pht('Copied from %s', $changeset->getOldFile());
         }
     }
     if (!$meta) {
         return null;
     }
     $meta = phutil_implode_html(phutil_tag('br'), $meta);
     return phutil_tag('div', array('class' => 'differential-toc-meta'), $meta);
 }