mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-14 09:36:14 +01:00
(stable) Promote 2018 Week 7
This commit is contained in:
commit
a6100a4ce7
149 changed files with 3494 additions and 1459 deletions
|
@ -10,10 +10,10 @@ return array(
|
|||
'conpherence.pkg.css' => 'e68cf1fa',
|
||||
'conpherence.pkg.js' => '15191c65',
|
||||
'core.pkg.css' => 'e4f098a5',
|
||||
'core.pkg.js' => '3ac6e174',
|
||||
'core.pkg.js' => 'bd19de1c',
|
||||
'darkconsole.pkg.js' => '1f9a31bc',
|
||||
'differential.pkg.css' => '113e692c',
|
||||
'differential.pkg.js' => '5d53d5ce',
|
||||
'differential.pkg.js' => 'f6d809c0',
|
||||
'diffusion.pkg.css' => 'a2d17c7d',
|
||||
'diffusion.pkg.js' => '6134c5a1',
|
||||
'favicon.ico' => '30672e08',
|
||||
|
@ -396,7 +396,7 @@ return array(
|
|||
'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375',
|
||||
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63',
|
||||
'rsrc/js/application/diff/DiffChangeset.js' => 'b49b59d6',
|
||||
'rsrc/js/application/diff/DiffChangesetList.js' => '1f2e5265',
|
||||
'rsrc/js/application/diff/DiffChangesetList.js' => 'e74b7517',
|
||||
'rsrc/js/application/diff/DiffInline.js' => 'e83d28f3',
|
||||
'rsrc/js/application/diff/behavior-preview-link.js' => '051c7832',
|
||||
'rsrc/js/application/differential/behavior-comment-preview.js' => '51c5ad07',
|
||||
|
@ -506,7 +506,7 @@ return array(
|
|||
'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e',
|
||||
'rsrc/js/core/behavior-reveal-content.js' => '60821bc7',
|
||||
'rsrc/js/core/behavior-scrollbar.js' => '834a1173',
|
||||
'rsrc/js/core/behavior-search-typeahead.js' => 'd0a99ab4',
|
||||
'rsrc/js/core/behavior-search-typeahead.js' => 'c3e917d9',
|
||||
'rsrc/js/core/behavior-select-content.js' => 'bf5374ef',
|
||||
'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6',
|
||||
'rsrc/js/core/behavior-setup-check-https.js' => '491416b3',
|
||||
|
@ -528,7 +528,7 @@ return array(
|
|||
'rsrc/js/phui/behavior-phui-tab-group.js' => '0a0b10e9',
|
||||
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
|
||||
'rsrc/js/phuix/PHUIXActionView.js' => '442efd08',
|
||||
'rsrc/js/phuix/PHUIXAutocomplete.js' => 'e0731603',
|
||||
'rsrc/js/phuix/PHUIXAutocomplete.js' => '7fa5c915',
|
||||
'rsrc/js/phuix/PHUIXButtonView.js' => '8a91e1ac',
|
||||
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '04b2ae03',
|
||||
'rsrc/js/phuix/PHUIXExample.js' => '68af71ca',
|
||||
|
@ -663,7 +663,7 @@ return array(
|
|||
'javelin-behavior-phabricator-oncopy' => '2926fff2',
|
||||
'javelin-behavior-phabricator-remarkup-assist' => 'acd29eee',
|
||||
'javelin-behavior-phabricator-reveal-content' => '60821bc7',
|
||||
'javelin-behavior-phabricator-search-typeahead' => 'd0a99ab4',
|
||||
'javelin-behavior-phabricator-search-typeahead' => 'c3e917d9',
|
||||
'javelin-behavior-phabricator-show-older-transactions' => '8f29b364',
|
||||
'javelin-behavior-phabricator-tooltips' => 'c420b0b9',
|
||||
'javelin-behavior-phabricator-transaction-comment-form' => 'b23b49e6',
|
||||
|
@ -776,7 +776,7 @@ return array(
|
|||
'phabricator-darkmessage' => 'c48cccdd',
|
||||
'phabricator-dashboard-css' => 'fe5b1869',
|
||||
'phabricator-diff-changeset' => 'b49b59d6',
|
||||
'phabricator-diff-changeset-list' => '1f2e5265',
|
||||
'phabricator-diff-changeset-list' => 'e74b7517',
|
||||
'phabricator-diff-inline' => 'e83d28f3',
|
||||
'phabricator-drag-and-drop-file-upload' => '58dea2fa',
|
||||
'phabricator-draggable-list' => 'bea6e7f4',
|
||||
|
@ -881,7 +881,7 @@ return array(
|
|||
'phui-workpanel-view-css' => 'a3a63478',
|
||||
'phuix-action-list-view' => 'b5c256b8',
|
||||
'phuix-action-view' => '442efd08',
|
||||
'phuix-autocomplete' => 'e0731603',
|
||||
'phuix-autocomplete' => '7fa5c915',
|
||||
'phuix-button-view' => '8a91e1ac',
|
||||
'phuix-dropdown-menu' => '04b2ae03',
|
||||
'phuix-form-control-view' => '16ad6224',
|
||||
|
@ -1044,10 +1044,6 @@ return array(
|
|||
'javelin-uri',
|
||||
'javelin-routable',
|
||||
),
|
||||
'1f2e5265' => array(
|
||||
'javelin-install',
|
||||
'phuix-button-view',
|
||||
),
|
||||
'1f6794f6' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -1561,6 +1557,12 @@ return array(
|
|||
'7f243deb' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
'7fa5c915' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'phuix-icon-view',
|
||||
'phabricator-prefab',
|
||||
),
|
||||
'81144dfa' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-behavior-device',
|
||||
|
@ -1922,6 +1924,17 @@ return array(
|
|||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
),
|
||||
'c3e917d9' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-typeahead-ondemand-source',
|
||||
'javelin-typeahead',
|
||||
'javelin-dom',
|
||||
'javelin-uri',
|
||||
'javelin-util',
|
||||
'javelin-stratcom',
|
||||
'phabricator-prefab',
|
||||
'phuix-icon-view',
|
||||
),
|
||||
'c420b0b9' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-behavior-device',
|
||||
|
@ -1973,17 +1986,6 @@ return array(
|
|||
'phabricator-notification',
|
||||
'conpherence-thread-manager',
|
||||
),
|
||||
'd0a99ab4' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-typeahead-ondemand-source',
|
||||
'javelin-typeahead',
|
||||
'javelin-dom',
|
||||
'javelin-uri',
|
||||
'javelin-util',
|
||||
'javelin-stratcom',
|
||||
'phabricator-prefab',
|
||||
'phuix-icon-view',
|
||||
),
|
||||
'd0c516d5' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
|
@ -2037,12 +2039,6 @@ return array(
|
|||
'javelin-typeahead-ondemand-source',
|
||||
'javelin-dom',
|
||||
),
|
||||
'e0731603' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'phuix-icon-view',
|
||||
'phabricator-prefab',
|
||||
),
|
||||
'e1d25dfb' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -2093,6 +2089,10 @@ return array(
|
|||
'javelin-workflow',
|
||||
'javelin-magical-init',
|
||||
),
|
||||
'e74b7517' => array(
|
||||
'javelin-install',
|
||||
'phuix-button-view',
|
||||
),
|
||||
'e83d28f3' => array(
|
||||
'javelin-dom',
|
||||
),
|
||||
|
|
|
@ -25,9 +25,9 @@ foreach (new LiskRawMigrationIterator($conn, $src_table) as $row) {
|
|||
$row['oldLen'],
|
||||
$row['newOffset'],
|
||||
$row['newLen'],
|
||||
DifferentialModernHunk::DATATYPE_TEXT,
|
||||
DifferentialHunk::DATATYPE_TEXT,
|
||||
'utf8',
|
||||
DifferentialModernHunk::DATAFORMAT_RAW,
|
||||
DifferentialHunk::DATAFORMAT_RAW,
|
||||
// In rare cases, this could be NULL. See T12090.
|
||||
(string)$row['changes'],
|
||||
$row['dateCreated'],
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
DROP TABLE {$NAMESPACE}_differential.differential_hunk;
|
|
@ -0,0 +1,2 @@
|
|||
RENAME TABLE {$NAMESPACE}_differential.differential_hunk_modern
|
||||
TO {$NAMESPACE}_differential.differential_hunk;
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildmessage
|
||||
CHANGE buildTargetPHID receiverPHID VARBINARY(64) NOT NULL;
|
27
resources/sql/autopatches/20180214.harbor.01.aborted.php
Normal file
27
resources/sql/autopatches/20180214.harbor.01.aborted.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
$table = new HarbormasterBuildable();
|
||||
$conn = $table->establishConnection('w');
|
||||
|
||||
foreach (new LiskMigrationIterator($table) as $buildable) {
|
||||
if ($buildable->getBuildableStatus() !== 'building') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$aborted = queryfx_one(
|
||||
$conn,
|
||||
'SELECT * FROM %T WHERE buildablePHID = %s AND buildStatus = %s',
|
||||
id(new HarbormasterBuild())->getTableName(),
|
||||
$buildable->getPHID(),
|
||||
'aborted');
|
||||
if (!$aborted) {
|
||||
continue;
|
||||
}
|
||||
|
||||
queryfx(
|
||||
$conn,
|
||||
'UPDATE %T SET buildableStatus = %s WHERE id = %d',
|
||||
$table->getTableName(),
|
||||
'failed',
|
||||
$buildable->getID());
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_phriction.phriction_content
|
||||
ADD phid VARBINARY(64) NOT NULL;
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
$table = new PhrictionContent();
|
||||
$conn = $table->establishConnection('w');
|
||||
|
||||
foreach (new LiskMigrationIterator($table) as $row) {
|
||||
if (strlen($row->getPHID())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
queryfx(
|
||||
$conn,
|
||||
'UPDATE %T SET phid = %s WHERE id = %d',
|
||||
$table->getTableName(),
|
||||
$table->generatePHID(),
|
||||
$row->getID());
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
UPDATE {$NAMESPACE}_phriction.phriction_content
|
||||
SET description = '' WHERE description IS NULL;
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_phriction.phriction_content
|
||||
CHANGE description description LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_phriction.phriction_document
|
||||
CHANGE status status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,11 @@
|
|||
UPDATE {$NAMESPACE}_phriction.phriction_document
|
||||
SET status = 'active' WHERE status = '0';
|
||||
|
||||
UPDATE {$NAMESPACE}_phriction.phriction_document
|
||||
SET status = 'deleted' WHERE status = '1';
|
||||
|
||||
UPDATE {$NAMESPACE}_phriction.phriction_document
|
||||
SET status = 'moved' WHERE status = '2';
|
||||
|
||||
UPDATE {$NAMESPACE}_phriction.phriction_document
|
||||
SET status = 'stub' WHERE status = '3';
|
|
@ -2,7 +2,7 @@
|
|||
<?php
|
||||
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $root.'/scripts/__init_script__.php';
|
||||
require_once $root.'/scripts/init/init-script-with-signals.php';
|
||||
|
||||
$args = new PhutilArgumentParser($argv);
|
||||
$args->setTagline(pht('manage drydock software resources'));
|
||||
|
|
11
scripts/init/init-script-with-signals.php
Normal file
11
scripts/init/init-script-with-signals.php
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
// Initialize a script that will handle signals.
|
||||
|
||||
if (function_exists('pcntl_async_signals')) {
|
||||
pcntl_async_signals(true);
|
||||
} else {
|
||||
declare(ticks = 1);
|
||||
}
|
||||
|
||||
require_once dirname(__FILE__).'/init-script.php';
|
|
@ -481,7 +481,6 @@ phutil_register_library_map(array(
|
|||
'DifferentialInlineCommentQuery' => 'applications/differential/query/DifferentialInlineCommentQuery.php',
|
||||
'DifferentialJIRAIssuesCommitMessageField' => 'applications/differential/field/DifferentialJIRAIssuesCommitMessageField.php',
|
||||
'DifferentialJIRAIssuesField' => 'applications/differential/customfield/DifferentialJIRAIssuesField.php',
|
||||
'DifferentialLegacyHunk' => 'applications/differential/storage/DifferentialLegacyHunk.php',
|
||||
'DifferentialLegacyQuery' => 'applications/differential/constants/DifferentialLegacyQuery.php',
|
||||
'DifferentialLineAdjustmentMap' => 'applications/differential/parser/DifferentialLineAdjustmentMap.php',
|
||||
'DifferentialLintField' => 'applications/differential/customfield/DifferentialLintField.php',
|
||||
|
@ -490,7 +489,6 @@ phutil_register_library_map(array(
|
|||
'DifferentialMailEngineExtension' => 'applications/differential/engineextension/DifferentialMailEngineExtension.php',
|
||||
'DifferentialMailView' => 'applications/differential/mail/DifferentialMailView.php',
|
||||
'DifferentialManiphestTasksField' => 'applications/differential/customfield/DifferentialManiphestTasksField.php',
|
||||
'DifferentialModernHunk' => 'applications/differential/storage/DifferentialModernHunk.php',
|
||||
'DifferentialParseCacheGarbageCollector' => 'applications/differential/garbagecollector/DifferentialParseCacheGarbageCollector.php',
|
||||
'DifferentialParseCommitMessageConduitAPIMethod' => 'applications/differential/conduit/DifferentialParseCommitMessageConduitAPIMethod.php',
|
||||
'DifferentialParseRenderTestCase' => 'applications/differential/__tests__/DifferentialParseRenderTestCase.php',
|
||||
|
@ -718,6 +716,7 @@ phutil_register_library_map(array(
|
|||
'DiffusionController' => 'applications/diffusion/controller/DiffusionController.php',
|
||||
'DiffusionCreateRepositoriesCapability' => 'applications/diffusion/capability/DiffusionCreateRepositoriesCapability.php',
|
||||
'DiffusionDaemonLockException' => 'applications/diffusion/exception/DiffusionDaemonLockException.php',
|
||||
'DiffusionDatasourceEngineExtension' => 'applications/diffusion/engineextension/DiffusionDatasourceEngineExtension.php',
|
||||
'DiffusionDefaultEditCapability' => 'applications/diffusion/capability/DiffusionDefaultEditCapability.php',
|
||||
'DiffusionDefaultPushCapability' => 'applications/diffusion/capability/DiffusionDefaultPushCapability.php',
|
||||
'DiffusionDefaultViewCapability' => 'applications/diffusion/capability/DiffusionDefaultViewCapability.php',
|
||||
|
@ -813,6 +812,8 @@ phutil_register_library_map(array(
|
|||
'DiffusionPreCommitContentHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentHeraldField.php',
|
||||
'DiffusionPreCommitContentMergeHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentMergeHeraldField.php',
|
||||
'DiffusionPreCommitContentMessageHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentMessageHeraldField.php',
|
||||
'DiffusionPreCommitContentPackageHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentPackageHeraldField.php',
|
||||
'DiffusionPreCommitContentPackageOwnerHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentPackageOwnerHeraldField.php',
|
||||
'DiffusionPreCommitContentPusherHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentPusherHeraldField.php',
|
||||
'DiffusionPreCommitContentPusherIsCommitterHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentPusherIsCommitterHeraldField.php',
|
||||
'DiffusionPreCommitContentPusherProjectsHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentPusherProjectsHeraldField.php',
|
||||
|
@ -846,7 +847,6 @@ phutil_register_library_map(array(
|
|||
'DiffusionQueryCommitsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionQueryCommitsConduitAPIMethod.php',
|
||||
'DiffusionQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionQueryConduitAPIMethod.php',
|
||||
'DiffusionQueryPathsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionQueryPathsConduitAPIMethod.php',
|
||||
'DiffusionQuickSearchEngineExtension' => 'applications/diffusion/engineextension/DiffusionQuickSearchEngineExtension.php',
|
||||
'DiffusionRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionRawDiffQuery.php',
|
||||
'DiffusionRawDiffQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRawDiffQueryConduitAPIMethod.php',
|
||||
'DiffusionReadmeView' => 'applications/diffusion/view/DiffusionReadmeView.php',
|
||||
|
@ -1002,6 +1002,7 @@ phutil_register_library_map(array(
|
|||
'DoorkeeperSchemaSpec' => 'applications/doorkeeper/storage/DoorkeeperSchemaSpec.php',
|
||||
'DoorkeeperTagView' => 'applications/doorkeeper/view/DoorkeeperTagView.php',
|
||||
'DoorkeeperTagsController' => 'applications/doorkeeper/controller/DoorkeeperTagsController.php',
|
||||
'DrydockAcquiredBrokenResourceException' => 'applications/drydock/exception/DrydockAcquiredBrokenResourceException.php',
|
||||
'DrydockAlmanacServiceHostBlueprintImplementation' => 'applications/drydock/blueprint/DrydockAlmanacServiceHostBlueprintImplementation.php',
|
||||
'DrydockApacheWebrootInterface' => 'applications/drydock/interface/webroot/DrydockApacheWebrootInterface.php',
|
||||
'DrydockAuthorization' => 'applications/drydock/storage/DrydockAuthorization.php',
|
||||
|
@ -1043,7 +1044,6 @@ phutil_register_library_map(array(
|
|||
'DrydockCommandInterface' => 'applications/drydock/interface/command/DrydockCommandInterface.php',
|
||||
'DrydockCommandQuery' => 'applications/drydock/query/DrydockCommandQuery.php',
|
||||
'DrydockConsoleController' => 'applications/drydock/controller/DrydockConsoleController.php',
|
||||
'DrydockConstants' => 'applications/drydock/constants/DrydockConstants.php',
|
||||
'DrydockController' => 'applications/drydock/controller/DrydockController.php',
|
||||
'DrydockCreateBlueprintsCapability' => 'applications/drydock/capability/DrydockCreateBlueprintsCapability.php',
|
||||
'DrydockDAO' => 'applications/drydock/storage/DrydockDAO.php',
|
||||
|
@ -1057,6 +1057,7 @@ phutil_register_library_map(array(
|
|||
'DrydockLeaseActivatedLogType' => 'applications/drydock/logtype/DrydockLeaseActivatedLogType.php',
|
||||
'DrydockLeaseActivationFailureLogType' => 'applications/drydock/logtype/DrydockLeaseActivationFailureLogType.php',
|
||||
'DrydockLeaseActivationYieldLogType' => 'applications/drydock/logtype/DrydockLeaseActivationYieldLogType.php',
|
||||
'DrydockLeaseAllocationFailureLogType' => 'applications/drydock/logtype/DrydockLeaseAllocationFailureLogType.php',
|
||||
'DrydockLeaseController' => 'applications/drydock/controller/DrydockLeaseController.php',
|
||||
'DrydockLeaseDatasource' => 'applications/drydock/typeahead/DrydockLeaseDatasource.php',
|
||||
'DrydockLeaseDestroyedLogType' => 'applications/drydock/logtype/DrydockLeaseDestroyedLogType.php',
|
||||
|
@ -1067,6 +1068,7 @@ phutil_register_library_map(array(
|
|||
'DrydockLeasePHIDType' => 'applications/drydock/phid/DrydockLeasePHIDType.php',
|
||||
'DrydockLeaseQuery' => 'applications/drydock/query/DrydockLeaseQuery.php',
|
||||
'DrydockLeaseQueuedLogType' => 'applications/drydock/logtype/DrydockLeaseQueuedLogType.php',
|
||||
'DrydockLeaseReacquireLogType' => 'applications/drydock/logtype/DrydockLeaseReacquireLogType.php',
|
||||
'DrydockLeaseReclaimLogType' => 'applications/drydock/logtype/DrydockLeaseReclaimLogType.php',
|
||||
'DrydockLeaseReleaseController' => 'applications/drydock/controller/DrydockLeaseReleaseController.php',
|
||||
'DrydockLeaseReleasedLogType' => 'applications/drydock/logtype/DrydockLeaseReleasedLogType.php',
|
||||
|
@ -1108,10 +1110,12 @@ phutil_register_library_map(array(
|
|||
'DrydockResource' => 'applications/drydock/storage/DrydockResource.php',
|
||||
'DrydockResourceActivationFailureLogType' => 'applications/drydock/logtype/DrydockResourceActivationFailureLogType.php',
|
||||
'DrydockResourceActivationYieldLogType' => 'applications/drydock/logtype/DrydockResourceActivationYieldLogType.php',
|
||||
'DrydockResourceAllocationFailureLogType' => 'applications/drydock/logtype/DrydockResourceAllocationFailureLogType.php',
|
||||
'DrydockResourceController' => 'applications/drydock/controller/DrydockResourceController.php',
|
||||
'DrydockResourceDatasource' => 'applications/drydock/typeahead/DrydockResourceDatasource.php',
|
||||
'DrydockResourceListController' => 'applications/drydock/controller/DrydockResourceListController.php',
|
||||
'DrydockResourceListView' => 'applications/drydock/view/DrydockResourceListView.php',
|
||||
'DrydockResourceLockException' => 'applications/drydock/exception/DrydockResourceLockException.php',
|
||||
'DrydockResourcePHIDType' => 'applications/drydock/phid/DrydockResourcePHIDType.php',
|
||||
'DrydockResourceQuery' => 'applications/drydock/query/DrydockResourceQuery.php',
|
||||
'DrydockResourceReclaimLogType' => 'applications/drydock/logtype/DrydockResourceReclaimLogType.php',
|
||||
|
@ -1274,6 +1278,7 @@ phutil_register_library_map(array(
|
|||
'HarbormasterBuildablePHIDType' => 'applications/harbormaster/phid/HarbormasterBuildablePHIDType.php',
|
||||
'HarbormasterBuildableQuery' => 'applications/harbormaster/query/HarbormasterBuildableQuery.php',
|
||||
'HarbormasterBuildableSearchEngine' => 'applications/harbormaster/query/HarbormasterBuildableSearchEngine.php',
|
||||
'HarbormasterBuildableStatus' => 'applications/harbormaster/constants/HarbormasterBuildableStatus.php',
|
||||
'HarbormasterBuildableTransaction' => 'applications/harbormaster/storage/HarbormasterBuildableTransaction.php',
|
||||
'HarbormasterBuildableTransactionEditor' => 'applications/harbormaster/editor/HarbormasterBuildableTransactionEditor.php',
|
||||
'HarbormasterBuildableTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildableTransactionQuery.php',
|
||||
|
@ -2742,8 +2747,11 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDatabaseRef' => 'infrastructure/cluster/PhabricatorDatabaseRef.php',
|
||||
'PhabricatorDatabaseRefParser' => 'infrastructure/cluster/PhabricatorDatabaseRefParser.php',
|
||||
'PhabricatorDatabaseSetupCheck' => 'applications/config/check/PhabricatorDatabaseSetupCheck.php',
|
||||
'PhabricatorDatasourceApplicationEngineExtension' => 'applications/meta/engineextension/PhabricatorDatasourceApplicationEngineExtension.php',
|
||||
'PhabricatorDatasourceEditField' => 'applications/transactions/editfield/PhabricatorDatasourceEditField.php',
|
||||
'PhabricatorDatasourceEditType' => 'applications/transactions/edittype/PhabricatorDatasourceEditType.php',
|
||||
'PhabricatorDatasourceEngine' => 'applications/search/engine/PhabricatorDatasourceEngine.php',
|
||||
'PhabricatorDatasourceEngineExtension' => 'applications/search/engineextension/PhabricatorDatasourceEngineExtension.php',
|
||||
'PhabricatorDateFormatSetting' => 'applications/settings/setting/PhabricatorDateFormatSetting.php',
|
||||
'PhabricatorDateTimeSettingsPanel' => 'applications/settings/panel/PhabricatorDateTimeSettingsPanel.php',
|
||||
'PhabricatorDebugController' => 'applications/system/controller/PhabricatorDebugController.php',
|
||||
|
@ -3148,7 +3156,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorJSONExportFormat' => 'infrastructure/export/format/PhabricatorJSONExportFormat.php',
|
||||
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php',
|
||||
'PhabricatorJiraIssueHasObjectEdgeType' => 'applications/doorkeeper/edge/PhabricatorJiraIssueHasObjectEdgeType.php',
|
||||
'PhabricatorJumpNavHandler' => 'applications/search/engine/PhabricatorJumpNavHandler.php',
|
||||
'PhabricatorKeyValueDatabaseCache' => 'applications/cache/PhabricatorKeyValueDatabaseCache.php',
|
||||
'PhabricatorKeyValueSerializingCacheProxy' => 'applications/cache/PhabricatorKeyValueSerializingCacheProxy.php',
|
||||
'PhabricatorKeyboardRemarkupRule' => 'infrastructure/markup/rule/PhabricatorKeyboardRemarkupRule.php',
|
||||
|
@ -3313,7 +3320,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMetronomicTriggerClock' => 'infrastructure/daemon/workers/clock/PhabricatorMetronomicTriggerClock.php',
|
||||
'PhabricatorModularTransaction' => 'applications/transactions/storage/PhabricatorModularTransaction.php',
|
||||
'PhabricatorModularTransactionType' => 'applications/transactions/storage/PhabricatorModularTransactionType.php',
|
||||
'PhabricatorMonogramQuickSearchEngineExtension' => 'applications/typeahead/engineextension/PhabricatorMonogramQuickSearchEngineExtension.php',
|
||||
'PhabricatorMonogramDatasourceEngineExtension' => 'applications/typeahead/engineextension/PhabricatorMonogramDatasourceEngineExtension.php',
|
||||
'PhabricatorMonospacedFontSetting' => 'applications/settings/setting/PhabricatorMonospacedFontSetting.php',
|
||||
'PhabricatorMonospacedTextareasSetting' => 'applications/settings/setting/PhabricatorMonospacedTextareasSetting.php',
|
||||
'PhabricatorMotivatorProfileMenuItem' => 'applications/search/menuitem/PhabricatorMotivatorProfileMenuItem.php',
|
||||
|
@ -3415,6 +3422,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorObjectRelationshipSource' => 'applications/search/relationship/PhabricatorObjectRelationshipSource.php',
|
||||
'PhabricatorObjectRemarkupRule' => 'infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php',
|
||||
'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php',
|
||||
'PhabricatorObjectStatus' => 'infrastructure/status/PhabricatorObjectStatus.php',
|
||||
'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php',
|
||||
'PhabricatorOldWorldContentSource' => 'infrastructure/contentsource/PhabricatorOldWorldContentSource.php',
|
||||
'PhabricatorOlderInlinesSetting' => 'applications/settings/setting/PhabricatorOlderInlinesSetting.php',
|
||||
|
@ -3611,6 +3619,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleCreateController' => 'applications/people/controller/PhabricatorPeopleCreateController.php',
|
||||
'PhabricatorPeopleCreateGuidanceContext' => 'applications/people/guidance/PhabricatorPeopleCreateGuidanceContext.php',
|
||||
'PhabricatorPeopleDatasource' => 'applications/people/typeahead/PhabricatorPeopleDatasource.php',
|
||||
'PhabricatorPeopleDatasourceEngineExtension' => 'applications/people/engineextension/PhabricatorPeopleDatasourceEngineExtension.php',
|
||||
'PhabricatorPeopleDeleteController' => 'applications/people/controller/PhabricatorPeopleDeleteController.php',
|
||||
'PhabricatorPeopleDetailsProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleDetailsProfileMenuItem.php',
|
||||
'PhabricatorPeopleDisableController' => 'applications/people/controller/PhabricatorPeopleDisableController.php',
|
||||
|
@ -3643,7 +3652,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleProfileTasksController' => 'applications/people/controller/PhabricatorPeopleProfileTasksController.php',
|
||||
'PhabricatorPeopleProfileViewController' => 'applications/people/controller/PhabricatorPeopleProfileViewController.php',
|
||||
'PhabricatorPeopleQuery' => 'applications/people/query/PhabricatorPeopleQuery.php',
|
||||
'PhabricatorPeopleQuickSearchEngineExtension' => 'applications/people/engineextension/PhabricatorPeopleQuickSearchEngineExtension.php',
|
||||
'PhabricatorPeopleRenameController' => 'applications/people/controller/PhabricatorPeopleRenameController.php',
|
||||
'PhabricatorPeopleRevisionsProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleRevisionsProfileMenuItem.php',
|
||||
'PhabricatorPeopleSearchEngine' => 'applications/people/query/PhabricatorPeopleSearchEngine.php',
|
||||
|
@ -3906,8 +3914,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorQueryOrderItem' => 'infrastructure/query/order/PhabricatorQueryOrderItem.php',
|
||||
'PhabricatorQueryOrderTestCase' => 'infrastructure/query/order/__tests__/PhabricatorQueryOrderTestCase.php',
|
||||
'PhabricatorQueryOrderVector' => 'infrastructure/query/order/PhabricatorQueryOrderVector.php',
|
||||
'PhabricatorQuickSearchApplicationEngineExtension' => 'applications/meta/engineextension/PhabricatorQuickSearchApplicationEngineExtension.php',
|
||||
'PhabricatorQuickSearchEngine' => 'applications/search/engine/PhabricatorQuickSearchEngine.php',
|
||||
'PhabricatorQuickSearchEngineExtension' => 'applications/search/engineextension/PhabricatorQuickSearchEngineExtension.php',
|
||||
'PhabricatorRateLimitRequestExceptionHandler' => 'aphront/handler/PhabricatorRateLimitRequestExceptionHandler.php',
|
||||
'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php',
|
||||
|
@ -4377,6 +4383,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorTypeaheadMonogramDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadMonogramDatasource.php',
|
||||
'PhabricatorTypeaheadResult' => 'applications/typeahead/storage/PhabricatorTypeaheadResult.php',
|
||||
'PhabricatorTypeaheadRuntimeCompositeDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadRuntimeCompositeDatasource.php',
|
||||
'PhabricatorTypeaheadTestNumbersDatasource' => 'applications/typeahead/datasource/__tests__/PhabricatorTypeaheadTestNumbersDatasource.php',
|
||||
'PhabricatorTypeaheadTokenView' => 'applications/typeahead/view/PhabricatorTypeaheadTokenView.php',
|
||||
'PhabricatorUIConfigOptions' => 'applications/config/option/PhabricatorUIConfigOptions.php',
|
||||
'PhabricatorUIExample' => 'applications/uiexample/examples/PhabricatorUIExample.php',
|
||||
|
@ -4840,9 +4847,15 @@ phutil_register_library_map(array(
|
|||
'PhrictionConduitAPIMethod' => 'applications/phriction/conduit/PhrictionConduitAPIMethod.php',
|
||||
'PhrictionConstants' => 'applications/phriction/constants/PhrictionConstants.php',
|
||||
'PhrictionContent' => 'applications/phriction/storage/PhrictionContent.php',
|
||||
'PhrictionContentPHIDType' => 'applications/phriction/phid/PhrictionContentPHIDType.php',
|
||||
'PhrictionContentQuery' => 'applications/phriction/query/PhrictionContentQuery.php',
|
||||
'PhrictionContentSearchConduitAPIMethod' => 'applications/phriction/conduit/PhrictionContentSearchConduitAPIMethod.php',
|
||||
'PhrictionContentSearchEngine' => 'applications/phriction/query/PhrictionContentSearchEngine.php',
|
||||
'PhrictionContentSearchEngineAttachment' => 'applications/phriction/engineextension/PhrictionContentSearchEngineAttachment.php',
|
||||
'PhrictionController' => 'applications/phriction/controller/PhrictionController.php',
|
||||
'PhrictionCreateConduitAPIMethod' => 'applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php',
|
||||
'PhrictionDAO' => 'applications/phriction/storage/PhrictionDAO.php',
|
||||
'PhrictionDatasourceEngineExtension' => 'applications/phriction/engineextension/PhrictionDatasourceEngineExtension.php',
|
||||
'PhrictionDeleteController' => 'applications/phriction/controller/PhrictionDeleteController.php',
|
||||
'PhrictionDiffController' => 'applications/phriction/controller/PhrictionDiffController.php',
|
||||
'PhrictionDocument' => 'applications/phriction/storage/PhrictionDocument.php',
|
||||
|
@ -4850,6 +4863,7 @@ phutil_register_library_map(array(
|
|||
'PhrictionDocumentContentHeraldField' => 'applications/phriction/herald/PhrictionDocumentContentHeraldField.php',
|
||||
'PhrictionDocumentContentTransaction' => 'applications/phriction/xaction/PhrictionDocumentContentTransaction.php',
|
||||
'PhrictionDocumentController' => 'applications/phriction/controller/PhrictionDocumentController.php',
|
||||
'PhrictionDocumentDatasource' => 'applications/phriction/typeahead/PhrictionDocumentDatasource.php',
|
||||
'PhrictionDocumentDeleteTransaction' => 'applications/phriction/xaction/PhrictionDocumentDeleteTransaction.php',
|
||||
'PhrictionDocumentFerretEngine' => 'applications/phriction/search/PhrictionDocumentFerretEngine.php',
|
||||
'PhrictionDocumentFulltextEngine' => 'applications/phriction/search/PhrictionDocumentFulltextEngine.php',
|
||||
|
@ -4861,6 +4875,8 @@ phutil_register_library_map(array(
|
|||
'PhrictionDocumentPHIDType' => 'applications/phriction/phid/PhrictionDocumentPHIDType.php',
|
||||
'PhrictionDocumentPathHeraldField' => 'applications/phriction/herald/PhrictionDocumentPathHeraldField.php',
|
||||
'PhrictionDocumentQuery' => 'applications/phriction/query/PhrictionDocumentQuery.php',
|
||||
'PhrictionDocumentSearchConduitAPIMethod' => 'applications/phriction/conduit/PhrictionDocumentSearchConduitAPIMethod.php',
|
||||
'PhrictionDocumentSearchEngine' => 'applications/phriction/query/PhrictionDocumentSearchEngine.php',
|
||||
'PhrictionDocumentStatus' => 'applications/phriction/constants/PhrictionDocumentStatus.php',
|
||||
'PhrictionDocumentTitleHeraldField' => 'applications/phriction/herald/PhrictionDocumentTitleHeraldField.php',
|
||||
'PhrictionDocumentTitleTransaction' => 'applications/phriction/xaction/PhrictionDocumentTitleTransaction.php',
|
||||
|
@ -4877,7 +4893,6 @@ phutil_register_library_map(array(
|
|||
'PhrictionRemarkupRule' => 'applications/phriction/markup/PhrictionRemarkupRule.php',
|
||||
'PhrictionReplyHandler' => 'applications/phriction/mail/PhrictionReplyHandler.php',
|
||||
'PhrictionSchemaSpec' => 'applications/phriction/storage/PhrictionSchemaSpec.php',
|
||||
'PhrictionSearchEngine' => 'applications/phriction/query/PhrictionSearchEngine.php',
|
||||
'PhrictionTransaction' => 'applications/phriction/storage/PhrictionTransaction.php',
|
||||
'PhrictionTransactionComment' => 'applications/phriction/storage/PhrictionTransactionComment.php',
|
||||
'PhrictionTransactionEditor' => 'applications/phriction/editor/PhrictionTransactionEditor.php',
|
||||
|
@ -4946,12 +4961,12 @@ phutil_register_library_map(array(
|
|||
'ProjectConduitAPIMethod' => 'applications/project/conduit/ProjectConduitAPIMethod.php',
|
||||
'ProjectCreateConduitAPIMethod' => 'applications/project/conduit/ProjectCreateConduitAPIMethod.php',
|
||||
'ProjectCreateProjectsCapability' => 'applications/project/capability/ProjectCreateProjectsCapability.php',
|
||||
'ProjectDatasourceEngineExtension' => 'applications/project/engineextension/ProjectDatasourceEngineExtension.php',
|
||||
'ProjectDefaultEditCapability' => 'applications/project/capability/ProjectDefaultEditCapability.php',
|
||||
'ProjectDefaultJoinCapability' => 'applications/project/capability/ProjectDefaultJoinCapability.php',
|
||||
'ProjectDefaultViewCapability' => 'applications/project/capability/ProjectDefaultViewCapability.php',
|
||||
'ProjectEditConduitAPIMethod' => 'applications/project/conduit/ProjectEditConduitAPIMethod.php',
|
||||
'ProjectQueryConduitAPIMethod' => 'applications/project/conduit/ProjectQueryConduitAPIMethod.php',
|
||||
'ProjectQuickSearchEngineExtension' => 'applications/project/engineextension/ProjectQuickSearchEngineExtension.php',
|
||||
'ProjectRemarkupRule' => 'applications/project/remarkup/ProjectRemarkupRule.php',
|
||||
'ProjectRemarkupRuleTestCase' => 'applications/project/remarkup/__tests__/ProjectRemarkupRuleTestCase.php',
|
||||
'ProjectReplyHandler' => 'applications/project/mail/ProjectReplyHandler.php',
|
||||
|
@ -5644,7 +5659,6 @@ phutil_register_library_map(array(
|
|||
'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery',
|
||||
'DifferentialJIRAIssuesCommitMessageField' => 'DifferentialCommitMessageCustomField',
|
||||
'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField',
|
||||
'DifferentialLegacyHunk' => 'DifferentialHunk',
|
||||
'DifferentialLegacyQuery' => 'Phobject',
|
||||
'DifferentialLineAdjustmentMap' => 'Phobject',
|
||||
'DifferentialLintField' => 'DifferentialHarbormasterField',
|
||||
|
@ -5653,7 +5667,6 @@ phutil_register_library_map(array(
|
|||
'DifferentialMailEngineExtension' => 'PhabricatorMailEngineExtension',
|
||||
'DifferentialMailView' => 'Phobject',
|
||||
'DifferentialManiphestTasksField' => 'DifferentialCoreCustomField',
|
||||
'DifferentialModernHunk' => 'DifferentialHunk',
|
||||
'DifferentialParseCacheGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||
'DifferentialParseCommitMessageConduitAPIMethod' => 'DifferentialConduitAPIMethod',
|
||||
'DifferentialParseRenderTestCase' => 'PhabricatorTestCase',
|
||||
|
@ -5899,6 +5912,7 @@ phutil_register_library_map(array(
|
|||
'DiffusionController' => 'PhabricatorController',
|
||||
'DiffusionCreateRepositoriesCapability' => 'PhabricatorPolicyCapability',
|
||||
'DiffusionDaemonLockException' => 'Exception',
|
||||
'DiffusionDatasourceEngineExtension' => 'PhabricatorDatasourceEngineExtension',
|
||||
'DiffusionDefaultEditCapability' => 'PhabricatorPolicyCapability',
|
||||
'DiffusionDefaultPushCapability' => 'PhabricatorPolicyCapability',
|
||||
'DiffusionDefaultViewCapability' => 'PhabricatorPolicyCapability',
|
||||
|
@ -5997,6 +6011,8 @@ phutil_register_library_map(array(
|
|||
'DiffusionPreCommitContentHeraldField' => 'HeraldField',
|
||||
'DiffusionPreCommitContentMergeHeraldField' => 'DiffusionPreCommitContentHeraldField',
|
||||
'DiffusionPreCommitContentMessageHeraldField' => 'DiffusionPreCommitContentHeraldField',
|
||||
'DiffusionPreCommitContentPackageHeraldField' => 'DiffusionPreCommitContentHeraldField',
|
||||
'DiffusionPreCommitContentPackageOwnerHeraldField' => 'DiffusionPreCommitContentHeraldField',
|
||||
'DiffusionPreCommitContentPusherHeraldField' => 'DiffusionPreCommitContentHeraldField',
|
||||
'DiffusionPreCommitContentPusherIsCommitterHeraldField' => 'DiffusionPreCommitContentHeraldField',
|
||||
'DiffusionPreCommitContentPusherProjectsHeraldField' => 'DiffusionPreCommitContentHeraldField',
|
||||
|
@ -6030,7 +6046,6 @@ phutil_register_library_map(array(
|
|||
'DiffusionQueryCommitsConduitAPIMethod' => 'DiffusionConduitAPIMethod',
|
||||
'DiffusionQueryConduitAPIMethod' => 'DiffusionConduitAPIMethod',
|
||||
'DiffusionQueryPathsConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
||||
'DiffusionQuickSearchEngineExtension' => 'PhabricatorQuickSearchEngineExtension',
|
||||
'DiffusionRawDiffQuery' => 'DiffusionFileFutureQuery',
|
||||
'DiffusionRawDiffQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
||||
'DiffusionReadmeView' => 'DiffusionView',
|
||||
|
@ -6200,6 +6215,7 @@ phutil_register_library_map(array(
|
|||
'DoorkeeperSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'DoorkeeperTagView' => 'AphrontView',
|
||||
'DoorkeeperTagsController' => 'PhabricatorController',
|
||||
'DrydockAcquiredBrokenResourceException' => 'Exception',
|
||||
'DrydockAlmanacServiceHostBlueprintImplementation' => 'DrydockBlueprintImplementation',
|
||||
'DrydockApacheWebrootInterface' => 'DrydockWebrootInterface',
|
||||
'DrydockAuthorization' => array(
|
||||
|
@ -6259,7 +6275,6 @@ phutil_register_library_map(array(
|
|||
'DrydockCommandInterface' => 'DrydockInterface',
|
||||
'DrydockCommandQuery' => 'DrydockQuery',
|
||||
'DrydockConsoleController' => 'DrydockController',
|
||||
'DrydockConstants' => 'Phobject',
|
||||
'DrydockController' => 'PhabricatorController',
|
||||
'DrydockCreateBlueprintsCapability' => 'PhabricatorPolicyCapability',
|
||||
'DrydockDAO' => 'PhabricatorLiskDAO',
|
||||
|
@ -6276,6 +6291,7 @@ phutil_register_library_map(array(
|
|||
'DrydockLeaseActivatedLogType' => 'DrydockLogType',
|
||||
'DrydockLeaseActivationFailureLogType' => 'DrydockLogType',
|
||||
'DrydockLeaseActivationYieldLogType' => 'DrydockLogType',
|
||||
'DrydockLeaseAllocationFailureLogType' => 'DrydockLogType',
|
||||
'DrydockLeaseController' => 'DrydockController',
|
||||
'DrydockLeaseDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'DrydockLeaseDestroyedLogType' => 'DrydockLogType',
|
||||
|
@ -6286,11 +6302,12 @@ phutil_register_library_map(array(
|
|||
'DrydockLeasePHIDType' => 'PhabricatorPHIDType',
|
||||
'DrydockLeaseQuery' => 'DrydockQuery',
|
||||
'DrydockLeaseQueuedLogType' => 'DrydockLogType',
|
||||
'DrydockLeaseReacquireLogType' => 'DrydockLogType',
|
||||
'DrydockLeaseReclaimLogType' => 'DrydockLogType',
|
||||
'DrydockLeaseReleaseController' => 'DrydockLeaseController',
|
||||
'DrydockLeaseReleasedLogType' => 'DrydockLogType',
|
||||
'DrydockLeaseSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'DrydockLeaseStatus' => 'DrydockConstants',
|
||||
'DrydockLeaseStatus' => 'PhabricatorObjectStatus',
|
||||
'DrydockLeaseUpdateWorker' => 'DrydockWorker',
|
||||
'DrydockLeaseViewController' => 'DrydockLeaseController',
|
||||
'DrydockLeaseWaitingForResourcesLogType' => 'DrydockLogType',
|
||||
|
@ -6336,16 +6353,18 @@ phutil_register_library_map(array(
|
|||
),
|
||||
'DrydockResourceActivationFailureLogType' => 'DrydockLogType',
|
||||
'DrydockResourceActivationYieldLogType' => 'DrydockLogType',
|
||||
'DrydockResourceAllocationFailureLogType' => 'DrydockLogType',
|
||||
'DrydockResourceController' => 'DrydockController',
|
||||
'DrydockResourceDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'DrydockResourceListController' => 'DrydockResourceController',
|
||||
'DrydockResourceListView' => 'AphrontView',
|
||||
'DrydockResourceLockException' => 'Exception',
|
||||
'DrydockResourcePHIDType' => 'PhabricatorPHIDType',
|
||||
'DrydockResourceQuery' => 'DrydockQuery',
|
||||
'DrydockResourceReclaimLogType' => 'DrydockLogType',
|
||||
'DrydockResourceReleaseController' => 'DrydockResourceController',
|
||||
'DrydockResourceSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'DrydockResourceStatus' => 'DrydockConstants',
|
||||
'DrydockResourceStatus' => 'PhabricatorObjectStatus',
|
||||
'DrydockResourceUpdateWorker' => 'DrydockWorker',
|
||||
'DrydockResourceViewController' => 'DrydockResourceController',
|
||||
'DrydockSFTPFilesystemInterface' => 'DrydockFilesystemInterface',
|
||||
|
@ -6553,6 +6572,7 @@ phutil_register_library_map(array(
|
|||
'HarbormasterBuildablePHIDType' => 'PhabricatorPHIDType',
|
||||
'HarbormasterBuildableQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'HarbormasterBuildableSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'HarbormasterBuildableStatus' => 'Phobject',
|
||||
'HarbormasterBuildableTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'HarbormasterBuildableTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'HarbormasterBuildableTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
|
@ -8247,8 +8267,11 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDatabaseRef' => 'Phobject',
|
||||
'PhabricatorDatabaseRefParser' => 'Phobject',
|
||||
'PhabricatorDatabaseSetupCheck' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorDatasourceApplicationEngineExtension' => 'PhabricatorDatasourceEngineExtension',
|
||||
'PhabricatorDatasourceEditField' => 'PhabricatorTokenizerEditField',
|
||||
'PhabricatorDatasourceEditType' => 'PhabricatorPHIDListEditType',
|
||||
'PhabricatorDatasourceEngine' => 'Phobject',
|
||||
'PhabricatorDatasourceEngineExtension' => 'Phobject',
|
||||
'PhabricatorDateFormatSetting' => 'PhabricatorSelectSetting',
|
||||
'PhabricatorDateTimeSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
|
||||
'PhabricatorDebugController' => 'PhabricatorController',
|
||||
|
@ -8697,7 +8720,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorJSONExportFormat' => 'PhabricatorExportFormat',
|
||||
'PhabricatorJavelinLinter' => 'ArcanistLinter',
|
||||
'PhabricatorJiraIssueHasObjectEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorJumpNavHandler' => 'Phobject',
|
||||
'PhabricatorKeyValueDatabaseCache' => 'PhutilKeyValueCache',
|
||||
'PhabricatorKeyValueSerializingCacheProxy' => 'PhutilKeyValueCacheProxy',
|
||||
'PhabricatorKeyboardRemarkupRule' => 'PhutilRemarkupRule',
|
||||
|
@ -8873,7 +8895,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMetronomicTriggerClock' => 'PhabricatorTriggerClock',
|
||||
'PhabricatorModularTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhabricatorModularTransactionType' => 'Phobject',
|
||||
'PhabricatorMonogramQuickSearchEngineExtension' => 'PhabricatorQuickSearchEngineExtension',
|
||||
'PhabricatorMonogramDatasourceEngineExtension' => 'PhabricatorDatasourceEngineExtension',
|
||||
'PhabricatorMonospacedFontSetting' => 'PhabricatorStringSetting',
|
||||
'PhabricatorMonospacedTextareasSetting' => 'PhabricatorSelectSetting',
|
||||
'PhabricatorMotivatorProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
|
@ -8992,6 +9014,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorObjectRelationshipSource' => 'Phobject',
|
||||
'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule',
|
||||
'PhabricatorObjectSelectorDialog' => 'Phobject',
|
||||
'PhabricatorObjectStatus' => 'Phobject',
|
||||
'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery',
|
||||
'PhabricatorOldWorldContentSource' => 'PhabricatorContentSource',
|
||||
'PhabricatorOlderInlinesSetting' => 'PhabricatorSelectSetting',
|
||||
|
@ -9240,6 +9263,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleCreateController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleCreateGuidanceContext' => 'PhabricatorGuidanceContext',
|
||||
'PhabricatorPeopleDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'PhabricatorPeopleDatasourceEngineExtension' => 'PhabricatorDatasourceEngineExtension',
|
||||
'PhabricatorPeopleDeleteController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleDetailsProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorPeopleDisableController' => 'PhabricatorPeopleController',
|
||||
|
@ -9272,7 +9296,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleProfileTasksController' => 'PhabricatorPeopleProfileController',
|
||||
'PhabricatorPeopleProfileViewController' => 'PhabricatorPeopleProfileController',
|
||||
'PhabricatorPeopleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorPeopleQuickSearchEngineExtension' => 'PhabricatorQuickSearchEngineExtension',
|
||||
'PhabricatorPeopleRenameController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleRevisionsProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorPeopleSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
|
@ -9590,9 +9613,7 @@ phutil_register_library_map(array(
|
|||
'Phobject',
|
||||
'Iterator',
|
||||
),
|
||||
'PhabricatorQuickSearchApplicationEngineExtension' => 'PhabricatorQuickSearchEngineExtension',
|
||||
'PhabricatorQuickSearchEngine' => 'Phobject',
|
||||
'PhabricatorQuickSearchEngineExtension' => 'Phobject',
|
||||
'PhabricatorQuickSearchEngineExtension' => 'PhabricatorDatasourceEngineExtension',
|
||||
'PhabricatorRateLimitRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
|
||||
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorRedirectController' => 'PhabricatorController',
|
||||
|
@ -10151,6 +10172,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorTypeaheadMonogramDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'PhabricatorTypeaheadResult' => 'Phobject',
|
||||
'PhabricatorTypeaheadRuntimeCompositeDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||
'PhabricatorTypeaheadTestNumbersDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'PhabricatorTypeaheadTokenView' => 'AphrontTagView',
|
||||
'PhabricatorUIConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorUIExample' => 'Phobject',
|
||||
|
@ -10745,11 +10767,19 @@ phutil_register_library_map(array(
|
|||
'PhrictionConstants' => 'Phobject',
|
||||
'PhrictionContent' => array(
|
||||
'PhrictionDAO',
|
||||
'PhabricatorMarkupInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
'PhabricatorConduitResultInterface',
|
||||
),
|
||||
'PhrictionContentPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhrictionContentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhrictionContentSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
|
||||
'PhrictionContentSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhrictionContentSearchEngineAttachment' => 'PhabricatorSearchEngineAttachment',
|
||||
'PhrictionController' => 'PhabricatorController',
|
||||
'PhrictionCreateConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
||||
'PhrictionDAO' => 'PhabricatorLiskDAO',
|
||||
'PhrictionDatasourceEngineExtension' => 'PhabricatorDatasourceEngineExtension',
|
||||
'PhrictionDeleteController' => 'PhrictionController',
|
||||
'PhrictionDiffController' => 'PhrictionController',
|
||||
'PhrictionDocument' => array(
|
||||
|
@ -10763,11 +10793,13 @@ phutil_register_library_map(array(
|
|||
'PhabricatorFerretInterface',
|
||||
'PhabricatorProjectInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorConduitResultInterface',
|
||||
),
|
||||
'PhrictionDocumentAuthorHeraldField' => 'PhrictionDocumentHeraldField',
|
||||
'PhrictionDocumentContentHeraldField' => 'PhrictionDocumentHeraldField',
|
||||
'PhrictionDocumentContentTransaction' => 'PhrictionDocumentTransactionType',
|
||||
'PhrictionDocumentController' => 'PhrictionController',
|
||||
'PhrictionDocumentDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'PhrictionDocumentDeleteTransaction' => 'PhrictionDocumentTransactionType',
|
||||
'PhrictionDocumentFerretEngine' => 'PhabricatorFerretEngine',
|
||||
'PhrictionDocumentFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||
|
@ -10779,7 +10811,9 @@ phutil_register_library_map(array(
|
|||
'PhrictionDocumentPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhrictionDocumentPathHeraldField' => 'PhrictionDocumentHeraldField',
|
||||
'PhrictionDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhrictionDocumentStatus' => 'PhrictionConstants',
|
||||
'PhrictionDocumentSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
|
||||
'PhrictionDocumentSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhrictionDocumentStatus' => 'PhabricatorObjectStatus',
|
||||
'PhrictionDocumentTitleHeraldField' => 'PhrictionDocumentHeraldField',
|
||||
'PhrictionDocumentTitleTransaction' => 'PhrictionDocumentTransactionType',
|
||||
'PhrictionDocumentTransactionType' => 'PhabricatorModularTransactionType',
|
||||
|
@ -10795,7 +10829,6 @@ phutil_register_library_map(array(
|
|||
'PhrictionRemarkupRule' => 'PhutilRemarkupRule',
|
||||
'PhrictionReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
||||
'PhrictionSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'PhrictionSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhrictionTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhrictionTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'PhrictionTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
|
@ -10885,12 +10918,12 @@ phutil_register_library_map(array(
|
|||
'ProjectConduitAPIMethod' => 'ConduitAPIMethod',
|
||||
'ProjectCreateConduitAPIMethod' => 'ProjectConduitAPIMethod',
|
||||
'ProjectCreateProjectsCapability' => 'PhabricatorPolicyCapability',
|
||||
'ProjectDatasourceEngineExtension' => 'PhabricatorDatasourceEngineExtension',
|
||||
'ProjectDefaultEditCapability' => 'PhabricatorPolicyCapability',
|
||||
'ProjectDefaultJoinCapability' => 'PhabricatorPolicyCapability',
|
||||
'ProjectDefaultViewCapability' => 'PhabricatorPolicyCapability',
|
||||
'ProjectEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
|
||||
'ProjectQueryConduitAPIMethod' => 'ProjectConduitAPIMethod',
|
||||
'ProjectQuickSearchEngineExtension' => 'PhabricatorQuickSearchEngineExtension',
|
||||
'ProjectRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
||||
'ProjectRemarkupRuleTestCase' => 'PhabricatorTestCase',
|
||||
'ProjectReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
||||
|
|
|
@ -300,6 +300,10 @@ final class PhabricatorAuthPasswordEngine
|
|||
$password->upgradePasswordHasher($envelope, $this->getObject());
|
||||
$new_hasher = $password->getHasher();
|
||||
|
||||
// NOTE: We must save the change before applying transactions because
|
||||
// the editor will reload the object to obtain a read lock.
|
||||
$password->save();
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = $password->getApplicationTransactionTemplate()
|
||||
|
|
|
@ -37,6 +37,24 @@ final class PhabricatorCoreConfigOptions
|
|||
$proto_doc_name = pht('User Guide: Prototype Applications');
|
||||
$applications_app_href = '/applications/';
|
||||
|
||||
$silent_description = $this->deformat(pht(<<<EOREMARKUP
|
||||
This option allows you to stop Phabricator from sending data to most external
|
||||
services: it will disable email, SMS, repository mirroring, remote builds,
|
||||
Doorkeeper writes, and webhooks.
|
||||
|
||||
This option is intended to allow a Phabricator instance to be exported, copied,
|
||||
imported, and run in a test environment without impacting users. For example,
|
||||
if you are migrating to new hardware, you could perform a test migration first
|
||||
with this flag set, make sure things work, and then do a production cutover
|
||||
later with higher confidence and less disruption.
|
||||
|
||||
Without making use of this flag to silence the temporary test environment,
|
||||
users would receive duplicate email during the time the test instance and old
|
||||
production instance were both in operation.
|
||||
EOREMARKUP
|
||||
));
|
||||
|
||||
|
||||
return array(
|
||||
$this->newOption('phabricator.base-uri', 'string', null)
|
||||
->setLocked(true)
|
||||
|
@ -232,21 +250,7 @@ final class PhabricatorCoreConfigOptions
|
|||
pht('Run Normally'),
|
||||
))
|
||||
->setSummary(pht('Stop Phabricator from sending any email, etc.'))
|
||||
->setDescription(
|
||||
pht(
|
||||
'This option allows you to stop Phabricator from sending '.
|
||||
'any data to external services. Among other things, it will '.
|
||||
'disable email, SMS, repository mirroring, and HTTP hooks.'.
|
||||
"\n\n".
|
||||
'This option is intended to allow a Phabricator instance to '.
|
||||
'be exported, copied, imported, and run in a test environment '.
|
||||
'without impacting users. For example, if you are migrating '.
|
||||
'to new hardware, you could perform a test migration first, '.
|
||||
'make sure things work, and then do a production cutover '.
|
||||
'later with higher confidence and less disruption. Without '.
|
||||
'this flag, users would receive duplicate email during the '.
|
||||
'time the test instance and old production instance were '.
|
||||
'both in operation.')),
|
||||
->setDescription($silent_description),
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -99,24 +99,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
|||
return pht('%s created this room.', $author);
|
||||
}
|
||||
|
||||
/**
|
||||
* We really only need a read lock if we have a comment. In that case, we
|
||||
* must update the messagesCount field on the conpherence and
|
||||
* seenMessagesCount(s) for the participant(s).
|
||||
*/
|
||||
protected function shouldReadLock(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
$lock = false;
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorTransactions::TYPE_COMMENT:
|
||||
$lock = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return $lock;
|
||||
}
|
||||
|
||||
protected function applyBuiltinInternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
|
|
|
@ -44,12 +44,12 @@ final class DifferentialUnitField
|
|||
->executeOne();
|
||||
if ($buildable) {
|
||||
switch ($buildable->getBuildableStatus()) {
|
||||
case HarbormasterBuildable::STATUS_BUILDING:
|
||||
case HarbormasterBuildableStatus::STATUS_BUILDING:
|
||||
$warnings[] = pht(
|
||||
'These changes have not finished building yet and may have build '.
|
||||
'failures.');
|
||||
break;
|
||||
case HarbormasterBuildable::STATUS_FAILED:
|
||||
case HarbormasterBuildableStatus::STATUS_FAILED:
|
||||
$warnings[] = pht(
|
||||
'These changes have failed to build.');
|
||||
break;
|
||||
|
|
|
@ -365,21 +365,22 @@ final class DifferentialTransactionEditor
|
|||
$diff->setRevisionID($object->getID());
|
||||
$diff->save();
|
||||
|
||||
// Update Harbormaster to set the containerPHID correctly for any
|
||||
// existing buildables. We may otherwise have buildables stuck with
|
||||
// the old (`null`) container.
|
||||
// If there are any outstanding buildables for this diff, tell
|
||||
// Harbormaster that their containers need to be updated. This is
|
||||
// common, because `arc` creates buildables so it can upload lint
|
||||
// and unit results.
|
||||
|
||||
// TODO: This is a bit iffy, maybe we can find a cleaner approach?
|
||||
// In particular, this could (rarely) be overwritten by Harbormaster
|
||||
// workers.
|
||||
$table = new HarbormasterBuildable();
|
||||
$conn_w = $table->establishConnection('w');
|
||||
queryfx(
|
||||
$conn_w,
|
||||
'UPDATE %T SET containerPHID = %s WHERE buildablePHID = %s',
|
||||
$table->getTableName(),
|
||||
$object->getPHID(),
|
||||
$diff->getPHID());
|
||||
$buildables = id(new HarbormasterBuildableQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withManualBuildables(false)
|
||||
->withBuildablePHIDs(array($diff->getPHID()))
|
||||
->execute();
|
||||
foreach ($buildables as $buildable) {
|
||||
$buildable->sendMessage(
|
||||
$this->getActor(),
|
||||
HarbormasterMessageType::BUILDABLE_CONTAINER,
|
||||
true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -217,8 +217,8 @@ final class DifferentialDiffExtractionEngine extends Phobject {
|
|||
// -echo "test";
|
||||
// -(empty line)
|
||||
|
||||
$hunk = id(new DifferentialModernHunk())->setChanges($context);
|
||||
$vs_hunk = id(new DifferentialModernHunk())->setChanges($vs_context);
|
||||
$hunk = id(new DifferentialHunk())->setChanges($context);
|
||||
$vs_hunk = id(new DifferentialHunk())->setChanges($vs_context);
|
||||
if ($hunk->makeOldFile() != $vs_hunk->makeOldFile() ||
|
||||
$hunk->makeNewFile() != $vs_hunk->makeNewFile()) {
|
||||
return true;
|
||||
|
|
|
@ -57,4 +57,8 @@ final class HeraldDifferentialDiffAdapter extends HeraldDifferentialAdapter {
|
|||
return pht('New Diff');
|
||||
}
|
||||
|
||||
public function supportsWebhooks() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ final class PhabricatorDifferentialMigrateHunkWorkflow
|
|||
|
||||
$storage = $args->getArg('to');
|
||||
switch ($storage) {
|
||||
case DifferentialModernHunk::DATATYPE_TEXT:
|
||||
case DifferentialModernHunk::DATATYPE_FILE:
|
||||
case DifferentialHunk::DATATYPE_TEXT:
|
||||
case DifferentialHunk::DATATYPE_FILE:
|
||||
break;
|
||||
default:
|
||||
throw new PhutilArgumentUsageException(
|
||||
|
@ -44,13 +44,13 @@ final class PhabricatorDifferentialMigrateHunkWorkflow
|
|||
$old_data = $hunk->getChanges();
|
||||
|
||||
switch ($storage) {
|
||||
case DifferentialModernHunk::DATATYPE_TEXT:
|
||||
case DifferentialHunk::DATATYPE_TEXT:
|
||||
$hunk->saveAsText();
|
||||
$this->logOkay(
|
||||
pht('TEXT'),
|
||||
pht('Convereted hunk to text storage.'));
|
||||
break;
|
||||
case DifferentialModernHunk::DATATYPE_FILE:
|
||||
case DifferentialHunk::DATATYPE_FILE:
|
||||
$hunk->saveAsFile();
|
||||
$this->logOkay(
|
||||
pht('FILE'),
|
||||
|
@ -71,7 +71,7 @@ final class PhabricatorDifferentialMigrateHunkWorkflow
|
|||
}
|
||||
|
||||
private function loadHunk($id) {
|
||||
$hunk = id(new DifferentialModernHunk())->load($id);
|
||||
$hunk = id(new DifferentialHunk())->load($id);
|
||||
if (!$hunk) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
final class DifferentialChangesetParserTestCase extends PhabricatorTestCase {
|
||||
|
||||
public function testDiffChangesets() {
|
||||
$hunk = new DifferentialModernHunk();
|
||||
$hunk = new DifferentialHunk();
|
||||
$hunk->setChanges("+a\n b\n-c");
|
||||
$hunk->setNewOffset(1);
|
||||
$hunk->setNewLen(2);
|
||||
|
@ -20,7 +20,7 @@ final class DifferentialChangesetParserTestCase extends PhabricatorTestCase {
|
|||
);
|
||||
|
||||
foreach ($tests as $changes => $expected) {
|
||||
$hunk = new DifferentialModernHunk();
|
||||
$hunk = new DifferentialHunk();
|
||||
$hunk->setChanges($changes);
|
||||
$hunk->setNewOffset(11);
|
||||
$hunk->setNewLen(3);
|
||||
|
|
|
@ -14,7 +14,7 @@ final class DifferentialHunkParserTestCase extends PhabricatorTestCase {
|
|||
$new_len,
|
||||
$changes) {
|
||||
|
||||
$hunk = id(new DifferentialModernHunk())
|
||||
$hunk = id(new DifferentialHunk())
|
||||
->setOldOffset($old_offset)
|
||||
->setOldLen($old_len)
|
||||
->setNewOffset($new_offset)
|
||||
|
|
|
@ -30,25 +30,12 @@ final class DifferentialHunkQuery
|
|||
}
|
||||
}
|
||||
|
||||
public function newResultObject() {
|
||||
return new DifferentialHunk();
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$all_results = array();
|
||||
|
||||
// Load modern hunks.
|
||||
$table = new DifferentialModernHunk();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
||||
$modern_data = queryfx_all(
|
||||
$conn_r,
|
||||
'SELECT * FROM %T %Q %Q %Q',
|
||||
$table->getTableName(),
|
||||
$this->buildWhereClause($conn_r),
|
||||
$this->buildOrderClause($conn_r),
|
||||
$this->buildLimitClause($conn_r));
|
||||
$modern_results = $table->loadAllFromArray($modern_data);
|
||||
|
||||
// Strip all the IDs off since they're not unique and nothing should be
|
||||
// using them.
|
||||
return array_values($modern_results);
|
||||
return $this->loadStandardPage($this->newResultObject());
|
||||
}
|
||||
|
||||
protected function willFilterPage(array $hunks) {
|
||||
|
@ -76,8 +63,8 @@ final class DifferentialHunkQuery
|
|||
return $hunks;
|
||||
}
|
||||
|
||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
||||
$where = array();
|
||||
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||
$where = parent::buildWhereClauseParts($conn);
|
||||
|
||||
if (!$this->changesets) {
|
||||
throw new Exception(
|
||||
|
@ -87,13 +74,11 @@ final class DifferentialHunkQuery
|
|||
}
|
||||
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
$conn,
|
||||
'changesetID IN (%Ld)',
|
||||
mpull($this->changesets, 'getID'));
|
||||
|
||||
$where[] = $this->buildPagingClause($conn_r);
|
||||
|
||||
return $this->formatWhereClause($where);
|
||||
return $where;
|
||||
}
|
||||
|
||||
public function getQueryApplicationClass() {
|
||||
|
|
|
@ -118,11 +118,11 @@ final class DifferentialChangeset
|
|||
public function delete() {
|
||||
$this->openTransaction();
|
||||
|
||||
$modern_hunks = id(new DifferentialModernHunk())->loadAllWhere(
|
||||
$hunks = id(new DifferentialHunk())->loadAllWhere(
|
||||
'changesetID = %d',
|
||||
$this->getID());
|
||||
foreach ($modern_hunks as $modern_hunk) {
|
||||
$modern_hunk->delete();
|
||||
foreach ($hunks as $hunk) {
|
||||
$hunk->delete();
|
||||
}
|
||||
|
||||
$this->unsavedHunks = array();
|
||||
|
@ -292,7 +292,7 @@ final class DifferentialChangeset
|
|||
PhabricatorDestructionEngine $engine) {
|
||||
$this->openTransaction();
|
||||
|
||||
$hunks = id(new DifferentialModernHunk())->loadAllWhere(
|
||||
$hunks = id(new DifferentialHunk())->loadAllWhere(
|
||||
'changesetID = %d',
|
||||
$this->getID());
|
||||
foreach ($hunks as $hunk) {
|
||||
|
|
|
@ -189,7 +189,7 @@ final class DifferentialDiff
|
|||
$hunks = $change->getHunks();
|
||||
if ($hunks) {
|
||||
foreach ($hunks as $hunk) {
|
||||
$dhunk = new DifferentialModernHunk();
|
||||
$dhunk = new DifferentialHunk();
|
||||
$dhunk->setOldOffset($hunk->getOldOffset());
|
||||
$dhunk->setOldLen($hunk->getOldLength());
|
||||
$dhunk->setNewOffset($hunk->getNewOffset());
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
abstract class DifferentialHunk
|
||||
final class DifferentialHunk
|
||||
extends DifferentialDAO
|
||||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
|
@ -11,16 +11,55 @@ abstract class DifferentialHunk
|
|||
protected $oldLen;
|
||||
protected $newOffset;
|
||||
protected $newLen;
|
||||
protected $dataType;
|
||||
protected $dataEncoding;
|
||||
protected $dataFormat;
|
||||
protected $data;
|
||||
|
||||
private $changeset;
|
||||
private $splitLines;
|
||||
private $structuredLines;
|
||||
private $structuredFiles = array();
|
||||
|
||||
private $rawData;
|
||||
private $forcedEncoding;
|
||||
private $fileData;
|
||||
|
||||
const FLAG_LINES_ADDED = 1;
|
||||
const FLAG_LINES_REMOVED = 2;
|
||||
const FLAG_LINES_STABLE = 4;
|
||||
|
||||
const DATATYPE_TEXT = 'text';
|
||||
const DATATYPE_FILE = 'file';
|
||||
|
||||
const DATAFORMAT_RAW = 'byte';
|
||||
const DATAFORMAT_DEFLATED = 'gzde';
|
||||
|
||||
protected function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_BINARY => array(
|
||||
'data' => true,
|
||||
),
|
||||
self::CONFIG_COLUMN_SCHEMA => array(
|
||||
'dataType' => 'bytes4',
|
||||
'dataEncoding' => 'text16?',
|
||||
'dataFormat' => 'bytes4',
|
||||
'oldOffset' => 'uint32',
|
||||
'oldLen' => 'uint32',
|
||||
'newOffset' => 'uint32',
|
||||
'newLen' => 'uint32',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_changeset' => array(
|
||||
'columns' => array('changesetID'),
|
||||
),
|
||||
'key_created' => array(
|
||||
'columns' => array('dateCreated'),
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
public function getAddedLines() {
|
||||
return $this->makeContent($include = '+');
|
||||
}
|
||||
|
@ -214,6 +253,197 @@ abstract class DifferentialHunk
|
|||
}
|
||||
|
||||
|
||||
/* -( Storage )------------------------------------------------------------ */
|
||||
|
||||
|
||||
public function setChanges($text) {
|
||||
$this->rawData = $text;
|
||||
|
||||
$this->dataEncoding = $this->detectEncodingForStorage($text);
|
||||
$this->dataType = self::DATATYPE_TEXT;
|
||||
|
||||
list($format, $data) = $this->formatDataForStorage($text);
|
||||
|
||||
$this->dataFormat = $format;
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getChanges() {
|
||||
return $this->getUTF8StringFromStorage(
|
||||
$this->getRawData(),
|
||||
nonempty($this->forcedEncoding, $this->getDataEncoding()));
|
||||
}
|
||||
|
||||
public function forceEncoding($encoding) {
|
||||
$this->forcedEncoding = $encoding;
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function formatDataForStorage($data) {
|
||||
$deflated = PhabricatorCaches::maybeDeflateData($data);
|
||||
if ($deflated !== null) {
|
||||
return array(self::DATAFORMAT_DEFLATED, $deflated);
|
||||
}
|
||||
|
||||
return array(self::DATAFORMAT_RAW, $data);
|
||||
}
|
||||
|
||||
public function saveAsText() {
|
||||
$old_type = $this->getDataType();
|
||||
$old_data = $this->getData();
|
||||
|
||||
if ($old_type == self::DATATYPE_TEXT) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$raw_data = $this->getRawData();
|
||||
|
||||
$this->setDataType(self::DATATYPE_TEXT);
|
||||
|
||||
list($format, $data) = $this->formatDataForStorage($raw_data);
|
||||
$this->setDataFormat($format);
|
||||
$this->setData($data);
|
||||
|
||||
$result = $this->save();
|
||||
|
||||
$this->destroyData($old_type, $old_data);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function saveAsFile() {
|
||||
$old_type = $this->getDataType();
|
||||
$old_data = $this->getData();
|
||||
|
||||
if ($old_type == self::DATATYPE_FILE) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$raw_data = $this->getRawData();
|
||||
|
||||
list($format, $data) = $this->formatDataForStorage($raw_data);
|
||||
$this->setDataFormat($format);
|
||||
|
||||
$file = PhabricatorFile::newFromFileData(
|
||||
$data,
|
||||
array(
|
||||
'name' => 'differential-hunk',
|
||||
'mime-type' => 'application/octet-stream',
|
||||
'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
|
||||
));
|
||||
|
||||
$this->setDataType(self::DATATYPE_FILE);
|
||||
$this->setData($file->getPHID());
|
||||
|
||||
// NOTE: Because hunks don't have a PHID and we just load hunk data with
|
||||
// the omnipotent viewer, we do not need to attach the file to anything.
|
||||
|
||||
$result = $this->save();
|
||||
|
||||
$this->destroyData($old_type, $old_data);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function getRawData() {
|
||||
if ($this->rawData === null) {
|
||||
$type = $this->getDataType();
|
||||
$data = $this->getData();
|
||||
|
||||
switch ($type) {
|
||||
case self::DATATYPE_TEXT:
|
||||
// In this storage type, the changes are stored on the object.
|
||||
$data = $data;
|
||||
break;
|
||||
case self::DATATYPE_FILE:
|
||||
$data = $this->loadFileData();
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
pht('Hunk has unsupported data type "%s"!', $type));
|
||||
}
|
||||
|
||||
$format = $this->getDataFormat();
|
||||
switch ($format) {
|
||||
case self::DATAFORMAT_RAW:
|
||||
// In this format, the changes are stored as-is.
|
||||
$data = $data;
|
||||
break;
|
||||
case self::DATAFORMAT_DEFLATED:
|
||||
$data = PhabricatorCaches::inflateData($data);
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
pht('Hunk has unsupported data encoding "%s"!', $type));
|
||||
}
|
||||
|
||||
$this->rawData = $data;
|
||||
}
|
||||
|
||||
return $this->rawData;
|
||||
}
|
||||
|
||||
private function loadFileData() {
|
||||
if ($this->fileData === null) {
|
||||
$type = $this->getDataType();
|
||||
if ($type !== self::DATATYPE_FILE) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Unable to load file data for hunk with wrong data type ("%s").',
|
||||
$type));
|
||||
}
|
||||
|
||||
$file_phid = $this->getData();
|
||||
|
||||
$file = $this->loadRawFile($file_phid);
|
||||
$data = $file->loadFileData();
|
||||
|
||||
$this->fileData = $data;
|
||||
}
|
||||
|
||||
return $this->fileData;
|
||||
}
|
||||
|
||||
private function loadRawFile($file_phid) {
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
|
||||
|
||||
$files = id(new PhabricatorFileQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($file_phid))
|
||||
->execute();
|
||||
if (!$files) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Failed to load file ("%s") with hunk data.',
|
||||
$file_phid));
|
||||
}
|
||||
|
||||
$file = head($files);
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function destroyData(
|
||||
$type,
|
||||
$data,
|
||||
PhabricatorDestructionEngine $engine = null) {
|
||||
|
||||
if (!$engine) {
|
||||
$engine = new PhabricatorDestructionEngine();
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case self::DATATYPE_FILE:
|
||||
$file = $this->loadRawFile($data);
|
||||
$engine->destroyObject($file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
||||
|
@ -237,8 +467,13 @@ abstract class DifferentialHunk
|
|||
|
||||
public function destroyObjectPermanently(
|
||||
PhabricatorDestructionEngine $engine) {
|
||||
|
||||
$type = $this->getDataType();
|
||||
$data = $this->getData();
|
||||
|
||||
$this->destroyData($type, $data, $engine);
|
||||
|
||||
$this->delete();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DifferentialLegacyHunk extends DifferentialHunk {
|
||||
|
||||
protected $changes;
|
||||
|
||||
protected function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_COLUMN_SCHEMA => array(
|
||||
'changes' => 'text?',
|
||||
'oldOffset' => 'uint32',
|
||||
'oldLen' => 'uint32',
|
||||
'newOffset' => 'uint32',
|
||||
'newLen' => 'uint32',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'changesetID' => array(
|
||||
'columns' => array('changesetID'),
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
public function getTableName() {
|
||||
return 'differential_hunk';
|
||||
}
|
||||
|
||||
public function getDataEncoding() {
|
||||
return 'utf8';
|
||||
}
|
||||
|
||||
public function forceEncoding($encoding) {
|
||||
// Not supported, these are always utf8.
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,249 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DifferentialModernHunk extends DifferentialHunk {
|
||||
|
||||
const DATATYPE_TEXT = 'text';
|
||||
const DATATYPE_FILE = 'file';
|
||||
|
||||
const DATAFORMAT_RAW = 'byte';
|
||||
const DATAFORMAT_DEFLATED = 'gzde';
|
||||
|
||||
protected $dataType;
|
||||
protected $dataEncoding;
|
||||
protected $dataFormat;
|
||||
protected $data;
|
||||
|
||||
private $rawData;
|
||||
private $forcedEncoding;
|
||||
private $fileData;
|
||||
|
||||
public function getTableName() {
|
||||
return 'differential_hunk_modern';
|
||||
}
|
||||
|
||||
protected function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_BINARY => array(
|
||||
'data' => true,
|
||||
),
|
||||
self::CONFIG_COLUMN_SCHEMA => array(
|
||||
'dataType' => 'bytes4',
|
||||
'dataEncoding' => 'text16?',
|
||||
'dataFormat' => 'bytes4',
|
||||
'oldOffset' => 'uint32',
|
||||
'oldLen' => 'uint32',
|
||||
'newOffset' => 'uint32',
|
||||
'newLen' => 'uint32',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_changeset' => array(
|
||||
'columns' => array('changesetID'),
|
||||
),
|
||||
'key_created' => array(
|
||||
'columns' => array('dateCreated'),
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
public function setChanges($text) {
|
||||
$this->rawData = $text;
|
||||
|
||||
$this->dataEncoding = $this->detectEncodingForStorage($text);
|
||||
$this->dataType = self::DATATYPE_TEXT;
|
||||
|
||||
list($format, $data) = $this->formatDataForStorage($text);
|
||||
|
||||
$this->dataFormat = $format;
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getChanges() {
|
||||
return $this->getUTF8StringFromStorage(
|
||||
$this->getRawData(),
|
||||
nonempty($this->forcedEncoding, $this->getDataEncoding()));
|
||||
}
|
||||
|
||||
public function forceEncoding($encoding) {
|
||||
$this->forcedEncoding = $encoding;
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function formatDataForStorage($data) {
|
||||
$deflated = PhabricatorCaches::maybeDeflateData($data);
|
||||
if ($deflated !== null) {
|
||||
return array(self::DATAFORMAT_DEFLATED, $deflated);
|
||||
}
|
||||
|
||||
return array(self::DATAFORMAT_RAW, $data);
|
||||
}
|
||||
|
||||
public function saveAsText() {
|
||||
$old_type = $this->getDataType();
|
||||
$old_data = $this->getData();
|
||||
|
||||
if ($old_type == self::DATATYPE_TEXT) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$raw_data = $this->getRawData();
|
||||
|
||||
$this->setDataType(self::DATATYPE_TEXT);
|
||||
|
||||
list($format, $data) = $this->formatDataForStorage($raw_data);
|
||||
$this->setDataFormat($format);
|
||||
$this->setData($data);
|
||||
|
||||
$result = $this->save();
|
||||
|
||||
$this->destroyData($old_type, $old_data);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function saveAsFile() {
|
||||
$old_type = $this->getDataType();
|
||||
$old_data = $this->getData();
|
||||
|
||||
if ($old_type == self::DATATYPE_FILE) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$raw_data = $this->getRawData();
|
||||
|
||||
list($format, $data) = $this->formatDataForStorage($raw_data);
|
||||
$this->setDataFormat($format);
|
||||
|
||||
$file = PhabricatorFile::newFromFileData(
|
||||
$data,
|
||||
array(
|
||||
'name' => 'differential-hunk',
|
||||
'mime-type' => 'application/octet-stream',
|
||||
'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
|
||||
));
|
||||
|
||||
$this->setDataType(self::DATATYPE_FILE);
|
||||
$this->setData($file->getPHID());
|
||||
|
||||
// NOTE: Because hunks don't have a PHID and we just load hunk data with
|
||||
// the omnipotent viewer, we do not need to attach the file to anything.
|
||||
|
||||
$result = $this->save();
|
||||
|
||||
$this->destroyData($old_type, $old_data);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function getRawData() {
|
||||
if ($this->rawData === null) {
|
||||
$type = $this->getDataType();
|
||||
$data = $this->getData();
|
||||
|
||||
switch ($type) {
|
||||
case self::DATATYPE_TEXT:
|
||||
// In this storage type, the changes are stored on the object.
|
||||
$data = $data;
|
||||
break;
|
||||
case self::DATATYPE_FILE:
|
||||
$data = $this->loadFileData();
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
pht('Hunk has unsupported data type "%s"!', $type));
|
||||
}
|
||||
|
||||
$format = $this->getDataFormat();
|
||||
switch ($format) {
|
||||
case self::DATAFORMAT_RAW:
|
||||
// In this format, the changes are stored as-is.
|
||||
$data = $data;
|
||||
break;
|
||||
case self::DATAFORMAT_DEFLATED:
|
||||
$data = PhabricatorCaches::inflateData($data);
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
pht('Hunk has unsupported data encoding "%s"!', $type));
|
||||
}
|
||||
|
||||
$this->rawData = $data;
|
||||
}
|
||||
|
||||
return $this->rawData;
|
||||
}
|
||||
|
||||
private function loadFileData() {
|
||||
if ($this->fileData === null) {
|
||||
$type = $this->getDataType();
|
||||
if ($type !== self::DATATYPE_FILE) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Unable to load file data for hunk with wrong data type ("%s").',
|
||||
$type));
|
||||
}
|
||||
|
||||
$file_phid = $this->getData();
|
||||
|
||||
$file = $this->loadRawFile($file_phid);
|
||||
$data = $file->loadFileData();
|
||||
|
||||
$this->fileData = $data;
|
||||
}
|
||||
|
||||
return $this->fileData;
|
||||
}
|
||||
|
||||
private function loadRawFile($file_phid) {
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
|
||||
|
||||
$files = id(new PhabricatorFileQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($file_phid))
|
||||
->execute();
|
||||
if (!$files) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Failed to load file ("%s") with hunk data.',
|
||||
$file_phid));
|
||||
}
|
||||
|
||||
$file = head($files);
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
|
||||
public function destroyObjectPermanently(
|
||||
PhabricatorDestructionEngine $engine) {
|
||||
|
||||
$type = $this->getDataType();
|
||||
$data = $this->getData();
|
||||
|
||||
$this->destroyData($type, $data, $engine);
|
||||
|
||||
return parent::destroyObjectPermanently($engine);
|
||||
}
|
||||
|
||||
|
||||
private function destroyData(
|
||||
$type,
|
||||
$data,
|
||||
PhabricatorDestructionEngine $engine = null) {
|
||||
|
||||
if (!$engine) {
|
||||
$engine = new PhabricatorDestructionEngine();
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case self::DATATYPE_FILE:
|
||||
$file = $this->loadRawFile($data);
|
||||
$engine->destroyObject($file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -743,9 +743,10 @@ final class DifferentialRevision extends DifferentialDAO
|
|||
public function loadActiveBuilds(PhabricatorUser $viewer) {
|
||||
$diff = $this->getActiveDiff();
|
||||
|
||||
// NOTE: We can't use `withContainerPHIDs()` here because the container
|
||||
// update in Harbormaster is not synchronous.
|
||||
$buildables = id(new HarbormasterBuildableQuery())
|
||||
->setViewer($viewer)
|
||||
->withContainerPHIDs(array($this->getPHID()))
|
||||
->withBuildablePHIDs(array($diff->getPHID()))
|
||||
->withManualBuildables(false)
|
||||
->execute();
|
||||
|
|
|
@ -5,7 +5,7 @@ final class DifferentialHunkTestCase extends PhutilTestCase {
|
|||
public function testMakeChanges() {
|
||||
$root = dirname(__FILE__).'/hunk/';
|
||||
|
||||
$hunk = new DifferentialModernHunk();
|
||||
$hunk = new DifferentialHunk();
|
||||
$hunk->setChanges(Filesystem::readFile($root.'basic.diff'));
|
||||
$hunk->setOldOffset(1);
|
||||
$hunk->setNewOffset(11);
|
||||
|
@ -23,7 +23,7 @@ final class DifferentialHunkTestCase extends PhutilTestCase {
|
|||
);
|
||||
$this->assertEqual($added, $hunk->getAddedLines());
|
||||
|
||||
$hunk = new DifferentialModernHunk();
|
||||
$hunk = new DifferentialHunk();
|
||||
$hunk->setChanges(Filesystem::readFile($root.'newline.diff'));
|
||||
$hunk->setOldOffset(1);
|
||||
$hunk->setNewOffset(11);
|
||||
|
|
|
@ -57,8 +57,19 @@ final class DifferentialRevisionPlanChangesTransaction
|
|||
|
||||
protected function validateAction($object, PhabricatorUser $viewer) {
|
||||
if ($object->isDraft()) {
|
||||
throw new Exception(
|
||||
pht('You can not plan changes to a draft revision.'));
|
||||
|
||||
// See PHI346. Until the "Draft" state fully unprototypes, allow drafts
|
||||
// to be moved to "changes planned" via the API. This preserves the
|
||||
// behavior of "arc diff --plan-changes". We still prevent this
|
||||
// transition from the web UI.
|
||||
// TODO: Remove this once drafts leave prototype.
|
||||
|
||||
$editor = $this->getEditor();
|
||||
$type_web = PhabricatorWebContentSource::SOURCECONST;
|
||||
if ($editor->getContentSource()->getSource() == $type_web) {
|
||||
throw new Exception(
|
||||
pht('You can not plan changes to a draft revision.'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($object->isChangePlanned()) {
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionDatasourceEngineExtension
|
||||
extends PhabricatorDatasourceEngineExtension {
|
||||
|
||||
public function newQuickSearchDatasources() {
|
||||
return array(
|
||||
new DiffusionRepositoryDatasource(),
|
||||
new DiffusionSymbolDatasource(),
|
||||
);
|
||||
}
|
||||
|
||||
public function newJumpURI($query) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
// Send "r" to Diffusion.
|
||||
if (preg_match('/^r\z/i', $query)) {
|
||||
return '/diffusion/';
|
||||
}
|
||||
|
||||
// Send "a" to the commit list ("Audit").
|
||||
if (preg_match('/^a\z/i', $query)) {
|
||||
return '/diffusion/commit/';
|
||||
}
|
||||
|
||||
// Send "r <string>" to a search for a matching repository.
|
||||
$matches = null;
|
||||
if (preg_match('/^r\s+(.+)\z/i', $query, $matches)) {
|
||||
$raw_query = $matches[1];
|
||||
|
||||
$engine = id(new PhabricatorRepository())
|
||||
->newFerretEngine();
|
||||
|
||||
$compiler = id(new PhutilSearchQueryCompiler())
|
||||
->setEnableFunctions(true);
|
||||
|
||||
$raw_tokens = $compiler->newTokens($raw_query);
|
||||
|
||||
$fulltext_tokens = array();
|
||||
foreach ($raw_tokens as $raw_token) {
|
||||
$fulltext_token = id(new PhabricatorFulltextToken())
|
||||
->setToken($raw_token);
|
||||
$fulltext_tokens[] = $fulltext_token;
|
||||
}
|
||||
|
||||
$repositories = id(new PhabricatorRepositoryQuery())
|
||||
->setViewer($viewer)
|
||||
->withFerretConstraint($engine, $fulltext_tokens)
|
||||
->execute();
|
||||
if (count($repositories) == 1) {
|
||||
// Just one match, jump to repository.
|
||||
return head($repositories)->getURI();
|
||||
} else {
|
||||
// More than one match, jump to search.
|
||||
return urisprintf(
|
||||
'/diffusion/?order=relevance&query=%s#R',
|
||||
$raw_query);
|
||||
}
|
||||
}
|
||||
|
||||
// Send "s <string>" to a symbol search.
|
||||
$matches = null;
|
||||
if (preg_match('/^s\s+(.+)\z/i', $query, $matches)) {
|
||||
$symbol = $matches[1];
|
||||
|
||||
$parts = null;
|
||||
if (preg_match('/(.*)(?:\\.|::|->)(.*)/', $symbol, $parts)) {
|
||||
return urisprintf(
|
||||
'/diffusion/symbol/%s/?jump=true&context=%s',
|
||||
$parts[2],
|
||||
$parts[1]);
|
||||
} else {
|
||||
return urisprintf(
|
||||
'/diffusion/symbol/%s/?jump=true',
|
||||
$symbol);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionQuickSearchEngineExtension
|
||||
extends PhabricatorQuickSearchEngineExtension {
|
||||
|
||||
public function newQuickSearchDatasources() {
|
||||
return array(
|
||||
new DiffusionRepositoryDatasource(),
|
||||
new DiffusionSymbolDatasource(),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionPreCommitContentPackageHeraldField
|
||||
extends DiffusionPreCommitContentHeraldField {
|
||||
|
||||
const FIELDCONST = 'diffusion.pre.content.package';
|
||||
|
||||
public function getHeraldFieldName() {
|
||||
return pht('Affected packages');
|
||||
}
|
||||
|
||||
public function getFieldGroupKey() {
|
||||
return HeraldRelatedFieldGroup::FIELDGROUPKEY;
|
||||
}
|
||||
|
||||
public function getHeraldFieldValue($object) {
|
||||
$packages = $this->getAdapter()->loadAffectedPackages();
|
||||
return mpull($packages, 'getPHID');
|
||||
}
|
||||
|
||||
protected function getHeraldFieldStandardType() {
|
||||
return self::STANDARD_PHID_LIST;
|
||||
}
|
||||
|
||||
protected function getDatasource() {
|
||||
return new PhabricatorOwnersPackageDatasource();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionPreCommitContentPackageOwnerHeraldField
|
||||
extends DiffusionPreCommitContentHeraldField {
|
||||
|
||||
const FIELDCONST = 'diffusion.pre.content.package.owners';
|
||||
|
||||
public function getHeraldFieldName() {
|
||||
return pht('Affected package owners');
|
||||
}
|
||||
|
||||
public function getFieldGroupKey() {
|
||||
return HeraldRelatedFieldGroup::FIELDGROUPKEY;
|
||||
}
|
||||
|
||||
public function getHeraldFieldValue($object) {
|
||||
$packages = $this->getAdapter()->loadAffectedPackages();
|
||||
if (!$packages) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$owners = PhabricatorOwnersOwner::loadAllForPackages($packages);
|
||||
return mpull($owners, 'getUserPHID');
|
||||
}
|
||||
|
||||
protected function getHeraldFieldStandardType() {
|
||||
return self::STANDARD_PHID_LIST;
|
||||
}
|
||||
|
||||
protected function getDatasource() {
|
||||
return new PhabricatorProjectOrUserDatasource();
|
||||
}
|
||||
|
||||
}
|
|
@ -87,4 +87,8 @@ abstract class HeraldPreCommitAdapter extends HeraldAdapter {
|
|||
$this->hookEngine->getRepository()->getProjectPHIDs());
|
||||
}
|
||||
|
||||
public function supportsWebhooks() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
|
|||
private $fields;
|
||||
private $revision = false;
|
||||
|
||||
private $affectedPackages;
|
||||
|
||||
public function getAdapterContentName() {
|
||||
return pht('Commit Hook: Commit Content');
|
||||
}
|
||||
|
@ -223,4 +225,16 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
|
|||
$this->getObject()->getRefNew());
|
||||
}
|
||||
|
||||
public function loadAffectedPackages() {
|
||||
if ($this->affectedPackages === null) {
|
||||
$packages = PhabricatorOwnersPackage::loadAffectedPackages(
|
||||
$this->getHookEngine()->getRepository(),
|
||||
$this->getDiffContent('name'));
|
||||
$this->affectedPackages = $packages;
|
||||
}
|
||||
|
||||
return $this->affectedPackages;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -205,12 +205,11 @@ abstract class DiffusionView extends AphrontView {
|
|||
final protected function renderBuildable(
|
||||
HarbormasterBuildable $buildable,
|
||||
$type = null) {
|
||||
$status = $buildable->getBuildableStatus();
|
||||
Javelin::initBehavior('phabricator-tooltips');
|
||||
|
||||
$icon = HarbormasterBuildable::getBuildableStatusIcon($status);
|
||||
$color = HarbormasterBuildable::getBuildableStatusColor($status);
|
||||
$name = HarbormasterBuildable::getBuildableStatusName($status);
|
||||
$icon = $buildable->getStatusIcon();
|
||||
$color = $buildable->getStatusColor();
|
||||
$name = $buildable->getStatusDisplayName();
|
||||
|
||||
if ($type == 'button') {
|
||||
return id(new PHUIButtonView())
|
||||
|
|
|
@ -80,20 +80,17 @@ final class PhabricatorVersionedDraft extends PhabricatorDraftDAO {
|
|||
|
||||
public static function purgeDrafts(
|
||||
$object_phid,
|
||||
$viewer_phid,
|
||||
$version) {
|
||||
$viewer_phid) {
|
||||
|
||||
$draft = new PhabricatorVersionedDraft();
|
||||
$conn_w = $draft->establishConnection('w');
|
||||
|
||||
queryfx(
|
||||
$conn_w,
|
||||
'DELETE FROM %T WHERE objectPHID = %s AND authorPHID = %s
|
||||
AND version <= %d',
|
||||
'DELETE FROM %T WHERE objectPHID = %s AND authorPHID = %s',
|
||||
$draft->getTableName(),
|
||||
$object_phid,
|
||||
$viewer_phid,
|
||||
$version);
|
||||
$viewer_phid);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -396,16 +396,20 @@ abstract class DrydockBlueprintImplementation extends Phobject {
|
|||
}
|
||||
|
||||
// For reasonable limits, actually check for an available slot.
|
||||
$locks = DrydockSlotLock::loadLocks($blueprint_phid);
|
||||
$locks = mpull($locks, null, 'getLockKey');
|
||||
|
||||
$slots = range(0, $limit - 1);
|
||||
shuffle($slots);
|
||||
|
||||
$lock_names = array();
|
||||
foreach ($slots as $slot) {
|
||||
$slot_lock = "allocator({$blueprint_phid}).limit({$slot})";
|
||||
if (empty($locks[$slot_lock])) {
|
||||
return $slot_lock;
|
||||
$lock_names[] = "allocator({$blueprint_phid}).limit({$slot})";
|
||||
}
|
||||
|
||||
$locks = DrydockSlotLock::loadHeldLocks($lock_names);
|
||||
$locks = mpull($locks, null, 'getLockKey');
|
||||
|
||||
foreach ($lock_names as $lock_name) {
|
||||
if (empty($locks[$lock_name])) {
|
||||
return $lock_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,7 +418,8 @@ abstract class DrydockBlueprintImplementation extends Phobject {
|
|||
// lock will be free by the time we try to take it, but usually we'll just
|
||||
// fail to grab the lock, throw an appropriate lock exception, and get back
|
||||
// on the right path to retry later.
|
||||
return $slot_lock;
|
||||
|
||||
return $lock_name;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -206,7 +206,7 @@ final class DrydockWorkingCopyBlueprintImplementation
|
|||
}
|
||||
|
||||
// Destroy the lease on the host.
|
||||
$lease->releaseOnDestruction();
|
||||
$lease->setReleaseOnDestruction(true);
|
||||
|
||||
if ($lease->isActive()) {
|
||||
// Destroy the working copy on disk.
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
<?php
|
||||
|
||||
abstract class DrydockConstants extends Phobject {}
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class DrydockLeaseStatus extends DrydockConstants {
|
||||
final class DrydockLeaseStatus
|
||||
extends PhabricatorObjectStatus {
|
||||
|
||||
const STATUS_PENDING = 'pending';
|
||||
const STATUS_ACQUIRED = 'acquired';
|
||||
|
@ -9,24 +10,105 @@ final class DrydockLeaseStatus extends DrydockConstants {
|
|||
const STATUS_BROKEN = 'broken';
|
||||
const STATUS_DESTROYED = 'destroyed';
|
||||
|
||||
public static function newStatusObject($key) {
|
||||
return new self($key, id(new self())->getStatusSpecification($key));
|
||||
}
|
||||
|
||||
public static function getStatusMap() {
|
||||
return array(
|
||||
self::STATUS_PENDING => pht('Pending'),
|
||||
self::STATUS_ACQUIRED => pht('Acquired'),
|
||||
self::STATUS_ACTIVE => pht('Active'),
|
||||
self::STATUS_RELEASED => pht('Released'),
|
||||
self::STATUS_BROKEN => pht('Broken'),
|
||||
self::STATUS_DESTROYED => pht('Destroyed'),
|
||||
);
|
||||
$map = id(new self())->getStatusSpecifications();
|
||||
return ipull($map, 'name', 'key');
|
||||
}
|
||||
|
||||
public static function getNameForStatus($status) {
|
||||
$map = self::getStatusMap();
|
||||
return idx($map, $status, pht('Unknown'));
|
||||
$map = id(new self())->getStatusSpecification($status);
|
||||
return $map['name'];
|
||||
}
|
||||
|
||||
public static function getAllStatuses() {
|
||||
return array_keys(self::getStatusMap());
|
||||
return array_keys(id(new self())->getStatusSpecifications());
|
||||
}
|
||||
|
||||
public function isActivating() {
|
||||
return $this->getStatusProperty('isActivating');
|
||||
}
|
||||
|
||||
public function isActive() {
|
||||
return ($this->getKey() === self::STATUS_ACTIVE);
|
||||
}
|
||||
|
||||
public function canRelease() {
|
||||
return $this->getStatusProperty('isReleasable');
|
||||
}
|
||||
|
||||
public function canReceiveCommands() {
|
||||
return $this->getStatusProperty('isCommandable');
|
||||
}
|
||||
|
||||
protected function newStatusSpecifications() {
|
||||
return array(
|
||||
array(
|
||||
'key' => self::STATUS_PENDING,
|
||||
'name' => pht('Pending'),
|
||||
'icon' => 'fa-clock-o',
|
||||
'color' => 'blue',
|
||||
'isReleasable' => true,
|
||||
'isCommandable' => true,
|
||||
'isActivating' => true,
|
||||
),
|
||||
array(
|
||||
'key' => self::STATUS_ACQUIRED,
|
||||
'name' => pht('Acquired'),
|
||||
'icon' => 'fa-refresh',
|
||||
'color' => 'blue',
|
||||
'isReleasable' => true,
|
||||
'isCommandable' => true,
|
||||
'isActivating' => true,
|
||||
),
|
||||
array(
|
||||
'key' => self::STATUS_ACTIVE,
|
||||
'name' => pht('Active'),
|
||||
'icon' => 'fa-check',
|
||||
'color' => 'green',
|
||||
'isReleasable' => true,
|
||||
'isCommandable' => true,
|
||||
'isActivating' => false,
|
||||
),
|
||||
array(
|
||||
'key' => self::STATUS_RELEASED,
|
||||
'name' => pht('Released'),
|
||||
'icon' => 'fa-circle-o',
|
||||
'color' => 'blue',
|
||||
'isReleasable' => false,
|
||||
'isCommandable' => false,
|
||||
'isActivating' => false,
|
||||
),
|
||||
array(
|
||||
'key' => self::STATUS_BROKEN,
|
||||
'name' => pht('Broken'),
|
||||
'icon' => 'fa-times',
|
||||
'color' => 'indigo',
|
||||
'isReleasable' => true,
|
||||
'isCommandable' => true,
|
||||
'isActivating' => false,
|
||||
),
|
||||
array(
|
||||
'key' => self::STATUS_DESTROYED,
|
||||
'name' => pht('Destroyed'),
|
||||
'icon' => 'fa-times',
|
||||
'color' => 'grey',
|
||||
'isReleasable' => false,
|
||||
'isCommandable' => false,
|
||||
'isActivating' => false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected function newUnknownStatusSpecification($status) {
|
||||
return array(
|
||||
'isReleasable' => false,
|
||||
'isCommandable' => false,
|
||||
'isActivating' => false,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class DrydockResourceStatus extends DrydockConstants {
|
||||
final class DrydockResourceStatus
|
||||
extends PhabricatorObjectStatus {
|
||||
|
||||
const STATUS_PENDING = 'pending';
|
||||
const STATUS_ACTIVE = 'active';
|
||||
|
@ -8,23 +9,86 @@ final class DrydockResourceStatus extends DrydockConstants {
|
|||
const STATUS_BROKEN = 'broken';
|
||||
const STATUS_DESTROYED = 'destroyed';
|
||||
|
||||
public static function newStatusObject($key) {
|
||||
return new self($key, id(new self())->getStatusSpecification($key));
|
||||
}
|
||||
|
||||
public static function getStatusMap() {
|
||||
return array(
|
||||
self::STATUS_PENDING => pht('Pending'),
|
||||
self::STATUS_ACTIVE => pht('Active'),
|
||||
self::STATUS_RELEASED => pht('Released'),
|
||||
self::STATUS_BROKEN => pht('Broken'),
|
||||
self::STATUS_DESTROYED => pht('Destroyed'),
|
||||
);
|
||||
$map = id(new self())->getStatusSpecifications();
|
||||
return ipull($map, 'name', 'key');
|
||||
}
|
||||
|
||||
public static function getNameForStatus($status) {
|
||||
$map = self::getStatusMap();
|
||||
return idx($map, $status, pht('Unknown'));
|
||||
$map = id(new self())->getStatusSpecification($status);
|
||||
return $map['name'];
|
||||
}
|
||||
|
||||
public static function getAllStatuses() {
|
||||
return array_keys(self::getStatusMap());
|
||||
return array_keys(id(new self())->getStatusSpecifications());
|
||||
}
|
||||
|
||||
public function isActive() {
|
||||
return ($this->getKey() === self::STATUS_ACTIVE);
|
||||
}
|
||||
|
||||
public function canRelease() {
|
||||
return $this->getStatusProperty('isReleasable');
|
||||
}
|
||||
|
||||
public function canReceiveCommands() {
|
||||
return $this->getStatusProperty('isCommandable');
|
||||
}
|
||||
|
||||
protected function newStatusSpecifications() {
|
||||
return array(
|
||||
array(
|
||||
'key' => self::STATUS_PENDING,
|
||||
'name' => pht('Pending'),
|
||||
'icon' => 'fa-clock-o',
|
||||
'color' => 'blue',
|
||||
'isReleasable' => true,
|
||||
'isCommandable' => true,
|
||||
),
|
||||
array(
|
||||
'key' => self::STATUS_ACTIVE,
|
||||
'name' => pht('Active'),
|
||||
'icon' => 'fa-check',
|
||||
'color' => 'green',
|
||||
'isReleasable' => true,
|
||||
'isCommandable' => true,
|
||||
),
|
||||
array(
|
||||
'key' => self::STATUS_RELEASED,
|
||||
'name' => pht('Released'),
|
||||
'icon' => 'fa-circle-o',
|
||||
'color' => 'blue',
|
||||
'isReleasable' => false,
|
||||
'isCommandable' => false,
|
||||
),
|
||||
array(
|
||||
'key' => self::STATUS_BROKEN,
|
||||
'name' => pht('Broken'),
|
||||
'icon' => 'fa-times',
|
||||
'color' => 'indigo',
|
||||
'isReleasable' => true,
|
||||
'isCommandable' => false,
|
||||
),
|
||||
array(
|
||||
'key' => self::STATUS_DESTROYED,
|
||||
'name' => pht('Destroyed'),
|
||||
'icon' => 'fa-times',
|
||||
'color' => 'grey',
|
||||
'isReleasable' => false,
|
||||
'isCommandable' => false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected function newUnknownStatusSpecification($status) {
|
||||
return array(
|
||||
'isReleasable' => false,
|
||||
'isCommandable' => false,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,10 +22,19 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
|
|||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon('fa-link');
|
||||
->setHeaderIcon('fa-link')
|
||||
->setStatus(
|
||||
$lease->getStatusIcon(),
|
||||
$lease->getStatusColor(),
|
||||
$lease->getStatusDisplayName());
|
||||
|
||||
if ($lease->isReleasing()) {
|
||||
$header->setStatus('fa-exclamation-triangle', 'red', pht('Releasing'));
|
||||
$header->addTag(
|
||||
id(new PHUITagView())
|
||||
->setType(PHUITagView::TYPE_SHADE)
|
||||
->setIcon('fa-exclamation-triangle')
|
||||
->setColor('red')
|
||||
->setName('Releasing'));
|
||||
}
|
||||
|
||||
$curtain = $this->buildCurtain($lease);
|
||||
|
@ -118,10 +127,6 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
|
|||
|
||||
$view = new PHUIPropertyListView();
|
||||
|
||||
$view->addProperty(
|
||||
pht('Status'),
|
||||
DrydockLeaseStatus::getNameForStatus($lease->getStatus()));
|
||||
|
||||
$view->addProperty(
|
||||
pht('Resource Type'),
|
||||
$lease->getResourceType());
|
||||
|
|
|
@ -24,10 +24,19 @@ final class DrydockResourceViewController extends DrydockResourceController {
|
|||
->setUser($viewer)
|
||||
->setPolicyObject($resource)
|
||||
->setHeader($title)
|
||||
->setHeaderIcon('fa-map');
|
||||
->setHeaderIcon('fa-map')
|
||||
->setStatus(
|
||||
$resource->getStatusIcon(),
|
||||
$resource->getStatusColor(),
|
||||
$resource->getStatusDisplayName());
|
||||
|
||||
if ($resource->isReleasing()) {
|
||||
$header->setStatus('fa-exclamation-triangle', 'red', pht('Releasing'));
|
||||
$header->addTag(
|
||||
id(new PHUITagView())
|
||||
->setType(PHUITagView::TYPE_SHADE)
|
||||
->setIcon('fa-exclamation-triangle')
|
||||
->setColor('red')
|
||||
->setName('Releasing'));
|
||||
}
|
||||
|
||||
$curtain = $this->buildCurtain($resource);
|
||||
|
@ -127,12 +136,6 @@ final class DrydockResourceViewController extends DrydockResourceController {
|
|||
$viewer = $this->getViewer();
|
||||
|
||||
$view = new PHUIPropertyListView();
|
||||
$status = $resource->getStatus();
|
||||
$status = DrydockResourceStatus::getNameForStatus($status);
|
||||
|
||||
$view->addProperty(
|
||||
pht('Status'),
|
||||
$status);
|
||||
|
||||
$until = $resource->getUntil();
|
||||
if ($until) {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
final class DrydockAcquiredBrokenResourceException
|
||||
extends Exception {}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
final class DrydockResourceLockException
|
||||
extends Exception {}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
final class DrydockLeaseAllocationFailureLogType extends DrydockLogType {
|
||||
|
||||
const LOGCONST = 'core.lease.allocation-failure';
|
||||
|
||||
public function getLogTypeName() {
|
||||
return pht('Allocation Failed');
|
||||
}
|
||||
|
||||
public function getLogTypeIcon(array $data) {
|
||||
return 'fa-times red';
|
||||
}
|
||||
|
||||
public function renderLog(array $data) {
|
||||
$class = idx($data, 'class');
|
||||
$message = idx($data, 'message');
|
||||
|
||||
return pht(
|
||||
'One or more blueprints promised a new resource, but failed when '.
|
||||
'allocating: [%s] %s',
|
||||
$class,
|
||||
$message);
|
||||
}
|
||||
|
||||
}
|
|
@ -13,14 +13,13 @@ final class DrydockLeaseNoAuthorizationsLogType extends DrydockLogType {
|
|||
}
|
||||
|
||||
public function renderLog(array $data) {
|
||||
$viewer = $this->getViewer();
|
||||
$authorizing_phid = idx($data, 'authorizingPHID');
|
||||
|
||||
return pht(
|
||||
'The object which authorized this lease (%s) is not authorized to use '.
|
||||
'any of the blueprints the lease lists. Approve the authorizations '.
|
||||
'before using the lease.',
|
||||
$viewer->renderHandle($authorizing_phid)->render());
|
||||
$this->renderHandle($authorizing_phid));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
final class DrydockLeaseReacquireLogType extends DrydockLogType {
|
||||
|
||||
const LOGCONST = 'core.lease.reacquire';
|
||||
|
||||
public function getLogTypeName() {
|
||||
return pht('Reacquiring Resource');
|
||||
}
|
||||
|
||||
public function getLogTypeIcon(array $data) {
|
||||
return 'fa-refresh yellow';
|
||||
}
|
||||
|
||||
public function renderLog(array $data) {
|
||||
$class = idx($data, 'class');
|
||||
$message = idx($data, 'message');
|
||||
|
||||
return pht(
|
||||
'Lease acquired a resource but failed to activate; acquisition '.
|
||||
'will be retried: [%s] %s',
|
||||
$class,
|
||||
$message);
|
||||
}
|
||||
|
||||
}
|
|
@ -13,13 +13,11 @@ final class DrydockLeaseReclaimLogType extends DrydockLogType {
|
|||
}
|
||||
|
||||
public function renderLog(array $data) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$resource_phids = idx($data, 'resourcePHIDs', array());
|
||||
|
||||
return pht(
|
||||
'Reclaimed resource %s.',
|
||||
$viewer->renderHandleList($resource_phids)->render());
|
||||
$this->renderHandleList($resource_phids));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,13 +13,11 @@ final class DrydockLeaseWaitingForResourcesLogType extends DrydockLogType {
|
|||
}
|
||||
|
||||
public function renderLog(array $data) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$blueprint_phids = idx($data, 'blueprintPHIDs', array());
|
||||
|
||||
return pht(
|
||||
'Waiting for available resources from: %s.',
|
||||
$viewer->renderHandleList($blueprint_phids)->render());
|
||||
$this->renderHandleList($blueprint_phids));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,17 +4,18 @@ abstract class DrydockLogType extends Phobject {
|
|||
|
||||
private $viewer;
|
||||
private $log;
|
||||
private $renderingMode = 'text';
|
||||
|
||||
abstract public function getLogTypeName();
|
||||
abstract public function getLogTypeIcon(array $data);
|
||||
abstract public function renderLog(array $data);
|
||||
|
||||
public function setViewer(PhabricatorUser $viewer) {
|
||||
final public function setViewer(PhabricatorUser $viewer) {
|
||||
$this->viewer = $viewer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getViewer() {
|
||||
final public function getViewer() {
|
||||
return $this->viewer;
|
||||
}
|
||||
|
||||
|
@ -38,4 +39,36 @@ abstract class DrydockLogType extends Phobject {
|
|||
->execute();
|
||||
}
|
||||
|
||||
final public function renderLogForText($data) {
|
||||
$this->renderingMode = 'text';
|
||||
return $this->renderLog($data);
|
||||
}
|
||||
|
||||
final public function renderLogForHTML($data) {
|
||||
$this->renderingMode = 'html';
|
||||
return $this->renderLog($data);
|
||||
}
|
||||
|
||||
final protected function renderHandle($phid) {
|
||||
$viewer = $this->getViewer();
|
||||
$handle = $viewer->renderHandle($phid);
|
||||
|
||||
if ($this->renderingMode == 'html') {
|
||||
return $handle->render();
|
||||
} else {
|
||||
return $handle->setAsText(true)->render();
|
||||
}
|
||||
}
|
||||
|
||||
final protected function renderHandleList(array $phids) {
|
||||
$viewer = $this->getViewer();
|
||||
$handle_list = $viewer->renderHandleList($phids);
|
||||
|
||||
if ($this->renderingMode == 'html') {
|
||||
return $handle_list->render();
|
||||
} else {
|
||||
return $handle_list->setAsText(true)->render();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
final class DrydockResourceAllocationFailureLogType extends DrydockLogType {
|
||||
|
||||
const LOGCONST = 'core.resource.allocation-failure';
|
||||
|
||||
public function getLogTypeName() {
|
||||
return pht('Allocation Failed');
|
||||
}
|
||||
|
||||
public function getLogTypeIcon(array $data) {
|
||||
return 'fa-times red';
|
||||
}
|
||||
|
||||
public function renderLog(array $data) {
|
||||
$class = idx($data, 'class');
|
||||
$message = idx($data, 'message');
|
||||
|
||||
return pht(
|
||||
'Blueprint failed to allocate a resource after claiming it would '.
|
||||
'be able to: [%s] %s',
|
||||
$class,
|
||||
$message);
|
||||
}
|
||||
|
||||
}
|
|
@ -13,12 +13,11 @@ final class DrydockResourceReclaimLogType extends DrydockLogType {
|
|||
}
|
||||
|
||||
public function renderLog(array $data) {
|
||||
$viewer = $this->getViewer();
|
||||
$reclaimer_phid = idx($data, 'reclaimerPHID');
|
||||
|
||||
return pht(
|
||||
'Resource reclaimed by %s.',
|
||||
$viewer->renderHandle($reclaimer_phid)->render());
|
||||
$this->renderHandle($reclaimer_phid));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ final class DrydockManagementLeaseWorkflow
|
|||
$drydock_phid = id(new PhabricatorDrydockApplication())->getPHID();
|
||||
$lease->setAuthorizingPHID($drydock_phid);
|
||||
|
||||
if ($attributes) {
|
||||
$lease->setAttributes($attributes);
|
||||
}
|
||||
|
||||
// TODO: This is not hugely scalable, although this is a debugging workflow
|
||||
// so maybe it's fine. Do we even need `bin/drydock lease` in the long run?
|
||||
$all_blueprints = id(new DrydockBlueprintQuery())
|
||||
|
@ -76,27 +80,129 @@ final class DrydockManagementLeaseWorkflow
|
|||
}
|
||||
$lease->setAllowedBlueprintPHIDs($allowed_phids);
|
||||
|
||||
if ($attributes) {
|
||||
$lease->setAttributes($attributes);
|
||||
}
|
||||
|
||||
if ($until) {
|
||||
$lease->setUntil($until);
|
||||
}
|
||||
|
||||
// If something fatals or the user interrupts the process (for example,
|
||||
// with "^C"), release the lease. We'll cancel this below, if the lease
|
||||
// actually activates.
|
||||
$lease->setReleaseOnDestruction(true);
|
||||
|
||||
// TODO: This would probably be better handled with PhutilSignalRouter,
|
||||
// but it currently doesn't route SIGINT. We're initializing it to setup
|
||||
// SIGTERM handling and make eventual migration easier.
|
||||
$router = PhutilSignalRouter::getRouter();
|
||||
pcntl_signal(SIGINT, array($this, 'didReceiveInterrupt'));
|
||||
|
||||
$t_start = microtime(true);
|
||||
$lease->queueForActivation();
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
"%s\n\n __%s__\n\n%s\n",
|
||||
pht('Queued lease for activation:'),
|
||||
PhabricatorEnv::getProductionURI($lease->getURI()),
|
||||
pht('Waiting for daemons to activate lease...'));
|
||||
|
||||
$lease->waitUntilActive();
|
||||
$this->waitUntilActive($lease);
|
||||
|
||||
// Now that we've survived activation and the lease is good, make it
|
||||
// durable.
|
||||
$lease->setReleaseOnDestruction(false);
|
||||
$t_end = microtime(true);
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht('Activated lease "%s".', $lease->getID()));
|
||||
"%s\n\n %s\n\n%s\n",
|
||||
pht(
|
||||
'Activation complete. This lease is permanent until manually '.
|
||||
'released with:'),
|
||||
pht('$ ./bin/drydock release-lease --id %d', $lease->getID()),
|
||||
pht(
|
||||
'Lease activated in %sms.',
|
||||
new PhutilNumber((int)(($t_end - $t_start) * 1000))));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function didReceiveInterrupt($signo) {
|
||||
// Doing this makes us run destructors, particularly the "release on
|
||||
// destruction" trigger on the lease.
|
||||
exit(128 + $signo);
|
||||
}
|
||||
|
||||
private function waitUntilActive(DrydockLease $lease) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$log_cursor = 0;
|
||||
$log_types = DrydockLogType::getAllLogTypes();
|
||||
|
||||
$is_active = false;
|
||||
while (!$is_active) {
|
||||
$lease->reload();
|
||||
|
||||
// While we're waiting, show the user any logs which the daemons have
|
||||
// generated to give them some clue about what's going on.
|
||||
$logs = id(new DrydockLogQuery())
|
||||
->setViewer($viewer)
|
||||
->withLeasePHIDs(array($lease->getPHID()))
|
||||
->setBeforeID($log_cursor)
|
||||
->execute();
|
||||
if ($logs) {
|
||||
$logs = mpull($logs, null, 'getID');
|
||||
ksort($logs);
|
||||
$log_cursor = last_key($logs);
|
||||
}
|
||||
|
||||
foreach ($logs as $log) {
|
||||
$type_key = $log->getType();
|
||||
if (isset($log_types[$type_key])) {
|
||||
$type_object = id(clone $log_types[$type_key])
|
||||
->setLog($log)
|
||||
->setViewer($viewer);
|
||||
|
||||
$log_data = $log->getData();
|
||||
|
||||
$type = $type_object->getLogTypeName();
|
||||
$data = $type_object->renderLogForText($log_data);
|
||||
} else {
|
||||
$type = pht('Unknown ("%s")', $type_key);
|
||||
$data = null;
|
||||
}
|
||||
|
||||
echo tsprintf(
|
||||
"<%s> %B\n",
|
||||
$type,
|
||||
$data);
|
||||
}
|
||||
|
||||
$status = $lease->getStatus();
|
||||
|
||||
switch ($status) {
|
||||
case DrydockLeaseStatus::STATUS_ACTIVE:
|
||||
$is_active = true;
|
||||
break;
|
||||
case DrydockLeaseStatus::STATUS_RELEASED:
|
||||
throw new Exception(pht('Lease has already been released!'));
|
||||
case DrydockLeaseStatus::STATUS_DESTROYED:
|
||||
throw new Exception(pht('Lease has already been destroyed!'));
|
||||
case DrydockLeaseStatus::STATUS_BROKEN:
|
||||
throw new Exception(pht('Lease has been broken!'));
|
||||
case DrydockLeaseStatus::STATUS_PENDING:
|
||||
case DrydockLeaseStatus::STATUS_ACQUIRED:
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Lease has unknown status "%s".',
|
||||
$status));
|
||||
}
|
||||
|
||||
if ($is_active) {
|
||||
break;
|
||||
} else {
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@ final class DrydockLease extends DrydockDAO
|
|||
* a lease, as you don't need to explicitly handle exceptions to properly
|
||||
* release the lease.
|
||||
*/
|
||||
public function releaseOnDestruction() {
|
||||
$this->releaseOnDestruction = true;
|
||||
public function setReleaseOnDestruction($release) {
|
||||
$this->releaseOnDestruction = $release;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -175,57 +175,6 @@ final class DrydockLease extends DrydockDAO
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function isActivating() {
|
||||
switch ($this->getStatus()) {
|
||||
case DrydockLeaseStatus::STATUS_PENDING:
|
||||
case DrydockLeaseStatus::STATUS_ACQUIRED:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isActive() {
|
||||
switch ($this->getStatus()) {
|
||||
case DrydockLeaseStatus::STATUS_ACTIVE:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function waitUntilActive() {
|
||||
while (true) {
|
||||
$lease = $this->reload();
|
||||
if (!$lease) {
|
||||
throw new Exception(pht('Failed to reload lease.'));
|
||||
}
|
||||
|
||||
$status = $lease->getStatus();
|
||||
|
||||
switch ($status) {
|
||||
case DrydockLeaseStatus::STATUS_ACTIVE:
|
||||
return;
|
||||
case DrydockLeaseStatus::STATUS_RELEASED:
|
||||
throw new Exception(pht('Lease has already been released!'));
|
||||
case DrydockLeaseStatus::STATUS_DESTROYED:
|
||||
throw new Exception(pht('Lease has already been destroyed!'));
|
||||
case DrydockLeaseStatus::STATUS_BROKEN:
|
||||
throw new Exception(pht('Lease has been broken!'));
|
||||
case DrydockLeaseStatus::STATUS_PENDING:
|
||||
case DrydockLeaseStatus::STATUS_ACQUIRED:
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Lease has unknown status "%s".',
|
||||
$status));
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
public function setActivateWhenAcquired($activate) {
|
||||
$this->activateWhenAcquired = true;
|
||||
return $this;
|
||||
|
@ -264,30 +213,75 @@ final class DrydockLease extends DrydockDAO
|
|||
}
|
||||
}
|
||||
|
||||
$this->openTransaction();
|
||||
// Before we associate the lease with the resource, we lock the resource
|
||||
// and reload it to make sure it is still pending or active. If we don't
|
||||
// do this, the resource may have just been reclaimed. (Once we acquire
|
||||
// the resource that stops it from being released, so we're nearly safe.)
|
||||
|
||||
$resource_phid = $resource->getPHID();
|
||||
$hash = PhabricatorHash::digestForIndex($resource_phid);
|
||||
$lock_key = 'drydock.resource:'.$hash;
|
||||
$lock = PhabricatorGlobalLock::newLock($lock_key);
|
||||
|
||||
try {
|
||||
DrydockSlotLock::acquireLocks($this->getPHID(), $this->slotLocks);
|
||||
$this->slotLocks = array();
|
||||
} catch (DrydockSlotLockException $ex) {
|
||||
$this->killTransaction();
|
||||
|
||||
$this->logEvent(
|
||||
DrydockSlotLockFailureLogType::LOGCONST,
|
||||
array(
|
||||
'locks' => $ex->getLockMap(),
|
||||
));
|
||||
|
||||
throw $ex;
|
||||
$lock->lock(15);
|
||||
} catch (Exception $ex) {
|
||||
throw new DrydockResourceLockException(
|
||||
pht(
|
||||
'Failed to acquire lock for resource ("%s") while trying to '.
|
||||
'acquire lease ("%s").',
|
||||
$resource->getPHID(),
|
||||
$this->getPHID()));
|
||||
}
|
||||
|
||||
$this
|
||||
->setResourcePHID($resource->getPHID())
|
||||
->attachResource($resource)
|
||||
->setStatus($new_status)
|
||||
->save();
|
||||
$resource->reload();
|
||||
|
||||
$this->saveTransaction();
|
||||
if (($resource->getStatus() !== DrydockResourceStatus::STATUS_ACTIVE) &&
|
||||
($resource->getStatus() !== DrydockResourceStatus::STATUS_PENDING)) {
|
||||
throw new DrydockAcquiredBrokenResourceException(
|
||||
pht(
|
||||
'Trying to acquire lease ("%s") on a resource ("%s") in the '.
|
||||
'wrong status ("%s").',
|
||||
$this->getPHID(),
|
||||
$resource->getPHID(),
|
||||
$resource->getStatus()));
|
||||
}
|
||||
|
||||
$caught = null;
|
||||
try {
|
||||
$this->openTransaction();
|
||||
|
||||
try {
|
||||
DrydockSlotLock::acquireLocks($this->getPHID(), $this->slotLocks);
|
||||
$this->slotLocks = array();
|
||||
} catch (DrydockSlotLockException $ex) {
|
||||
$this->killTransaction();
|
||||
|
||||
$this->logEvent(
|
||||
DrydockSlotLockFailureLogType::LOGCONST,
|
||||
array(
|
||||
'locks' => $ex->getLockMap(),
|
||||
));
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
$this
|
||||
->setResourcePHID($resource->getPHID())
|
||||
->attachResource($resource)
|
||||
->setStatus($new_status)
|
||||
->save();
|
||||
|
||||
$this->saveTransaction();
|
||||
} catch (Exception $ex) {
|
||||
$caught = $ex;
|
||||
}
|
||||
|
||||
$lock->unlock();
|
||||
|
||||
if ($caught) {
|
||||
throw $caught;
|
||||
}
|
||||
|
||||
$this->isAcquired = true;
|
||||
|
||||
|
@ -357,30 +351,6 @@ final class DrydockLease extends DrydockDAO
|
|||
return $this->isActivated;
|
||||
}
|
||||
|
||||
public function canRelease() {
|
||||
if (!$this->getID()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ($this->getStatus()) {
|
||||
case DrydockLeaseStatus::STATUS_RELEASED:
|
||||
case DrydockLeaseStatus::STATUS_DESTROYED:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function canReceiveCommands() {
|
||||
switch ($this->getStatus()) {
|
||||
case DrydockLeaseStatus::STATUS_RELEASED:
|
||||
case DrydockLeaseStatus::STATUS_DESTROYED:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function scheduleUpdate($epoch = null) {
|
||||
PhabricatorWorker::scheduleTask(
|
||||
'DrydockLeaseUpdateWorker',
|
||||
|
@ -468,6 +438,51 @@ final class DrydockLease extends DrydockDAO
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
$id = $this->getID();
|
||||
return "/drydock/lease/{$id}/";
|
||||
}
|
||||
|
||||
|
||||
/* -( Status )------------------------------------------------------------- */
|
||||
|
||||
|
||||
public function getStatusObject() {
|
||||
return DrydockLeaseStatus::newStatusObject($this->getStatus());
|
||||
}
|
||||
|
||||
public function getStatusIcon() {
|
||||
return $this->getStatusObject()->getIcon();
|
||||
}
|
||||
|
||||
public function getStatusColor() {
|
||||
return $this->getStatusObject()->getColor();
|
||||
}
|
||||
|
||||
public function getStatusDisplayName() {
|
||||
return $this->getStatusObject()->getDisplayName();
|
||||
}
|
||||
|
||||
public function isActivating() {
|
||||
return $this->getStatusObject()->isActivating();
|
||||
}
|
||||
|
||||
public function isActive() {
|
||||
return $this->getStatusObject()->isActive();
|
||||
}
|
||||
|
||||
public function canRelease() {
|
||||
if (!$this->getID()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->getStatusObject()->canRelease();
|
||||
}
|
||||
|
||||
public function canReceiveCommands() {
|
||||
return $this->getStatusObject()->canReceiveCommands();
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
|
|
@ -235,16 +235,6 @@ final class DrydockResource extends DrydockDAO
|
|||
return $this->isActivated;
|
||||
}
|
||||
|
||||
public function canRelease() {
|
||||
switch ($this->getStatus()) {
|
||||
case DrydockResourceStatus::STATUS_RELEASED:
|
||||
case DrydockResourceStatus::STATUS_DESTROYED:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function scheduleUpdate($epoch = null) {
|
||||
PhabricatorWorker::scheduleTask(
|
||||
'DrydockResourceUpdateWorker',
|
||||
|
@ -282,26 +272,6 @@ final class DrydockResource extends DrydockDAO
|
|||
}
|
||||
}
|
||||
|
||||
public function canReceiveCommands() {
|
||||
switch ($this->getStatus()) {
|
||||
case DrydockResourceStatus::STATUS_RELEASED:
|
||||
case DrydockResourceStatus::STATUS_BROKEN:
|
||||
case DrydockResourceStatus::STATUS_DESTROYED:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function isActive() {
|
||||
switch ($this->getStatus()) {
|
||||
case DrydockResourceStatus::STATUS_ACTIVE:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function logEvent($type, array $data = array()) {
|
||||
$log = id(new DrydockLog())
|
||||
->setEpoch(PhabricatorTime::getNow())
|
||||
|
@ -315,6 +285,38 @@ final class DrydockResource extends DrydockDAO
|
|||
}
|
||||
|
||||
|
||||
/* -( Status )------------------------------------------------------------- */
|
||||
|
||||
|
||||
public function getStatusObject() {
|
||||
return DrydockResourceStatus::newStatusObject($this->getStatus());
|
||||
}
|
||||
|
||||
public function getStatusIcon() {
|
||||
return $this->getStatusObject()->getIcon();
|
||||
}
|
||||
|
||||
public function getStatusColor() {
|
||||
return $this->getStatusObject()->getColor();
|
||||
}
|
||||
|
||||
public function getStatusDisplayName() {
|
||||
return $this->getStatusObject()->getDisplayName();
|
||||
}
|
||||
|
||||
public function canRelease() {
|
||||
return $this->getStatusObject()->canRelease();
|
||||
}
|
||||
|
||||
public function canReceiveCommands() {
|
||||
return $this->getStatusObject()->canReceiveCommands();
|
||||
}
|
||||
|
||||
public function isActive() {
|
||||
return $this->getStatusObject()->isActive();
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -26,20 +26,20 @@ final class DrydockLeaseListView extends AphrontView {
|
|||
if ($resource_phid) {
|
||||
$item->addAttribute(
|
||||
$viewer->renderHandle($resource_phid));
|
||||
} else {
|
||||
$item->addAttribute(
|
||||
pht(
|
||||
'Resource: %s',
|
||||
$lease->getResourceType()));
|
||||
}
|
||||
|
||||
$status = DrydockLeaseStatus::getNameForStatus($lease->getStatus());
|
||||
$item->addAttribute($status);
|
||||
$item->setEpoch($lease->getDateCreated());
|
||||
|
||||
// TODO: Tailor this for clarity.
|
||||
if ($lease->isActivating()) {
|
||||
$item->setStatusIcon('fa-dot-circle-o yellow');
|
||||
} else if ($lease->isActive()) {
|
||||
$item->setStatusIcon('fa-dot-circle-o green');
|
||||
} else {
|
||||
$item->setStatusIcon('fa-dot-circle-o red');
|
||||
}
|
||||
$icon = $lease->getStatusIcon();
|
||||
$color = $lease->getStatusColor();
|
||||
$label = $lease->getStatusDisplayName();
|
||||
|
||||
$item->setStatusIcon("{$icon} {$color}", $label);
|
||||
|
||||
$view->addItem($item);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,8 @@ final class DrydockLogListView extends AphrontView {
|
|||
|
||||
$type = $type_object->getLogTypeName();
|
||||
$icon = $type_object->getLogTypeIcon($log_data);
|
||||
$data = $type_object->renderLog($log_data);
|
||||
$data = $type_object->renderLogForHTML($log_data);
|
||||
$data = phutil_escape_html_newlines($data);
|
||||
} else {
|
||||
$type = pht('<Unknown: %s>', $type_key);
|
||||
$data = null;
|
||||
|
|
|
@ -23,23 +23,11 @@ final class DrydockResourceListView extends AphrontView {
|
|||
->setObjectName(pht('Resource %d', $id))
|
||||
->setHeader($resource->getResourceName());
|
||||
|
||||
$status = DrydockResourceStatus::getNameForStatus($resource->getStatus());
|
||||
$item->addAttribute($status);
|
||||
$icon = $resource->getStatusIcon();
|
||||
$color = $resource->getStatusColor();
|
||||
$label = $resource->getStatusDisplayName();
|
||||
|
||||
switch ($resource->getStatus()) {
|
||||
case DrydockResourceStatus::STATUS_PENDING:
|
||||
$item->setStatusIcon('fa-dot-circle-o yellow');
|
||||
break;
|
||||
case DrydockResourceStatus::STATUS_ACTIVE:
|
||||
$item->setStatusIcon('fa-dot-circle-o green');
|
||||
break;
|
||||
case DrydockResourceStatus::STATUS_DESTROYED:
|
||||
$item->setStatusIcon('fa-times-circle-o black');
|
||||
break;
|
||||
default:
|
||||
$item->setStatusIcon('fa-dot-circle-o red');
|
||||
break;
|
||||
}
|
||||
$item->setStatusIcon("{$icon} {$color}", $label);
|
||||
|
||||
$view->addItem($item);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,27 @@ final class DrydockLeaseUpdateWorker extends DrydockWorker {
|
|||
private function handleUpdate(DrydockLease $lease) {
|
||||
try {
|
||||
$this->updateLease($lease);
|
||||
} catch (DrydockAcquiredBrokenResourceException $ex) {
|
||||
// If this lease acquired a resource but failed to activate, we don't
|
||||
// need to break the lease. We can throw it back in the pool and let
|
||||
// it take another shot at acquiring a new resource.
|
||||
|
||||
// Before we throw it back, release any locks the lease is holding.
|
||||
DrydockSlotLock::releaseLocks($lease->getPHID());
|
||||
|
||||
$lease
|
||||
->setStatus(DrydockLeaseStatus::STATUS_PENDING)
|
||||
->setResourcePHID(null)
|
||||
->save();
|
||||
|
||||
$lease->logEvent(
|
||||
DrydockLeaseReacquireLogType::LOGCONST,
|
||||
array(
|
||||
'class' => get_class($ex),
|
||||
'message' => $ex->getMessage(),
|
||||
));
|
||||
|
||||
$this->yieldLease($lease, $ex);
|
||||
} catch (Exception $ex) {
|
||||
if ($this->isTemporaryException($ex)) {
|
||||
$this->yieldLease($lease, $ex);
|
||||
|
@ -216,17 +237,51 @@ final class DrydockLeaseUpdateWorker extends DrydockWorker {
|
|||
// this.
|
||||
break;
|
||||
} catch (Exception $ex) {
|
||||
// This failure is not normally expected, so log it. It can be
|
||||
// caused by something mundane and recoverable, however (see below
|
||||
// for discussion).
|
||||
|
||||
// We log to the blueprint separately from the log to the lease:
|
||||
// the lease is not attached to a blueprint yet so the lease log
|
||||
// will not show up on the blueprint; more than one blueprint may
|
||||
// fail; and the lease is not really impacted (and won't log) if at
|
||||
// least one blueprint actually works.
|
||||
|
||||
$blueprint->logEvent(
|
||||
DrydockResourceAllocationFailureLogType::LOGCONST,
|
||||
array(
|
||||
'class' => get_class($ex),
|
||||
'message' => $ex->getMessage(),
|
||||
));
|
||||
|
||||
$exceptions[] = $ex;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$resources) {
|
||||
throw new PhutilAggregateException(
|
||||
// If one or more blueprints claimed that they would be able to
|
||||
// allocate resources but none are actually able to allocate resources,
|
||||
// log the failure and yield so we try again soon.
|
||||
|
||||
// This can happen if some unexpected issue occurs during allocation
|
||||
// (for example, a call to build a VM fails for some reason) or if we
|
||||
// raced another allocator and the blueprint is now full.
|
||||
|
||||
$ex = new PhutilAggregateException(
|
||||
pht(
|
||||
'All blueprints failed to allocate a suitable new resource when '.
|
||||
'trying to allocate lease "%s".',
|
||||
'trying to allocate lease ("%s").',
|
||||
$lease->getPHID()),
|
||||
$exceptions);
|
||||
|
||||
$lease->logEvent(
|
||||
DrydockLeaseAllocationFailureLogType::LOGCONST,
|
||||
array(
|
||||
'class' => get_class($ex),
|
||||
'message' => $ex->getMessage(),
|
||||
));
|
||||
|
||||
throw new PhabricatorWorkerYieldException(15);
|
||||
}
|
||||
|
||||
$resources = $this->removeUnacquirableResources($resources, $lease);
|
||||
|
@ -247,23 +302,38 @@ final class DrydockLeaseUpdateWorker extends DrydockWorker {
|
|||
$resources = $this->rankResources($resources, $lease);
|
||||
|
||||
$exceptions = array();
|
||||
$yields = array();
|
||||
$allocated = false;
|
||||
foreach ($resources as $resource) {
|
||||
try {
|
||||
$this->acquireLease($resource, $lease);
|
||||
$allocated = true;
|
||||
break;
|
||||
} catch (DrydockResourceLockException $ex) {
|
||||
// We need to lock the resource to actually acquire it. If we aren't
|
||||
// able to acquire the lock quickly enough, we can yield and try again
|
||||
// later.
|
||||
$yields[] = $ex;
|
||||
} catch (DrydockAcquiredBrokenResourceException $ex) {
|
||||
// If a resource was reclaimed or destroyed by the time we actually
|
||||
// got around to acquiring it, we just got unlucky. We can yield and
|
||||
// try again later.
|
||||
$yields[] = $ex;
|
||||
} catch (Exception $ex) {
|
||||
$exceptions[] = $ex;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$allocated) {
|
||||
throw new PhutilAggregateException(
|
||||
pht(
|
||||
'Unable to acquire lease "%s" on any resource.',
|
||||
$lease->getPHID()),
|
||||
$exceptions);
|
||||
if ($yields) {
|
||||
throw new PhabricatorWorkerYieldException(15);
|
||||
} else {
|
||||
throw new PhutilAggregateException(
|
||||
pht(
|
||||
'Unable to acquire lease "%s" on any resource.',
|
||||
$lease->getPHID()),
|
||||
$exceptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -715,9 +785,12 @@ final class DrydockLeaseUpdateWorker extends DrydockWorker {
|
|||
}
|
||||
|
||||
if ($resource_status != DrydockResourceStatus::STATUS_ACTIVE) {
|
||||
throw new Exception(
|
||||
throw new DrydockAcquiredBrokenResourceException(
|
||||
pht(
|
||||
'Trying to activate lease on a dead resource (in status "%s").',
|
||||
'Trying to activate lease ("%s") on a resource ("%s") in '.
|
||||
'the wrong status ("%s").',
|
||||
$lease->getPHID(),
|
||||
$resource->getPHID(),
|
||||
$resource_status));
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ final class DrydockRepositoryOperationUpdateWorker
|
|||
DrydockCommandInterface::INTERFACE_TYPE);
|
||||
|
||||
// No matter what happens here, destroy the lease away once we're done.
|
||||
$lease->releaseOnDestruction(true);
|
||||
$lease->setReleaseOnDestruction(true);
|
||||
|
||||
$operation->applyOperation($interface);
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ final class HarbormasterQueryBuildablesConduitAPIMethod
|
|||
$monogram = $buildable->getMonogram();
|
||||
|
||||
$status = $buildable->getBuildableStatus();
|
||||
$status_name = HarbormasterBuildable::getBuildableStatusName($status);
|
||||
$status_name = $buildable->getStatusDisplayName();
|
||||
|
||||
$data[] = array(
|
||||
'id' => $buildable->getID(),
|
||||
|
|
|
@ -245,7 +245,7 @@ final class HarbormasterSendMessageConduitAPIMethod
|
|||
}
|
||||
|
||||
$save[] = HarbormasterBuildMessage::initializeNewMessage($viewer)
|
||||
->setBuildTargetPHID($build_target->getPHID())
|
||||
->setReceiverPHID($build_target->getPHID())
|
||||
->setType($message_type);
|
||||
|
||||
$build_target->openTransaction();
|
||||
|
|
|
@ -2,51 +2,56 @@
|
|||
|
||||
final class HarbormasterBuildStatus extends Phobject {
|
||||
|
||||
/**
|
||||
* Not currently being built.
|
||||
*/
|
||||
const STATUS_INACTIVE = 'inactive';
|
||||
|
||||
/**
|
||||
* Pending pick up by the Harbormaster daemon.
|
||||
*/
|
||||
const STATUS_PENDING = 'pending';
|
||||
|
||||
/**
|
||||
* Current building the buildable.
|
||||
*/
|
||||
const STATUS_BUILDING = 'building';
|
||||
|
||||
/**
|
||||
* The build has passed.
|
||||
*/
|
||||
const STATUS_PASSED = 'passed';
|
||||
|
||||
/**
|
||||
* The build has failed.
|
||||
*/
|
||||
const STATUS_FAILED = 'failed';
|
||||
|
||||
/**
|
||||
* The build has aborted.
|
||||
*/
|
||||
const STATUS_ABORTED = 'aborted';
|
||||
|
||||
/**
|
||||
* The build encountered an unexpected error.
|
||||
*/
|
||||
const STATUS_ERROR = 'error';
|
||||
|
||||
/**
|
||||
* The build has been paused.
|
||||
*/
|
||||
const STATUS_PAUSED = 'paused';
|
||||
|
||||
/**
|
||||
* The build has been deadlocked.
|
||||
*/
|
||||
const STATUS_DEADLOCKED = 'deadlocked';
|
||||
|
||||
private $key;
|
||||
private $properties;
|
||||
|
||||
public function __construct($key, array $properties) {
|
||||
$this->key = $key;
|
||||
$this->properties = $properties;
|
||||
}
|
||||
|
||||
public static function newBuildStatusObject($status) {
|
||||
$spec = self::getBuildStatusSpec($status);
|
||||
return new self($status, $spec);
|
||||
}
|
||||
|
||||
private function getProperty($key) {
|
||||
if (!array_key_exists($key, $this->properties)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Attempting to access unknown build status property ("%s").',
|
||||
$key));
|
||||
}
|
||||
|
||||
return $this->properties[$key];
|
||||
}
|
||||
|
||||
public function isBuilding() {
|
||||
return $this->getProperty('isBuilding');
|
||||
}
|
||||
|
||||
public function isPaused() {
|
||||
return ($this->key === self::STATUS_PAUSED);
|
||||
}
|
||||
|
||||
public function isComplete() {
|
||||
return $this->getProperty('isComplete');
|
||||
}
|
||||
|
||||
public function isPassed() {
|
||||
return ($this->key === self::STATUS_PASSED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a human readable name for a build status constant.
|
||||
|
@ -56,7 +61,7 @@ final class HarbormasterBuildStatus extends Phobject {
|
|||
*/
|
||||
public static function getBuildStatusName($status) {
|
||||
$spec = self::getBuildStatusSpec($status);
|
||||
return idx($spec, 'name', pht('Unknown ("%s")', $status));
|
||||
return $spec['name'];
|
||||
}
|
||||
|
||||
public static function getBuildStatusMap() {
|
||||
|
@ -66,17 +71,17 @@ final class HarbormasterBuildStatus extends Phobject {
|
|||
|
||||
public static function getBuildStatusIcon($status) {
|
||||
$spec = self::getBuildStatusSpec($status);
|
||||
return idx($spec, 'icon', 'fa-question-circle');
|
||||
return $spec['icon'];
|
||||
}
|
||||
|
||||
public static function getBuildStatusColor($status) {
|
||||
$spec = self::getBuildStatusSpec($status);
|
||||
return idx($spec, 'color', 'bluegrey');
|
||||
return $spec['color'];
|
||||
}
|
||||
|
||||
public static function getBuildStatusANSIColor($status) {
|
||||
$spec = self::getBuildStatusSpec($status);
|
||||
return idx($spec, 'color.ansi', 'magenta');
|
||||
return $spec['color.ansi'];
|
||||
}
|
||||
|
||||
public static function getWaitingStatusConstants() {
|
||||
|
@ -110,60 +115,90 @@ final class HarbormasterBuildStatus extends Phobject {
|
|||
'icon' => 'fa-circle-o',
|
||||
'color' => 'dark',
|
||||
'color.ansi' => 'yellow',
|
||||
'isBuilding' => false,
|
||||
'isComplete' => false,
|
||||
),
|
||||
self::STATUS_PENDING => array(
|
||||
'name' => pht('Pending'),
|
||||
'icon' => 'fa-circle-o',
|
||||
'color' => 'blue',
|
||||
'color.ansi' => 'yellow',
|
||||
'isBuilding' => true,
|
||||
'isComplete' => false,
|
||||
),
|
||||
self::STATUS_BUILDING => array(
|
||||
'name' => pht('Building'),
|
||||
'icon' => 'fa-chevron-circle-right',
|
||||
'color' => 'blue',
|
||||
'color.ansi' => 'yellow',
|
||||
'isBuilding' => true,
|
||||
'isComplete' => false,
|
||||
),
|
||||
self::STATUS_PASSED => array(
|
||||
'name' => pht('Passed'),
|
||||
'icon' => 'fa-check-circle',
|
||||
'color' => 'green',
|
||||
'color.ansi' => 'green',
|
||||
'isBuilding' => false,
|
||||
'isComplete' => true,
|
||||
),
|
||||
self::STATUS_FAILED => array(
|
||||
'name' => pht('Failed'),
|
||||
'icon' => 'fa-times-circle',
|
||||
'color' => 'red',
|
||||
'color.ansi' => 'red',
|
||||
'isBuilding' => false,
|
||||
'isComplete' => true,
|
||||
),
|
||||
self::STATUS_ABORTED => array(
|
||||
'name' => pht('Aborted'),
|
||||
'icon' => 'fa-minus-circle',
|
||||
'color' => 'red',
|
||||
'color.ansi' => 'red',
|
||||
'isBuilding' => false,
|
||||
'isComplete' => true,
|
||||
),
|
||||
self::STATUS_ERROR => array(
|
||||
'name' => pht('Unexpected Error'),
|
||||
'icon' => 'fa-minus-circle',
|
||||
'color' => 'red',
|
||||
'color.ansi' => 'red',
|
||||
'isBuilding' => false,
|
||||
'isComplete' => true,
|
||||
),
|
||||
self::STATUS_PAUSED => array(
|
||||
'name' => pht('Paused'),
|
||||
'icon' => 'fa-minus-circle',
|
||||
'color' => 'dark',
|
||||
'color.ansi' => 'yellow',
|
||||
'isBuilding' => false,
|
||||
'isComplete' => false,
|
||||
),
|
||||
self::STATUS_DEADLOCKED => array(
|
||||
'name' => pht('Deadlocked'),
|
||||
'icon' => 'fa-exclamation-circle',
|
||||
'color' => 'red',
|
||||
'color.ansi' => 'red',
|
||||
'isBuilding' => false,
|
||||
'isComplete' => true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private static function getBuildStatusSpec($status) {
|
||||
return idx(self::getBuildStatusSpecMap(), $status, array());
|
||||
$map = self::getBuildStatusSpecMap();
|
||||
if (isset($map[$status])) {
|
||||
return $map[$status];
|
||||
}
|
||||
|
||||
return array(
|
||||
'name' => pht('Unknown ("%s")', $status),
|
||||
'icon' => 'fa-question-circle',
|
||||
'color' => 'bluegrey',
|
||||
'color.ansi' => 'magenta',
|
||||
'isBuilding' => false,
|
||||
'isComplete' => false,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
final class HarbormasterBuildableStatus extends Phobject {
|
||||
|
||||
const STATUS_PREPARING = 'preparing';
|
||||
const STATUS_BUILDING = 'building';
|
||||
const STATUS_PASSED = 'passed';
|
||||
const STATUS_FAILED = 'failed';
|
||||
|
||||
private $key;
|
||||
private $properties;
|
||||
|
||||
public function __construct($key, array $properties) {
|
||||
$this->key = $key;
|
||||
$this->properties = $properties;
|
||||
}
|
||||
|
||||
public static function newBuildableStatusObject($status) {
|
||||
$spec = self::getSpecification($status);
|
||||
return new self($status, $spec);
|
||||
}
|
||||
|
||||
private function getProperty($key) {
|
||||
if (!array_key_exists($key, $this->properties)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Attempting to access unknown buildable status property ("%s").',
|
||||
$key));
|
||||
}
|
||||
|
||||
return $this->properties[$key];
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
return $this->getProperty('icon');
|
||||
}
|
||||
|
||||
public function getDisplayName() {
|
||||
return $this->getProperty('name');
|
||||
}
|
||||
|
||||
public function getColor() {
|
||||
return $this->getProperty('color');
|
||||
}
|
||||
|
||||
public function isPreparing() {
|
||||
return ($this->key === self::STATUS_PREPARING);
|
||||
}
|
||||
|
||||
public static function getOptionMap() {
|
||||
return ipull(self::getSpecifications(), 'name');
|
||||
}
|
||||
|
||||
private static function getSpecifications() {
|
||||
return array(
|
||||
self::STATUS_PREPARING => array(
|
||||
'name' => pht('Preparing'),
|
||||
'color' => 'blue',
|
||||
'icon' => 'fa-hourglass-o',
|
||||
),
|
||||
self::STATUS_BUILDING => array(
|
||||
'name' => pht('Building'),
|
||||
'color' => 'blue',
|
||||
'icon' => 'fa-chevron-circle-right',
|
||||
),
|
||||
self::STATUS_PASSED => array(
|
||||
'name' => pht('Passed'),
|
||||
'color' => 'green',
|
||||
'icon' => 'fa-check-circle',
|
||||
),
|
||||
self::STATUS_FAILED => array(
|
||||
'name' => pht('Failed'),
|
||||
'color' => 'red',
|
||||
'icon' => 'fa-times-circle',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private static function getSpecification($status) {
|
||||
$map = self::getSpecifications();
|
||||
if (isset($map[$status])) {
|
||||
return $map[$status];
|
||||
}
|
||||
|
||||
return array(
|
||||
'name' => pht('Unknown ("%s")', $status),
|
||||
'icon' => 'fa-question-circle',
|
||||
'color' => 'bluegrey',
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -65,9 +65,9 @@ final class HarbormasterBuildViewController
|
|||
if ($build_targets) {
|
||||
$messages = id(new HarbormasterBuildMessageQuery())
|
||||
->setViewer($viewer)
|
||||
->withBuildTargetPHIDs(mpull($build_targets, 'getPHID'))
|
||||
->withReceiverPHIDs(mpull($build_targets, 'getPHID'))
|
||||
->execute();
|
||||
$messages = mgroup($messages, 'getBuildTargetPHID');
|
||||
$messages = mgroup($messages, 'getReceiverPHID');
|
||||
} else {
|
||||
$messages = array();
|
||||
}
|
||||
|
|
|
@ -36,6 +36,10 @@ final class HarbormasterBuildableViewController
|
|||
->setHeader($title)
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($buildable)
|
||||
->setStatus(
|
||||
$buildable->getStatusIcon(),
|
||||
$buildable->getStatusColor(),
|
||||
$buildable->getStatusDisplayName())
|
||||
->setHeaderIcon('fa-recycle');
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
|
|
|
@ -59,6 +59,12 @@ final class HarbormasterPlanRunController extends HarbormasterPlanController {
|
|||
|
||||
if (!$errors) {
|
||||
$buildable->save();
|
||||
|
||||
$buildable->sendMessage(
|
||||
$viewer,
|
||||
HarbormasterMessageType::BUILDABLE_BUILD,
|
||||
false);
|
||||
|
||||
$buildable->applyPlan($plan, array(), $viewer->getPHID());
|
||||
|
||||
$buildable_uri = '/B'.$buildable->getID();
|
||||
|
|
|
@ -382,12 +382,12 @@ final class HarbormasterBuildEngine extends Phobject {
|
|||
|
||||
$messages = id(new HarbormasterBuildMessageQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withBuildTargetPHIDs(array_keys($waiting_targets))
|
||||
->withReceiverPHIDs(array_keys($waiting_targets))
|
||||
->withConsumed(false)
|
||||
->execute();
|
||||
|
||||
foreach ($messages as $message) {
|
||||
$target = $waiting_targets[$message->getBuildTargetPHID()];
|
||||
$target = $waiting_targets[$message->getReceiverPHID()];
|
||||
|
||||
switch ($message->getType()) {
|
||||
case HarbormasterMessageType::MESSAGE_PASS:
|
||||
|
@ -428,7 +428,7 @@ final class HarbormasterBuildEngine extends Phobject {
|
|||
* @param HarbormasterBuild The buildable to update.
|
||||
* @return void
|
||||
*/
|
||||
private function updateBuildable(HarbormasterBuildable $buildable) {
|
||||
public function updateBuildable(HarbormasterBuildable $buildable) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$lock_key = 'harbormaster.buildable:'.$buildable->getID();
|
||||
|
@ -440,39 +440,96 @@ final class HarbormasterBuildEngine extends Phobject {
|
|||
->needBuilds(true)
|
||||
->executeOne();
|
||||
|
||||
$all_pass = true;
|
||||
$any_fail = false;
|
||||
foreach ($buildable->getBuilds() as $build) {
|
||||
if ($build->getBuildStatus() != HarbormasterBuildStatus::STATUS_PASSED) {
|
||||
$all_pass = false;
|
||||
}
|
||||
if (in_array($build->getBuildStatus(), array(
|
||||
HarbormasterBuildStatus::STATUS_FAILED,
|
||||
HarbormasterBuildStatus::STATUS_ERROR,
|
||||
HarbormasterBuildStatus::STATUS_DEADLOCKED,
|
||||
))) {
|
||||
$messages = id(new HarbormasterBuildMessageQuery())
|
||||
->setViewer($viewer)
|
||||
->withReceiverPHIDs(array($buildable->getPHID()))
|
||||
->withConsumed(false)
|
||||
->execute();
|
||||
|
||||
$any_fail = true;
|
||||
$done_preparing = false;
|
||||
$update_container = false;
|
||||
foreach ($messages as $message) {
|
||||
switch ($message->getType()) {
|
||||
case HarbormasterMessageType::BUILDABLE_BUILD:
|
||||
$done_preparing = true;
|
||||
break;
|
||||
case HarbormasterMessageType::BUILDABLE_CONTAINER:
|
||||
$update_container = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
$message
|
||||
->setIsConsumed(true)
|
||||
->save();
|
||||
}
|
||||
|
||||
// If we received a "build" command, all builds are scheduled and we can
|
||||
// move out of "preparing" into "building".
|
||||
if ($done_preparing) {
|
||||
if ($buildable->isPreparing()) {
|
||||
$buildable
|
||||
->setBuildableStatus(HarbormasterBuildableStatus::STATUS_BUILDING)
|
||||
->save();
|
||||
}
|
||||
}
|
||||
|
||||
if ($any_fail) {
|
||||
$new_status = HarbormasterBuildable::STATUS_FAILED;
|
||||
} else if ($all_pass) {
|
||||
$new_status = HarbormasterBuildable::STATUS_PASSED;
|
||||
} else {
|
||||
$new_status = HarbormasterBuildable::STATUS_BUILDING;
|
||||
// If we've been informed that the container for the buildable has
|
||||
// changed, update it.
|
||||
if ($update_container) {
|
||||
$object = id(new PhabricatorObjectQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($buildable->getBuildablePHID()))
|
||||
->executeOne();
|
||||
if ($object) {
|
||||
$buildable
|
||||
->setContainerPHID($object->getHarbormasterContainerPHID())
|
||||
->save();
|
||||
}
|
||||
}
|
||||
|
||||
$old_status = $buildable->getBuildableStatus();
|
||||
$did_update = ($old_status != $new_status);
|
||||
if ($did_update) {
|
||||
$buildable->setBuildableStatus($new_status);
|
||||
$buildable->save();
|
||||
// Don't update the buildable status if we're still preparing builds: more
|
||||
// builds may still be scheduled shortly, so even if every build we know
|
||||
// about so far has passed, that doesn't mean the buildable has actually
|
||||
// passed everything it needs to.
|
||||
|
||||
if (!$buildable->isPreparing()) {
|
||||
$all_pass = true;
|
||||
$any_fail = false;
|
||||
foreach ($buildable->getBuilds() as $build) {
|
||||
if (!$build->isPassed()) {
|
||||
$all_pass = false;
|
||||
}
|
||||
|
||||
if ($build->isComplete() && !$build->isPassed()) {
|
||||
$any_fail = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($any_fail) {
|
||||
$new_status = HarbormasterBuildableStatus::STATUS_FAILED;
|
||||
} else if ($all_pass) {
|
||||
$new_status = HarbormasterBuildableStatus::STATUS_PASSED;
|
||||
} else {
|
||||
$new_status = HarbormasterBuildableStatus::STATUS_BUILDING;
|
||||
}
|
||||
|
||||
$old_status = $buildable->getBuildableStatus();
|
||||
$did_update = ($old_status != $new_status);
|
||||
if ($did_update) {
|
||||
$buildable->setBuildableStatus($new_status);
|
||||
$buildable->save();
|
||||
}
|
||||
}
|
||||
|
||||
$lock->unlock();
|
||||
|
||||
// Don't publish anything if we're still preparing builds.
|
||||
if ($buildable->isPreparing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we changed the buildable status, try to post a transaction to the
|
||||
// object about it. We can safely do this outside of the locked region.
|
||||
|
||||
|
@ -481,9 +538,10 @@ final class HarbormasterBuildEngine extends Phobject {
|
|||
// can look at the results themselves, and other users generally don't
|
||||
// care about the outcome.
|
||||
|
||||
$should_publish = $did_update &&
|
||||
$new_status != HarbormasterBuildable::STATUS_BUILDING &&
|
||||
!$buildable->getIsManualBuildable();
|
||||
$should_publish =
|
||||
($did_update) &&
|
||||
($new_status != HarbormasterBuildableStatus::STATUS_BUILDING) &&
|
||||
(!$buildable->getIsManualBuildable());
|
||||
|
||||
if (!$should_publish) {
|
||||
return;
|
||||
|
|
|
@ -6,6 +6,9 @@ final class HarbormasterMessageType extends Phobject {
|
|||
const MESSAGE_FAIL = 'fail';
|
||||
const MESSAGE_WORK = 'work';
|
||||
|
||||
const BUILDABLE_BUILD = 'build';
|
||||
const BUILDABLE_CONTAINER = 'container';
|
||||
|
||||
public static function getAllMessages() {
|
||||
return array_keys(self::getMessageSpecifications());
|
||||
}
|
||||
|
|
|
@ -87,13 +87,9 @@ final class HarbormasterUIEventListener
|
|||
|
||||
$status_view = new PHUIStatusListView();
|
||||
|
||||
$buildable_status = $buildable->getBuildableStatus();
|
||||
$buildable_icon = HarbormasterBuildable::getBuildableStatusIcon(
|
||||
$buildable_status);
|
||||
$buildable_color = HarbormasterBuildable::getBuildableStatusColor(
|
||||
$buildable_status);
|
||||
$buildable_name = HarbormasterBuildable::getBuildableStatusName(
|
||||
$buildable_status);
|
||||
$buildable_icon = $buildable->getStatusIcon();
|
||||
$buildable_color = $buildable->getStatusColor();
|
||||
$buildable_name = $buildable->getStatusDisplayName();
|
||||
|
||||
$target = phutil_tag(
|
||||
'a',
|
||||
|
|
|
@ -83,6 +83,11 @@ final class HarbormasterManagementBuildWorkflow
|
|||
->setContainerPHID($buildable->getHarbormasterContainerPHID())
|
||||
->save();
|
||||
|
||||
$buildable->sendMessage(
|
||||
$viewer,
|
||||
HarbormasterMessageType::BUILDABLE_BUILD,
|
||||
false);
|
||||
|
||||
$console->writeOut(
|
||||
"%s\n",
|
||||
pht(
|
||||
|
|
|
@ -4,7 +4,7 @@ final class HarbormasterBuildMessageQuery
|
|||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||
|
||||
private $ids;
|
||||
private $buildTargetPHIDs;
|
||||
private $receiverPHIDs;
|
||||
private $consumed;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
|
@ -12,8 +12,8 @@ final class HarbormasterBuildMessageQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withBuildTargetPHIDs(array $phids) {
|
||||
$this->buildTargetPHIDs = $phids;
|
||||
public function withReceiverPHIDs(array $phids) {
|
||||
$this->receiverPHIDs = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -22,73 +22,67 @@ final class HarbormasterBuildMessageQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function newResultObject() {
|
||||
return new HarbormasterBuildMessage();
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$table = new HarbormasterBuildMessage();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
||||
$data = queryfx_all(
|
||||
$conn_r,
|
||||
'SELECT * FROM %T %Q %Q %Q',
|
||||
$table->getTableName(),
|
||||
$this->buildWhereClause($conn_r),
|
||||
$this->buildOrderClause($conn_r),
|
||||
$this->buildLimitClause($conn_r));
|
||||
|
||||
return $table->loadAllFromArray($data);
|
||||
return $this->loadStandardPage($this->newResultObject());
|
||||
}
|
||||
|
||||
protected function willFilterPage(array $page) {
|
||||
$build_target_phids = array_filter(mpull($page, 'getBuildTargetPHID'));
|
||||
if ($build_target_phids) {
|
||||
$build_targets = id(new PhabricatorObjectQuery())
|
||||
$receiver_phids = array_filter(mpull($page, 'getReceiverPHID'));
|
||||
if ($receiver_phids) {
|
||||
$receivers = id(new PhabricatorObjectQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withPHIDs($build_target_phids)
|
||||
->withPHIDs($receiver_phids)
|
||||
->setParentQuery($this)
|
||||
->execute();
|
||||
$build_targets = mpull($build_targets, null, 'getPHID');
|
||||
$receivers = mpull($receivers, null, 'getPHID');
|
||||
} else {
|
||||
$build_targets = array();
|
||||
$receivers = array();
|
||||
}
|
||||
|
||||
foreach ($page as $key => $message) {
|
||||
$build_target_phid = $message->getBuildTargetPHID();
|
||||
if (empty($build_targets[$build_target_phid])) {
|
||||
$receiver_phid = $message->getReceiverPHID();
|
||||
|
||||
if (empty($receivers[$receiver_phid])) {
|
||||
unset($page[$key]);
|
||||
$this->didRejectResult($message);
|
||||
continue;
|
||||
}
|
||||
$message->attachBuildTarget($build_targets[$build_target_phid]);
|
||||
|
||||
$message->attachReceiver($receivers[$receiver_phid]);
|
||||
}
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
||||
$where = array();
|
||||
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||
$where = parent::buildWhereClauseParts($conn);
|
||||
|
||||
if ($this->ids) {
|
||||
if ($this->ids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
$conn,
|
||||
'id IN (%Ld)',
|
||||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->buildTargetPHIDs) {
|
||||
if ($this->receiverPHIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'buildTargetPHID IN (%Ls)',
|
||||
$this->buildTargetPHIDs);
|
||||
$conn,
|
||||
'receiverPHID IN (%Ls)',
|
||||
$this->receiverPHIDs);
|
||||
}
|
||||
|
||||
if ($this->consumed !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
$conn,
|
||||
'isConsumed = %d',
|
||||
(int)$this->consumed);
|
||||
}
|
||||
|
||||
$where[] = $this->buildPagingClause($conn_r);
|
||||
|
||||
return $this->formatWhereClause($where);
|
||||
return $where;
|
||||
}
|
||||
|
||||
public function getQueryApplicationClass() {
|
||||
|
|
|
@ -33,7 +33,7 @@ final class HarbormasterBuildableSearchEngine
|
|||
id(new PhabricatorSearchCheckboxesField())
|
||||
->setKey('statuses')
|
||||
->setLabel(pht('Statuses'))
|
||||
->setOptions(HarbormasterBuildable::getBuildStatusMap())
|
||||
->setOptions(HarbormasterBuildableStatus::getOptionMap())
|
||||
->setDescription(pht('Search for builds by buildable status.')),
|
||||
id(new PhabricatorSearchThreeStateField())
|
||||
->setLabel(pht('Manual'))
|
||||
|
@ -169,11 +169,9 @@ final class HarbormasterBuildableSearchEngine
|
|||
$item->addIcon('fa-wrench grey', pht('Manual'));
|
||||
}
|
||||
|
||||
$status = $buildable->getBuildableStatus();
|
||||
|
||||
$status_icon = HarbormasterBuildable::getBuildableStatusIcon($status);
|
||||
$status_color = HarbormasterBuildable::getBuildableStatusColor($status);
|
||||
$status_label = HarbormasterBuildable::getBuildableStatusName($status);
|
||||
$status_icon = $buildable->getStatusIcon();
|
||||
$status_color = $buildable->getStatusColor();
|
||||
$status_label = $buildable->getStatusDisplayName();
|
||||
|
||||
$item->setStatusIcon("{$status_icon} {$status_color}", $status_label);
|
||||
|
||||
|
|
|
@ -295,6 +295,18 @@ abstract class HarbormasterBuildStepImplementation extends Phobject {
|
|||
->append($body);
|
||||
}
|
||||
|
||||
protected function logSilencedCall(
|
||||
HarbormasterBuild $build,
|
||||
HarbormasterBuildTarget $build_target,
|
||||
$label) {
|
||||
|
||||
$build_target
|
||||
->newLog($label, 'silenced')
|
||||
->append(
|
||||
pht(
|
||||
'Declining to make service call because `phabricator.silent` is '.
|
||||
'enabled in configuration.'));
|
||||
}
|
||||
|
||||
|
||||
/* -( Automatic Targets )-------------------------------------------------- */
|
||||
|
|
|
@ -72,6 +72,11 @@ EOTEXT
|
|||
HarbormasterBuildTarget $build_target) {
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
|
||||
if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
|
||||
$this->logSilencedCall($build, $build_target, pht('Buildkite'));
|
||||
throw new HarbormasterBuildFailureException();
|
||||
}
|
||||
|
||||
$buildable = $build->getBuildable();
|
||||
|
||||
$object = $buildable->getBuildableObject();
|
||||
|
|
|
@ -84,6 +84,11 @@ EOTEXT
|
|||
HarbormasterBuildTarget $build_target) {
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
|
||||
if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
|
||||
$this->logSilencedCall($build, $build_target, pht('CircleCI'));
|
||||
throw new HarbormasterBuildFailureException();
|
||||
}
|
||||
|
||||
$buildable = $build->getBuildable();
|
||||
|
||||
$object = $buildable->getBuildableObject();
|
||||
|
|
|
@ -43,6 +43,12 @@ final class HarbormasterHTTPRequestBuildStepImplementation
|
|||
HarbormasterBuildTarget $build_target) {
|
||||
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
|
||||
if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
|
||||
$this->logSilencedCall($build, $build_target, pht('HTTP Request'));
|
||||
throw new HarbormasterBuildFailureException();
|
||||
}
|
||||
|
||||
$settings = $this->getSettings();
|
||||
$variables = $build_target->getVariables();
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@ final class HarbormasterBuildMessage extends HarbormasterDAO
|
|||
implements PhabricatorPolicyInterface {
|
||||
|
||||
protected $authorPHID;
|
||||
protected $buildTargetPHID;
|
||||
protected $receiverPHID;
|
||||
protected $type;
|
||||
protected $isConsumed;
|
||||
|
||||
private $buildTarget = self::ATTACHABLE;
|
||||
private $receiver = self::ATTACHABLE;
|
||||
|
||||
public static function initializeNewMessage(PhabricatorUser $actor) {
|
||||
$actor_phid = $actor->getPHID();
|
||||
|
@ -34,19 +34,19 @@ final class HarbormasterBuildMessage extends HarbormasterDAO
|
|||
'isConsumed' => 'bool',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_buildtarget' => array(
|
||||
'columns' => array('buildTargetPHID'),
|
||||
'key_receiver' => array(
|
||||
'columns' => array('receiverPHID'),
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
public function getBuildTarget() {
|
||||
return $this->assertAttached($this->buildTarget);
|
||||
public function getReceiver() {
|
||||
return $this->assertAttached($this->receiver);
|
||||
}
|
||||
|
||||
public function attachBuildTarget(HarbormasterBuildTarget $target) {
|
||||
$this->buildTarget = $target;
|
||||
public function attachReceiver($receiver) {
|
||||
$this->receiver = $receiver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -61,17 +61,17 @@ final class HarbormasterBuildMessage extends HarbormasterDAO
|
|||
}
|
||||
|
||||
public function getPolicy($capability) {
|
||||
return $this->getBuildTarget()->getPolicy($capability);
|
||||
return $this->getReceiver()->getPolicy($capability);
|
||||
}
|
||||
|
||||
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||
return $this->getBuildTarget()->hasAutomaticCapability(
|
||||
return $this->getReceiver()->hasAutomaticCapability(
|
||||
$capability,
|
||||
$viewer);
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return pht('Build messages have the same policies as their targets.');
|
||||
return pht('Build messages have the same policies as their receivers.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,53 +15,10 @@ final class HarbormasterBuildable extends HarbormasterDAO
|
|||
private $containerObject = self::ATTACHABLE;
|
||||
private $builds = self::ATTACHABLE;
|
||||
|
||||
const STATUS_BUILDING = 'building';
|
||||
const STATUS_PASSED = 'passed';
|
||||
const STATUS_FAILED = 'failed';
|
||||
|
||||
public static function getBuildableStatusName($status) {
|
||||
$map = self::getBuildStatusMap();
|
||||
return idx($map, $status, pht('Unknown ("%s")', $status));
|
||||
}
|
||||
|
||||
public static function getBuildStatusMap() {
|
||||
return array(
|
||||
self::STATUS_BUILDING => pht('Building'),
|
||||
self::STATUS_PASSED => pht('Passed'),
|
||||
self::STATUS_FAILED => pht('Failed'),
|
||||
);
|
||||
}
|
||||
|
||||
public static function getBuildableStatusIcon($status) {
|
||||
switch ($status) {
|
||||
case self::STATUS_BUILDING:
|
||||
return PHUIStatusItemView::ICON_RIGHT;
|
||||
case self::STATUS_PASSED:
|
||||
return PHUIStatusItemView::ICON_ACCEPT;
|
||||
case self::STATUS_FAILED:
|
||||
return PHUIStatusItemView::ICON_REJECT;
|
||||
default:
|
||||
return PHUIStatusItemView::ICON_QUESTION;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getBuildableStatusColor($status) {
|
||||
switch ($status) {
|
||||
case self::STATUS_BUILDING:
|
||||
return 'blue';
|
||||
case self::STATUS_PASSED:
|
||||
return 'green';
|
||||
case self::STATUS_FAILED:
|
||||
return 'red';
|
||||
default:
|
||||
return 'bluegrey';
|
||||
}
|
||||
}
|
||||
|
||||
public static function initializeNewBuildable(PhabricatorUser $actor) {
|
||||
return id(new HarbormasterBuildable())
|
||||
->setIsManualBuildable(0)
|
||||
->setBuildableStatus(self::STATUS_BUILDING);
|
||||
->setBuildableStatus(HarbormasterBuildableStatus::STATUS_PREPARING);
|
||||
}
|
||||
|
||||
public function getMonogram() {
|
||||
|
@ -250,6 +207,59 @@ final class HarbormasterBuildable extends HarbormasterDAO
|
|||
}
|
||||
|
||||
|
||||
/* -( Status )------------------------------------------------------------- */
|
||||
|
||||
|
||||
public function getBuildableStatusObject() {
|
||||
$status = $this->getBuildableStatus();
|
||||
return HarbormasterBuildableStatus::newBuildableStatusObject($status);
|
||||
}
|
||||
|
||||
public function getStatusIcon() {
|
||||
return $this->getBuildableStatusObject()->getIcon();
|
||||
}
|
||||
|
||||
public function getStatusDisplayName() {
|
||||
return $this->getBuildableStatusObject()->getDisplayName();
|
||||
}
|
||||
|
||||
public function getStatusColor() {
|
||||
return $this->getBuildableStatusObject()->getColor();
|
||||
}
|
||||
|
||||
public function isPreparing() {
|
||||
return $this->getBuildableStatusObject()->isPreparing();
|
||||
}
|
||||
|
||||
|
||||
/* -( Messages )----------------------------------------------------------- */
|
||||
|
||||
|
||||
public function sendMessage(
|
||||
PhabricatorUser $viewer,
|
||||
$message_type,
|
||||
$queue_update) {
|
||||
|
||||
$message = HarbormasterBuildMessage::initializeNewMessage($viewer)
|
||||
->setReceiverPHID($this->getPHID())
|
||||
->setType($message_type)
|
||||
->save();
|
||||
|
||||
if ($queue_update) {
|
||||
PhabricatorWorker::scheduleTask(
|
||||
'HarbormasterBuildWorker',
|
||||
array(
|
||||
'buildablePHID' => $this->getPHID(),
|
||||
),
|
||||
array(
|
||||
'objectPHID' => $this->getPHID(),
|
||||
));
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -108,9 +108,7 @@ final class HarbormasterBuild extends HarbormasterDAO
|
|||
}
|
||||
|
||||
public function isBuilding() {
|
||||
return
|
||||
$this->getBuildStatus() === HarbormasterBuildStatus::STATUS_PENDING ||
|
||||
$this->getBuildStatus() === HarbormasterBuildStatus::STATUS_BUILDING;
|
||||
return $this->getBuildStatusObject()->isBuilding();
|
||||
}
|
||||
|
||||
public function isAutobuild() {
|
||||
|
@ -173,13 +171,15 @@ final class HarbormasterBuild extends HarbormasterDAO
|
|||
}
|
||||
|
||||
public function isComplete() {
|
||||
return in_array(
|
||||
$this->getBuildStatus(),
|
||||
HarbormasterBuildStatus::getCompletedStatusConstants());
|
||||
return $this->getBuildStatusObject()->isComplete();
|
||||
}
|
||||
|
||||
public function isPaused() {
|
||||
return ($this->getBuildStatus() == HarbormasterBuildStatus::STATUS_PAUSED);
|
||||
return $this->getBuildStatusObject()->isPaused();
|
||||
}
|
||||
|
||||
public function isPassed() {
|
||||
return $this->getBuildStatusObject()->isPassed();
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
|
@ -187,6 +187,11 @@ final class HarbormasterBuild extends HarbormasterDAO
|
|||
return "/harbormaster/build/{$id}/";
|
||||
}
|
||||
|
||||
protected function getBuildStatusObject() {
|
||||
$status_key = $this->getBuildStatus();
|
||||
return HarbormasterBuildStatus::newBuildStatusObject($status_key);
|
||||
}
|
||||
|
||||
|
||||
/* -( Build Commands )----------------------------------------------------- */
|
||||
|
||||
|
|
|
@ -17,12 +17,21 @@ final class HarbormasterBuildWorker extends HarbormasterWorker {
|
|||
|
||||
protected function doWork() {
|
||||
$viewer = $this->getViewer();
|
||||
$build = $this->loadBuild();
|
||||
|
||||
id(new HarbormasterBuildEngine())
|
||||
->setViewer($viewer)
|
||||
->setBuild($build)
|
||||
->continueBuild();
|
||||
$engine = id(new HarbormasterBuildEngine())
|
||||
->setViewer($viewer);
|
||||
|
||||
$data = $this->getTaskData();
|
||||
$build_id = idx($data, 'buildID');
|
||||
|
||||
if ($build_id) {
|
||||
$build = $this->loadBuild();
|
||||
$engine->setBuild($build);
|
||||
$engine->continueBuild();
|
||||
} else {
|
||||
$buildable = $this->loadBuildable();
|
||||
$engine->updateBuildable($buildable);
|
||||
}
|
||||
}
|
||||
|
||||
private function loadBuild() {
|
||||
|
@ -42,4 +51,21 @@ final class HarbormasterBuildWorker extends HarbormasterWorker {
|
|||
return $build;
|
||||
}
|
||||
|
||||
private function loadBuildable() {
|
||||
$data = $this->getTaskData();
|
||||
$phid = idx($data, 'buildablePHID');
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$buildable = id(new HarbormasterBuildableQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($phid))
|
||||
->executeOne();
|
||||
if (!$buildable) {
|
||||
throw new PhabricatorWorkerPermanentFailureException(
|
||||
pht('Invalid buildable PHID "%s".', $phid));
|
||||
}
|
||||
|
||||
return $buildable;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,10 @@ final class HeraldCallWebhookAction extends HeraldAction {
|
|||
}
|
||||
|
||||
public function supportsObject($object) {
|
||||
if (!$this->getAdapter()->supportsWebhooks()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1211,6 +1211,11 @@ abstract class HeraldAdapter extends Phobject {
|
|||
/* -( Webhooks )----------------------------------------------------------- */
|
||||
|
||||
|
||||
public function supportsWebhooks() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
final public function queueWebhook($webhook_phid, $rule_phid) {
|
||||
$this->webhookMap[$webhook_phid][] = $rule_phid;
|
||||
return $this;
|
||||
|
|
|
@ -32,6 +32,13 @@ final class HeraldWebhookWorker
|
|||
$status));
|
||||
}
|
||||
|
||||
// If we're in silent mode, permanently fail the webhook request and then
|
||||
// return to complete this task.
|
||||
if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
|
||||
$this->failRequest($request, 'hook', 'silent');
|
||||
return;
|
||||
}
|
||||
|
||||
$hook = $request->getWebhook();
|
||||
|
||||
if ($hook->isDisabled()) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorQuickSearchApplicationEngineExtension
|
||||
extends PhabricatorQuickSearchEngineExtension {
|
||||
final class PhabricatorDatasourceApplicationEngineExtension
|
||||
extends PhabricatorDatasourceEngineExtension {
|
||||
|
||||
public function newQuickSearchDatasources() {
|
||||
return array(
|
|
@ -64,4 +64,8 @@ final class PhabricatorMailOutboundMailHeraldAdapter
|
|||
return pht('Mail %d', $this->getObject()->getID());
|
||||
}
|
||||
|
||||
public function supportsWebhooks() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ final class PhabricatorMetaMTAMailBody extends Phobject {
|
|||
private $attachments = array();
|
||||
|
||||
private $viewer;
|
||||
private $contextObject;
|
||||
|
||||
public function getViewer() {
|
||||
return $this->viewer;
|
||||
|
@ -23,6 +24,16 @@ final class PhabricatorMetaMTAMailBody extends Phobject {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setContextObject($context_object) {
|
||||
$this->contextObject = $context_object;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContextObject() {
|
||||
return $this->contextObject;
|
||||
}
|
||||
|
||||
|
||||
/* -( Composition )-------------------------------------------------------- */
|
||||
|
||||
|
||||
|
@ -45,9 +56,9 @@ final class PhabricatorMetaMTAMailBody extends Phobject {
|
|||
|
||||
public function addRemarkupSection($header, $text) {
|
||||
try {
|
||||
$engine = PhabricatorMarkupEngine::newMarkupEngine(array());
|
||||
$engine->setConfig('viewer', $this->getViewer());
|
||||
$engine->setMode(PhutilRemarkupEngine::MODE_TEXT);
|
||||
$engine = $this->newMarkupEngine()
|
||||
->setMode(PhutilRemarkupEngine::MODE_TEXT);
|
||||
|
||||
$styled_text = $engine->markupText($text);
|
||||
$this->addPlaintextSection($header, $styled_text);
|
||||
} catch (Exception $ex) {
|
||||
|
@ -56,12 +67,9 @@ final class PhabricatorMetaMTAMailBody extends Phobject {
|
|||
}
|
||||
|
||||
try {
|
||||
$mail_engine = PhabricatorMarkupEngine::newMarkupEngine(array());
|
||||
$mail_engine->setConfig('viewer', $this->getViewer());
|
||||
$mail_engine->setMode(PhutilRemarkupEngine::MODE_HTML_MAIL);
|
||||
$mail_engine->setConfig(
|
||||
'uri.base',
|
||||
PhabricatorEnv::getProductionURI('/'));
|
||||
$mail_engine = $this->newMarkupEngine()
|
||||
->setMode(PhutilRemarkupEngine::MODE_HTML_MAIL);
|
||||
|
||||
$html = $mail_engine->markupText($text);
|
||||
$this->addHTMLSection($header, $html);
|
||||
} catch (Exception $ex) {
|
||||
|
@ -215,4 +223,19 @@ final class PhabricatorMetaMTAMailBody extends Phobject {
|
|||
private function indent($text) {
|
||||
return rtrim(" ".str_replace("\n", "\n ", $text));
|
||||
}
|
||||
|
||||
|
||||
private function newMarkupEngine() {
|
||||
$engine = PhabricatorMarkupEngine::newMarkupEngine(array())
|
||||
->setConfig('viewer', $this->getViewer())
|
||||
->setConfig('uri.base', PhabricatorEnv::getProductionURI('/'));
|
||||
|
||||
$context = $this->getContextObject();
|
||||
if ($context) {
|
||||
$engine->setConfig('contextObject', $context);
|
||||
}
|
||||
|
||||
return $engine;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorPeopleDatasourceEngineExtension
|
||||
extends PhabricatorDatasourceEngineExtension {
|
||||
|
||||
public function newQuickSearchDatasources() {
|
||||
return array(
|
||||
new PhabricatorPeopleDatasource(),
|
||||
);
|
||||
}
|
||||
|
||||
public function newJumpURI($query) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
// Send "u" to the user directory.
|
||||
if (preg_match('/^u\z/i', $query)) {
|
||||
return '/people/';
|
||||
}
|
||||
|
||||
// Send "u <string>" to the user's profile page.
|
||||
$matches = null;
|
||||
if (preg_match('/^u\s+(.+)\z/i', $query, $matches)) {
|
||||
$raw_query = $matches[1];
|
||||
|
||||
// TODO: We could test that this is a valid username and jump to
|
||||
// a search in the user directory if it isn't.
|
||||
|
||||
return urisprintf(
|
||||
'/p/%s/',
|
||||
$raw_query);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorPeopleQuickSearchEngineExtension
|
||||
extends PhabricatorQuickSearchEngineExtension {
|
||||
|
||||
public function newQuickSearchDatasources() {
|
||||
return array(
|
||||
new PhabricatorPeopleDatasource(),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class PhrictionContentSearchConduitAPIMethod
|
||||
extends PhabricatorSearchEngineAPIMethod {
|
||||
|
||||
public function getAPIMethodName() {
|
||||
return 'phriction.content.search';
|
||||
}
|
||||
|
||||
public function newSearchEngine() {
|
||||
return new PhrictionContentSearchEngine();
|
||||
}
|
||||
|
||||
public function getMethodSummary() {
|
||||
return pht('Read information about Phriction document history.');
|
||||
}
|
||||
|
||||
}
|
|
@ -57,7 +57,7 @@ final class PhrictionCreateConduitAPIMethod extends PhrictionConduitAPIMethod {
|
|||
->setActor($request->getUser())
|
||||
->setContentSource($request->newContentSource())
|
||||
->setContinueOnNoEffect(true)
|
||||
->setDescription($request->getValue('description'));
|
||||
->setDescription((string)$request->getValue('description'));
|
||||
|
||||
try {
|
||||
$editor->applyTransactions($doc, $xactions);
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class PhrictionDocumentSearchConduitAPIMethod
|
||||
extends PhabricatorSearchEngineAPIMethod {
|
||||
|
||||
public function getAPIMethodName() {
|
||||
return 'phriction.document.search';
|
||||
}
|
||||
|
||||
public function newSearchEngine() {
|
||||
return new PhrictionDocumentSearchEngine();
|
||||
}
|
||||
|
||||
public function getMethodSummary() {
|
||||
return pht('Read information about Phriction documents.');
|
||||
}
|
||||
|
||||
}
|
|
@ -52,7 +52,7 @@ final class PhrictionEditConduitAPIMethod extends PhrictionConduitAPIMethod {
|
|||
->setActor($request->getUser())
|
||||
->setContentSource($request->newContentSource())
|
||||
->setContinueOnNoEffect(true)
|
||||
->setDescription($request->getValue('description'));
|
||||
->setDescription((string)$request->getValue('description'));
|
||||
|
||||
try {
|
||||
$editor->applyTransactions($doc, $xactions);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue