Initial commit of differential baking changes
NOTE: This branch is not to be deployed as a website, but instead to be used as a client of a cluster (to have access to the database) and run the baking script in a unattended mode. A lot of tweaks all over the place to make the generated HTML suitable for use in a static HTML with remapped paths to be relative and so on. NOTE: Because of those tweaks the file rendering and access will not work as expected when viewed from the website: it will be 404 because it has different means accessing files than the static HTML. It is not possible to keep website rendering correct, but it makes it harder to investigate what parts needs attention without running the baker. The baking script is found in `scripts/bake/bake_differential.php` and it receives a single argument which is a directory with the baked files. Covers the following aspects: - File attachments - Image previews - Pastes The user avatars are replaced with the default user avatar.
This commit is contained in:
@@ -12,7 +12,7 @@ return array(
|
||||
'core.pkg.css' => '0fbedea0',
|
||||
'core.pkg.js' => '74ad315f',
|
||||
'dark-console.pkg.js' => '187792c2',
|
||||
'differential.pkg.css' => '5c459f92',
|
||||
'differential.pkg.css' => '32879ab6',
|
||||
'differential.pkg.js' => '218fda21',
|
||||
'diffusion.pkg.css' => '42c75c37',
|
||||
'diffusion.pkg.js' => 'a98c0bf7',
|
||||
@@ -67,7 +67,7 @@ return array(
|
||||
'rsrc/css/application/differential/core.css' => '7300a73e',
|
||||
'rsrc/css/application/differential/phui-inline-comment.css' => '9863a85e',
|
||||
'rsrc/css/application/differential/revision-comment.css' => '7dbc8d1d',
|
||||
'rsrc/css/application/differential/revision-history.css' => '8aa3eac5',
|
||||
'rsrc/css/application/differential/revision-history.css' => '04edcc29',
|
||||
'rsrc/css/application/differential/revision-list.css' => '93d2df7d',
|
||||
'rsrc/css/application/differential/table-of-contents.css' => 'bba788b9',
|
||||
'rsrc/css/application/diffusion/diffusion-icons.css' => '23b31a1b',
|
||||
@@ -574,7 +574,7 @@ return array(
|
||||
'differential-core-view-css' => '7300a73e',
|
||||
'differential-revision-add-comment-css' => '7e5900d9',
|
||||
'differential-revision-comment-css' => '7dbc8d1d',
|
||||
'differential-revision-history-css' => '8aa3eac5',
|
||||
'differential-revision-history-css' => '04edcc29',
|
||||
'differential-revision-list-css' => '93d2df7d',
|
||||
'differential-table-of-contents-css' => 'bba788b9',
|
||||
'diffusion-css' => 'b54c77b0',
|
||||
|
||||
293
scripts/bake/bake_differential.php
Normal file
293
scripts/bake/bake_differential.php
Normal file
@@ -0,0 +1,293 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Bootstrap.
|
||||
|
||||
$PHABRICATOR_ROOT = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $PHABRICATOR_ROOT.'/scripts/__init_script__.php';
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Command line.
|
||||
|
||||
if (count($argv) != 2) {
|
||||
print("Usage: $argv[0] <output_directory>\n");
|
||||
die;
|
||||
}
|
||||
|
||||
$OUTPUT_DIR = $argv[1];
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Global configuration.
|
||||
|
||||
$HOST = 'phabricator.local';
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Utilities.
|
||||
|
||||
// Create an instance of the AphrontApplicationConfiguration configured with all
|
||||
// invariant settings (settings which do not change between handlers of different
|
||||
// revisions).
|
||||
function CreateApplicationConfiguration() {
|
||||
global $HOST;
|
||||
|
||||
$application_configuration = new AphrontApplicationConfiguration();
|
||||
$application_configuration->setHost($HOST);
|
||||
return $application_configuration;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Global state.
|
||||
|
||||
$site = id(new PhabricatorPlatformSite());
|
||||
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
|
||||
$application_configuration = CreateApplicationConfiguration();
|
||||
|
||||
$application = id(new PhabricatorDifferentialApplication());
|
||||
$revision_controller = id(new DifferentialRevisionViewController())
|
||||
->setCurrentApplication($application);
|
||||
|
||||
$routing_map = id(new AphrontRoutingMap())
|
||||
->setSite($site)
|
||||
->setApplication($application)
|
||||
->setRoutes($application->getRoutes());
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Baking logic and loop.
|
||||
|
||||
function EnsureDirectoryOrDie($dir) {
|
||||
if (!is_dir($dir)) {
|
||||
if (!mkdir($dir, 0777, true)) {
|
||||
print("Error creating output durectory $dir\n");
|
||||
die;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function EnsureOutputDirectoryOrDie() {
|
||||
global $OUTPUT_DIR;
|
||||
EnsureDirectoryOrDie($OUTPUT_DIR);
|
||||
}
|
||||
|
||||
function MakeGenericOutputDirectory($subject) {
|
||||
global $OUTPUT_DIR;
|
||||
|
||||
$dir = $OUTPUT_DIR . DIRECTORY_SEPARATOR . $subject;
|
||||
EnsureDirectoryOrDie($dir);
|
||||
|
||||
return $dir;
|
||||
}
|
||||
|
||||
function MakeRevisionBaseOutputFileName($revision, $diff_id, $subject) {
|
||||
$dir = MakeGenericOutputDirectory($subject);
|
||||
|
||||
$file_name = $dir . DIRECTORY_SEPARATOR . 'D' . $revision->getID();
|
||||
|
||||
if (!is_null($diff_id)) {
|
||||
$file_name .= '.' . $diff_id;
|
||||
}
|
||||
|
||||
return $file_name;
|
||||
}
|
||||
|
||||
function MakeRevisionHTMLOutputFileName($revision, $diff_id) {
|
||||
return MakeRevisionBaseOutputFileName(
|
||||
$revision, $diff_id, 'revision') . '.html';
|
||||
}
|
||||
|
||||
function MakeRawDiffOutputFileName($revision, $diff_id) {
|
||||
return MakeRevisionBaseOutputFileName(
|
||||
$revision, $diff_id, 'raw_diff') . '.diff';
|
||||
}
|
||||
|
||||
function MakePasteOutputFileNameFromHandle($handle) {
|
||||
return MakeGenericOutputDirectory('paste') .
|
||||
DIRECTORY_SEPARATOR .
|
||||
$handle->getName() . '.txt';
|
||||
}
|
||||
|
||||
|
||||
function MakeFileOutputFileNameFromFile($file) {
|
||||
$dir = MakeGenericOutputDirectory('file');
|
||||
|
||||
$id = $file->getID();
|
||||
|
||||
EnsureDirectoryOrDie($dir . DIRECTORY_SEPARATOR . 'F' . $id);
|
||||
|
||||
return $dir.
|
||||
DIRECTORY_SEPARATOR .
|
||||
$file->getSafeFileNameForBake();
|
||||
}
|
||||
|
||||
function BakeDifferentialToResponse($revision, $diff_id = NULL) {
|
||||
global $application_configuration;
|
||||
global $revision_controller;
|
||||
global $routing_map;
|
||||
global $viewer;
|
||||
|
||||
$revision_id = $revision->getID();
|
||||
|
||||
if (is_null($diff_id)) {
|
||||
printf('Baking D' . $revision_id . ' ...' . "\n");
|
||||
} else {
|
||||
printf('Baking D' . $revision_id . ', diff ' . $diff_id . ' ...' . "\n");
|
||||
}
|
||||
|
||||
$path = '/D' . $revision_id;
|
||||
|
||||
$route_result = $routing_map->routePath($path);
|
||||
$uri_data = $route_result->getURIData();
|
||||
|
||||
$application_configuration->setPath($path);
|
||||
|
||||
$request_data = array(
|
||||
);
|
||||
|
||||
if (!is_null($diff_id)) {
|
||||
$request_data['id'] = $diff_id;
|
||||
}
|
||||
|
||||
$request = $application_configuration->buildRequest()
|
||||
->setUser($viewer)
|
||||
->setRequestData($request_data)
|
||||
->setURIMap($uri_data);
|
||||
|
||||
$response = id($revision_controller)
|
||||
->setRequest($request)
|
||||
->handleRequest($request);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
function BakeResponseToHTML($response) {
|
||||
$html = '';
|
||||
foreach ($response->renderChildren() as $child) {
|
||||
$html .= $child->render();
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
function StorePasteHandle($handle) {
|
||||
global $viewer;
|
||||
|
||||
$file_name = MakePasteOutputFileNameFromHandle($handle);
|
||||
if (file_exists($file_name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$paste = id(new PhabricatorPasteQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($handle->getPHID()))
|
||||
->needRawContent(true)
|
||||
->executeOne();
|
||||
|
||||
file_put_contents($file_name, $paste->getRawContent());
|
||||
}
|
||||
|
||||
function StoreFile($file) {
|
||||
$file_name = MakeFileOutputFileNameFromFile($file);
|
||||
file_put_contents($file_name, $file->loadFileData());
|
||||
}
|
||||
|
||||
function StoreFileHandle($handle) {
|
||||
global $viewer;
|
||||
|
||||
$file = id(new PhabricatorFileQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($handle->getPHID()))
|
||||
->needTransforms(
|
||||
array(
|
||||
PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW,
|
||||
))
|
||||
->executeOne();
|
||||
|
||||
$file_name = MakeFileOutputFileNameFromFile($file);
|
||||
if (file_exists($file_name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
StoreFile($file);
|
||||
|
||||
$preview_xform = $file->getTransform(PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW);
|
||||
if ($preview_xform) {
|
||||
StoreFile($preview_xform);
|
||||
}
|
||||
}
|
||||
|
||||
function StoreResponseAttachments($response) {
|
||||
$user = $response->getRequest()->getUser();
|
||||
$handlePool = $user->getHandlePool();
|
||||
$handles = $handlePool->getHandles();
|
||||
|
||||
foreach ($handles as $phid => $handle) {
|
||||
$type = $handle->getType();
|
||||
if ($type == PhabricatorPastePastePHIDType::TYPECONST) {
|
||||
StorePasteHandle($handle);
|
||||
} else if ($type == PhabricatorFileFilePHIDType::TYPECONST) {
|
||||
StoreFileHandle($handle);
|
||||
} else {
|
||||
// print("$type\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function StoreRawDiff($revision, $diff_id) {
|
||||
if (is_null($diff_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $viewer;
|
||||
|
||||
$diff = id(new DifferentialDiffQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($diff_id))
|
||||
->needChangesets(true)
|
||||
->executeOne();
|
||||
|
||||
$raw_changes = $diff->buildChangesList();
|
||||
|
||||
$changes = array();
|
||||
foreach ($raw_changes as $changedict) {
|
||||
$changes[] = ArcanistDiffChange::newFromDictionary($changedict);
|
||||
}
|
||||
|
||||
$bundle = ArcanistBundle::newFromChanges($changes);
|
||||
$raw_diff = $bundle->toGitPatch();
|
||||
|
||||
$output_file = MakeRawDiffOutputFileName($revision, $diff_id);
|
||||
file_put_contents($output_file, $raw_diff);
|
||||
}
|
||||
|
||||
function BakeDifferentialToFile($revision, $diff_id = NULL) {
|
||||
$response = BakeDifferentialToResponse($revision, $diff_id);
|
||||
|
||||
$html = BakeResponseToHTML($response);
|
||||
|
||||
$output_file = MakeRevisionHTMLOutputFileName($revision, $diff_id);
|
||||
file_put_contents($output_file, $html);
|
||||
|
||||
file_put_contents($output_file . '.title', $response->getTitle());
|
||||
|
||||
StoreResponseAttachments($response);
|
||||
StoreRawDiff($revision, $diff_id);
|
||||
}
|
||||
|
||||
EnsureOutputDirectoryOrDie();
|
||||
|
||||
$revisions = id(new DifferentialRevisionQuery())
|
||||
->setViewer($viewer)
|
||||
->needDiffIDs(true)
|
||||
->execute();
|
||||
|
||||
foreach ($revisions as $revision_id => $revision) {
|
||||
BakeDifferentialToFile($revision);
|
||||
|
||||
foreach ($revision->getDiffIDs() as $diff_id) {
|
||||
BakeDifferentialToFile($revision, $diff_id);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -334,7 +334,7 @@ abstract class PhabricatorController extends AphrontController {
|
||||
}
|
||||
|
||||
$crumbs[] = id(new PHUICrumbView())
|
||||
->setHref($this->getApplicationURI())
|
||||
// ->setHref($this->getApplicationURI())
|
||||
->setName($application->getName())
|
||||
->setIcon($icon);
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ final class DifferentialRevisionViewController
|
||||
|
||||
$request_uri = $request->getRequestURI();
|
||||
|
||||
$large = $request->getStr('large');
|
||||
$large = $request->getStr('large') && true;
|
||||
|
||||
$large_warning =
|
||||
($this->isLargeDiff()) &&
|
||||
@@ -310,7 +310,7 @@ final class DifferentialRevisionViewController
|
||||
$header = $this->buildHeader($revision);
|
||||
$subheader = $this->buildSubheaderView($revision);
|
||||
$details = $this->buildDetails($revision, $field_list);
|
||||
$curtain = $this->buildCurtain($revision);
|
||||
$curtain = $this->buildCurtain($revision, $target_id);
|
||||
|
||||
$repository = $revision->getRepository();
|
||||
if ($repository) {
|
||||
@@ -553,7 +553,8 @@ final class DifferentialRevisionViewController
|
||||
|
||||
$tab_header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Revision Contents'))
|
||||
->addActionLink($view_button);
|
||||
// ->addActionLink($view_button)
|
||||
;
|
||||
|
||||
$tab_view = id(new PHUIObjectBoxView())
|
||||
->setHeader($tab_header)
|
||||
@@ -663,7 +664,7 @@ final class DifferentialRevisionViewController
|
||||
$view = id(new PHUIHeaderView())
|
||||
->setHeader($revision->getTitle($revision))
|
||||
->setUser($this->getViewer())
|
||||
->setPolicyObject($revision)
|
||||
// ->setPolicyObject($revision)
|
||||
->setHeaderIcon('fa-cog');
|
||||
|
||||
$status_tag = id(new PHUITagView())
|
||||
@@ -737,7 +738,7 @@ final class DifferentialRevisionViewController
|
||||
->appendChild($properties);
|
||||
}
|
||||
|
||||
private function buildCurtain(DifferentialRevision $revision) {
|
||||
private function buildCurtain(DifferentialRevision $revision, $diff_id) {
|
||||
$viewer = $this->getViewer();
|
||||
$revision_id = $revision->getID();
|
||||
$revision_phid = $revision->getPHID();
|
||||
@@ -748,48 +749,48 @@ final class DifferentialRevisionViewController
|
||||
$revision,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setHref("/differential/revision/edit/{$revision_id}/")
|
||||
->setName(pht('Edit Revision'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
// $curtain->addAction(
|
||||
// id(new PhabricatorActionView())
|
||||
// ->setIcon('fa-pencil')
|
||||
// ->setHref("/differential/revision/edit/{$revision_id}/")
|
||||
// ->setName(pht('Edit Revision'))
|
||||
// ->setDisabled(!$can_edit)
|
||||
// ->setWorkflow(!$can_edit));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-upload')
|
||||
->setHref("/differential/revision/update/{$revision_id}/")
|
||||
->setName(pht('Update Diff'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
// $curtain->addAction(
|
||||
// id(new PhabricatorActionView())
|
||||
// ->setIcon('fa-upload')
|
||||
// ->setHref("/differential/revision/update/{$revision_id}/")
|
||||
// ->setName(pht('Update Diff'))
|
||||
// ->setDisabled(!$can_edit)
|
||||
// ->setWorkflow(!$can_edit));
|
||||
|
||||
$request_uri = $this->getRequest()->getRequestURI();
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-download')
|
||||
->setName(pht('Download Raw Diff'))
|
||||
->setHref($request_uri->alter('download', 'true')));
|
||||
->setHref('raw_diff/D' . $revision_id . '.' . $diff_id . '.diff'));
|
||||
|
||||
$relationship_list = PhabricatorObjectRelationshipList::newForObject(
|
||||
$viewer,
|
||||
$revision);
|
||||
|
||||
$revision_actions = array(
|
||||
DifferentialRevisionHasParentRelationship::RELATIONSHIPKEY,
|
||||
DifferentialRevisionHasChildRelationship::RELATIONSHIPKEY,
|
||||
);
|
||||
|
||||
$revision_submenu = $relationship_list->newActionSubmenu($revision_actions)
|
||||
->setName(pht('Edit Related Revisions...'))
|
||||
->setIcon('fa-cog');
|
||||
|
||||
$curtain->addAction($revision_submenu);
|
||||
|
||||
$relationship_submenu = $relationship_list->newActionMenu();
|
||||
if ($relationship_submenu) {
|
||||
$curtain->addAction($relationship_submenu);
|
||||
}
|
||||
// $revision_actions = array(
|
||||
// DifferentialRevisionHasParentRelationship::RELATIONSHIPKEY,
|
||||
// DifferentialRevisionHasChildRelationship::RELATIONSHIPKEY,
|
||||
// );
|
||||
//
|
||||
// $revision_submenu = $relationship_list->newActionSubmenu($revision_actions)
|
||||
// ->setName(pht('Edit Related Revisions...'))
|
||||
// ->setIcon('fa-cog');
|
||||
//
|
||||
// $curtain->addAction($revision_submenu);
|
||||
//
|
||||
// $relationship_submenu = $relationship_list->newActionMenu();
|
||||
// if ($relationship_submenu) {
|
||||
// $curtain->addAction($relationship_submenu);
|
||||
// }
|
||||
|
||||
$repository = $revision->getRepository();
|
||||
if ($repository && $repository->canPerformAutomation()) {
|
||||
@@ -870,6 +871,7 @@ final class DifferentialRevisionViewController
|
||||
$raw_changesets = id(new DifferentialChangesetQuery())
|
||||
->setViewer($viewer)
|
||||
->withDiffs($load_diffs)
|
||||
->needHunks(true)
|
||||
->execute();
|
||||
$changeset_groups = mgroup($raw_changesets, 'getDiffID');
|
||||
|
||||
|
||||
@@ -33,9 +33,10 @@ final class DifferentialDiffPHIDType extends PhabricatorPHIDType {
|
||||
$diff = $objects[$phid];
|
||||
|
||||
$id = $diff->getID();
|
||||
$revision_id = $diff->getRevisionID();
|
||||
|
||||
$handle->setName(pht('Diff %d', $id));
|
||||
$handle->setURI("/differential/diff/{$id}/");
|
||||
$handle->setURI("D{$revision_id}.{$id}.html");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -589,15 +589,15 @@ abstract class DifferentialChangesetHTMLRenderer
|
||||
$reference = $this->getRenderingReference();
|
||||
|
||||
return javelin_tag(
|
||||
'a',
|
||||
'span',
|
||||
array(
|
||||
'href' => '#',
|
||||
'mustcapture' => true,
|
||||
'sigil' => 'show-more',
|
||||
'meta' => array(
|
||||
'type' => ($is_all ? 'all' : null),
|
||||
'range' => $range,
|
||||
),
|
||||
// 'href' => '#',
|
||||
// 'mustcapture' => true,
|
||||
// 'sigil' => 'show-more',
|
||||
// 'meta' => array(
|
||||
// 'type' => ($is_all ? 'all' : null),
|
||||
// 'range' => $range,
|
||||
// ),
|
||||
),
|
||||
$text);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ final class DifferentialRevision extends DifferentialDAO
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
return $this->getMonogram() . '.html';
|
||||
}
|
||||
|
||||
public function getCommitPHIDs() {
|
||||
|
||||
@@ -187,13 +187,13 @@ final class DifferentialChangesetListView extends AphrontView {
|
||||
$uniq_id = 'diff-'.$changeset->getAnchorName();
|
||||
$detail->setID($uniq_id);
|
||||
|
||||
$view_options = $this->renderViewOptionsDropdown(
|
||||
$detail,
|
||||
$ref,
|
||||
$changeset);
|
||||
// $view_options = $this->renderViewOptionsDropdown(
|
||||
// $detail,
|
||||
// $ref,
|
||||
// $changeset);
|
||||
|
||||
$detail->setChangeset($changeset);
|
||||
$detail->addButton($view_options);
|
||||
// $detail->addButton($view_options);
|
||||
$detail->setSymbolIndex(idx($this->symbolIndexes, $key));
|
||||
$detail->setVsChangesetID(idx($this->vsMap, $changeset->getID()));
|
||||
$detail->setEditable(true);
|
||||
@@ -202,7 +202,107 @@ final class DifferentialChangesetListView extends AphrontView {
|
||||
|
||||
$detail->setRenderURI($this->renderURI);
|
||||
|
||||
$parser = $this->getParser();
|
||||
// $parser = $this->getParser();
|
||||
|
||||
$revision_id = $diff->getRevisionID();
|
||||
$revision = id(new DifferentialRevisionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($revision_id))
|
||||
->executeOne();
|
||||
|
||||
$old = array();
|
||||
$new = array();
|
||||
|
||||
$right = $changeset;
|
||||
$left = null;
|
||||
|
||||
$right_source = $right->getID();
|
||||
$right_new = true;
|
||||
$left_source = $right->getID();
|
||||
$left_new = false;
|
||||
|
||||
$render_cache_key = $right->getID();
|
||||
|
||||
$old[] = $changeset;
|
||||
$new[] = $changeset;
|
||||
|
||||
$parser = id(new DifferentialChangesetParser())
|
||||
->setViewer($viewer)
|
||||
->setViewState(new PhabricatorChangesetViewState())
|
||||
// ->setCoverage($coverage)
|
||||
->setChangeset($changeset)
|
||||
->setRenderingReference($ref)
|
||||
->setRenderCacheKey($render_cache_key)
|
||||
->setRightSideCommentMapping($right_source, $right_new)
|
||||
->setLeftSideCommentMapping($left_source, $left_new)
|
||||
->setMask(array())
|
||||
;
|
||||
|
||||
if ($left && $right) {
|
||||
$parser->setOriginals($left, $right);
|
||||
}
|
||||
|
||||
if ($revision) {
|
||||
$inlines = id(new DifferentialDiffInlineCommentQuery())
|
||||
->setViewer($viewer)
|
||||
->withRevisionPHIDs(array($revision->getPHID()))
|
||||
->withPublishableComments(true)
|
||||
->withPublishedComments(true)
|
||||
->needHidden(true)
|
||||
->needInlineContext(true)
|
||||
->execute();
|
||||
|
||||
$inlines = mpull($inlines, 'newInlineCommentObject');
|
||||
|
||||
$inlines = id(new PhabricatorInlineCommentAdjustmentEngine())
|
||||
->setViewer($viewer)
|
||||
->setRevision($revision)
|
||||
->setOldChangesets($old)
|
||||
->setNewChangesets($new)
|
||||
->setInlines($inlines)
|
||||
->execute();
|
||||
} else {
|
||||
$inlines = array();
|
||||
}
|
||||
|
||||
if ($left_new) {
|
||||
$inlines = array_merge(
|
||||
$inlines,
|
||||
$this->buildLintInlineComments($left));
|
||||
}
|
||||
|
||||
if ($right_new) {
|
||||
$inlines = array_merge(
|
||||
$inlines,
|
||||
$this->buildLintInlineComments($right));
|
||||
}
|
||||
|
||||
$phids = array();
|
||||
foreach ($inlines as $inline) {
|
||||
$parser->parseInlineComment($inline);
|
||||
if ($inline->getAuthorPHID()) {
|
||||
$phids[$inline->getAuthorPHID()] = true;
|
||||
}
|
||||
}
|
||||
$phids = array_keys($phids);
|
||||
|
||||
$handles = $this->loadViewerHandles($phids);
|
||||
$parser->setHandles($handles);
|
||||
|
||||
$engine = new PhabricatorMarkupEngine();
|
||||
$engine->setViewer($viewer);
|
||||
|
||||
foreach ($inlines as $inline) {
|
||||
$engine->addObject(
|
||||
$inline,
|
||||
PhabricatorInlineComment::MARKUP_FIELD_BODY);
|
||||
}
|
||||
|
||||
$engine->process();
|
||||
|
||||
$parser
|
||||
->setMarkupEngine($engine);
|
||||
|
||||
if ($parser) {
|
||||
$response = $parser->newChangesetResponse();
|
||||
$detail->setChangesetResponse($response);
|
||||
@@ -471,4 +571,92 @@ final class DifferentialChangesetListView extends AphrontView {
|
||||
return $uri;
|
||||
}
|
||||
|
||||
private function buildLintInlineComments($changeset) {
|
||||
$diff = $changeset->getDiff();
|
||||
|
||||
$target_phids = $diff->getBuildTargetPHIDs();
|
||||
if (!$target_phids) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$messages = id(new HarbormasterBuildLintMessage())->loadAllWhere(
|
||||
'buildTargetPHID IN (%Ls) AND path = %s',
|
||||
$target_phids,
|
||||
$changeset->getFilename());
|
||||
|
||||
if (!$messages) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$change_type = $changeset->getChangeType();
|
||||
if (DifferentialChangeType::isDeleteChangeType($change_type)) {
|
||||
// If this is a lint message on a deleted file, show it on the left
|
||||
// side of the UI because there are no source code lines on the right
|
||||
// side of the UI so inlines don't have anywhere to render. See PHI416.
|
||||
$is_new = 0;
|
||||
} else {
|
||||
$is_new = 1;
|
||||
}
|
||||
|
||||
$template = id(new DifferentialInlineComment())
|
||||
->setChangesetID($changeset->getID())
|
||||
->setIsNewFile($is_new)
|
||||
->setLineLength(0);
|
||||
|
||||
$inlines = array();
|
||||
foreach ($messages as $message) {
|
||||
$description = $message->getProperty('description');
|
||||
|
||||
$inlines[] = id(clone $template)
|
||||
->setSyntheticAuthor(pht('Lint: %s', $message->getName()))
|
||||
->setLineNumber($message->getLine())
|
||||
->setContent($description);
|
||||
}
|
||||
|
||||
return $inlines;
|
||||
}
|
||||
|
||||
private function loadCoverage(DifferentialChangeset $changeset) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$target_phids = $changeset->getDiff()->getBuildTargetPHIDs();
|
||||
if (!$target_phids) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$unit = id(new HarbormasterBuildUnitMessageQuery())
|
||||
->setViewer($viewer)
|
||||
->withBuildTargetPHIDs($target_phids)
|
||||
->execute();
|
||||
if (!$unit) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$coverage = array();
|
||||
foreach ($unit as $message) {
|
||||
$test_coverage = $message->getProperty('coverage');
|
||||
if ($test_coverage === null) {
|
||||
continue;
|
||||
}
|
||||
$coverage_data = idx($test_coverage, $changeset->getFileName());
|
||||
if (!strlen($coverage_data)) {
|
||||
continue;
|
||||
}
|
||||
$coverage[] = $coverage_data;
|
||||
}
|
||||
|
||||
if (!$coverage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ArcanistUnitTestResult::mergeCoverage($coverage);
|
||||
}
|
||||
|
||||
protected function loadViewerHandles(array $phids) {
|
||||
return id(new PhabricatorHandleQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withPHIDs($phids)
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
$id_link = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/D'.$revision_id.'?id='.$id,
|
||||
'href' => 'D'.$revision_id.'.'.$id.'.html',
|
||||
),
|
||||
$id);
|
||||
} else {
|
||||
@@ -196,19 +196,27 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
$base,
|
||||
$desc,
|
||||
$age,
|
||||
$lint,
|
||||
$unit,
|
||||
$old,
|
||||
$new,
|
||||
// $lint,
|
||||
// $unit,
|
||||
// $old,
|
||||
// $new,
|
||||
);
|
||||
|
||||
$classes = array();
|
||||
|
||||
/*
|
||||
if ($old_class) {
|
||||
$classes[] = 'differential-update-history-old-now';
|
||||
}
|
||||
if ($new_class) {
|
||||
$classes[] = 'differential-update-history-new-now';
|
||||
}
|
||||
*/
|
||||
|
||||
if ($id && $this->selectedDiffID == $id) {
|
||||
$classes[] = 'differential-update-history-current';
|
||||
}
|
||||
|
||||
$rowc[] = nonempty(implode(' ', $classes), null);
|
||||
}
|
||||
|
||||
@@ -226,10 +234,10 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
pht('Base'),
|
||||
pht('Description'),
|
||||
pht('Created'),
|
||||
pht('Lint'),
|
||||
pht('Unit'),
|
||||
'',
|
||||
'',
|
||||
// pht('Lint'),
|
||||
// pht('Unit'),
|
||||
// '',
|
||||
// '',
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
@@ -238,8 +246,8 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
'',
|
||||
'wide',
|
||||
'date',
|
||||
'center',
|
||||
'center',
|
||||
// 'center',
|
||||
// 'center',
|
||||
'center differential-update-history-old',
|
||||
'center differential-update-history-new',
|
||||
));
|
||||
@@ -251,8 +259,8 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
// false,
|
||||
// false,
|
||||
true,
|
||||
true,
|
||||
));
|
||||
@@ -276,7 +284,7 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
),
|
||||
array(
|
||||
$table,
|
||||
$show_diff,
|
||||
// $show_diff,
|
||||
));
|
||||
|
||||
return $content;
|
||||
|
||||
@@ -143,11 +143,12 @@ final class PhabricatorEmbedFileRemarkupRule
|
||||
$xform = PhabricatorFileTransform::getTransformByKey($preview_key);
|
||||
|
||||
$existing_xform = $file->getTransform($preview_key);
|
||||
if ($existing_xform) {
|
||||
$xform_uri = $existing_xform->getCDNURI('data');
|
||||
} else {
|
||||
$xform_uri = $file->getURIForTransform($xform);
|
||||
}
|
||||
// if ($existing_xform) {
|
||||
// $xform_uri = $existing_xform->getCDNURI('data');
|
||||
// } else {
|
||||
// $xform_uri = $file->getURIForTransform($xform);
|
||||
// }
|
||||
$xform_uri = $existing_xform->getInfoURI();
|
||||
|
||||
$attrs['src'] = $xform_uri;
|
||||
|
||||
|
||||
@@ -829,7 +829,6 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||
throw new Exception(
|
||||
pht('You must save a file before you can generate a view URI.'));
|
||||
}
|
||||
|
||||
return $this->getCDNURI('data');
|
||||
}
|
||||
|
||||
@@ -875,13 +874,23 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||
}
|
||||
}
|
||||
|
||||
public static function makeFileNameForURI($id, $name) {
|
||||
// $safe_name = preg_replace('/[\\/\\\\]/', '_', $name);
|
||||
$safe_name = preg_replace('/[^A-Za-z0-9\\-_\\+\\.]/', '_', $name);
|
||||
return 'F' . $id . DIRECTORY_SEPARATOR . $safe_name;
|
||||
}
|
||||
|
||||
public function getSafeFileNameForBake() {
|
||||
return PhabricatorFile::makeFileNameForURI(
|
||||
$this->getID(), $this->getName());
|
||||
}
|
||||
|
||||
public function getInfoURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
return 'file/'.$this->getSafeFileNameForBake();
|
||||
}
|
||||
|
||||
public function getBestURI() {
|
||||
if ($this->isViewableInBrowser()) {
|
||||
if ($this->isViewableInBrowser() && false) {
|
||||
return $this->getViewURI();
|
||||
} else {
|
||||
return $this->getInfoURI();
|
||||
@@ -889,7 +898,8 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||
}
|
||||
|
||||
public function getDownloadURI() {
|
||||
return $this->getCDNURI('download');
|
||||
return $this->getInfoURI();
|
||||
// return $this->getCDNURI('download');
|
||||
}
|
||||
|
||||
public function getURIForTransform(PhabricatorFileTransform $transform) {
|
||||
|
||||
@@ -55,7 +55,7 @@ final class PhabricatorFlagsUIEventListener extends PhabricatorEventListener {
|
||||
}
|
||||
|
||||
$actions = $event->getValue('actions');
|
||||
$actions[] = $flag_action;
|
||||
// $actions[] = $flag_action;
|
||||
$event->setValue('actions', $actions);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ final class PhabricatorPastePastePHIDType extends PhabricatorPHIDType {
|
||||
|
||||
$handle->setName("P{$id}");
|
||||
$handle->setFullName($name);
|
||||
$handle->setURI("/P{$id}");
|
||||
$handle->setURI("paste/P{$id}.txt");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ final class PhabricatorPasteSearchEngine
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName('P'.$paste->getID())
|
||||
->setHeader($title)
|
||||
->setHref('/P'.$paste->getID())
|
||||
->setHref('paste/P'.$paste->getID().'.txt')
|
||||
->setObject($paste)
|
||||
->addByline(pht('Author: %s', $author))
|
||||
->addIcon('none', $created)
|
||||
|
||||
@@ -60,7 +60,7 @@ final class PhabricatorPaste extends PhabricatorPasteDAO
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
return 'paste/'.$this->getMonogram();
|
||||
}
|
||||
|
||||
public function getMonogram() {
|
||||
|
||||
@@ -38,7 +38,7 @@ final class PasteEmbedView extends AphrontView {
|
||||
$link = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/P'.$this->paste->getID(),
|
||||
'href' => 'paste/P'.$this->paste->getID().'.txt',
|
||||
),
|
||||
$this->handle->getFullName());
|
||||
|
||||
|
||||
@@ -608,6 +608,8 @@ final class PhabricatorUser
|
||||
}
|
||||
|
||||
public function getProfileImageURI() {
|
||||
return '/rsrc/image/avatar.png';
|
||||
|
||||
$uri_key = PhabricatorUserProfileImageCacheType::KEY_URI;
|
||||
return $this->requireCacheData($uri_key);
|
||||
}
|
||||
@@ -982,6 +984,10 @@ final class PhabricatorUser
|
||||
return $this->handlePool->newHandleList($phids);
|
||||
}
|
||||
|
||||
public function getHandlePool() {
|
||||
return $this->handlePool;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a @{class:PHUIHandleView} for a single handle.
|
||||
|
||||
@@ -146,7 +146,15 @@ final class PhabricatorObjectHandle
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return $this->uri;
|
||||
$type = $this->getType();
|
||||
if ($type == 'TASK') {
|
||||
// XXX: Use real link to gitea task
|
||||
// At least for now rely on the existence of the manip[hest task redirector.
|
||||
return 'https://developer.blender.org' . $this->uri;
|
||||
} else if ($type == 'DREV' || $type == 'DIFF' || $type == 'PSTE' || $type == 'FILE') {
|
||||
return $this->uri;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setPHID($phid) {
|
||||
@@ -357,7 +365,7 @@ final class PhabricatorObjectHandle
|
||||
);
|
||||
|
||||
return javelin_tag(
|
||||
$uri ? 'a' : 'span',
|
||||
$uri ? 'a' : 'b',
|
||||
$attributes,
|
||||
array($circle, $icon, $name));
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ final class PhabricatorHandlePool extends Phobject {
|
||||
return $this->viewer;
|
||||
}
|
||||
|
||||
public function getHandles() {
|
||||
return $this->handles;
|
||||
}
|
||||
|
||||
public function newHandleList(array $phids) {
|
||||
// Mark any PHIDs we haven't loaded yet as unloaded. This will let us bulk
|
||||
// load them later.
|
||||
|
||||
@@ -112,8 +112,8 @@ final class PhabricatorSubscriptionsUIEventListener
|
||||
|
||||
|
||||
$actions = $event->getValue('actions');
|
||||
$actions[] = $sub_action;
|
||||
$actions[] = $mute_action;
|
||||
// $actions[] = $sub_action;
|
||||
// $actions[] = $mute_action;
|
||||
$event->setValue('actions', $actions);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ final class PhabricatorTokenUIEventListener
|
||||
}
|
||||
|
||||
$actions = $event->getValue('actions');
|
||||
$actions[] = $token_action;
|
||||
// $actions[] = $token_action;
|
||||
$event->setValue('actions', $actions);
|
||||
}
|
||||
|
||||
|
||||
@@ -184,6 +184,7 @@ final class PhabricatorApplicationTransactionCommentView
|
||||
if ($this->getNoPermission()) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
|
||||
$lock = $this->getEditEngineLock();
|
||||
if ($lock) {
|
||||
|
||||
@@ -203,7 +203,7 @@ class PhabricatorApplicationTransactionView extends AphrontView {
|
||||
throw new PhutilInvalidStateException('setObjectPHID');
|
||||
}
|
||||
|
||||
$view = $this->buildPHUITimelineView();
|
||||
$view = $this->buildPHUITimelineView(false);
|
||||
|
||||
if ($this->getShowEditActions()) {
|
||||
Javelin::initBehavior('phabricator-transaction-list');
|
||||
|
||||
@@ -377,7 +377,7 @@ final class PHUIDiffInlineCommentDetailView
|
||||
}
|
||||
|
||||
$actions = null;
|
||||
if ($action_buttons || $menu_items) {
|
||||
if (($action_buttons || $menu_items) && false) {
|
||||
$actions = new PHUIButtonBarView();
|
||||
$actions->setBorderless(true);
|
||||
$actions->addClass('inline-button-divider');
|
||||
|
||||
@@ -125,7 +125,7 @@ abstract class AphrontView extends Phobject
|
||||
* @return wild Renderable children.
|
||||
* @task
|
||||
*/
|
||||
final protected function renderChildren() {
|
||||
final public function renderChildren() {
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
|
||||
@@ -331,12 +331,12 @@ final class PHUITimelineEventView extends AphrontView {
|
||||
|
||||
$menu = null;
|
||||
$items = array();
|
||||
if (!$this->getIsPreview() && !$this->getHideCommentOptions()) {
|
||||
foreach ($this->getEventGroup() as $event) {
|
||||
$items[] = $event->getMenuItems($this->anchor);
|
||||
}
|
||||
$items = array_mergev($items);
|
||||
}
|
||||
// if (!$this->getIsPreview() && !$this->getHideCommentOptions()) {
|
||||
// foreach ($this->getEventGroup() as $event) {
|
||||
// $items[] = $event->getMenuItems($this->anchor);
|
||||
// }
|
||||
// $items = array_mergev($items);
|
||||
// }
|
||||
|
||||
if ($items) {
|
||||
$icon = id(new PHUIIconView())
|
||||
@@ -431,11 +431,10 @@ final class PHUITimelineEventView extends AphrontView {
|
||||
$badges = null;
|
||||
if ($image_uri) {
|
||||
$image = javelin_tag(
|
||||
($this->userHandle->getURI()) ? 'a' : 'div',
|
||||
'div',
|
||||
array(
|
||||
'style' => 'background-image: url('.$image_uri.')',
|
||||
'class' => 'phui-timeline-image',
|
||||
'href' => $this->userHandle->getURI(),
|
||||
'aural' => false,
|
||||
),
|
||||
'');
|
||||
|
||||
@@ -37,6 +37,11 @@
|
||||
background: #d0ffd0;
|
||||
}
|
||||
|
||||
.aphront-table-view tr.differential-update-history-current td,
|
||||
.aphront-table-view tr.alt-differential-update-history-current td {
|
||||
background: #d0ffd0;
|
||||
}
|
||||
|
||||
.aphront-table-view
|
||||
.differential-update-history-old-now
|
||||
td.differential-update-history-old,
|
||||
|
||||
Reference in New Issue
Block a user