mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-10 23:01:04 +01:00
(stable) Promote 2018 Week 13
This commit is contained in:
commit
126f7f0d56
27 changed files with 892 additions and 92 deletions
|
@ -9,8 +9,8 @@ return array(
|
|||
'names' => array(
|
||||
'conpherence.pkg.css' => 'e68cf1fa',
|
||||
'conpherence.pkg.js' => '15191c65',
|
||||
'core.pkg.css' => '3fd3b7b8',
|
||||
'core.pkg.js' => 'b9b4a943',
|
||||
'core.pkg.css' => '1dd5fa4b',
|
||||
'core.pkg.js' => '1ea38af8',
|
||||
'differential.pkg.css' => '113e692c',
|
||||
'differential.pkg.js' => 'f6d809c0',
|
||||
'diffusion.pkg.css' => 'a2d17c7d',
|
||||
|
@ -112,7 +112,7 @@ return array(
|
|||
'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
|
||||
'rsrc/css/application/uiexample/example.css' => '528b19de',
|
||||
'rsrc/css/core/core.css' => '62fa3ace',
|
||||
'rsrc/css/core/remarkup.css' => 'b375546d',
|
||||
'rsrc/css/core/remarkup.css' => '1828e2ad',
|
||||
'rsrc/css/core/syntax.css' => 'cae95e89',
|
||||
'rsrc/css/core/z-index.css' => '9d8f7c4b',
|
||||
'rsrc/css/diviner/diviner-shared.css' => '896f1d43',
|
||||
|
@ -392,7 +392,7 @@ return array(
|
|||
'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => 'f01586dc',
|
||||
'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => '1db13e70',
|
||||
'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef',
|
||||
'rsrc/js/application/files/behavior-document-engine.js' => 'd3f8623c',
|
||||
'rsrc/js/application/files/behavior-document-engine.js' => '9108ee1a',
|
||||
'rsrc/js/application/files/behavior-icon-composer.js' => '8499b6ab',
|
||||
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
|
||||
'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => '191b4909',
|
||||
|
@ -508,8 +508,8 @@ return array(
|
|||
'rsrc/js/phui/behavior-phui-submenu.js' => 'a6f7a73b',
|
||||
'rsrc/js/phui/behavior-phui-tab-group.js' => '0a0b10e9',
|
||||
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
|
||||
'rsrc/js/phuix/PHUIXActionView.js' => 'ed18356a',
|
||||
'rsrc/js/phuix/PHUIXAutocomplete.js' => '7fa5c915',
|
||||
'rsrc/js/phuix/PHUIXActionView.js' => '8d4a8c72',
|
||||
'rsrc/js/phuix/PHUIXAutocomplete.js' => 'df1bbd34',
|
||||
'rsrc/js/phuix/PHUIXButtonView.js' => '8a91e1ac',
|
||||
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '04b2ae03',
|
||||
'rsrc/js/phuix/PHUIXExample.js' => '68af71ca',
|
||||
|
@ -607,7 +607,7 @@ return array(
|
|||
'javelin-behavior-diffusion-jump-to' => '73d09eef',
|
||||
'javelin-behavior-diffusion-locate-file' => '6d3e1947',
|
||||
'javelin-behavior-diffusion-pull-lastmodified' => 'f01586dc',
|
||||
'javelin-behavior-document-engine' => 'd3f8623c',
|
||||
'javelin-behavior-document-engine' => '9108ee1a',
|
||||
'javelin-behavior-doorkeeper-tag' => '1db13e70',
|
||||
'javelin-behavior-drydock-live-operation-status' => '901935ef',
|
||||
'javelin-behavior-durable-column' => '2ae077e1',
|
||||
|
@ -780,7 +780,7 @@ return array(
|
|||
'phabricator-object-selector-css' => '85ee8ce6',
|
||||
'phabricator-phtize' => 'd254d646',
|
||||
'phabricator-prefab' => '77b0ae28',
|
||||
'phabricator-remarkup-css' => 'b375546d',
|
||||
'phabricator-remarkup-css' => '1828e2ad',
|
||||
'phabricator-search-results-css' => '505dd8cf',
|
||||
'phabricator-shaped-request' => '7cbe244b',
|
||||
'phabricator-slowvote-css' => 'a94b7230',
|
||||
|
@ -864,8 +864,8 @@ return array(
|
|||
'phui-workcard-view-css' => 'cca5fa92',
|
||||
'phui-workpanel-view-css' => 'a3a63478',
|
||||
'phuix-action-list-view' => 'b5c256b8',
|
||||
'phuix-action-view' => 'ed18356a',
|
||||
'phuix-autocomplete' => '7fa5c915',
|
||||
'phuix-action-view' => '8d4a8c72',
|
||||
'phuix-autocomplete' => 'df1bbd34',
|
||||
'phuix-button-view' => '8a91e1ac',
|
||||
'phuix-dropdown-menu' => '04b2ae03',
|
||||
'phuix-form-control-view' => '210a16c1',
|
||||
|
@ -1553,12 +1553,6 @@ return array(
|
|||
'7f243deb' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
'7fa5c915' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'phuix-icon-view',
|
||||
'phabricator-prefab',
|
||||
),
|
||||
'834a1173' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-scrollbar',
|
||||
|
@ -1620,6 +1614,11 @@ return array(
|
|||
'javelin-stratcom',
|
||||
'javelin-install',
|
||||
),
|
||||
'8d4a8c72' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
),
|
||||
'8e1baf68' => array(
|
||||
'phui-button-css',
|
||||
),
|
||||
|
@ -1645,6 +1644,11 @@ return array(
|
|||
'javelin-stratcom',
|
||||
'javelin-vector',
|
||||
),
|
||||
'9108ee1a' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-stratcom',
|
||||
),
|
||||
'92b9ec77' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -2002,11 +2006,6 @@ return array(
|
|||
'd254d646' => array(
|
||||
'javelin-util',
|
||||
),
|
||||
'd3f8623c' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-stratcom',
|
||||
),
|
||||
'd4505101' => array(
|
||||
'javelin-stratcom',
|
||||
'javelin-install',
|
||||
|
@ -2047,6 +2046,12 @@ return array(
|
|||
'javelin-typeahead-ondemand-source',
|
||||
'javelin-dom',
|
||||
),
|
||||
'df1bbd34' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'phuix-icon-view',
|
||||
'phabricator-prefab',
|
||||
),
|
||||
'e1d25dfb' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -2125,11 +2130,6 @@ return array(
|
|||
'javelin-stratcom',
|
||||
'javelin-vector',
|
||||
),
|
||||
'ed18356a' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
),
|
||||
'edf8a145' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-uri',
|
||||
|
|
|
@ -4020,6 +4020,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRepositoryManagementRefsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementRefsWorkflow.php',
|
||||
'PhabricatorRepositoryManagementReparseWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementReparseWorkflow.php',
|
||||
'PhabricatorRepositoryManagementThawWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementThawWorkflow.php',
|
||||
'PhabricatorRepositoryManagementUnpublishWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementUnpublishWorkflow.php',
|
||||
'PhabricatorRepositoryManagementUpdateWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementUpdateWorkflow.php',
|
||||
'PhabricatorRepositoryManagementWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementWorkflow.php',
|
||||
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryMercurialCommitChangeParserWorker.php',
|
||||
|
@ -6525,6 +6526,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorConduitResultInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'HarbormasterBuildAbortedException' => 'Exception',
|
||||
'HarbormasterBuildActionController' => 'HarbormasterController',
|
||||
|
@ -6532,6 +6534,7 @@ phutil_register_library_map(array(
|
|||
'HarbormasterBuildArtifact' => array(
|
||||
'HarbormasterDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'HarbormasterBuildArtifactPHIDType' => 'PhabricatorPHIDType',
|
||||
'HarbormasterBuildArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
|
@ -6564,6 +6567,7 @@ phutil_register_library_map(array(
|
|||
'HarbormasterBuildMessage' => array(
|
||||
'HarbormasterDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'HarbormasterBuildMessageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'HarbormasterBuildPHIDType' => 'PhabricatorPHIDType',
|
||||
|
@ -6614,6 +6618,7 @@ phutil_register_library_map(array(
|
|||
'HarbormasterBuildTarget' => array(
|
||||
'HarbormasterDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'HarbormasterBuildTargetPHIDType' => 'PhabricatorPHIDType',
|
||||
'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
|
@ -6628,6 +6633,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
'HarbormasterBuildableInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'HarbormasterBuildableActionController' => 'HarbormasterController',
|
||||
'HarbormasterBuildableListController' => 'HarbormasterController',
|
||||
|
@ -8558,7 +8564,10 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorMarkupInterface',
|
||||
),
|
||||
'PhabricatorFeedStoryData' => 'PhabricatorFeedDAO',
|
||||
'PhabricatorFeedStoryData' => array(
|
||||
'PhabricatorFeedDAO',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'PhabricatorFeedStoryNotification' => 'PhabricatorFeedDAO',
|
||||
'PhabricatorFeedStoryPublisher' => 'Phobject',
|
||||
'PhabricatorFeedStoryReference' => 'PhabricatorFeedDAO',
|
||||
|
@ -9809,6 +9818,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRepositoryManagementRefsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementReparseWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementThawWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementUnpublishWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementUpdateWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
|
||||
|
|
|
@ -137,7 +137,34 @@ final class DifferentialRevisionUpdateTransaction
|
|||
continue;
|
||||
}
|
||||
|
||||
if ($diff->getRevisionID()) {
|
||||
$is_attached =
|
||||
($diff->getRevisionID()) &&
|
||||
($diff->getRevisionID() == $object->getID());
|
||||
if ($is_attached) {
|
||||
$is_active = ($diff_phid == $object->getActiveDiffPHID());
|
||||
} else {
|
||||
$is_active = false;
|
||||
}
|
||||
|
||||
if ($is_attached) {
|
||||
if ($is_active) {
|
||||
// This is a no-op: we're reattaching the current active diff to the
|
||||
// revision it is already attached to. This is valid and will just
|
||||
// be dropped later on in the process.
|
||||
} else {
|
||||
// At least for now, there's no support for "undoing" a diff and
|
||||
// reverting to an older proposed change without just creating a
|
||||
// new diff from whole cloth.
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht(
|
||||
'You can not update this revision with the specified diff '.
|
||||
'("%s") because this diff is already attached to the revision '.
|
||||
'as an older version of the change.',
|
||||
$diff_phid),
|
||||
$xaction);
|
||||
continue;
|
||||
}
|
||||
} else if ($diff->getRevisionID()) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht(
|
||||
'You can not update this revision with the specified diff ("%s") '.
|
||||
|
|
|
@ -126,7 +126,6 @@ final class DiffusionCommitHookEngine extends Phobject {
|
|||
|
||||
public function execute() {
|
||||
$ref_updates = $this->findRefUpdates();
|
||||
$all_updates = $ref_updates;
|
||||
|
||||
$caught = null;
|
||||
try {
|
||||
|
@ -140,21 +139,32 @@ final class DiffusionCommitHookEngine extends Phobject {
|
|||
throw $ex;
|
||||
}
|
||||
|
||||
$this->applyHeraldRefRules($ref_updates, $all_updates);
|
||||
|
||||
$content_updates = $this->findContentUpdates($ref_updates);
|
||||
$all_updates = array_merge($ref_updates, $content_updates);
|
||||
|
||||
// If this is an "initial import" (a sizable push to a previously empty
|
||||
// repository) we'll allow enormous changes and disable Herald rules.
|
||||
// These rulesets can consume a large amount of time and memory and are
|
||||
// generally not relevant when importing repository history.
|
||||
$is_initial_import = $this->isInitialImport($all_updates);
|
||||
|
||||
if (!$is_initial_import) {
|
||||
$this->applyHeraldRefRules($ref_updates);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->rejectEnormousChanges($content_updates);
|
||||
if (!$is_initial_import) {
|
||||
$this->rejectEnormousChanges($content_updates);
|
||||
}
|
||||
} catch (DiffusionCommitHookRejectException $ex) {
|
||||
// If we're rejecting enormous changes, flag everything.
|
||||
$this->rejectCode = PhabricatorRepositoryPushLog::REJECT_ENORMOUS;
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
$all_updates = array_merge($all_updates, $content_updates);
|
||||
|
||||
$this->applyHeraldContentRules($content_updates, $all_updates);
|
||||
if (!$is_initial_import) {
|
||||
$this->applyHeraldContentRules($content_updates);
|
||||
}
|
||||
|
||||
// Run custom scripts in `hook.d/` directories.
|
||||
$this->applyCustomHooks($all_updates);
|
||||
|
@ -186,12 +196,10 @@ final class DiffusionCommitHookEngine extends Phobject {
|
|||
throw $caught;
|
||||
}
|
||||
|
||||
// If this went through cleanly, detect pushes which are actually imports
|
||||
// of an existing repository rather than an addition of new commits. If
|
||||
// this push is importing a bunch of stuff, set the importing flag on
|
||||
// the repository. It will be cleared once we fully process everything.
|
||||
// If this went through cleanly and was an import, set the importing flag
|
||||
// on the repository. It will be cleared once we fully process everything.
|
||||
|
||||
if ($this->isInitialImport($all_updates)) {
|
||||
if ($is_initial_import) {
|
||||
$repository = $this->getRepository();
|
||||
$repository->markImporting();
|
||||
}
|
||||
|
@ -281,28 +289,21 @@ final class DiffusionCommitHookEngine extends Phobject {
|
|||
|
||||
/* -( Herald )------------------------------------------------------------- */
|
||||
|
||||
private function applyHeraldRefRules(
|
||||
array $ref_updates,
|
||||
array $all_updates) {
|
||||
private function applyHeraldRefRules(array $ref_updates) {
|
||||
$this->applyHeraldRules(
|
||||
$ref_updates,
|
||||
new HeraldPreCommitRefAdapter(),
|
||||
$all_updates);
|
||||
new HeraldPreCommitRefAdapter());
|
||||
}
|
||||
|
||||
private function applyHeraldContentRules(
|
||||
array $content_updates,
|
||||
array $all_updates) {
|
||||
private function applyHeraldContentRules(array $content_updates) {
|
||||
$this->applyHeraldRules(
|
||||
$content_updates,
|
||||
new HeraldPreCommitContentAdapter(),
|
||||
$all_updates);
|
||||
new HeraldPreCommitContentAdapter());
|
||||
}
|
||||
|
||||
private function applyHeraldRules(
|
||||
array $updates,
|
||||
HeraldAdapter $adapter_template,
|
||||
array $all_updates) {
|
||||
HeraldAdapter $adapter_template) {
|
||||
|
||||
if (!$updates) {
|
||||
return;
|
||||
|
|
|
@ -57,8 +57,8 @@ final class DrydockManagementCommandWorkflow
|
|||
array($interface, 'execx'),
|
||||
array('%Ls', $argv));
|
||||
|
||||
fprintf(STDOUT, $stdout);
|
||||
fprintf(STDERR, $stderr);
|
||||
fwrite(STDOUT, $stdout);
|
||||
fwrite(STDERR, $stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorFeedStoryData extends PhabricatorFeedDAO {
|
||||
final class PhabricatorFeedStoryData
|
||||
extends PhabricatorFeedDAO
|
||||
implements PhabricatorDestructibleInterface {
|
||||
|
||||
protected $phid;
|
||||
|
||||
|
@ -66,4 +68,30 @@ final class PhabricatorFeedStoryData extends PhabricatorFeedDAO {
|
|||
return idx($this->storyData, $key, $default);
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
||||
public function destroyObjectPermanently(
|
||||
PhabricatorDestructionEngine $engine) {
|
||||
|
||||
$this->openTransaction();
|
||||
$conn = $this->establishConnection('w');
|
||||
|
||||
queryfx(
|
||||
$conn,
|
||||
'DELETE FROM %T WHERE chronologicalKey = %s',
|
||||
id(new PhabricatorFeedStoryNotification())->getTableName(),
|
||||
$this->getChronologicalKey());
|
||||
|
||||
queryfx(
|
||||
$conn,
|
||||
'DELETE FROM %T WHERE chronologicalKey = %s',
|
||||
id(new PhabricatorFeedStoryReference())->getTableName(),
|
||||
$this->getChronologicalKey());
|
||||
|
||||
$this->delete();
|
||||
$this->saveTransaction();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@ final class PhabricatorFileDocumentController
|
|||
private $engine;
|
||||
private $ref;
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
|
@ -39,6 +43,16 @@ final class PhabricatorFileDocumentController
|
|||
$engine = $engines[$engine_key];
|
||||
$this->engine = $engine;
|
||||
|
||||
$encode_setting = $request->getStr('encode');
|
||||
if (strlen($encode_setting)) {
|
||||
$engine->setEncodingConfiguration($encode_setting);
|
||||
}
|
||||
|
||||
$highlight_setting = $request->getStr('highlight');
|
||||
if (strlen($highlight_setting)) {
|
||||
$engine->setHighlightingConfiguration($highlight_setting);
|
||||
}
|
||||
|
||||
try {
|
||||
$content = $engine->newDocument($ref);
|
||||
} catch (Exception $ex) {
|
||||
|
|
|
@ -422,6 +422,16 @@ final class PhabricatorFileViewController extends PhabricatorFileController {
|
|||
$engine->setHighlightedLines(range($lines[0], $lines[1]));
|
||||
}
|
||||
|
||||
$encode_setting = $request->getStr('encode');
|
||||
if (strlen($encode_setting)) {
|
||||
$engine->setEncodingConfiguration($encode_setting);
|
||||
}
|
||||
|
||||
$highlight_setting = $request->getStr('highlight');
|
||||
if (strlen($highlight_setting)) {
|
||||
$engine->setHighlightingConfiguration($highlight_setting);
|
||||
}
|
||||
|
||||
$views = array();
|
||||
foreach ($engines as $candidate_key => $candidate_engine) {
|
||||
$label = $candidate_engine->getViewAsLabel($ref);
|
||||
|
@ -443,6 +453,8 @@ final class PhabricatorFileViewController extends PhabricatorFileController {
|
|||
'engineURI' => $candidate_engine->getRenderURI($ref),
|
||||
'viewURI' => $view_uri,
|
||||
'loadingMarkup' => hsprintf('%s', $loading),
|
||||
'canEncode' => $candidate_engine->canConfigureEncoding($ref),
|
||||
'canHighlight' => $candidate_engine->CanConfigureHighlighting($ref),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -474,6 +486,18 @@ final class PhabricatorFileViewController extends PhabricatorFileController {
|
|||
'viewKey' => $engine->getDocumentEngineKey(),
|
||||
'views' => $views,
|
||||
'standaloneURI' => $engine->getRenderURI($ref),
|
||||
'encode' => array(
|
||||
'icon' => 'fa-font',
|
||||
'name' => pht('Change Text Encoding...'),
|
||||
'uri' => '/services/encoding/',
|
||||
'value' => $encode_setting,
|
||||
),
|
||||
'highlight' => array(
|
||||
'icon' => 'fa-lightbulb-o',
|
||||
'name' => pht('Highlight As...'),
|
||||
'uri' => '/services/highlight/',
|
||||
'value' => $highlight_setting,
|
||||
),
|
||||
);
|
||||
|
||||
$view_button = id(new PHUIButtonView())
|
||||
|
|
|
@ -5,6 +5,8 @@ abstract class PhabricatorDocumentEngine
|
|||
|
||||
private $viewer;
|
||||
private $highlightedLines = array();
|
||||
private $encodingConfiguration;
|
||||
private $highlightingConfiguration;
|
||||
|
||||
final public function setViewer(PhabricatorUser $viewer) {
|
||||
$this->viewer = $viewer;
|
||||
|
@ -28,6 +30,32 @@ abstract class PhabricatorDocumentEngine
|
|||
return $this->canRenderDocumentType($ref);
|
||||
}
|
||||
|
||||
public function canConfigureEncoding(PhabricatorDocumentRef $ref) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canConfigureHighlighting(PhabricatorDocumentRef $ref) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final public function setEncodingConfiguration($config) {
|
||||
$this->encodingConfiguration = $config;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getEncodingConfiguration() {
|
||||
return $this->encodingConfiguration;
|
||||
}
|
||||
|
||||
final public function setHighlightingConfiguration($config) {
|
||||
$this->highlightingConfiguration = $config;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getHighlightingConfiguration() {
|
||||
return $this->highlightingConfiguration;
|
||||
}
|
||||
|
||||
public function shouldRenderAsync(PhabricatorDocumentRef $ref) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ final class PhabricatorJupyterDocumentEngine
|
|||
$content = implode('', $content);
|
||||
|
||||
$content = PhabricatorSyntaxHighlighter::highlightWithLanguage(
|
||||
'python',
|
||||
'py',
|
||||
$content);
|
||||
|
||||
$outputs = array();
|
||||
|
@ -260,9 +260,8 @@ final class PhabricatorJupyterDocumentEngine
|
|||
|
||||
$raw_data = $data[$image_format];
|
||||
if (!is_array($raw_data)) {
|
||||
continue;
|
||||
$raw_data = array($raw_data);
|
||||
}
|
||||
|
||||
$raw_data = implode('', $raw_data);
|
||||
|
||||
$content = phutil_tag(
|
||||
|
|
|
@ -9,6 +9,10 @@ final class PhabricatorSourceDocumentEngine
|
|||
return pht('View as Source');
|
||||
}
|
||||
|
||||
public function canConfigureHighlighting(PhabricatorDocumentRef $ref) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getDocumentIconIcon(PhabricatorDocumentRef $ref) {
|
||||
return 'fa-code';
|
||||
}
|
||||
|
@ -20,9 +24,16 @@ final class PhabricatorSourceDocumentEngine
|
|||
protected function newDocumentContent(PhabricatorDocumentRef $ref) {
|
||||
$content = $this->loadTextData($ref);
|
||||
|
||||
$content = PhabricatorSyntaxHighlighter::highlightWithFilename(
|
||||
$ref->getName(),
|
||||
$content);
|
||||
$highlighting = $this->getHighlightingConfiguration();
|
||||
if ($highlighting !== null) {
|
||||
$content = PhabricatorSyntaxHighlighter::highlightWithLanguage(
|
||||
$highlighting,
|
||||
$content);
|
||||
} else {
|
||||
$content = PhabricatorSyntaxHighlighter::highlightWithFilename(
|
||||
$ref->getName(),
|
||||
$content);
|
||||
}
|
||||
|
||||
return $this->newTextDocumentContent($content);
|
||||
}
|
||||
|
|
|
@ -3,10 +3,16 @@
|
|||
abstract class PhabricatorTextDocumentEngine
|
||||
extends PhabricatorDocumentEngine {
|
||||
|
||||
private $encodingMessage = null;
|
||||
|
||||
protected function canRenderDocumentType(PhabricatorDocumentRef $ref) {
|
||||
return $ref->isProbablyText();
|
||||
}
|
||||
|
||||
public function canConfigureEncoding(PhabricatorDocumentRef $ref) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function newTextDocumentContent($content) {
|
||||
$lines = phutil_split_lines($content);
|
||||
|
||||
|
@ -14,19 +20,69 @@ abstract class PhabricatorTextDocumentEngine
|
|||
->setHighlights($this->getHighlightedLines())
|
||||
->setLines($lines);
|
||||
|
||||
$message = null;
|
||||
if ($this->encodingMessage !== null) {
|
||||
$message = $this->newMessage($this->encodingMessage);
|
||||
}
|
||||
|
||||
$container = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'document-engine-text',
|
||||
),
|
||||
$view);
|
||||
array(
|
||||
$message,
|
||||
$view,
|
||||
));
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
protected function loadTextData(PhabricatorDocumentRef $ref) {
|
||||
$content = $ref->loadData();
|
||||
$content = phutil_utf8ize($content);
|
||||
|
||||
$encoding = $this->getEncodingConfiguration();
|
||||
if ($encoding !== null) {
|
||||
if (function_exists('mb_convert_encoding')) {
|
||||
$content = mb_convert_encoding($content, 'UTF-8', $encoding);
|
||||
$this->encodingMessage = pht(
|
||||
'This document was converted from %s to UTF8 for display.',
|
||||
$encoding);
|
||||
} else {
|
||||
$this->encodingMessage = pht(
|
||||
'Unable to perform text encoding conversion: mbstring extension '.
|
||||
'is not available.');
|
||||
}
|
||||
} else {
|
||||
if (!phutil_is_utf8($content)) {
|
||||
if (function_exists('mb_detect_encoding')) {
|
||||
$try_encodings = array(
|
||||
'JIS' => pht('JIS'),
|
||||
'EUC-JP' => pht('EUC-JP'),
|
||||
'SJIS' => pht('Shift JIS'),
|
||||
'ISO-8859-1' => pht('ISO-8859-1 (Latin 1)'),
|
||||
);
|
||||
|
||||
$guess = mb_detect_encoding($content, array_keys($try_encodings));
|
||||
if ($guess) {
|
||||
$content = mb_convert_encoding($content, 'UTF-8', $guess);
|
||||
$this->encodingMessage = pht(
|
||||
'This document is not UTF8. It was detected as %s and '.
|
||||
'converted to UTF8 for display.',
|
||||
idx($try_encodings, $guess, $guess));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!phutil_is_utf8($content)) {
|
||||
$content = phutil_utf8ize($content);
|
||||
$this->encodingMessage = pht(
|
||||
'This document is not UTF8 and its text encoding could not be '.
|
||||
'detected automatically. Use "Change Text Encoding..." to choose '.
|
||||
'an encoding.');
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
* conditions where we receive a message before a build plan is ready to
|
||||
* accept it.
|
||||
*/
|
||||
final class HarbormasterBuildMessage extends HarbormasterDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
final class HarbormasterBuildMessage
|
||||
extends HarbormasterDAO
|
||||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorDestructibleInterface {
|
||||
|
||||
protected $authorPHID;
|
||||
protected $receiverPHID;
|
||||
|
@ -74,4 +77,13 @@ final class HarbormasterBuildMessage extends HarbormasterDAO
|
|||
return pht('Build messages have the same policies as their receivers.');
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
||||
public function destroyObjectPermanently(
|
||||
PhabricatorDestructionEngine $engine) {
|
||||
$this->delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<?php
|
||||
|
||||
final class HarbormasterBuildable extends HarbormasterDAO
|
||||
final class HarbormasterBuildable
|
||||
extends HarbormasterDAO
|
||||
implements
|
||||
PhabricatorApplicationTransactionInterface,
|
||||
PhabricatorPolicyInterface,
|
||||
HarbormasterBuildableInterface {
|
||||
HarbormasterBuildableInterface,
|
||||
PhabricatorDestructibleInterface {
|
||||
|
||||
protected $buildablePHID;
|
||||
protected $containerPHID;
|
||||
|
@ -340,4 +342,32 @@ final class HarbormasterBuildable extends HarbormasterDAO
|
|||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
||||
public function destroyObjectPermanently(
|
||||
PhabricatorDestructionEngine $engine) {
|
||||
$viewer = $engine->getViewer();
|
||||
|
||||
$this->openTransaction();
|
||||
$builds = id(new HarbormasterBuildQuery())
|
||||
->setViewer($viewer)
|
||||
->withBuildablePHIDs(array($this->getPHID()))
|
||||
->execute();
|
||||
foreach ($builds as $build) {
|
||||
$engine->destroyObject($build);
|
||||
}
|
||||
|
||||
$messages = id(new HarbormasterBuildMessageQuery())
|
||||
->setViewer($viewer)
|
||||
->withReceiverPHIDs(array($this->getPHID()))
|
||||
->execute();
|
||||
foreach ($messages as $message) {
|
||||
$engine->destroyObject($message);
|
||||
}
|
||||
|
||||
$this->delete();
|
||||
$this->saveTransaction();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@ final class HarbormasterBuild extends HarbormasterDAO
|
|||
implements
|
||||
PhabricatorApplicationTransactionInterface,
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorConduitResultInterface {
|
||||
PhabricatorConduitResultInterface,
|
||||
PhabricatorDestructibleInterface {
|
||||
|
||||
protected $buildablePHID;
|
||||
protected $buildPlanPHID;
|
||||
|
@ -455,4 +456,33 @@ final class HarbormasterBuild extends HarbormasterDAO
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
public function destroyObjectPermanently(
|
||||
PhabricatorDestructionEngine $engine) {
|
||||
$viewer = $engine->getViewer();
|
||||
|
||||
$this->openTransaction();
|
||||
$targets = id(new HarbormasterBuildTargetQuery())
|
||||
->setViewer($viewer)
|
||||
->withBuildPHIDs(array($this->getPHID()))
|
||||
->execute();
|
||||
foreach ($targets as $target) {
|
||||
$engine->destroyObject($target);
|
||||
}
|
||||
|
||||
$messages = id(new HarbormasterBuildMessageQuery())
|
||||
->setViewer($viewer)
|
||||
->withReceiverPHIDs(array($this->getPHID()))
|
||||
->execute();
|
||||
foreach ($messages as $message) {
|
||||
$engine->destroyObject($message);
|
||||
}
|
||||
|
||||
$this->delete();
|
||||
$this->saveTransaction();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
|
||||
final class HarbormasterBuildArtifact extends HarbormasterDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
final class HarbormasterBuildArtifact
|
||||
extends HarbormasterDAO
|
||||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorDestructibleInterface {
|
||||
|
||||
protected $buildTargetPHID;
|
||||
protected $artifactType;
|
||||
|
@ -147,4 +150,19 @@ final class HarbormasterBuildArtifact extends HarbormasterDAO
|
|||
return pht('Users must be able to see a buildable to see its artifacts.');
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
||||
public function destroyObjectPermanently(
|
||||
PhabricatorDestructionEngine $engine) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$this->openTransaction();
|
||||
$this->releaseArtifact($viewer);
|
||||
$this->delete();
|
||||
$this->saveTransaction();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
|
||||
final class HarbormasterBuildTarget extends HarbormasterDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
final class HarbormasterBuildTarget
|
||||
extends HarbormasterDAO
|
||||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorDestructibleInterface {
|
||||
|
||||
protected $name;
|
||||
protected $buildPHID;
|
||||
|
@ -354,4 +357,59 @@ final class HarbormasterBuildTarget extends HarbormasterDAO
|
|||
return pht('Users must be able to see a build to view its build targets.');
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
||||
public function destroyObjectPermanently(
|
||||
PhabricatorDestructionEngine $engine) {
|
||||
$viewer = $engine->getViewer();
|
||||
|
||||
$this->openTransaction();
|
||||
|
||||
$lint_message = new HarbormasterBuildLintMessage();
|
||||
$conn = $lint_message->establishConnection('w');
|
||||
queryfx(
|
||||
$conn,
|
||||
'DELETE FROM %T WHERE buildTargetPHID = %s',
|
||||
$lint_message->getTableName(),
|
||||
$this->getPHID());
|
||||
|
||||
$unit_message = new HarbormasterBuildUnitMessage();
|
||||
$conn = $unit_message->establishConnection('w');
|
||||
queryfx(
|
||||
$conn,
|
||||
'DELETE FROM %T WHERE buildTargetPHID = %s',
|
||||
$unit_message->getTableName(),
|
||||
$this->getPHID());
|
||||
|
||||
$logs = id(new HarbormasterBuildLogQuery())
|
||||
->setViewer($viewer)
|
||||
->withBuildTargetPHIDs(array($this->getPHID()))
|
||||
->execute();
|
||||
foreach ($logs as $log) {
|
||||
$engine->destroyObject($log);
|
||||
}
|
||||
|
||||
$artifacts = id(new HarbormasterBuildArtifactQuery())
|
||||
->setViewer($viewer)
|
||||
->withBuildTargetPHIDs(array($this->getPHID()))
|
||||
->execute();
|
||||
foreach ($artifacts as $artifact) {
|
||||
$engine->destroyObject($artifact);
|
||||
}
|
||||
|
||||
$messages = id(new HarbormasterBuildMessageQuery())
|
||||
->setViewer($viewer)
|
||||
->withReceiverPHIDs(array($this->getPHID()))
|
||||
->execute();
|
||||
foreach ($messages as $message) {
|
||||
$engine->destroyObject($message);
|
||||
}
|
||||
|
||||
$this->delete();
|
||||
$this->saveTransaction();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -393,19 +393,22 @@ final class PhabricatorOwnersPackage
|
|||
}
|
||||
|
||||
public static function splitPath($path) {
|
||||
$trailing_slash = preg_match('@/$@', $path) ? '/' : '';
|
||||
$path = trim($path, '/');
|
||||
$result = array(
|
||||
'/',
|
||||
);
|
||||
|
||||
$parts = explode('/', $path);
|
||||
$buffer = '/';
|
||||
foreach ($parts as $part) {
|
||||
if (!strlen($part)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
while (count($parts)) {
|
||||
$result[] = '/'.implode('/', $parts).$trailing_slash;
|
||||
$trailing_slash = '/';
|
||||
array_pop($parts);
|
||||
$buffer = $buffer.$part.'/';
|
||||
$result[] = $buffer;
|
||||
}
|
||||
$result[] = '/';
|
||||
|
||||
return array_reverse($result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function attachPaths(array $paths) {
|
||||
|
|
|
@ -0,0 +1,273 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRepositoryManagementUnpublishWorkflow
|
||||
extends PhabricatorRepositoryManagementWorkflow {
|
||||
|
||||
protected function didConstruct() {
|
||||
$this
|
||||
->setName('unpublish')
|
||||
->setExamples(
|
||||
'**unpublish** [__options__] __repository__')
|
||||
->setSynopsis(
|
||||
pht(
|
||||
'Unpublish all feed stories and notifications that a repository '.
|
||||
'has generated. Keep expectations low; can not rewind time.'))
|
||||
->setArguments(
|
||||
array(
|
||||
array(
|
||||
'name' => 'force',
|
||||
'help' => pht('Do not prompt for confirmation.'),
|
||||
),
|
||||
array(
|
||||
'name' => 'dry-run',
|
||||
'help' => pht('Do not perform any writes.'),
|
||||
),
|
||||
array(
|
||||
'name' => 'repositories',
|
||||
'wildcard' => true,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
$viewer = $this->getViewer();
|
||||
$is_force = $args->getArg('force');
|
||||
$is_dry_run = $args->getArg('dry-run');
|
||||
|
||||
$repositories = $this->loadLocalRepositories($args, 'repositories');
|
||||
if (count($repositories) !== 1) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht('Specify exactly one repository to unpublish.'));
|
||||
}
|
||||
$repository = head($repositories);
|
||||
|
||||
if (!$is_force) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'This script will unpublish all feed stories and notifications '.
|
||||
'which a repository generated during import. This action can not '.
|
||||
'be undone.'));
|
||||
|
||||
$prompt = pht(
|
||||
'Permanently unpublish "%s"?',
|
||||
$repository->getDisplayName());
|
||||
if (!phutil_console_confirm($prompt)) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht('User aborted workflow.'));
|
||||
}
|
||||
}
|
||||
|
||||
$commits = id(new DiffusionCommitQuery())
|
||||
->setViewer($viewer)
|
||||
->withRepositoryPHIDs(array($repository->getPHID()))
|
||||
->execute();
|
||||
|
||||
echo pht("Will unpublish %s commits.\n", count($commits));
|
||||
|
||||
foreach ($commits as $commit) {
|
||||
$this->unpublishCommit($commit, $is_dry_run);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function unpublishCommit(
|
||||
PhabricatorRepositoryCommit $commit,
|
||||
$is_dry_run) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Unpublishing commit "%s".',
|
||||
$commit->getMonogram()));
|
||||
|
||||
$stories = id(new PhabricatorFeedQuery())
|
||||
->setViewer($viewer)
|
||||
->withFilterPHIDs(array($commit->getPHID()))
|
||||
->execute();
|
||||
|
||||
if ($stories) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Found %s feed storie(s).',
|
||||
count($stories)));
|
||||
|
||||
if (!$is_dry_run) {
|
||||
$engine = new PhabricatorDestructionEngine();
|
||||
foreach ($stories as $story) {
|
||||
$story_data = $story->getStoryData();
|
||||
$engine->destroyObject($story_data);
|
||||
}
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Destroyed %s feed storie(s).',
|
||||
count($stories)));
|
||||
}
|
||||
}
|
||||
|
||||
$edge_types = array(
|
||||
PhabricatorObjectMentionsObjectEdgeType::EDGECONST => true,
|
||||
DiffusionCommitHasTaskEdgeType::EDGECONST => true,
|
||||
DiffusionCommitHasRevisionEdgeType::EDGECONST => true,
|
||||
DiffusionCommitRevertsCommitEdgeType::EDGECONST => true,
|
||||
);
|
||||
|
||||
$query = id(new PhabricatorEdgeQuery())
|
||||
->withSourcePHIDs(array($commit->getPHID()))
|
||||
->withEdgeTypes(array_keys($edge_types));
|
||||
$edges = $query->execute();
|
||||
|
||||
foreach ($edges[$commit->getPHID()] as $type => $edge_list) {
|
||||
foreach ($edge_list as $edge) {
|
||||
$dst = $edge['dst'];
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Commit "%s" has edge of type "%s" to object "%s".',
|
||||
$commit->getMonogram(),
|
||||
$type,
|
||||
$dst));
|
||||
|
||||
$object = id(new PhabricatorObjectQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($dst))
|
||||
->executeOne();
|
||||
if ($object) {
|
||||
if ($object instanceof PhabricatorApplicationTransactionInterface) {
|
||||
$this->unpublishEdgeTransaction(
|
||||
$commit,
|
||||
$type,
|
||||
$object,
|
||||
$is_dry_run);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function unpublishEdgeTransaction(
|
||||
$src,
|
||||
$type,
|
||||
PhabricatorApplicationTransactionInterface $dst,
|
||||
$is_dry_run) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$query = PhabricatorApplicationTransactionQuery::newQueryForObject($dst)
|
||||
->setViewer($viewer)
|
||||
->withObjectPHIDs(array($dst->getPHID()));
|
||||
|
||||
$xactions = id(clone $query)
|
||||
->withTransactionTypes(
|
||||
array(
|
||||
PhabricatorTransactions::TYPE_EDGE,
|
||||
))
|
||||
->execute();
|
||||
|
||||
$type_obj = PhabricatorEdgeType::getByConstant($type);
|
||||
$inverse_type = $type_obj->getInverseEdgeConstant();
|
||||
|
||||
$engine = new PhabricatorDestructionEngine();
|
||||
foreach ($xactions as $xaction) {
|
||||
$edge_type = $xaction->getMetadataValue('edge:type');
|
||||
if ($edge_type != $inverse_type) {
|
||||
// Some other type of edge was edited.
|
||||
continue;
|
||||
}
|
||||
|
||||
$record = PhabricatorEdgeChangeRecord::newFromTransaction($xaction);
|
||||
$changed = $record->getChangedPHIDs();
|
||||
if ($changed !== array($src->getPHID())) {
|
||||
// Affected objects were not just the object we're unpublishing.
|
||||
continue;
|
||||
}
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Found edge transaction "%s" on object "%s" for type "%s".',
|
||||
$xaction->getPHID(),
|
||||
$dst->getPHID(),
|
||||
$type));
|
||||
|
||||
if (!$is_dry_run) {
|
||||
$engine->destroyObject($xaction);
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Destroyed transaction "%s" on object "%s".',
|
||||
$xaction->getPHID(),
|
||||
$dst->getPHID()));
|
||||
}
|
||||
}
|
||||
|
||||
if ($type === DiffusionCommitHasTaskEdgeType::EDGECONST) {
|
||||
$xactions = id(clone $query)
|
||||
->withTransactionTypes(
|
||||
array(
|
||||
ManiphestTaskStatusTransaction::TRANSACTIONTYPE,
|
||||
))
|
||||
->execute();
|
||||
|
||||
if ($xactions) {
|
||||
foreach ($xactions as $xaction) {
|
||||
$metadata = $xaction->getMetadata();
|
||||
if (idx($metadata, 'commitPHID') === $src->getPHID()) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'MANUAL Task "%s" was likely closed improperly by "%s".',
|
||||
$dst->getMonogram(),
|
||||
$src->getMonogram()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($type === DiffusionCommitHasRevisionEdgeType::EDGECONST) {
|
||||
$xactions = id(clone $query)
|
||||
->withTransactionTypes(
|
||||
array(
|
||||
DifferentialRevisionCloseTransaction::TRANSACTIONTYPE,
|
||||
))
|
||||
->execute();
|
||||
|
||||
if ($xactions) {
|
||||
foreach ($xactions as $xaction) {
|
||||
$metadata = $xaction->getMetadata();
|
||||
if (idx($metadata, 'isCommitClose')) {
|
||||
if (idx($metadata, 'commitPHID') === $src->getPHID()) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'MANUAL Revision "%s" was likely closed improperly by "%s".',
|
||||
$dst->getMonogram(),
|
||||
$src->getMonogram()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$is_dry_run) {
|
||||
id(new PhabricatorEdgeEditor())
|
||||
->removeEdge($src->getPHID(), $type, $dst->getPHID())
|
||||
->save();
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Destroyed edge of type "%s" between "%s" and "%s".',
|
||||
$type,
|
||||
$src->getPHID(),
|
||||
$dst->getPHID()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1120,6 +1120,11 @@ abstract class PhabricatorApplicationTransactionEditor
|
|||
// We are the Herald editor, so stop work here and return the updated
|
||||
// transactions.
|
||||
return $xactions;
|
||||
} else if ($this->getIsInverseEdgeEditor()) {
|
||||
// Do not run Herald if we're just recording that this object was
|
||||
// mentioned elsewhere. This tends to create Herald side effects which
|
||||
// feel arbitrary, and can really slow down edits which mention a large
|
||||
// number of other objects. See T13114.
|
||||
} else if ($this->shouldApplyHeraldRules($object, $xactions)) {
|
||||
// We are not the Herald editor, so try to apply Herald rules.
|
||||
$herald_xactions = $this->applyHeraldRules($object, $xactions);
|
||||
|
|
|
@ -7,6 +7,7 @@ final class PhabricatorCustomFieldEditField
|
|||
private $httpParameterType;
|
||||
private $conduitParameterType;
|
||||
private $bulkParameterType;
|
||||
private $commentAction;
|
||||
|
||||
public function setCustomField(PhabricatorCustomField $custom_field) {
|
||||
$this->customField = $custom_field;
|
||||
|
@ -47,6 +48,16 @@ final class PhabricatorCustomFieldEditField
|
|||
return $this->bulkParameterType;
|
||||
}
|
||||
|
||||
public function setCustomFieldCommentAction(
|
||||
PhabricatorEditEngineCommentAction $comment_action) {
|
||||
$this->commentAction = $comment_action;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCustomFieldCommentAction() {
|
||||
return $this->commentAction;
|
||||
}
|
||||
|
||||
protected function buildControl() {
|
||||
if ($this->getIsConduitOnly()) {
|
||||
return null;
|
||||
|
@ -77,6 +88,19 @@ final class PhabricatorCustomFieldEditField
|
|||
return $clone->getNewValueForApplicationTransactions();
|
||||
}
|
||||
|
||||
protected function getValueForCommentAction($value) {
|
||||
$field = $this->getCustomField();
|
||||
$clone = clone $field;
|
||||
$clone->setValueFromApplicationTransactions($value);
|
||||
|
||||
// TODO: This is somewhat bogus because only StandardCustomFields
|
||||
// implement a getFieldValue() method -- not all CustomFields. Today,
|
||||
// only StandardCustomFields can ever actually generate a comment action
|
||||
// so we never reach this method with other field types.
|
||||
|
||||
return $clone->getFieldValue();
|
||||
}
|
||||
|
||||
protected function getValueExistsInSubmit(AphrontRequest $request, $key) {
|
||||
return true;
|
||||
}
|
||||
|
@ -110,6 +134,16 @@ final class PhabricatorCustomFieldEditField
|
|||
return null;
|
||||
}
|
||||
|
||||
protected function newCommentAction() {
|
||||
$action = $this->getCustomFieldCommentAction();
|
||||
|
||||
if ($action) {
|
||||
return clone $action;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function newConduitParameterType() {
|
||||
$type = $this->getCustomFieldConduitParameterType();
|
||||
|
||||
|
|
|
@ -1127,6 +1127,16 @@ abstract class PhabricatorCustomField extends Phobject {
|
|||
$field->setCustomFieldBulkParameterType($bulk_type);
|
||||
}
|
||||
|
||||
$comment_action = $this->getCommentAction();
|
||||
if ($comment_action) {
|
||||
$field
|
||||
->setCustomFieldCommentAction($comment_action)
|
||||
->setCommentActionLabel(
|
||||
pht(
|
||||
'Change %s',
|
||||
$this->getFieldName()));
|
||||
}
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
|
@ -1459,6 +1469,17 @@ abstract class PhabricatorCustomField extends Phobject {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function getCommentAction() {
|
||||
return $this->newCommentAction();
|
||||
}
|
||||
|
||||
protected function newCommentAction() {
|
||||
if ($this->proxy) {
|
||||
return $this->proxy->newCommentAction();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( Herald )------------------------------------------------------------- */
|
||||
|
||||
|
|
|
@ -143,4 +143,26 @@ abstract class PhabricatorStandardCustomFieldTokenizer
|
|||
->setDatasource($datasource);
|
||||
}
|
||||
|
||||
protected function newCommentAction() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$datasource = $this->getDatasource()
|
||||
->setViewer($viewer);
|
||||
|
||||
$action = id(new PhabricatorEditEngineTokenizerCommentAction())
|
||||
->setDatasource($datasource);
|
||||
|
||||
$limit = $this->getFieldConfigValue('limit');
|
||||
if ($limit) {
|
||||
$action->setLimit($limit);
|
||||
}
|
||||
|
||||
$value = $this->getFieldValue();
|
||||
if ($value !== null) {
|
||||
$action->setInitialValue($value);
|
||||
}
|
||||
|
||||
return $action;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -724,6 +724,11 @@ var.remarkup-assist-textarea {
|
|||
color: {$darkgreytext};
|
||||
}
|
||||
|
||||
.phuix-autocomplete-list a.jx-result .tokenizer-result-closed {
|
||||
color: {$lightgreytext};
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.phuix-autocomplete-list a.jx-result .phui-icon-view {
|
||||
margin-right: 4px;
|
||||
color: {$lightbluetext};
|
||||
|
|
|
@ -52,6 +52,61 @@ JX.behavior('document-engine', function(config, statics) {
|
|||
});
|
||||
}
|
||||
|
||||
list.addItem(
|
||||
new JX.PHUIXActionView()
|
||||
.setDivider(true));
|
||||
|
||||
var encode_item = new JX.PHUIXActionView()
|
||||
.setName(data.encode.name)
|
||||
.setIcon(data.encode.icon);
|
||||
|
||||
var onencode = JX.bind(null, function(data, e) {
|
||||
e.prevent();
|
||||
|
||||
if (encode_item.getDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
new JX.Workflow(data.encode.uri, {encoding: data.encode.value})
|
||||
.setHandler(function(r) {
|
||||
data.encode.value = r.encoding;
|
||||
onview(data);
|
||||
})
|
||||
.start();
|
||||
|
||||
menu.close();
|
||||
|
||||
}, data);
|
||||
|
||||
encode_item.setHandler(onencode);
|
||||
|
||||
list.addItem(encode_item);
|
||||
|
||||
var highlight_item = new JX.PHUIXActionView()
|
||||
.setName(data.highlight.name)
|
||||
.setIcon(data.highlight.icon);
|
||||
|
||||
var onhighlight = JX.bind(null, function(data, e) {
|
||||
e.prevent();
|
||||
|
||||
if (highlight_item.getDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
new JX.Workflow(data.highlight.uri, {highlight: data.highlight.value})
|
||||
.setHandler(function(r) {
|
||||
data.highlight.value = r.highlight;
|
||||
onview(data);
|
||||
})
|
||||
.start();
|
||||
|
||||
menu.close();
|
||||
}, data);
|
||||
|
||||
highlight_item.setHandler(onhighlight);
|
||||
|
||||
list.addItem(highlight_item);
|
||||
|
||||
menu.setContent(list.getNode());
|
||||
|
||||
menu.listen('open', function() {
|
||||
|
@ -61,6 +116,11 @@ JX.behavior('document-engine', function(config, statics) {
|
|||
// Highlight the current rendering engine.
|
||||
var is_selected = (engine.spec.viewKey == data.viewKey);
|
||||
engine.view.setSelected(is_selected);
|
||||
|
||||
if (is_selected) {
|
||||
encode_item.setDisabled(!engine.spec.canEncode);
|
||||
highlight_item.setDisabled(!engine.spec.canHighlight);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -68,14 +128,38 @@ JX.behavior('document-engine', function(config, statics) {
|
|||
menu.open();
|
||||
}
|
||||
|
||||
function add_params(uri, data) {
|
||||
uri = JX.$U(uri);
|
||||
|
||||
if (data.highlight.value) {
|
||||
uri.setQueryParam('highlight', data.highlight.value);
|
||||
}
|
||||
|
||||
if (data.encode.value) {
|
||||
uri.setQueryParam('encode', data.encode.value);
|
||||
}
|
||||
|
||||
return uri.toString();
|
||||
}
|
||||
|
||||
function onview(data, spec, immediate) {
|
||||
if (!spec) {
|
||||
for (var ii = 0; ii < data.views.length; ii++) {
|
||||
if (data.views[ii].viewKey == data.viewKey) {
|
||||
spec = data.views[ii];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.sequence = (data.sequence || 0) + 1;
|
||||
var handler = JX.bind(null, onrender, data, data.sequence);
|
||||
|
||||
data.viewKey = spec.viewKey;
|
||||
JX.History.replace(spec.viewURI);
|
||||
|
||||
new JX.Request(spec.engineURI, handler)
|
||||
var uri = add_params(spec.engineURI, data);
|
||||
|
||||
new JX.Request(uri, handler)
|
||||
.send();
|
||||
|
||||
if (data.loadingView) {
|
||||
|
@ -91,6 +175,12 @@ JX.behavior('document-engine', function(config, statics) {
|
|||
|
||||
var load = JX.bind(null, onloading, data, spec);
|
||||
data.loadTimer = setTimeout(load, 333);
|
||||
|
||||
// Replace the URI with the URI for the specific rendering the user
|
||||
// has selected.
|
||||
|
||||
var view_uri = add_params(spec.viewURI, data);
|
||||
JX.History.replace(view_uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,16 +218,10 @@ JX.behavior('document-engine', function(config, statics) {
|
|||
statics.initialized = true;
|
||||
}
|
||||
|
||||
if (config.renderControlID) {
|
||||
if (config && config.renderControlID) {
|
||||
var control = JX.$(config.renderControlID);
|
||||
var data = JX.Stratcom.getData(control);
|
||||
|
||||
for (var ii = 0; ii < data.views.length; ii++) {
|
||||
if (data.views[ii].viewKey == data.viewKey) {
|
||||
onview(data, data.views[ii], true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
onview(data, null, true);
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -34,6 +34,10 @@ JX.install('PHUIXActionView', {
|
|||
return this;
|
||||
},
|
||||
|
||||
getDisabled: function() {
|
||||
return this._disabled;
|
||||
},
|
||||
|
||||
setLabel: function(label) {
|
||||
this._label = label;
|
||||
JX.DOM.alterClass(
|
||||
|
|
|
@ -185,7 +185,10 @@ JX.install('PHUIXAutocomplete', {
|
|||
.getNode();
|
||||
}
|
||||
|
||||
map.display = [icon, map.displayName];
|
||||
var display = JX.$N('span', {}, [icon, map.displayName]);
|
||||
JX.DOM.alterClass(display, 'tokenizer-result-closed', !!map.closed);
|
||||
|
||||
map.display = display;
|
||||
|
||||
return map;
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue