Merge branch 'master' into blender-tweaks

This commit is contained in:
2018-12-04 10:29:38 +01:00
305 changed files with 6071 additions and 2728 deletions

1
bin/herald Symbolic link
View File

@@ -0,0 +1 @@
../scripts/setup/manage_herald.php

View File

@@ -9,10 +9,10 @@ return array(
'names' => array(
'conpherence.pkg.css' => 'e68cf1fa',
'conpherence.pkg.js' => '15191c65',
'core.pkg.css' => '5efaf405',
'core.pkg.js' => 'b5a949ca',
'core.pkg.css' => '7489ba0d',
'core.pkg.js' => '4bde473b',
'differential.pkg.css' => '06dc617c',
'differential.pkg.js' => 'c1cfa143',
'differential.pkg.js' => 'ef0b989b',
'diffusion.pkg.css' => 'a2d17c7d',
'diffusion.pkg.js' => '6134c5a1',
'maniphest.pkg.css' => '4845691a',
@@ -32,7 +32,7 @@ return array(
'rsrc/css/aphront/phabricator-nav-view.css' => '694d7723',
'rsrc/css/aphront/table-view.css' => '8c9bbafe',
'rsrc/css/aphront/tokenizer.css' => '15d5ff71',
'rsrc/css/aphront/tooltip.css' => '173b9431',
'rsrc/css/aphront/tooltip.css' => 'cb1397a4',
'rsrc/css/aphront/typeahead-browse.css' => 'f2818435',
'rsrc/css/aphront/typeahead.css' => 'a4a21016',
'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af',
@@ -155,7 +155,7 @@ return array(
'rsrc/css/phui/phui-form.css' => '7aaa04e3',
'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f',
'rsrc/css/phui/phui-header-view.css' => '1ba8b707',
'rsrc/css/phui/phui-hovercard.css' => 'f0592bcf',
'rsrc/css/phui/phui-hovercard.css' => '4a484541',
'rsrc/css/phui/phui-icon-set-selector.css' => '87db8fee',
'rsrc/css/phui/phui-icon.css' => 'cf24ceec',
'rsrc/css/phui/phui-image-mask.css' => 'a8498f9c',
@@ -209,13 +209,13 @@ return array(
'rsrc/externals/font/lato/lato-regular.ttf' => 'e270165b',
'rsrc/externals/font/lato/lato-regular.woff' => '13d39fe2',
'rsrc/externals/font/lato/lato-regular.woff2' => '57a9f742',
'rsrc/externals/javelin/core/Event.js' => '2ee659ce',
'rsrc/externals/javelin/core/Event.js' => 'ef7e057f',
'rsrc/externals/javelin/core/Stratcom.js' => '327f418a',
'rsrc/externals/javelin/core/__tests__/event-stop-and-kill.js' => '717554e4',
'rsrc/externals/javelin/core/__tests__/install.js' => 'c432ee85',
'rsrc/externals/javelin/core/__tests__/stratcom.js' => '88bf7313',
'rsrc/externals/javelin/core/__tests__/util.js' => 'e251703d',
'rsrc/externals/javelin/core/init.js' => '638a4e2b',
'rsrc/externals/javelin/core/init.js' => '8d83d2a1',
'rsrc/externals/javelin/core/init_node.js' => 'c234aded',
'rsrc/externals/javelin/core/install.js' => '05270951',
'rsrc/externals/javelin/core/util.js' => '93cc50d6',
@@ -375,7 +375,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' => 'e0b984b5',
'rsrc/js/application/diff/DiffChangesetList.js' => '0a84bcc1',
'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',
@@ -424,8 +424,7 @@ return array(
'rsrc/js/application/repository/repository-crossreference.js' => '9a860428',
'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072',
'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08',
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f',
'rsrc/js/application/transactions/behavior-comment-actions.js' => '038bf27f',
'rsrc/js/application/transactions/behavior-comment-actions.js' => '59e27e74',
'rsrc/js/application/transactions/behavior-reorder-configs.js' => 'd7a74243',
'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96',
'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '8f29b364',
@@ -524,7 +523,7 @@ return array(
'aphront-panel-view-css' => '8427b78d',
'aphront-table-view-css' => '8c9bbafe',
'aphront-tokenizer-control-css' => '15d5ff71',
'aphront-tooltip-css' => '173b9431',
'aphront-tooltip-css' => 'cb1397a4',
'aphront-typeahead-control-css' => 'a4a21016',
'application-search-view-css' => '787f5b76',
'auth-css' => '0877ed6e',
@@ -577,7 +576,7 @@ return array(
'javelin-behavior-bulk-job-reload' => 'edf8a145',
'javelin-behavior-calendar-month-view' => 'fe33e256',
'javelin-behavior-choose-control' => '327a00d1',
'javelin-behavior-comment-actions' => '038bf27f',
'javelin-behavior-comment-actions' => '59e27e74',
'javelin-behavior-config-reorder-fields' => 'b6993408',
'javelin-behavior-conpherence-menu' => '4047cd35',
'javelin-behavior-conpherence-participant-pane' => 'd057e45a',
@@ -676,7 +675,6 @@ return array(
'javelin-behavior-select-content' => 'bf5374ef',
'javelin-behavior-select-on-click' => '4e3e79a6',
'javelin-behavior-setup-check-https' => '491416b3',
'javelin-behavior-slowvote-embed' => '887ad43f',
'javelin-behavior-stripe-payment-form' => 'a6b98425',
'javelin-behavior-test-payment-form' => 'fc91ab6c',
'javelin-behavior-time-typeahead' => '522431f7',
@@ -692,13 +690,13 @@ return array(
'javelin-diffusion-locate-file-source' => '00676f00',
'javelin-dom' => '4976858c',
'javelin-dynval' => 'f6555212',
'javelin-event' => '2ee659ce',
'javelin-event' => 'ef7e057f',
'javelin-fx' => '54b612ba',
'javelin-history' => 'd4505101',
'javelin-install' => '05270951',
'javelin-json' => '69adf288',
'javelin-leader' => '7f243deb',
'javelin-magical-init' => '638a4e2b',
'javelin-magical-init' => '8d83d2a1',
'javelin-mask' => '8a41885b',
'javelin-quicksand' => '6b8ef10b',
'javelin-reactor' => '2b8de964',
@@ -754,7 +752,7 @@ return array(
'phabricator-darkmessage' => 'c48cccdd',
'phabricator-dashboard-css' => 'fe5b1869',
'phabricator-diff-changeset' => 'b49b59d6',
'phabricator-diff-changeset-list' => 'e0b984b5',
'phabricator-diff-changeset-list' => '0a84bcc1',
'phabricator-diff-inline' => 'e83d28f3',
'phabricator-drag-and-drop-file-upload' => '58dea2fa',
'phabricator-draggable-list' => 'bea6e7f4',
@@ -826,7 +824,7 @@ return array(
'phui-head-thing-view-css' => 'fd311e5f',
'phui-header-view-css' => '1ba8b707',
'phui-hovercard' => '1bd28176',
'phui-hovercard-view-css' => 'f0592bcf',
'phui-hovercard-view-css' => '4a484541',
'phui-icon-set-selector-css' => '87db8fee',
'phui-icon-view-css' => 'cf24ceec',
'phui-image-mask-css' => 'a8498f9c',
@@ -908,15 +906,6 @@ return array(
'javelin-behavior',
'javelin-uri',
),
'038bf27f' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-workflow',
'javelin-dom',
'phuix-form-control-view',
'phuix-icon-view',
'javelin-behavior-phabricator-gesture',
),
'040fce04' => array(
'javelin-behavior',
'javelin-request',
@@ -958,6 +947,10 @@ return array(
'javelin-dom',
'javelin-router',
),
'0a84bcc1' => array(
'javelin-install',
'phuix-button-view',
),
'0f764c35' => array(
'javelin-install',
'javelin-util',
@@ -1060,9 +1053,6 @@ return array(
'javelin-install',
'javelin-event',
),
'2ee659ce' => array(
'javelin-install',
),
'31420f77' => array(
'javelin-behavior',
),
@@ -1321,6 +1311,15 @@ return array(
'javelin-vector',
'javelin-dom',
),
'59e27e74' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-workflow',
'javelin-dom',
'phuix-form-control-view',
'phuix-icon-view',
'javelin-behavior-phabricator-gesture',
),
'5c54cbf3' => array(
'javelin-behavior',
'javelin-stratcom',
@@ -1553,12 +1552,6 @@ return array(
'phabricator-keyboard-shortcut',
'javelin-stratcom',
),
'887ad43f' => array(
'javelin-behavior',
'javelin-request',
'javelin-stratcom',
'javelin-dom',
),
'8935deef' => array(
'javelin-install',
'javelin-dom',
@@ -2020,10 +2013,6 @@ return array(
'phuix-icon-view',
'phabricator-prefab',
),
'e0b984b5' => array(
'javelin-install',
'phuix-button-view',
),
'e1d25dfb' => array(
'javelin-behavior',
'javelin-stratcom',
@@ -2105,6 +2094,9 @@ return array(
'javelin-behavior',
'javelin-uri',
),
'ef7e057f' => array(
'javelin-install',
),
'efe49472' => array(
'javelin-install',
'javelin-util',

View File

@@ -45,7 +45,7 @@ foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
queryfx(
$conn_w,
'INSERT INTO %T (boardPHID, columnPHID, objectPHID, sequence)
VALUES %Q',
VALUES %LQ',
id(new PhabricatorProjectColumnPosition())->getTableName(),
$chunk);
}

View File

@@ -12,17 +12,11 @@ $status_map = array(
5 => 'needs-verification',
);
foreach (new LiskMigrationIterator($table) as $commit) {
$status = $commit->getAuditStatus();
if (!isset($status_map[$status])) {
continue;
}
foreach ($status_map as $old_status => $new_status) {
queryfx(
$conn,
'UPDATE %T SET auditStatus = %s WHERE id = %d',
$table->getTableName(),
$status_map[$status],
$commit->getID());
'UPDATE %R SET auditStatus = %s WHERE auditStatus = %s',
$table,
$new_status,
$old_status);
}

View File

@@ -8,19 +8,27 @@ $properties_table = new PhabricatorMetaMTAMailProperties();
$conn = $properties_table->establishConnection('w');
$iterator = new LiskRawMigrationIterator($commit_conn, $commit_name);
foreach ($iterator as $commit) {
$chunks = new PhutilChunkedIterator($iterator, 100);
foreach ($chunks as $chunk) {
$sql = array();
foreach ($chunk as $commit) {
$sql[] = qsprintf(
$conn,
'(%s, %s, %d, %d)',
$commit['phid'],
phutil_json_encode(
array(
'mailKey' => $commit['mailKey'],
)),
PhabricatorTime::getNow(),
PhabricatorTime::getNow());
}
queryfx(
$conn,
'INSERT IGNORE INTO %T
'INSERT IGNORE INTO %R
(objectPHID, mailProperties, dateCreated, dateModified)
VALUES
(%s, %s, %d, %d)',
$properties_table->getTableName(),
$commit['phid'],
phutil_json_encode(
array(
'mailKey' => $commit['mailKey'],
)),
PhabricatorTime::getNow(),
PhabricatorTime::getNow());
VALUES %LQ',
$properties_table,
$sql);
}

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_drydock.drydock_command
ADD properties LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT};

View File

@@ -0,0 +1,2 @@
UPDATE {$NAMESPACE}_drydock.drydock_command
SET properties = '{}' WHERE properties = '';

View File

@@ -0,0 +1,50 @@
<?php
// See T13208. It was previously possible to replace a saved query with another
// saved query, causing loss of the first query. Find projects which have their
// default query set to an invalid query and throw the setting away.
$viewer = PhabricatorUser::getOmnipotentUser();
$table = new PhabricatorProject();
$conn = $table->establishConnection('w');
$iterator = new LiskMigrationIterator($table);
$search_engine = id(new ManiphestTaskSearchEngine())
->setViewer($viewer);
foreach ($iterator as $project) {
$default_filter = $project->getDefaultWorkboardFilter();
if (!strlen($default_filter)) {
continue;
}
if ($search_engine->isBuiltinQuery($default_filter)) {
continue;
}
$saved = id(new PhabricatorSavedQueryQuery())
->setViewer($viewer)
->withQueryKeys(array($default_filter))
->executeOne();
if ($saved) {
continue;
}
$properties = $project->getProperties();
unset($properties['workboard.filter.default']);
queryfx(
$conn,
'UPDATE %T SET properties = %s WHERE id = %d',
$table->getTableName(),
phutil_json_encode($properties),
$project->getID());
echo tsprintf(
"%s\n",
pht(
'Project ("%s") had an invalid query saved as a default workboard '.
'query. The query has been reset. See T13208.',
$project->getDisplayName()));
}

View File

@@ -0,0 +1,14 @@
CREATE TABLE {$NAMESPACE}_repository.repository_syncevent (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARBINARY(64) NOT NULL,
repositoryPHID VARBINARY(64) NOT NULL,
epoch INT UNSIGNED NOT NULL,
devicePHID VARBINARY(64) NOT NULL,
fromDevicePHID VARBINARY(64) NOT NULL,
deviceVersion INT UNSIGNED,
fromDeviceVersion INT UNSIGNED,
resultType VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
resultCode INT UNSIGNED NOT NULL,
syncWait BIGINT UNSIGNED NOT NULL,
properties LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_repository.repository_pushevent
ADD hookWait BIGINT UNSIGNED;

View File

@@ -22,12 +22,12 @@ foreach (new LiskRawMigrationIterator($conn_w, 'file') as $row) {
}
if ($sql) {
foreach (PhabricatorLiskDAO::chunkSQL($sql, ', ') as $chunk) {
foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
queryfx(
$conn_w,
'INSERT INTO %T
(id, mailKey, phid, byteSize, storageEngine, storageFormat,
storageHandle, dateCreated, dateModified, metadata) VALUES %Q '.
storageHandle, dateCreated, dateModified, metadata) VALUES %LQ '.
'ON DUPLICATE KEY UPDATE mailKey = VALUES(mailKey)',
$table_name,
$chunk);

View File

@@ -34,10 +34,10 @@ foreach ($chunk_iter as $chunk) {
continue;
}
foreach (PhabricatorLiskDAO::chunkSQL($sql, ', ') as $sql_chunk) {
foreach (PhabricatorLiskDAO::chunkSQL($sql) as $sql_chunk) {
queryfx(
$conn_w,
'INSERT IGNORE INTO %T (id, phid) VALUES %Q
'INSERT IGNORE INTO %T (id, phid) VALUES %LQ
ON DUPLICATE KEY UPDATE phid = VALUES(phid)',
$diff_table->getTableName(),
$sql_chunk);

View File

@@ -17,6 +17,8 @@
// subclasses of PhabricatorConfigSiteSource to read it and build an instance
// environment.
$hook_start = microtime(true);
if ($argc > 1) {
$context = $argv[1];
$context = explode(':', $context, 2);
@@ -35,7 +37,8 @@ if ($argc < 2) {
throw new Exception(pht('usage: commit-hook <repository>'));
}
$engine = new DiffusionCommitHookEngine();
$engine = id(new DiffusionCommitHookEngine())
->setStartTime($hook_start);
$repository = id(new PhabricatorRepositoryQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
@@ -204,23 +207,23 @@ try {
+---------------------------------------------------------------+
| * * * PUSH REJECTED BY EVIL DRAGON BUREAUCRATS * * * |
+---------------------------------------------------------------+
\
\ ^ /^
\ / \ // \
\ |\___/| / \// .\
\ /V V \__ / // | \ \ *----*
/ / \/_/ // | \ \ \ |
@___@` \/_ // | \ \ \/\ \
0/0/| \/_ // | \ \ \ \
0/0/0/0/| \/// | \ \ | |
0/0/0/0/0/_|_ / ( // | \ _\ | /
0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / /
,-} _ *-.|.-~-. .~ ~
\ \__/ `/\ / ~-. _ .-~ /
\____(Oo) *. } { /
( (--) .----~-.\ \-` .~
//__\\\\ \ DENIED! ///.----..< \ _ -~
// \\\\ ///-._ _ _ _ _ _ _{^ - - - - ~
\
\ ^ /^
\ / \ // \
\ |\___/| / \// .\
\ /V V \__ / // | \ \ *----*
/ / \/_/ // | \ \ \ |
@___@` \/_ // | \ \ \/\ \
0/0/| \/_ // | \ \ \ \
0/0/0/0/| \/// | \ \ | |
0/0/0/0/0/_|_ / ( // | \ _\ | /
0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / /
,-} _ *-.|.-~-. .~ ~
* \__/ `/\ / ~-. _ .-~ /
\____(Oo) *. } { /
( (..) .----~-.\ \-` .~
//___\\\\ \ DENIED! ///.----..< \ _ -~
// \\\\ ///-._ _ _ _ _ _ _{^ - - - - ~
EOTXT
);

21
scripts/setup/manage_herald.php Executable file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/env php
<?php
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/init/init-script.php';
$args = new PhutilArgumentParser($argv);
$args->setTagline(pht('manage Herald'));
$args->setSynopsis(<<<EOSYNOPSIS
**herald** __command__ [__options__]
Manage and debug Herald.
EOSYNOPSIS
);
$args->parseStandardArguments();
$workflows = id(new PhutilClassMapQuery())
->setAncestorClass('HeraldManagementWorkflow')
->execute();
$workflows[] = new PhutilHelpArgumentWorkflow();
$args->parseWorkflows($workflows);

View File

@@ -307,7 +307,7 @@ try {
$ssh_log->setData(
array(
'c' => $err,
'T' => (int)(1000000 * (microtime(true) - $ssh_start_time)),
'T' => phutil_microseconds_since($ssh_start_time),
));
exit($err);

View File

@@ -839,6 +839,7 @@ phutil_register_library_map(array(
'DiffusionLookSoonConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionLookSoonConduitAPIMethod.php',
'DiffusionLowLevelCommitFieldsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelCommitFieldsQuery.php',
'DiffusionLowLevelCommitQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelCommitQuery.php',
'DiffusionLowLevelFilesizeQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelFilesizeQuery.php',
'DiffusionLowLevelGitRefQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php',
'DiffusionLowLevelMercurialBranchesQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialBranchesQuery.php',
'DiffusionLowLevelMercurialPathsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php',
@@ -949,10 +950,16 @@ phutil_register_library_map(array(
'DiffusionRepositoryHistoryManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryHistoryManagementPanel.php',
'DiffusionRepositoryIdentityEditor' => 'applications/diffusion/editor/DiffusionRepositoryIdentityEditor.php',
'DiffusionRepositoryIdentitySearchEngine' => 'applications/diffusion/query/DiffusionRepositoryIdentitySearchEngine.php',
'DiffusionRepositoryLimitsManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryLimitsManagementPanel.php',
'DiffusionRepositoryListController' => 'applications/diffusion/controller/DiffusionRepositoryListController.php',
'DiffusionRepositoryManageController' => 'applications/diffusion/controller/DiffusionRepositoryManageController.php',
'DiffusionRepositoryManagePanelsController' => 'applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php',
'DiffusionRepositoryManagementBuildsPanelGroup' => 'applications/diffusion/management/DiffusionRepositoryManagementBuildsPanelGroup.php',
'DiffusionRepositoryManagementIntegrationsPanelGroup' => 'applications/diffusion/management/DiffusionRepositoryManagementIntegrationsPanelGroup.php',
'DiffusionRepositoryManagementMainPanelGroup' => 'applications/diffusion/management/DiffusionRepositoryManagementMainPanelGroup.php',
'DiffusionRepositoryManagementOtherPanelGroup' => 'applications/diffusion/management/DiffusionRepositoryManagementOtherPanelGroup.php',
'DiffusionRepositoryManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryManagementPanel.php',
'DiffusionRepositoryManagementPanelGroup' => 'applications/diffusion/management/DiffusionRepositoryManagementPanelGroup.php',
'DiffusionRepositoryPath' => 'applications/diffusion/data/DiffusionRepositoryPath.php',
'DiffusionRepositoryPoliciesManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryPoliciesManagementPanel.php',
'DiffusionRepositoryProfilePictureController' => 'applications/diffusion/controller/DiffusionRepositoryProfilePictureController.php',
@@ -992,6 +999,9 @@ phutil_register_library_map(array(
'DiffusionSymbolController' => 'applications/diffusion/controller/DiffusionSymbolController.php',
'DiffusionSymbolDatasource' => 'applications/diffusion/typeahead/DiffusionSymbolDatasource.php',
'DiffusionSymbolQuery' => 'applications/diffusion/query/DiffusionSymbolQuery.php',
'DiffusionSyncLogListController' => 'applications/diffusion/controller/DiffusionSyncLogListController.php',
'DiffusionSyncLogListView' => 'applications/diffusion/view/DiffusionSyncLogListView.php',
'DiffusionSyncLogSearchEngine' => 'applications/diffusion/query/DiffusionSyncLogSearchEngine.php',
'DiffusionTagListController' => 'applications/diffusion/controller/DiffusionTagListController.php',
'DiffusionTagListView' => 'applications/diffusion/view/DiffusionTagListView.php',
'DiffusionTagTableView' => 'applications/diffusion/view/DiffusionTagTableView.php',
@@ -1146,6 +1156,7 @@ phutil_register_library_map(array(
'DrydockLeaseReclaimLogType' => 'applications/drydock/logtype/DrydockLeaseReclaimLogType.php',
'DrydockLeaseReleaseController' => 'applications/drydock/controller/DrydockLeaseReleaseController.php',
'DrydockLeaseReleasedLogType' => 'applications/drydock/logtype/DrydockLeaseReleasedLogType.php',
'DrydockLeaseSearchConduitAPIMethod' => 'applications/drydock/conduit/DrydockLeaseSearchConduitAPIMethod.php',
'DrydockLeaseSearchEngine' => 'applications/drydock/query/DrydockLeaseSearchEngine.php',
'DrydockLeaseStatus' => 'applications/drydock/constants/DrydockLeaseStatus.php',
'DrydockLeaseUpdateWorker' => 'applications/drydock/worker/DrydockLeaseUpdateWorker.php',
@@ -1325,6 +1336,7 @@ phutil_register_library_map(array(
'HarbormasterBuildPlanNameNgrams' => 'applications/harbormaster/storage/configuration/HarbormasterBuildPlanNameNgrams.php',
'HarbormasterBuildPlanPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildPlanPHIDType.php',
'HarbormasterBuildPlanQuery' => 'applications/harbormaster/query/HarbormasterBuildPlanQuery.php',
'HarbormasterBuildPlanSearchAPIMethod' => 'applications/harbormaster/conduit/HarbormasterBuildPlanSearchAPIMethod.php',
'HarbormasterBuildPlanSearchEngine' => 'applications/harbormaster/query/HarbormasterBuildPlanSearchEngine.php',
'HarbormasterBuildPlanTransaction' => 'applications/harbormaster/storage/configuration/HarbormasterBuildPlanTransaction.php',
'HarbormasterBuildPlanTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildPlanTransactionQuery.php',
@@ -1348,6 +1360,7 @@ phutil_register_library_map(array(
'HarbormasterBuildTarget' => 'applications/harbormaster/storage/build/HarbormasterBuildTarget.php',
'HarbormasterBuildTargetPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildTargetPHIDType.php',
'HarbormasterBuildTargetQuery' => 'applications/harbormaster/query/HarbormasterBuildTargetQuery.php',
'HarbormasterBuildTargetSearchEngine' => 'applications/harbormaster/query/HarbormasterBuildTargetSearchEngine.php',
'HarbormasterBuildTransaction' => 'applications/harbormaster/storage/HarbormasterBuildTransaction.php',
'HarbormasterBuildTransactionEditor' => 'applications/harbormaster/editor/HarbormasterBuildTransactionEditor.php',
'HarbormasterBuildTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildTransactionQuery.php',
@@ -1362,6 +1375,7 @@ phutil_register_library_map(array(
'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php',
'HarbormasterBuildablePHIDType' => 'applications/harbormaster/phid/HarbormasterBuildablePHIDType.php',
'HarbormasterBuildableQuery' => 'applications/harbormaster/query/HarbormasterBuildableQuery.php',
'HarbormasterBuildableSearchAPIMethod' => 'applications/harbormaster/conduit/HarbormasterBuildableSearchAPIMethod.php',
'HarbormasterBuildableSearchEngine' => 'applications/harbormaster/query/HarbormasterBuildableSearchEngine.php',
'HarbormasterBuildableStatus' => 'applications/harbormaster/constants/HarbormasterBuildableStatus.php',
'HarbormasterBuildableTransaction' => 'applications/harbormaster/storage/HarbormasterBuildableTransaction.php',
@@ -1427,6 +1441,7 @@ phutil_register_library_map(array(
'HarbormasterStepEditController' => 'applications/harbormaster/controller/HarbormasterStepEditController.php',
'HarbormasterStepViewController' => 'applications/harbormaster/controller/HarbormasterStepViewController.php',
'HarbormasterTargetEngine' => 'applications/harbormaster/engine/HarbormasterTargetEngine.php',
'HarbormasterTargetSearchAPIMethod' => 'applications/harbormaster/conduit/HarbormasterTargetSearchAPIMethod.php',
'HarbormasterTargetWorker' => 'applications/harbormaster/worker/HarbormasterTargetWorker.php',
'HarbormasterTestBuildStepGroup' => 'applications/harbormaster/stepgroup/HarbormasterTestBuildStepGroup.php',
'HarbormasterThrowExceptionBuildStep' => 'applications/harbormaster/step/HarbormasterThrowExceptionBuildStep.php',
@@ -1483,6 +1498,7 @@ phutil_register_library_map(array(
'HeraldInvalidConditionException' => 'applications/herald/engine/exception/HeraldInvalidConditionException.php',
'HeraldMailableState' => 'applications/herald/state/HeraldMailableState.php',
'HeraldManageGlobalRulesCapability' => 'applications/herald/capability/HeraldManageGlobalRulesCapability.php',
'HeraldManagementWorkflow' => 'applications/herald/management/HeraldManagementWorkflow.php',
'HeraldManiphestTaskAdapter' => 'applications/maniphest/herald/HeraldManiphestTaskAdapter.php',
'HeraldNewController' => 'applications/herald/controller/HeraldNewController.php',
'HeraldNewObjectField' => 'applications/herald/field/HeraldNewObjectField.php',
@@ -1532,6 +1548,7 @@ phutil_register_library_map(array(
'HeraldSupportActionGroup' => 'applications/herald/action/HeraldSupportActionGroup.php',
'HeraldSupportFieldGroup' => 'applications/herald/field/HeraldSupportFieldGroup.php',
'HeraldTestConsoleController' => 'applications/herald/controller/HeraldTestConsoleController.php',
'HeraldTestManagementWorkflow' => 'applications/herald/management/HeraldTestManagementWorkflow.php',
'HeraldTextFieldValue' => 'applications/herald/value/HeraldTextFieldValue.php',
'HeraldTokenizerFieldValue' => 'applications/herald/value/HeraldTokenizerFieldValue.php',
'HeraldTransactionQuery' => 'applications/herald/query/HeraldTransactionQuery.php',
@@ -4073,8 +4090,13 @@ phutil_register_library_map(array(
'PhabricatorRemarkupUIExample' => 'applications/uiexample/examples/PhabricatorRemarkupUIExample.php',
'PhabricatorRepositoriesSetupCheck' => 'applications/config/check/PhabricatorRepositoriesSetupCheck.php',
'PhabricatorRepository' => 'applications/repository/storage/PhabricatorRepository.php',
'PhabricatorRepositoryActivateTransaction' => 'applications/repository/xaction/PhabricatorRepositoryActivateTransaction.php',
'PhabricatorRepositoryAuditRequest' => 'applications/repository/storage/PhabricatorRepositoryAuditRequest.php',
'PhabricatorRepositoryAutocloseOnlyTransaction' => 'applications/repository/xaction/PhabricatorRepositoryAutocloseOnlyTransaction.php',
'PhabricatorRepositoryAutocloseTransaction' => 'applications/repository/xaction/PhabricatorRepositoryAutocloseTransaction.php',
'PhabricatorRepositoryBlueprintsTransaction' => 'applications/repository/xaction/PhabricatorRepositoryBlueprintsTransaction.php',
'PhabricatorRepositoryBranch' => 'applications/repository/storage/PhabricatorRepositoryBranch.php',
'PhabricatorRepositoryCallsignTransaction' => 'applications/repository/xaction/PhabricatorRepositoryCallsignTransaction.php',
'PhabricatorRepositoryCommit' => 'applications/repository/storage/PhabricatorRepositoryCommit.php',
'PhabricatorRepositoryCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryCommitChangeParserWorker.php',
'PhabricatorRepositoryCommitData' => 'applications/repository/storage/PhabricatorRepositoryCommitData.php',
@@ -4087,12 +4109,19 @@ phutil_register_library_map(array(
'PhabricatorRepositoryCommitRef' => 'applications/repository/engine/PhabricatorRepositoryCommitRef.php',
'PhabricatorRepositoryCommitTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryCommitTestCase.php',
'PhabricatorRepositoryConfigOptions' => 'applications/repository/config/PhabricatorRepositoryConfigOptions.php',
'PhabricatorRepositoryCopyTimeLimitTransaction' => 'applications/repository/xaction/PhabricatorRepositoryCopyTimeLimitTransaction.php',
'PhabricatorRepositoryDAO' => 'applications/repository/storage/PhabricatorRepositoryDAO.php',
'PhabricatorRepositoryDangerousTransaction' => 'applications/repository/xaction/PhabricatorRepositoryDangerousTransaction.php',
'PhabricatorRepositoryDefaultBranchTransaction' => 'applications/repository/xaction/PhabricatorRepositoryDefaultBranchTransaction.php',
'PhabricatorRepositoryDescriptionTransaction' => 'applications/repository/xaction/PhabricatorRepositoryDescriptionTransaction.php',
'PhabricatorRepositoryDestructibleCodex' => 'applications/repository/codex/PhabricatorRepositoryDestructibleCodex.php',
'PhabricatorRepositoryDiscoveryEngine' => 'applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php',
'PhabricatorRepositoryEditor' => 'applications/repository/editor/PhabricatorRepositoryEditor.php',
'PhabricatorRepositoryEncodingTransaction' => 'applications/repository/xaction/PhabricatorRepositoryEncodingTransaction.php',
'PhabricatorRepositoryEngine' => 'applications/repository/engine/PhabricatorRepositoryEngine.php',
'PhabricatorRepositoryEnormousTransaction' => 'applications/repository/xaction/PhabricatorRepositoryEnormousTransaction.php',
'PhabricatorRepositoryFerretEngine' => 'applications/repository/search/PhabricatorRepositoryFerretEngine.php',
'PhabricatorRepositoryFilesizeLimitTransaction' => 'applications/repository/xaction/PhabricatorRepositoryFilesizeLimitTransaction.php',
'PhabricatorRepositoryFulltextEngine' => 'applications/repository/search/PhabricatorRepositoryFulltextEngine.php',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php',
@@ -4135,6 +4164,8 @@ phutil_register_library_map(array(
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryMercurialCommitMessageParserWorker.php',
'PhabricatorRepositoryMirror' => 'applications/repository/storage/PhabricatorRepositoryMirror.php',
'PhabricatorRepositoryMirrorEngine' => 'applications/repository/engine/PhabricatorRepositoryMirrorEngine.php',
'PhabricatorRepositoryNameTransaction' => 'applications/repository/xaction/PhabricatorRepositoryNameTransaction.php',
'PhabricatorRepositoryNotifyTransaction' => 'applications/repository/xaction/PhabricatorRepositoryNotifyTransaction.php',
'PhabricatorRepositoryOldRef' => 'applications/repository/storage/PhabricatorRepositoryOldRef.php',
'PhabricatorRepositoryParsedChange' => 'applications/repository/data/PhabricatorRepositoryParsedChange.php',
'PhabricatorRepositoryPullEngine' => 'applications/repository/engine/PhabricatorRepositoryPullEngine.php',
@@ -4151,6 +4182,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryPushLogQuery' => 'applications/repository/query/PhabricatorRepositoryPushLogQuery.php',
'PhabricatorRepositoryPushLogSearchEngine' => 'applications/repository/query/PhabricatorRepositoryPushLogSearchEngine.php',
'PhabricatorRepositoryPushMailWorker' => 'applications/repository/worker/PhabricatorRepositoryPushMailWorker.php',
'PhabricatorRepositoryPushPolicyTransaction' => 'applications/repository/xaction/PhabricatorRepositoryPushPolicyTransaction.php',
'PhabricatorRepositoryPushReplyHandler' => 'applications/repository/mail/PhabricatorRepositoryPushReplyHandler.php',
'PhabricatorRepositoryQuery' => 'applications/repository/query/PhabricatorRepositoryQuery.php',
'PhabricatorRepositoryRefCursor' => 'applications/repository/storage/PhabricatorRepositoryRefCursor.php',
@@ -4159,15 +4191,27 @@ phutil_register_library_map(array(
'PhabricatorRepositoryRefEngine' => 'applications/repository/engine/PhabricatorRepositoryRefEngine.php',
'PhabricatorRepositoryRefPosition' => 'applications/repository/storage/PhabricatorRepositoryRefPosition.php',
'PhabricatorRepositoryRepositoryPHIDType' => 'applications/repository/phid/PhabricatorRepositoryRepositoryPHIDType.php',
'PhabricatorRepositorySVNSubpathTransaction' => 'applications/repository/xaction/PhabricatorRepositorySVNSubpathTransaction.php',
'PhabricatorRepositorySchemaSpec' => 'applications/repository/storage/PhabricatorRepositorySchemaSpec.php',
'PhabricatorRepositorySearchEngine' => 'applications/repository/query/PhabricatorRepositorySearchEngine.php',
'PhabricatorRepositoryServiceTransaction' => 'applications/repository/xaction/PhabricatorRepositoryServiceTransaction.php',
'PhabricatorRepositorySlugTransaction' => 'applications/repository/xaction/PhabricatorRepositorySlugTransaction.php',
'PhabricatorRepositoryStagingURITransaction' => 'applications/repository/xaction/PhabricatorRepositoryStagingURITransaction.php',
'PhabricatorRepositoryStatusMessage' => 'applications/repository/storage/PhabricatorRepositoryStatusMessage.php',
'PhabricatorRepositorySvnCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositorySvnCommitChangeParserWorker.php',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositorySvnCommitMessageParserWorker.php',
'PhabricatorRepositorySymbol' => 'applications/repository/storage/PhabricatorRepositorySymbol.php',
'PhabricatorRepositorySymbolLanguagesTransaction' => 'applications/repository/xaction/PhabricatorRepositorySymbolLanguagesTransaction.php',
'PhabricatorRepositorySymbolSourcesTransaction' => 'applications/repository/xaction/PhabricatorRepositorySymbolSourcesTransaction.php',
'PhabricatorRepositorySyncEvent' => 'applications/repository/storage/PhabricatorRepositorySyncEvent.php',
'PhabricatorRepositorySyncEventPHIDType' => 'applications/repository/phid/PhabricatorRepositorySyncEventPHIDType.php',
'PhabricatorRepositorySyncEventQuery' => 'applications/repository/query/PhabricatorRepositorySyncEventQuery.php',
'PhabricatorRepositoryTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryTestCase.php',
'PhabricatorRepositoryTouchLimitTransaction' => 'applications/repository/xaction/PhabricatorRepositoryTouchLimitTransaction.php',
'PhabricatorRepositoryTrackOnlyTransaction' => 'applications/repository/xaction/PhabricatorRepositoryTrackOnlyTransaction.php',
'PhabricatorRepositoryTransaction' => 'applications/repository/storage/PhabricatorRepositoryTransaction.php',
'PhabricatorRepositoryTransactionQuery' => 'applications/repository/query/PhabricatorRepositoryTransactionQuery.php',
'PhabricatorRepositoryTransactionType' => 'applications/repository/xaction/PhabricatorRepositoryTransactionType.php',
'PhabricatorRepositoryType' => 'applications/repository/constants/PhabricatorRepositoryType.php',
'PhabricatorRepositoryURI' => 'applications/repository/storage/PhabricatorRepositoryURI.php',
'PhabricatorRepositoryURIIndex' => 'applications/repository/storage/PhabricatorRepositoryURIIndex.php',
@@ -4178,6 +4222,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryURITestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryURITestCase.php',
'PhabricatorRepositoryURITransaction' => 'applications/repository/storage/PhabricatorRepositoryURITransaction.php',
'PhabricatorRepositoryURITransactionQuery' => 'applications/repository/query/PhabricatorRepositoryURITransactionQuery.php',
'PhabricatorRepositoryVCSTransaction' => 'applications/repository/xaction/PhabricatorRepositoryVCSTransaction.php',
'PhabricatorRepositoryWorkingCopyVersion' => 'applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php',
'PhabricatorRequestExceptionHandler' => 'aphront/handler/PhabricatorRequestExceptionHandler.php',
'PhabricatorResourceSite' => 'aphront/site/PhabricatorResourceSite.php',
@@ -6217,6 +6262,7 @@ phutil_register_library_map(array(
'DiffusionLookSoonConduitAPIMethod' => 'DiffusionConduitAPIMethod',
'DiffusionLowLevelCommitFieldsQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelCommitQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelFilesizeQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelGitRefQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelMercurialBranchesQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelMercurialPathsQuery' => 'DiffusionLowLevelQuery',
@@ -6326,10 +6372,16 @@ phutil_register_library_map(array(
'DiffusionRepositoryHistoryManagementPanel' => 'DiffusionRepositoryManagementPanel',
'DiffusionRepositoryIdentityEditor' => 'PhabricatorApplicationTransactionEditor',
'DiffusionRepositoryIdentitySearchEngine' => 'PhabricatorApplicationSearchEngine',
'DiffusionRepositoryLimitsManagementPanel' => 'DiffusionRepositoryManagementPanel',
'DiffusionRepositoryListController' => 'DiffusionController',
'DiffusionRepositoryManageController' => 'DiffusionController',
'DiffusionRepositoryManagePanelsController' => 'DiffusionRepositoryManageController',
'DiffusionRepositoryManagementBuildsPanelGroup' => 'DiffusionRepositoryManagementPanelGroup',
'DiffusionRepositoryManagementIntegrationsPanelGroup' => 'DiffusionRepositoryManagementPanelGroup',
'DiffusionRepositoryManagementMainPanelGroup' => 'DiffusionRepositoryManagementPanelGroup',
'DiffusionRepositoryManagementOtherPanelGroup' => 'DiffusionRepositoryManagementPanelGroup',
'DiffusionRepositoryManagementPanel' => 'Phobject',
'DiffusionRepositoryManagementPanelGroup' => 'Phobject',
'DiffusionRepositoryPath' => 'Phobject',
'DiffusionRepositoryPoliciesManagementPanel' => 'DiffusionRepositoryManagementPanel',
'DiffusionRepositoryProfilePictureController' => 'DiffusionController',
@@ -6369,6 +6421,9 @@ phutil_register_library_map(array(
'DiffusionSymbolController' => 'DiffusionController',
'DiffusionSymbolDatasource' => 'PhabricatorTypeaheadDatasource',
'DiffusionSymbolQuery' => 'PhabricatorOffsetPagedQuery',
'DiffusionSyncLogListController' => 'DiffusionLogController',
'DiffusionSyncLogListView' => 'AphrontView',
'DiffusionSyncLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DiffusionTagListController' => 'DiffusionController',
'DiffusionTagListView' => 'DiffusionView',
'DiffusionTagTableView' => 'DiffusionView',
@@ -6539,6 +6594,7 @@ phutil_register_library_map(array(
'DrydockLease' => array(
'DrydockDAO',
'PhabricatorPolicyInterface',
'PhabricatorConduitResultInterface',
),
'DrydockLeaseAcquiredLogType' => 'DrydockLogType',
'DrydockLeaseActivatedLogType' => 'DrydockLogType',
@@ -6559,6 +6615,7 @@ phutil_register_library_map(array(
'DrydockLeaseReclaimLogType' => 'DrydockLogType',
'DrydockLeaseReleaseController' => 'DrydockLeaseController',
'DrydockLeaseReleasedLogType' => 'DrydockLogType',
'DrydockLeaseSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'DrydockLeaseSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DrydockLeaseStatus' => 'PhabricatorObjectStatus',
'DrydockLeaseUpdateWorker' => 'DrydockWorker',
@@ -6779,6 +6836,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyInterface',
'PhabricatorSubscribableInterface',
'PhabricatorNgramsInterface',
'PhabricatorConduitResultInterface',
'PhabricatorProjectInterface',
),
'HarbormasterBuildPlanDatasource' => 'PhabricatorTypeaheadDatasource',
@@ -6789,6 +6847,7 @@ phutil_register_library_map(array(
'HarbormasterBuildPlanNameNgrams' => 'PhabricatorSearchNgrams',
'HarbormasterBuildPlanPHIDType' => 'PhabricatorPHIDType',
'HarbormasterBuildPlanQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'HarbormasterBuildPlanSearchAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'HarbormasterBuildPlanSearchEngine' => 'PhabricatorApplicationSearchEngine',
'HarbormasterBuildPlanTransaction' => 'PhabricatorApplicationTransaction',
'HarbormasterBuildPlanTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
@@ -6821,9 +6880,11 @@ phutil_register_library_map(array(
'HarbormasterDAO',
'PhabricatorPolicyInterface',
'PhabricatorDestructibleInterface',
'PhabricatorConduitResultInterface',
),
'HarbormasterBuildTargetPHIDType' => 'PhabricatorPHIDType',
'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'HarbormasterBuildTargetSearchEngine' => 'PhabricatorApplicationSearchEngine',
'HarbormasterBuildTransaction' => 'PhabricatorApplicationTransaction',
'HarbormasterBuildTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'HarbormasterBuildTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
@@ -6835,6 +6896,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface',
'HarbormasterBuildableInterface',
'PhabricatorConduitResultInterface',
'PhabricatorDestructibleInterface',
),
'HarbormasterBuildableActionController' => 'HarbormasterController',
@@ -6842,6 +6904,7 @@ phutil_register_library_map(array(
'HarbormasterBuildableListController' => 'HarbormasterController',
'HarbormasterBuildablePHIDType' => 'PhabricatorPHIDType',
'HarbormasterBuildableQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'HarbormasterBuildableSearchAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'HarbormasterBuildableSearchEngine' => 'PhabricatorApplicationSearchEngine',
'HarbormasterBuildableStatus' => 'Phobject',
'HarbormasterBuildableTransaction' => 'PhabricatorApplicationTransaction',
@@ -6905,6 +6968,7 @@ phutil_register_library_map(array(
'HarbormasterStepEditController' => 'HarbormasterPlanController',
'HarbormasterStepViewController' => 'HarbormasterPlanController',
'HarbormasterTargetEngine' => 'Phobject',
'HarbormasterTargetSearchAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'HarbormasterTargetWorker' => 'HarbormasterWorker',
'HarbormasterTestBuildStepGroup' => 'HarbormasterBuildStepGroup',
'HarbormasterThrowExceptionBuildStep' => 'HarbormasterBuildStepImplementation',
@@ -6967,6 +7031,7 @@ phutil_register_library_map(array(
'HeraldInvalidConditionException' => 'Exception',
'HeraldMailableState' => 'HeraldState',
'HeraldManageGlobalRulesCapability' => 'PhabricatorPolicyCapability',
'HeraldManagementWorkflow' => 'PhabricatorManagementWorkflow',
'HeraldManiphestTaskAdapter' => 'HeraldAdapter',
'HeraldNewController' => 'HeraldController',
'HeraldNewObjectField' => 'HeraldField',
@@ -7023,6 +7088,7 @@ phutil_register_library_map(array(
'HeraldSupportActionGroup' => 'HeraldActionGroup',
'HeraldSupportFieldGroup' => 'HeraldFieldGroup',
'HeraldTestConsoleController' => 'HeraldController',
'HeraldTestManagementWorkflow' => 'HeraldManagementWorkflow',
'HeraldTextFieldValue' => 'HeraldFieldValue',
'HeraldTokenizerFieldValue' => 'HeraldFieldValue',
'HeraldTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
@@ -7132,7 +7198,10 @@ phutil_register_library_map(array(
'LegalpadTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'LegalpadTransactionView' => 'PhabricatorApplicationTransactionView',
'LiskChunkTestCase' => 'PhabricatorTestCase',
'LiskDAO' => 'Phobject',
'LiskDAO' => array(
'Phobject',
'AphrontDatabaseTableRefInterface',
),
'LiskDAOSet' => 'Phobject',
'LiskDAOTestCase' => 'PhabricatorTestCase',
'LiskEphemeralObjectException' => 'Exception',
@@ -9975,11 +10044,16 @@ phutil_register_library_map(array(
'PhabricatorFulltextInterface',
'PhabricatorFerretInterface',
),
'PhabricatorRepositoryActivateTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryAuditRequest' => array(
'PhabricatorRepositoryDAO',
'PhabricatorPolicyInterface',
),
'PhabricatorRepositoryAutocloseOnlyTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryAutocloseTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryBlueprintsTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryBranch' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCallsignTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryCommit' => array(
'PhabricatorRepositoryDAO',
'PhabricatorPolicyInterface',
@@ -10012,12 +10086,19 @@ phutil_register_library_map(array(
'PhabricatorRepositoryCommitRef' => 'Phobject',
'PhabricatorRepositoryCommitTestCase' => 'PhabricatorTestCase',
'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorRepositoryCopyTimeLimitTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorRepositoryDangerousTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryDefaultBranchTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryDescriptionTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryDestructibleCodex' => 'PhabricatorDestructibleCodex',
'PhabricatorRepositoryDiscoveryEngine' => 'PhabricatorRepositoryEngine',
'PhabricatorRepositoryEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorRepositoryEncodingTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryEngine' => 'Phobject',
'PhabricatorRepositoryEnormousTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryFerretEngine' => 'PhabricatorFerretEngine',
'PhabricatorRepositoryFilesizeLimitTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryFulltextEngine' => 'PhabricatorFulltextEngine',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
@@ -10068,6 +10149,8 @@ phutil_register_library_map(array(
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositoryMirror' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryMirrorEngine' => 'PhabricatorRepositoryEngine',
'PhabricatorRepositoryNameTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryNotifyTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryOldRef' => array(
'PhabricatorRepositoryDAO',
'PhabricatorPolicyInterface',
@@ -10096,6 +10179,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryPushLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorRepositoryPushLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorRepositoryPushMailWorker' => 'PhabricatorWorker',
'PhabricatorRepositoryPushPolicyTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryPushReplyHandler' => 'PhabricatorMailReplyHandler',
'PhabricatorRepositoryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorRepositoryRefCursor' => array(
@@ -10107,15 +10191,30 @@ phutil_register_library_map(array(
'PhabricatorRepositoryRefEngine' => 'PhabricatorRepositoryEngine',
'PhabricatorRepositoryRefPosition' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryRepositoryPHIDType' => 'PhabricatorPHIDType',
'PhabricatorRepositorySVNSubpathTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositorySchemaSpec' => 'PhabricatorConfigSchemaSpec',
'PhabricatorRepositorySearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorRepositoryServiceTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositorySlugTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryStagingURITransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryStatusMessage' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositorySvnCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositorySymbol' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositorySymbolLanguagesTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositorySymbolSourcesTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositorySyncEvent' => array(
'PhabricatorRepositoryDAO',
'PhabricatorPolicyInterface',
),
'PhabricatorRepositorySyncEventPHIDType' => 'PhabricatorPHIDType',
'PhabricatorRepositorySyncEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorRepositoryTestCase' => 'PhabricatorTestCase',
'PhabricatorRepositoryTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorRepositoryTouchLimitTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryTrackOnlyTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryTransaction' => 'PhabricatorModularTransaction',
'PhabricatorRepositoryTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorRepositoryTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorRepositoryType' => 'Phobject',
'PhabricatorRepositoryURI' => array(
'PhabricatorRepositoryDAO',
@@ -10132,6 +10231,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryURITestCase' => 'PhabricatorTestCase',
'PhabricatorRepositoryURITransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorRepositoryURITransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorRepositoryVCSTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryWorkingCopyVersion' => 'PhabricatorRepositoryDAO',
'PhabricatorRequestExceptionHandler' => 'AphrontRequestExceptionHandler',
'PhabricatorResourceSite' => 'PhabricatorSite',

View File

@@ -83,6 +83,18 @@ final class PhabricatorPolicyRequestExceptionHandler
$dialog->appendList($list);
}
// If the install is in developer mode, include a stack trace for the
// exception. When debugging things, it isn't always obvious where a
// policy exception came from and this can make it easier to hunt down
// bugs or improve ambiguous/confusing messaging.
$is_developer = PhabricatorEnv::getEnvConfig('phabricator.developer-mode');
if ($is_developer) {
$dialog->appendChild(
id(new AphrontStackTraceView())
->setTrace($throwable->getTrace()));
}
if ($request->isAjax()) {
$dialog->addCancelButton('/', pht('Close'));
} else {

View File

@@ -136,7 +136,7 @@ final class AlmanacBindingEditEngine
id(new PhabricatorTextEditField())
->setKey('service')
->setLabel(pht('Service'))
->setIsConduitOnly(true)
->setIsFormField(false)
->setTransactionType(
AlmanacBindingServiceTransaction::TRANSACTIONTYPE)
->setDescription(pht('Service to create a binding for.'))
@@ -146,7 +146,7 @@ final class AlmanacBindingEditEngine
id(new PhabricatorTextEditField())
->setKey('interface')
->setLabel(pht('Interface'))
->setIsConduitOnly(true)
->setIsFormField(false)
->setTransactionType(
AlmanacBindingInterfaceTransaction::TRANSACTIONTYPE)
->setDescription(pht('Interface to bind the service to.'))
@@ -156,7 +156,7 @@ final class AlmanacBindingEditEngine
id(new PhabricatorBoolEditField())
->setKey('disabled')
->setLabel(pht('Disabled'))
->setIsConduitOnly(true)
->setIsFormField(false)
->setTransactionType(
AlmanacBindingDisableTransaction::TRANSACTIONTYPE)
->setDescription(pht('Disable or enable the binding.'))

View File

@@ -150,7 +150,7 @@ final class AlmanacInterfaceEditEngine
id(new PhabricatorTextEditField())
->setKey('device')
->setLabel(pht('Device'))
->setIsConduitOnly(true)
->setIsFormField(false)
->setTransactionType(
AlmanacInterfaceDeviceTransaction::TRANSACTIONTYPE)
->setDescription(pht('When creating an interface, set the device.'))

View File

@@ -136,7 +136,7 @@ final class AlmanacServiceEditEngine
id(new PhabricatorTextEditField())
->setKey('type')
->setLabel(pht('Type'))
->setIsConduitOnly(true)
->setIsFormField(false)
->setTransactionType(
AlmanacServiceTypeTransaction::TRANSACTIONTYPE)
->setDescription(pht('When creating a service, set the type.'))

View File

@@ -30,14 +30,14 @@ final class AlmanacPropertiesEditEngineExtension
->setConduitDescription(
pht('Pass a map of values to set one or more properties.'))
->setConduitTypeDescription(pht('Map of property names to values.'))
->setIsConduitOnly(true),
->setIsFormField(false),
id(new AlmanacDeletePropertyEditField())
->setKey('property.delete')
->setTransactionType($object->getAlmanacPropertyDeleteTransactionType())
->setConduitDescription(
pht('Pass a list of property names to delete properties.'))
->setConduitTypeDescription(pht('List of property names.'))
->setIsConduitOnly(true),
->setIsFormField(false),
);
}

View File

@@ -121,7 +121,7 @@ final class AlmanacInterfaceQuery
$address->getAddress(),
$address->getPort());
}
$where[] = implode(' OR ', $parts);
$where[] = qsprintf($conn, '%LO', $parts);
}
return $where;

View File

@@ -58,6 +58,10 @@ final class PhabricatorCommitSearchEngine
$query->withAncestorsOf($map['ancestorsOf']);
}
if ($map['identifiers']) {
$query->withIdentifiers($map['identifiers']);
}
return $query;
}
@@ -130,6 +134,15 @@ final class PhabricatorCommitSearchEngine
pht(
'Find commits which are ancestors of a particular ref, '.
'like "master".')),
id(new PhabricatorSearchStringListField())
->setLabel(pht('Identifiers'))
->setKey('identifiers')
->setDescription(
pht(
'Find commits with particular identifiers (usually, hashes). '.
'Supports full or partial identifiers (like "abcd12340987..." or '.
'"abcd1234") and qualified or unqualified identifiers (like '.
'"rXabcd1234" or "abcd1234").')),
);
}

View File

@@ -99,6 +99,82 @@ final class PhabricatorAuthPasswordTestCase extends PhabricatorTestCase {
$this->assertTrue($account_engine->isUniquePassword($password2));
}
public function testPasswordBlocklisting() {
$user = $this->generateNewTestUser();
$user
->setUsername('iasimov')
->setRealName('Isaac Asimov')
->save();
$test_type = PhabricatorAuthPassword::PASSWORD_TYPE_TEST;
$content_source = $this->newContentSource();
$engine = id(new PhabricatorAuthPasswordEngine())
->setViewer($user)
->setContentSource($content_source)
->setPasswordType($test_type)
->setObject($user);
$env = PhabricatorEnv::beginScopedEnv();
$env->overrideEnvConfig('account.minimum-password-length', 4);
$passwords = array(
'a23li432m9mdf' => true,
// Empty.
'' => false,
// Password length tests.
'xh3' => false,
'xh32' => true,
// In common password blocklist.
'password1' => false,
// Tests for the account identifier blocklist.
'isaac' => false,
'iasimov' => false,
'iasimov1' => false,
'asimov' => false,
'iSaAc' => false,
'32IASIMOV' => false,
'i-am-iasimov-this-is-my-long-strong-password' => false,
'iasimo' => false,
// These are okay: although they're visually similar, they aren't mutual
// substrings of any identifier.
'iasimo1' => true,
'isa1mov' => true,
);
foreach ($passwords as $password => $expect) {
$this->assertBlocklistedPassword($engine, $password, $expect);
}
}
private function assertBlocklistedPassword(
PhabricatorAuthPasswordEngine $engine,
$raw_password,
$expect_valid) {
$envelope_1 = new PhutilOpaqueEnvelope($raw_password);
$envelope_2 = new PhutilOpaqueEnvelope($raw_password);
$caught = null;
try {
$engine->checkNewPassword($envelope_1, $envelope_2);
} catch (PhabricatorAuthPasswordException $exception) {
$caught = $exception;
}
$this->assertEqual(
$expect_valid,
!($caught instanceof PhabricatorAuthPasswordException),
pht('Validity of password "%s".', $raw_password));
}
public function testPasswordUpgrade() {
$weak_hasher = new PhabricatorIteratedMD5PasswordHasher();

View File

@@ -115,7 +115,9 @@ final class PhabricatorAuthPasswordEngine
// revoked passwords or colliding passwords either, so we can skip these
// checks.
if ($this->getObject()->getPHID()) {
$object = $this->getObject();
if ($object->getPHID()) {
if ($this->isRevokedPassword($password)) {
throw new PhabricatorAuthPasswordException(
pht(
@@ -132,6 +134,66 @@ final class PhabricatorAuthPasswordEngine
pht('Not Unique'));
}
}
// Prevent use of passwords which are similar to any object identifier.
// For example, if your username is "alincoln", your password may not be
// "alincoln", "lincoln", or "alincoln1".
$viewer = $this->getViewer();
$blocklist = $object->newPasswordBlocklist($viewer, $this);
// Smallest number of overlapping characters that we'll consider to be
// too similar.
$minimum_similarity = 4;
// Add the domain name to the blocklist.
$base_uri = PhabricatorEnv::getAnyBaseURI();
$base_uri = new PhutilURI($base_uri);
$blocklist[] = $base_uri->getDomain();
// Generate additional subterms by splitting the raw blocklist on
// characters like "@", " " (space), and "." to break up email addresses,
// readable names, and domain names into components.
$terms_map = array();
foreach ($blocklist as $term) {
$terms_map[$term] = $term;
foreach (preg_split('/[ @.]/', $term) as $subterm) {
$terms_map[$subterm] = $term;
}
}
// Skip very short terms: it's okay if your password has the substring
// "com" in it somewhere even if the install is on "mycompany.com".
foreach ($terms_map as $term => $source) {
if (strlen($term) < $minimum_similarity) {
unset($terms_map[$term]);
}
}
// Normalize terms for comparison.
$normal_map = array();
foreach ($terms_map as $term => $source) {
$term = phutil_utf8_strtolower($term);
$normal_map[$term] = $source;
}
// Finally, make sure that none of the terms appear in the password,
// and that the password does not appear in any of the terms.
$normal_password = phutil_utf8_strtolower($raw_password);
if (strlen($normal_password) >= $minimum_similarity) {
foreach ($normal_map as $term => $source) {
if (strpos($term, $normal_password) === false &&
strpos($normal_password, $term) === false) {
continue;
}
throw new PhabricatorAuthPasswordException(
pht(
'The password you entered is very similar to a nonsecret account '.
'identifier (like a username or email address). Choose a more '.
'distinct password.'),
pht('Not Distinct'));
}
}
}
public function isValidPassword(PhutilOpaqueEnvelope $envelope) {

View File

@@ -127,12 +127,12 @@ final class PhabricatorAuthSessionEngine extends Phobject {
u.*
%Q
FROM %T u JOIN %T s ON u.phid = s.userPHID
AND s.type = %s AND s.sessionKey = %s %Q',
AND s.type = %s AND s.sessionKey = %P %Q',
$cache_selects,
$user_table->getTableName(),
$session_table->getTableName(),
$session_type,
$session_key,
new PhutilOpaqueEnvelope($session_key),
$cache_joins);
if (!$info) {
@@ -345,6 +345,33 @@ final class PhabricatorAuthSessionEngine extends Phobject {
/* -( High Security )------------------------------------------------------ */
/**
* Require the user respond to a high security (MFA) check.
*
* This method differs from @{method:requireHighSecuritySession} in that it
* does not upgrade the user's session as a side effect. This method is
* appropriate for one-time checks.
*
* @param PhabricatorUser User whose session needs to be in high security.
* @param AphrontReqeust Current request.
* @param string URI to return the user to if they cancel.
* @return PhabricatorAuthHighSecurityToken Security token.
* @task hisec
*/
public function requireHighSecurityToken(
PhabricatorUser $viewer,
AphrontRequest $request,
$cancel_uri) {
return $this->newHighSecurityToken(
$viewer,
$request,
$cancel_uri,
false,
false);
}
/**
* Require high security, or prompt the user to enter high security.
*
@@ -352,6 +379,11 @@ final class PhabricatorAuthSessionEngine extends Phobject {
* token. Otherwise, it will throw an exception which will eventually
* be converted into a multi-factor authentication workflow.
*
* This method upgrades the user's session to high security for a short
* period of time, and is appropriate if you anticipate they may need to
* take multiple high security actions. To perform a one-time check instead,
* use @{method:requireHighSecurityToken}.
*
* @param PhabricatorUser User whose session needs to be in high security.
* @param AphrontReqeust Current request.
* @param string URI to return the user to if they cancel.
@@ -367,11 +399,30 @@ final class PhabricatorAuthSessionEngine extends Phobject {
$cancel_uri,
$jump_into_hisec = false) {
return $this->newHighSecurityToken(
$viewer,
$request,
$cancel_uri,
false,
true);
}
private function newHighSecurityToken(
PhabricatorUser $viewer,
AphrontRequest $request,
$cancel_uri,
$jump_into_hisec,
$upgrade_session) {
if (!$viewer->hasSession()) {
throw new Exception(
pht('Requiring a high-security session from a user with no session!'));
}
// TODO: If a user answers a "requireHighSecurityToken()" prompt and hits
// a "requireHighSecuritySession()" prompt a short time later, the one-shot
// token should be good enough to upgrade the session.
$session = $viewer->getSession();
// Check if the session is already in high security mode.
@@ -441,6 +492,11 @@ final class PhabricatorAuthSessionEngine extends Phobject {
return $this->issueHighSecurityToken($session, true);
}
// If we aren't upgrading the session itself, just issue a token.
if (!$upgrade_session) {
return $this->issueHighSecurityToken($session, true);
}
$until = time() + phutil_units('15 minutes in seconds');
$session->setHighSecurityUntil($until);
@@ -809,15 +865,15 @@ final class PhabricatorAuthSessionEngine extends Phobject {
}
if ($cache_selects) {
$cache_selects = ', '.implode(', ', $cache_selects);
$cache_selects = qsprintf($conn, ', %LQ', $cache_selects);
} else {
$cache_selects = '';
$cache_selects = qsprintf($conn, '');
}
if ($cache_joins) {
$cache_joins = implode(' ', $cache_joins);
$cache_joins = qsprintf($conn, '%LJ', $cache_joins);
} else {
$cache_joins = '';
$cache_joins = qsprintf($conn, '');
}
return array($cache_selects, $cache_joins, $cache_map, $types_map);

View File

@@ -185,7 +185,7 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
public static function generateNewTOTPKey() {
return strtoupper(Filesystem::readRandomCharacters(16));
return strtoupper(Filesystem::readRandomCharacters(32));
}
public static function verifyTOTPCode(

View File

@@ -6,4 +6,22 @@ interface PhabricatorAuthPasswordHashInterface {
PhutilOpaqueEnvelope $envelope,
PhabricatorAuthPassword $password);
/**
* Return a list of strings which passwords associated with this object may
* not be similar to.
*
* This method allows you to prevent users from selecting their username
* as their password or picking other passwords which are trivially similar
* to an account or object identifier.
*
* @param PhabricatorUser The user selecting the password.
* @param PhabricatorAuthPasswordEngine The password engine updating a
* password.
* @return list<string> Blocklist of nonsecret identifiers which the password
* should not be similar to.
*/
public function newPasswordBlocklist(
PhabricatorUser $viewer,
PhabricatorAuthPasswordEngine $engine);
}

View File

@@ -59,26 +59,26 @@ final class PhabricatorAuthInviteQuery
return $invites;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->emailAddresses !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'emailAddress IN (%Ls)',
$this->emailAddresses);
}
@@ -90,21 +90,21 @@ final class PhabricatorAuthInviteQuery
}
$where[] = qsprintf(
$conn_r,
$conn,
'verificationHash IN (%Ls)',
$hashes);
}
if ($this->authorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'authorPHID IN (%Ls)',
$this->authorPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
public function getQueryApplicationClass() {

View File

@@ -54,26 +54,26 @@ final class PhabricatorAuthProviderConfigQuery
return $table->loadAllFromArray($data);
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids) {
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->providerClasses) {
if ($this->providerClasses !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'providerClass IN (%Ls)',
$this->providerClasses);
}
@@ -84,16 +84,16 @@ final class PhabricatorAuthProviderConfigQuery
break;
case self::STATUS_ENABLED:
$where[] = qsprintf(
$conn_r,
$conn,
'isEnabled = 1');
break;
default:
throw new Exception(pht("Unknown status '%s'!", $status));
}
$where[] = $this->buildPagingClause($conn_r);
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
public function getQueryApplicationClass() {

View File

@@ -111,7 +111,7 @@ final class PhabricatorAuthSSHKeyQuery
$key->getType(),
$key->getHash());
}
$where[] = implode(' OR ', $sql);
$where[] = qsprintf($conn, '%LO', $sql);
}
if ($this->isActive !== null) {

View File

@@ -65,44 +65,44 @@ final class PhabricatorAuthSessionQuery
return $sessions;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids) {
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->identityPHIDs) {
if ($this->identityPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'userPHID IN (%Ls)',
$this->identityPHIDs);
}
if ($this->sessionKeys) {
if ($this->sessionKeys !== null) {
$hashes = array();
foreach ($this->sessionKeys as $session_key) {
$hashes[] = PhabricatorHash::weakDigest($session_key);
}
$where[] = qsprintf(
$conn_r,
$conn,
'sessionKey IN (%Ls)',
$hashes);
}
if ($this->sessionTypes) {
if ($this->sessionTypes !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'type IN (%Ls)',
$this->sessionTypes);
}
$where[] = $this->buildPagingClause($conn_r);
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
public function getQueryApplicationClass() {

View File

@@ -126,7 +126,7 @@ final class PhabricatorBadgesEditEngine
->setValue($object->getDescription()),
id(new PhabricatorUsersEditField())
->setKey('award')
->setIsConduitOnly(true)
->setIsFormField(false)
->setDescription(pht('New badge award recipients.'))
->setConduitTypeDescription(pht('New badge award recipients.'))
->setTransactionType(
@@ -134,7 +134,7 @@ final class PhabricatorBadgesEditEngine
->setLabel(pht('Award Recipients')),
id(new PhabricatorUsersEditField())
->setKey('revoke')
->setIsConduitOnly(true)
->setIsFormField(false)
->setDescription(pht('Revoke badge award recipients.'))
->setConduitTypeDescription(pht('Revoke badge award recipients.'))
->setTransactionType(

View File

@@ -545,7 +545,7 @@ abstract class PhabricatorApplication
case PhabricatorPolicyCapability::CAN_VIEW:
return $this->canUninstall();
case PhabricatorPolicyCapability::CAN_EDIT:
return false;
return true;
default:
$spec = $this->getCustomCapabilitySpecification($capability);
return idx($spec, 'edit', true);

View File

@@ -38,7 +38,7 @@ final class PhabricatorKeyValueDatabaseCache
$conn_w,
'INSERT INTO %T
(cacheKeyHash, cacheKey, cacheFormat, cacheData,
cacheCreated, cacheExpires) VALUES %Q
cacheCreated, cacheExpires) VALUES %LQ
ON DUPLICATE KEY UPDATE
cacheKey = VALUES(cacheKey),
cacheFormat = VALUES(cacheFormat),

View File

@@ -148,7 +148,7 @@ final class PhabricatorCalendarEventEditEngine
->setDescription(pht('Cancel the event.'))
->setTransactionType(
PhabricatorCalendarEventCancelTransaction::TRANSACTIONTYPE)
->setIsConduitOnly(true)
->setIsFormField(false)
->setConduitDescription(pht('Cancel or restore the event.'))
->setConduitTypeDescription(pht('True to cancel the event.'))
->setValue($object->getIsCancelled()),
@@ -161,7 +161,7 @@ final class PhabricatorCalendarEventEditEngine
->setDescription(pht('Host of the event.'))
->setTransactionType(
PhabricatorCalendarEventHostTransaction::TRANSACTIONTYPE)
->setIsConduitOnly($this->getIsCreate())
->setIsFormField(!$this->getIsCreate())
->setConduitDescription(pht('Change the host of the event.'))
->setConduitTypeDescription(pht('New event host.'))
->setSingleValue($object->getHostPHID()),

View File

@@ -99,7 +99,7 @@ final class PhabricatorCalendarExportEditEngine
->setDescription(pht('Disable the export.'))
->setTransactionType(
PhabricatorCalendarExportDisableTransaction::TRANSACTIONTYPE)
->setIsConduitOnly(true)
->setIsFormField(false)
->setConduitDescription(pht('Disable or restore the export.'))
->setConduitTypeDescription(pht('True to cancel the export.'))
->setValue($object->getIsDisabled()),

View File

@@ -101,7 +101,7 @@ final class PhabricatorCalendarImportEditEngine
->setDescription(pht('Disable the import.'))
->setTransactionType(
PhabricatorCalendarImportDisableTransaction::TRANSACTIONTYPE)
->setIsConduitOnly(true)
->setIsFormField(false)
->setConduitDescription(pht('Disable or restore the import.'))
->setConduitTypeDescription(pht('True to cancel the import.'))
->setValue($object->getIsDisabled()),
@@ -111,7 +111,7 @@ final class PhabricatorCalendarImportEditEngine
->setDescription(pht('Delete all events from this source.'))
->setTransactionType(
PhabricatorCalendarImportDisableTransaction::TRANSACTIONTYPE)
->setIsConduitOnly(true)
->setIsFormField(false)
->setConduitDescription(pht('Disable or restore the import.'))
->setConduitTypeDescription(pht('True to delete imported events.'))
->setValue(false),
@@ -121,7 +121,7 @@ final class PhabricatorCalendarImportEditEngine
->setDescription(pht('Reload events imported from this source.'))
->setTransactionType(
PhabricatorCalendarImportDisableTransaction::TRANSACTIONTYPE)
->setIsConduitOnly(true)
->setIsFormField(false)
->setConduitDescription(pht('Disable or restore the import.'))
->setConduitTypeDescription(pht('True to reload the import.'))
->setValue(false),

View File

@@ -245,7 +245,7 @@ final class PhabricatorCalendarNotificationEngine
$conn,
'INSERT IGNORE INTO %T
(eventPHID, targetPHID, utcInitialEpoch, didNotifyEpoch)
VALUES %Q',
VALUES %LQ',
$table->getTableName(),
$chunk);
}

View File

@@ -49,47 +49,47 @@ final class PhabricatorCalendarEventInviteeQuery
return $table->loadAllFromArray($data);
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->eventPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'eventPHID IN (%Ls)',
$this->eventPHIDs);
}
if ($this->inviteePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'inviteePHID IN (%Ls)',
$this->inviteePHIDs);
}
if ($this->inviterPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'inviterPHID IN (%Ls)',
$this->inviterPHIDs);
}
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'status = %d',
$this->statuses);
}
$where[] = $this->buildPagingClause($conn_r);
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
public function getQueryApplicationClass() {

View File

@@ -444,8 +444,8 @@ final class PhabricatorCalendarEventQuery
$where[] = qsprintf(
$conn,
'%Q',
implode(' OR ', $sql));
'%LO',
$sql);
}
if ($this->isStub !== null) {
@@ -509,15 +509,10 @@ final class PhabricatorCalendarEventQuery
return parent::shouldGroupQueryResultRows();
}
protected function getApplicationSearchObjectPHIDColumn() {
return 'event.phid';
}
public function getQueryApplicationClass() {
return 'PhabricatorCalendarApplication';
}
protected function willFilterPage(array $events) {
$instance_of_event_phids = array();
$recurring_events = array();

View File

@@ -33,14 +33,14 @@ final class PhabricatorChatLogChannelQuery
return $logs;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
$where[] = $this->buildPagingClause($conn);
if ($this->channelIDs) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->channelIDs);
@@ -48,12 +48,12 @@ final class PhabricatorChatLogChannelQuery
if ($this->channels) {
$where[] = qsprintf(
$conn_r,
$conn,
'channelName IN (%Ls)',
$this->channels);
}
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
public function getQueryApplicationClass() {

View File

@@ -55,26 +55,26 @@ final class PhabricatorChatLogQuery
return $events;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
$where[] = $this->buildPagingClause($conn);
if ($this->maximumEpoch) {
if ($this->maximumEpoch !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'epoch <= %d',
$this->maximumEpoch);
}
if ($this->channelIDs) {
if ($this->channelIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'channelID IN (%Ld)',
$this->channelIDs);
}
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
public function getQueryApplicationClass() {

View File

@@ -109,15 +109,13 @@ final class PhabricatorConduitAPIController
$error_info = $ex->getMessage();
}
$time_end = microtime(true);
$log
->setCallerPHID(
isset($conduit_user)
? $conduit_user->getPHID()
: null)
->setError((string)$error_code)
->setDuration(1000000 * ($time_end - $time_start));
->setDuration(phutil_microseconds_since($time_start));
if (!PhabricatorEnv::isReadOnly()) {
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();

View File

@@ -73,15 +73,13 @@ final class ConduitSSHWorkflow extends PhabricatorSSHWorkflow {
// if the response is large and the receiver is slow to read it.
$this->getIOChannel()->flush();
$time_end = microtime(true);
$connection_id = idx($metadata, 'connectionID');
$log = id(new PhabricatorConduitMethodCallLog())
->setCallerPHID($this->getSSHUser()->getPHID())
->setConnectionID($connection_id)
->setMethod($method)
->setError((string)$error_code)
->setDuration(1000000 * ($time_end - $time_start))
->setDuration(phutil_microseconds_since($time_start))
->save();
}
}

View File

@@ -118,7 +118,8 @@ final class PhabricatorConfigEditor
PhabricatorUser $user,
PhabricatorConfigEntry $config_entry,
$value,
PhabricatorContentSource $source) {
PhabricatorContentSource $source,
$acting_as_phid = null) {
$xaction = id(new PhabricatorConfigTransaction())
->setTransactionType(PhabricatorConfigTransaction::TYPE_EDIT)
@@ -133,6 +134,10 @@ final class PhabricatorConfigEditor
->setContinueOnNoEffect(true)
->setContentSource($source);
if ($acting_as_phid) {
$editor->setActingAsPHID($acting_as_phid);
}
$editor->applyTransactions($config_entry, array($xaction));
}

View File

@@ -81,14 +81,6 @@ of each approach are:
- Required if private reply-to addresses are configured.
- Mail messages are sent in the language of user preference.
EODOC
));
$herald_hints_description = $this->deformat(pht(<<<EODOC
You can disable the Herald hints in email if users prefer smaller messages.
These are the links under the header "WHY DID I GET THIS EMAIL?". If you set
this to `false`, they will not appear in any mail. Users can still navigate to
the links via the web interface.
EODOC
));
@@ -256,14 +248,6 @@ EODOC
->setLocked(true)
->setDescription(pht('Domain used for reply email addresses.'))
->addExample('phabricator.example.com', ''),
$this->newOption('metamta.herald.show-hints', 'bool', true)
->setBoolOptions(
array(
pht('Show Herald Hints'),
pht('No Herald Hints'),
))
->setSummary(pht('Show hints about Herald rules in email.'))
->setDescription($herald_hints_description),
$this->newOption('metamta.recipients.show-hints', 'bool', true)
->setBoolOptions(
array(

View File

@@ -31,26 +31,26 @@ final class PhabricatorConfigEntryQuery
return $table->loadAllFromArray($data);
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids) {
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
public function getQueryApplicationClass() {

View File

@@ -115,8 +115,8 @@ final class PhabricatorConfigSchemaQuery extends Phobject {
'SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME,
COLLATION_NAME, COLUMN_TYPE, IS_NULLABLE, EXTRA
FROM INFORMATION_SCHEMA.COLUMNS
WHERE (%Q)',
'('.implode(') OR (', $sql).')');
WHERE %LO',
$sql);
$column_info = igroup($column_info, 'TABLE_SCHEMA');
} else {
$column_info = array();

View File

@@ -76,8 +76,8 @@ final class ConpherenceEditEngine
$initial_phids = $participant_phids;
}
// Only show participants on create or conduit, not edit
$conduit_only = !$this->getIsCreate();
// Only show participants on create or conduit, not edit.
$show_participants = (bool)$this->getIsCreate();
return array(
id(new PhabricatorTextEditField())
@@ -103,7 +103,7 @@ final class ConpherenceEditEngine
->setKey('participants')
->setValue($participant_phids)
->setInitialValue($initial_phids)
->setIsConduitOnly($conduit_only)
->setIsFormField($show_participants)
->setAliases(array('users', 'members', 'participants', 'userPHID'))
->setDescription(pht('Room participants.'))
->setUseEdgeTransactions(true)

View File

@@ -38,19 +38,19 @@ final class ConpherenceFulltextQuery
return $rows;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->threadPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'i.threadPHID IN (%Ls)',
$this->threadPHIDs);
}
if ($this->previousTransactionPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'i.previousTransactionPHID IN (%Ls)',
$this->previousTransactionPHIDs);
}
@@ -61,12 +61,12 @@ final class ConpherenceFulltextQuery
$compiled_query = $compiler->compileQuery($tokens);
$where[] = qsprintf(
$conn_r,
$conn,
'MATCH(i.corpus) AGAINST (%s IN BOOLEAN MODE)',
$compiled_query);
}
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
private function buildOrderByClause(AphrontDatabaseConnection $conn_r) {

View File

@@ -57,7 +57,7 @@ final class ConpherenceParticipantCountQuery
}
}
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
private function buildGroupByClause(AphrontDatabaseConnection $conn) {

View File

@@ -38,7 +38,7 @@ final class ConpherenceParticipantQuery extends PhabricatorOffsetPagedQuery {
$this->participantPHIDs);
}
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
private function buildOrderClause(AphrontDatabaseConnection $conn) {

View File

@@ -40,15 +40,20 @@ final class PhabricatorDaemonManagementLogWorkflow
$query->withIDs($ids);
}
$daemons = $query->execute();
$daemons = mpull($daemons, null, 'getID');
if (!$daemons) {
if ($ids) {
throw new PhutilArgumentUsageException(
pht('No daemon(s) with id(s) "%s" exist!', implode(', ', $ids)));
} else {
throw new PhutilArgumentUsageException(
pht('No daemons are running.'));
if ($ids) {
foreach ($ids as $id) {
if (!isset($daemons[$id])) {
throw new PhutilArgumentUsageException(
pht(
'No log record exists for a daemon with ID "%s".',
$id));
}
}
} else if (!$daemons) {
throw new PhutilArgumentUsageException(
pht('No log records exist for any daemons.'));
}
$console = PhutilConsole::getConsole();

View File

@@ -107,9 +107,9 @@ final class PhabricatorLockLogManagementWorkflow
}
if (!$parts) {
$constraint = '1 = 1';
$constraint = qsprintf($conn, '1 = 1');
} else {
$constraint = '('.implode(') AND (', $parts).')';
$constraint = qsprintf($conn, '%LA', $parts);
}
$logs = $table->loadAllWhere(

View File

@@ -124,46 +124,47 @@ final class PhabricatorDaemonLogQuery
return $daemons;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->notIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'id NOT IN (%Ld)',
$this->notIDs);
}
if ($this->getStatusConstants()) {
$where[] = qsprintf(
$conn_r,
$conn,
'status IN (%Ls)',
$this->getStatusConstants());
}
if ($this->daemonClasses !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'daemon IN (%Ls)',
$this->daemonClasses);
}
if ($this->daemonIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'daemonID IN (%Ls)',
$this->daemonIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($conn, $where);
}
private function getStatusConstants() {

View File

@@ -72,20 +72,35 @@ final class DifferentialReviewersField
return array();
}
$all_resigned = true;
$all_disabled = true;
$any_reviewers = false;
foreach ($this->getValue() as $reviewer) {
if (!$handles[$reviewer->getReviewerPHID()]->isDisabled()) {
return array();
$reviewer_phid = $reviewer->getReviewerPHID();
$any_reviewers = true;
if (!$handles[$reviewer_phid]->isDisabled()) {
$all_disabled = false;
}
if (!$reviewer->isResigned()) {
$all_resigned = false;
}
}
$warnings = array();
if ($this->getValue()) {
if (!$any_reviewers) {
$warnings[] = pht(
'This revision needs review, but there are no reviewers specified.');
} else if ($all_disabled) {
$warnings[] = pht(
'This revision needs review, but all specified reviewers are '.
'disabled or inactive.');
} else {
} else if ($all_resigned) {
$warnings[] = pht(
'This revision needs review, but there are no reviewers specified.');
'This revision needs review, but all reviewers have resigned.');
}
return $warnings;

View File

@@ -138,7 +138,7 @@ final class DifferentialRevisionEditEngine
DifferentialRevisionUpdateTransaction::TRANSACTIONTYPE)
->setHandleParameterType(new AphrontPHIDListHTTPParameterType())
->setSingleValue($diff_phid)
->setIsConduitOnly(!$diff)
->setIsFormField((bool)$diff)
->setIsReorderable(false)
->setIsDefaultable(false)
->setIsInvisible(true)
@@ -225,7 +225,7 @@ final class DifferentialRevisionEditEngine
$fields[] = id(new PhabricatorHandlesEditField())
->setKey('tasks')
->setUseEdgeTransactions(true)
->setIsConduitOnly(true)
->setIsFormField(false)
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue(
'edge:type',
@@ -245,7 +245,7 @@ final class DifferentialRevisionEditEngine
$fields[] = id(new PhabricatorBoolEditField())
->setKey('draft')
->setLabel(pht('Hold as Draft'))
->setIsConduitOnly(true)
->setIsFormField(false)
->setOptions(
pht('Autosubmit Once Builds Finish'),
pht('Hold as Draft'))

View File

@@ -451,6 +451,11 @@ final class DifferentialTransactionEditor
// conditions for acceptance. This usually happens after an accepting
// reviewer resigns or is removed.
$new_status = DifferentialRevisionStatus::NEEDS_REVIEW;
} else if ($was_revision) {
// This revision was "Needs Revision", but no longer has any rejecting
// reviewers. This usually happens after the last rejecting reviewer
// resigns or is removed. Put the revision back in "Needs Review".
$new_status = DifferentialRevisionStatus::NEEDS_REVIEW;
}
if ($new_status === null) {

View File

@@ -361,7 +361,7 @@ final class DifferentialInlineCommentMailView
return $parser->render(
$start - $context,
$length + 1 + (2 * $context),
$length + (2 * $context),
array());
}

View File

@@ -874,9 +874,16 @@ final class DifferentialChangesetParser extends Phobject {
$offset_map = $this->old;
}
// NOTE: Inline comments use zero-based lengths. For example, a comment
// that starts and ends on line 123 has length 0. Rendering considers
// this range to have length 1. Probably both should agree, but that
// ship likely sailed long ago. Tweak things here to get the two systems
// to agree. See PHI985, where this affected mail rendering of inline
// comments left on the final line of a file.
$range_end = $this->getOffset($offset_map, $range_start + $range_len);
$range_start = $this->getOffset($offset_map, $range_start);
$range_len = ($range_end - $range_start);
$range_len = ($range_end - $range_start) + 1;
}
$render_pch = $this->shouldRenderPropertyChangeHeader($this->changeset);

View File

@@ -107,31 +107,31 @@ final class DifferentialInlineCommentQuery
return head($this->execute());
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
// Only find inline comments.
$where[] = qsprintf(
$conn_r,
$conn,
'changesetID IS NOT NULL');
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->revisionPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'revisionPHID IN (%Ls)',
$this->revisionPHIDs);
}
@@ -139,28 +139,28 @@ final class DifferentialInlineCommentQuery
if ($this->drafts === null) {
if ($this->deletedDrafts) {
$where[] = qsprintf(
$conn_r,
$conn,
'(authorPHID = %s) OR (transactionPHID IS NOT NULL)',
$this->getViewer()->getPHID());
} else {
$where[] = qsprintf(
$conn_r,
$conn,
'(authorPHID = %s AND isDeleted = 0)
OR (transactionPHID IS NOT NULL)',
$this->getViewer()->getPHID());
}
} else if ($this->drafts) {
$where[] = qsprintf(
$conn_r,
$conn,
'(authorPHID = %s AND isDeleted = 0) AND (transactionPHID IS NULL)',
$this->getViewer()->getPHID());
} else {
$where[] = qsprintf(
$conn_r,
$conn,
'transactionPHID IS NOT NULL');
}
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
public function adjustInlinesForChangesets(

View File

@@ -453,7 +453,7 @@ final class DifferentialRevisionQuery
private function loadData() {
$table = $this->newResultObject();
$conn_r = $table->establishConnection('r');
$conn = $table->establishConnection('r');
$selects = array();
@@ -469,13 +469,13 @@ final class DifferentialRevisionQuery
$this->authors = array_merge($basic_authors, $this->responsibles);
$this->reviewers = $basic_reviewers;
$selects[] = $this->buildSelectStatement($conn_r);
$selects[] = $this->buildSelectStatement($conn);
// Build the query where the responsible users are reviewers, or
// projects they are members of are reviewers.
$this->authors = $basic_authors;
$this->reviewers = array_merge($basic_reviewers, $this->responsibles);
$selects[] = $this->buildSelectStatement($conn_r);
$selects[] = $this->buildSelectStatement($conn);
// Put everything back like it was.
$this->authors = $basic_authors;
@@ -486,21 +486,35 @@ final class DifferentialRevisionQuery
throw $ex;
}
} else {
$selects[] = $this->buildSelectStatement($conn_r);
$selects[] = $this->buildSelectStatement($conn);
}
if (count($selects) > 1) {
$unions = null;
foreach ($selects as $select) {
if (!$unions) {
$unions = $select;
continue;
}
$unions = qsprintf(
$conn,
'%Q UNION DISTINCT %Q',
$unions,
$select);
}
$query = qsprintf(
$conn_r,
$conn,
'%Q %Q %Q',
implode(' UNION DISTINCT ', $selects),
$this->buildOrderClause($conn_r, true),
$this->buildLimitClause($conn_r));
$unions,
$this->buildOrderClause($conn, true),
$this->buildLimitClause($conn));
} else {
$query = head($selects);
}
return queryfx_all($conn_r, '%Q', $query);
return queryfx_all($conn, '%Q', $query);
}
private function buildSelectStatement(AphrontDatabaseConnection $conn_r) {
@@ -542,26 +556,26 @@ final class DifferentialRevisionQuery
/**
* @task internal
*/
private function buildJoinsClause($conn_r) {
private function buildJoinsClause(AphrontDatabaseConnection $conn) {
$joins = array();
if ($this->pathIDs) {
$path_table = new DifferentialAffectedPath();
$joins[] = qsprintf(
$conn_r,
$conn,
'JOIN %T p ON p.revisionID = r.id',
$path_table->getTableName());
}
if ($this->commitHashes) {
$joins[] = qsprintf(
$conn_r,
$conn,
'JOIN %T hash_rel ON hash_rel.revisionID = r.id',
ArcanistDifferentialRevisionHash::TABLE_NAME);
}
if ($this->ccs) {
$joins[] = qsprintf(
$conn_r,
$conn,
'JOIN %T e_ccs ON e_ccs.src = r.phid '.
'AND e_ccs.type = %s '.
'AND e_ccs.dst in (%Ls)',
@@ -572,7 +586,7 @@ final class DifferentialRevisionQuery
if ($this->reviewers) {
$joins[] = qsprintf(
$conn_r,
$conn,
'JOIN %T reviewer ON reviewer.revisionPHID = r.phid
AND reviewer.reviewerStatus != %s
AND reviewer.reviewerPHID in (%Ls)',
@@ -583,7 +597,7 @@ final class DifferentialRevisionQuery
if ($this->draftAuthors) {
$joins[] = qsprintf(
$conn_r,
$conn,
'JOIN %T has_draft ON has_draft.srcPHID = r.phid
AND has_draft.type = %s
AND has_draft.dstPHID IN (%Ls)',
@@ -594,21 +608,21 @@ final class DifferentialRevisionQuery
if ($this->commitPHIDs) {
$joins[] = qsprintf(
$conn_r,
$conn,
'JOIN %T commits ON commits.revisionID = r.id',
DifferentialRevision::TABLE_COMMIT);
}
$joins[] = $this->buildJoinClauseParts($conn_r);
$joins[] = $this->buildJoinClauseParts($conn);
return $this->formatJoinClause($joins);
return $this->formatJoinClause($conn, $joins);
}
/**
* @task internal
*/
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->pathIDs) {
@@ -616,32 +630,32 @@ final class DifferentialRevisionQuery
$repo_info = igroup($this->pathIDs, 'repositoryID');
foreach ($repo_info as $repository_id => $paths) {
$path_clauses[] = qsprintf(
$conn_r,
$conn,
'(p.repositoryID = %d AND p.pathID IN (%Ld))',
$repository_id,
ipull($paths, 'pathID'));
}
$path_clauses = '('.implode(' OR ', $path_clauses).')';
$path_clauses = qsprintf($conn, '%LO', $path_clauses);
$where[] = $path_clauses;
}
if ($this->authors) {
$where[] = qsprintf(
$conn_r,
$conn,
'r.authorPHID IN (%Ls)',
$this->authors);
}
if ($this->revIDs) {
$where[] = qsprintf(
$conn_r,
$conn,
'r.id IN (%Ld)',
$this->revIDs);
}
if ($this->repositoryPHIDs) {
$where[] = qsprintf(
$conn_r,
$conn,
'r.repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
@@ -651,67 +665,67 @@ final class DifferentialRevisionQuery
foreach ($this->commitHashes as $info) {
list($type, $hash) = $info;
$hash_clauses[] = qsprintf(
$conn_r,
$conn,
'(hash_rel.type = %s AND hash_rel.hash = %s)',
$type,
$hash);
}
$hash_clauses = '('.implode(' OR ', $hash_clauses).')';
$hash_clauses = qsprintf($conn, '%LO', $hash_clauses);
$where[] = $hash_clauses;
}
if ($this->commitPHIDs) {
$where[] = qsprintf(
$conn_r,
$conn,
'commits.commitPHID IN (%Ls)',
$this->commitPHIDs);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
$conn,
'r.phid IN (%Ls)',
$this->phids);
}
if ($this->branches) {
$where[] = qsprintf(
$conn_r,
$conn,
'r.branchName in (%Ls)',
$this->branches);
}
if ($this->updatedEpochMin !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'r.dateModified >= %d',
$this->updatedEpochMin);
}
if ($this->updatedEpochMax !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'r.dateModified <= %d',
$this->updatedEpochMax);
}
if ($this->createdEpochMin !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'r.dateCreated >= %d',
$this->createdEpochMin);
}
if ($this->createdEpochMax !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'r.dateCreated <= %d',
$this->createdEpochMax);
}
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'r.status in (%Ls)',
$this->statuses);
}
@@ -725,13 +739,14 @@ final class DifferentialRevisionQuery
DifferentialLegacyQuery::STATUS_CLOSED);
}
$where[] = qsprintf(
$conn_r,
$conn,
'r.status in (%Ls)',
$statuses);
}
$where[] = $this->buildWhereClauseParts($conn_r);
return $this->formatWhereClause($where);
$where[] = $this->buildWhereClauseParts($conn);
return $this->formatWhereClause($conn, $where);
}

View File

@@ -57,6 +57,11 @@ abstract class DifferentialRevisionActionTransaction
return null;
}
protected function getRevisionActionSubmitButtonText(
DifferentialRevision $revision) {
return null;
}
public static function loadAllActions() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
@@ -110,6 +115,9 @@ abstract class DifferentialRevisionActionTransaction
$group_key = $this->getRevisionActionGroupKey();
$field->setCommentActionGroupKey($group_key);
$button_text = $this->getRevisionActionSubmitButtonText($revision);
$field->setActionSubmitButtonText($button_text);
// Currently, every revision action conflicts with every other
// revision action: for example, you can not simultaneously Accept and
// Reject a revision.

View File

@@ -59,11 +59,21 @@ final class DifferentialRevisionCommandeerTransaction
}
protected function validateAction($object, PhabricatorUser $viewer) {
if ($object->isClosed()) {
// If a revision has already landed, we generally want to discourage
// reopening and reusing it since this tends to create a big mess (users
// should create a new revision instead). Thus, we stop you from
// commandeering closed revisions.
// See PHI985. If the revision was abandoned, there's no peril in allowing
// the commandeer since the change (likely) never actually landed. So
// it's okay to commandeer abandoned revisions.
if ($object->isClosed() && !$object->isAbandoned()) {
throw new Exception(
pht(
'You can not commandeer this revision because it has already '.
'been closed. You can only commandeer open revisions.'));
'been closed. You can only commandeer open or abandoned '.
'revisions.'));
}
if ($this->isViewerRevisionAuthor($object, $viewer)) {

View File

@@ -19,6 +19,19 @@ final class DifferentialRevisionRequestReviewTransaction
}
}
protected function getRevisionActionSubmitButtonText(
DifferentialRevision $revision) {
// See PHI975. When the action stack will promote the revision out of
// draft, change the button text from "Submit Quietly".
if ($revision->isDraft()) {
return pht('Publish Revision');
}
return null;
}
public function getColor() {
return 'sky';
}

View File

@@ -57,6 +57,12 @@ final class DifferentialRevisionUpdateTransaction
// Harbormaster. See discussion in T8650.
$diff->setRevisionID($object->getID());
$diff->save();
}
public function didCommitTransaction($object, $value) {
$editor = $this->getEditor();
$diff = $editor->requireDiff($value);
$omnipotent = PhabricatorUser::getOmnipotentUser();
// If there are any outstanding buildables for this diff, tell
// Harbormaster that their containers need to be updated. This is
@@ -64,7 +70,7 @@ final class DifferentialRevisionUpdateTransaction
// and unit results.
$buildables = id(new HarbormasterBuildableQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->setViewer($omnipotent)
->withManualBuildables(false)
->withBuildablePHIDs(array($diff->getPHID()))
->execute();

View File

@@ -229,9 +229,9 @@ final class DiffusionLintSaveRunner extends Phobject {
$this->conn,
'INSERT INTO %T
(branchID, path, line, code, severity, name, description)
VALUES %Q',
VALUES %LQ',
PhabricatorRepository::TABLE_LINTMESSAGE,
implode(', ', $values));
$values);
}
$this->conn->saveTransaction();
@@ -295,10 +295,10 @@ final class DiffusionLintSaveRunner extends Phobject {
}
queryfx(
$this->conn,
'UPDATE %T SET authorPHID = %s WHERE %Q',
'UPDATE %T SET authorPHID = %s WHERE %LO',
PhabricatorRepository::TABLE_LINTMESSAGE,
$author,
implode(' OR ', $where));
$where);
}
$this->conn->saveTransaction();

View File

@@ -118,6 +118,9 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
$this->getQueryRoutePattern() => 'DiffusionPushLogListController',
'view/(?P<id>\d+)/' => 'DiffusionPushEventViewController',
),
'synclog/' => array(
$this->getQueryRoutePattern() => 'DiffusionSyncLogListController',
),
'pulllog/' => array(
$this->getQueryRoutePattern() => 'DiffusionPullLogListController',
),

View File

@@ -21,6 +21,7 @@ final class DiffusionBranchQueryConduitAPIMethod
'limit' => 'optional int',
'offset' => 'optional int',
'contains' => 'optional string',
'patterns' => 'optional list<string>',
);
}
@@ -31,15 +32,17 @@ final class DiffusionBranchQueryConduitAPIMethod
$contains = $request->getValue('contains');
if (strlen($contains)) {
// See PHI720. If the standard "branch" field is provided, use it
// as the "pattern" argument to "git branch ..." to let callers test
// for reachability from a particular branch head.
$pattern = $request->getValue('branch');
if (strlen($pattern)) {
$pattern_argv = array($pattern);
} else {
$pattern_argv = array();
}
// See PHI958 (and, earlier, PHI720). If "patterns" are provided, pass
// them to "git branch ..." to let callers test for reachability from
// particular branch heads.
$patterns_argv = $request->getValue('patterns', array());
PhutilTypeSpec::checkMap(
array(
'patterns' => $patterns_argv,
),
array(
'patterns' => 'list<string>',
));
// NOTE: We can't use DiffusionLowLevelGitRefQuery here because
// `git for-each-ref` does not support `--contains`.
@@ -47,14 +50,14 @@ final class DiffusionBranchQueryConduitAPIMethod
list($stdout) = $repository->execxLocalCommand(
'branch --verbose --no-abbrev --contains %s -- %Ls',
$contains,
$pattern_argv);
$patterns_argv);
$ref_map = DiffusionGitBranch::parseLocalBranchOutput(
$stdout);
} else {
list($stdout) = $repository->execxLocalCommand(
'branch -r --verbose --no-abbrev --contains %s -- %Ls',
$contains,
$pattern_argv);
$patterns_argv);
$ref_map = DiffusionGitBranch::parseRemoteBranchOutput(
$stdout,
DiffusionGitBranch::DEFAULT_GIT_REMOTE);

View File

@@ -451,13 +451,13 @@ final class DiffusionBrowseQueryConduitAPIMethod
WHERE repositoryID = %d
AND parentID = %d
AND existed = 1
AND (%Q)
AND (%LO)
ORDER BY pathName',
PhabricatorRepository::TABLE_FILESYSTEM,
PhabricatorRepository::TABLE_PATH,
$repository->getID(),
$path_id,
implode(' OR ', $sql));
$sql);
$loadable_commits = array();
foreach ($browse as $key => $file) {

View File

@@ -106,8 +106,8 @@ final class DiffusionUpdateCoverageConduitAPIMethod
foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
queryfx(
$conn,
'INSERT INTO %T (branchID, pathID, commitID, coverage) VALUES %Q'.
' ON DUPLICATE KEY UPDATE coverage=VALUES(coverage)',
'INSERT INTO %T (branchID, pathID, commitID, coverage) VALUES %LQ'.
' ON DUPLICATE KEY UPDATE coverage = VALUES(coverage)',
$table_name,
$chunk);
}

View File

@@ -276,13 +276,13 @@ final class DiffusionLintController extends DiffusionController {
array_keys($branch),
$path->getPath());
if ($path->getExcluded()) {
$where[] = 'NOT '.$condition;
$where[] = qsprintf($conn, 'NOT %Q', $condition);
} else {
$or[] = $condition;
}
}
}
$where[] = '('.implode(' OR ', $or).')';
$where[] = qsprintf($conn, '%LO', $or);
}
return queryfx_all(
@@ -296,11 +296,11 @@ final class DiffusionLintController extends DiffusionController {
COUNT(DISTINCT path) AS files,
COUNT(*) AS n
FROM %T
WHERE %Q
WHERE %LA
GROUP BY branchID, code
ORDER BY n DESC',
PhabricatorRepository::TABLE_LINTMESSAGE,
implode(' AND ', $where));
$where);
}
protected function buildActionView(DiffusionRequest $drequest) {
@@ -526,10 +526,10 @@ final class DiffusionLintController extends DiffusionController {
$conn,
'SELECT *
FROM %T
WHERE %Q
WHERE %LA
ORDER BY path, code, line LIMIT %d OFFSET %d',
PhabricatorRepository::TABLE_LINTMESSAGE,
implode(' AND ', $where),
$where,
$limit,
$offset);
}

View File

@@ -370,8 +370,17 @@ final class DiffusionRepositoryController extends DiffusionController {
$action_view->addAction(
id(new PhabricatorActionView())
->setName(pht('View Push Logs'))
->setIcon('fa-list-alt')
->setIcon('fa-upload')
->setHref($push_uri));
$pull_uri = $this->getApplicationURI(
'synclog/?repositories='.$repository->getPHID());
$action_view->addAction(
id(new PhabricatorActionView())
->setName(pht('View Sync Logs'))
->setIcon('fa-exchange')
->setHref($pull_uri));
}
$pull_uri = $this->getApplicationURI(
@@ -380,7 +389,7 @@ final class DiffusionRepositoryController extends DiffusionController {
$action_view->addAction(
id(new PhabricatorActionView())
->setName(pht('View Pull Logs'))
->setIcon('fa-list-alt')
->setIcon('fa-download')
->setHref($pull_uri));
return $action_view;

View File

@@ -25,7 +25,8 @@ final class DiffusionRepositoryEditActivateController
}
$xaction = id(new PhabricatorRepositoryTransaction())
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_ACTIVATE)
->setTransactionType(
PhabricatorRepositoryActivateTransaction::TRANSACTIONTYPE)
->setNewValue($new_status);
$editor = id(new PhabricatorRepositoryEditor())

View File

@@ -30,7 +30,8 @@ final class DiffusionRepositoryEditDangerousController
if ($request->isFormPost()) {
$xaction = id(new PhabricatorRepositoryTransaction())
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_DANGEROUS)
->setTransactionType(
PhabricatorRepositoryDangerousTransaction::TRANSACTIONTYPE)
->setNewValue(!$repository->shouldAllowDangerousChanges());
$editor = id(new PhabricatorRepositoryEditor())

View File

@@ -30,7 +30,8 @@ final class DiffusionRepositoryEditEnormousController
if ($request->isFormPost()) {
$xaction = id(new PhabricatorRepositoryTransaction())
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_ENORMOUS)
->setTransactionType(
PhabricatorRepositoryEnormousTransaction::TRANSACTIONTYPE)
->setNewValue(!$repository->shouldAllowEnormousChanges());
$editor = id(new PhabricatorRepositoryEditor())

View File

@@ -68,13 +68,17 @@ final class DiffusionRepositoryManagePanelsController
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setNavigation($nav)
->setFixed(true)
->setMainColumn($content);
$curtain = $panel->buildManagementPanelCurtain();
if ($curtain) {
$view->setCurtain($curtain);
}
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->setNavigation($nav)
->appendChild($view);
}
@@ -89,20 +93,45 @@ final class DiffusionRepositoryManagePanelsController
$nav = id(new AphrontSideNavFilterView())
->setBaseURI($base_uri);
foreach ($panels as $panel) {
$key = $panel->getManagementPanelKey();
$label = $panel->getManagementPanelLabel();
$icon = $panel->getManagementPanelIcon();
$href = $panel->getPanelNavigationURI();
$groups = DiffusionRepositoryManagementPanelGroup::getAllPanelGroups();
$panel_groups = mgroup($panels, 'getManagementPanelGroupKey');
$other_key = DiffusionRepositoryManagementOtherPanelGroup::PANELGROUPKEY;
$item = id(new PHUIListItemView())
->setKey($key)
->setName($label)
->setType(PHUIListItemView::TYPE_LINK)
->setHref($href)
->setIcon($icon);
foreach ($groups as $group_key => $group) {
// If this is the "Other" group, include everything else that isn't in
// some actual group.
if ($group_key === $other_key) {
$group_panels = array_mergev($panel_groups);
$panel_groups = array();
} else {
$group_panels = idx($panel_groups, $group_key);
unset($panel_groups[$group_key]);
}
$nav->addMenuItem($item);
if (!$group_panels) {
continue;
}
$label = $group->getManagementPanelGroupLabel();
if ($label) {
$nav->addLabel($label);
}
foreach ($group_panels as $panel) {
$key = $panel->getManagementPanelKey();
$label = $panel->getManagementPanelLabel();
$icon = $panel->getManagementPanelIcon();
$href = $panel->getPanelNavigationURI();
$item = id(new PHUIListItemView())
->setKey($key)
->setName($label)
->setType(PHUIListItemView::TYPE_LINK)
->setHref($href)
->setIcon($icon);
$nav->addMenuItem($item);
}
}
$nav->selectFilter($selected);

View File

@@ -0,0 +1,17 @@
<?php
final class DiffusionSyncLogListController
extends DiffusionLogController {
public function handleRequest(AphrontRequest $request) {
return id(new DiffusionSyncLogSearchEngine())
->setController($this)
->buildResponse();
}
protected function buildApplicationCrumbs() {
return parent::buildApplicationCrumbs()
->addTextCrumb(pht('Sync Logs'), $this->getApplicationURI('synclog/'));
}
}

View File

@@ -243,8 +243,9 @@ final class DiffusionRepositoryEditEngine
id(new PhabricatorSelectEditField())
->setKey('vcs')
->setLabel(pht('Version Control System'))
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_VCS)
->setIsConduitOnly(true)
->setTransactionType(
PhabricatorRepositoryVCSTransaction::TRANSACTIONTYPE)
->setIsFormField(false)
->setIsCopyable(true)
->setOptions(PhabricatorRepositoryType::getAllRepositoryTypes())
->setDescription(pht('Underlying repository version control system.'))
@@ -258,7 +259,8 @@ final class DiffusionRepositoryEditEngine
->setKey('name')
->setLabel(pht('Name'))
->setIsRequired(true)
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_NAME)
->setTransactionType(
PhabricatorRepositoryNameTransaction::TRANSACTIONTYPE)
->setDescription(pht('The repository name.'))
->setConduitDescription(pht('Rename the repository.'))
->setConduitTypeDescription(pht('New repository name.'))
@@ -266,7 +268,8 @@ final class DiffusionRepositoryEditEngine
id(new PhabricatorTextEditField())
->setKey('callsign')
->setLabel(pht('Callsign'))
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_CALLSIGN)
->setTransactionType(
PhabricatorRepositoryCallsignTransaction::TRANSACTIONTYPE)
->setDescription(pht('The repository callsign.'))
->setConduitDescription(pht('Change the repository callsign.'))
->setConduitTypeDescription(pht('New repository callsign.'))
@@ -274,7 +277,8 @@ final class DiffusionRepositoryEditEngine
id(new PhabricatorTextEditField())
->setKey('shortName')
->setLabel(pht('Short Name'))
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_SLUG)
->setTransactionType(
PhabricatorRepositorySlugTransaction::TRANSACTIONTYPE)
->setDescription(pht('Short, unique repository name.'))
->setConduitDescription(pht('Change the repository short name.'))
->setConduitTypeDescription(pht('New short name for the repository.'))
@@ -282,7 +286,8 @@ final class DiffusionRepositoryEditEngine
id(new PhabricatorRemarkupEditField())
->setKey('description')
->setLabel(pht('Description'))
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_DESCRIPTION)
->setTransactionType(
PhabricatorRepositoryDescriptionTransaction::TRANSACTIONTYPE)
->setDescription(pht('Repository description.'))
->setConduitDescription(pht('Change the repository description.'))
->setConduitTypeDescription(pht('New repository description.'))
@@ -291,7 +296,8 @@ final class DiffusionRepositoryEditEngine
->setKey('encoding')
->setLabel(pht('Text Encoding'))
->setIsCopyable(true)
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_ENCODING)
->setTransactionType(
PhabricatorRepositoryEncodingTransaction::TRANSACTIONTYPE)
->setDescription(pht('Default text encoding.'))
->setConduitDescription(pht('Change the default text encoding.'))
->setConduitTypeDescription(pht('New text encoding.'))
@@ -300,11 +306,12 @@ final class DiffusionRepositoryEditEngine
->setKey('allowDangerousChanges')
->setLabel(pht('Allow Dangerous Changes'))
->setIsCopyable(true)
->setIsConduitOnly(true)
->setIsFormField(false)
->setOptions(
pht('Prevent Dangerous Changes'),
pht('Allow Dangerous Changes'))
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_DANGEROUS)
->setTransactionType(
PhabricatorRepositoryDangerousTransaction::TRANSACTIONTYPE)
->setDescription(pht('Permit dangerous changes to be made.'))
->setConduitDescription(pht('Allow or prevent dangerous changes.'))
->setConduitTypeDescription(pht('New protection setting.'))
@@ -313,11 +320,12 @@ final class DiffusionRepositoryEditEngine
->setKey('allowEnormousChanges')
->setLabel(pht('Allow Enormous Changes'))
->setIsCopyable(true)
->setIsConduitOnly(true)
->setIsFormField(false)
->setOptions(
pht('Prevent Enormous Changes'),
pht('Allow Enormous Changes'))
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_ENORMOUS)
->setTransactionType(
PhabricatorRepositoryEnormousTransaction::TRANSACTIONTYPE)
->setDescription(pht('Permit enormous changes to be made.'))
->setConduitDescription(pht('Allow or prevent enormous changes.'))
->setConduitTypeDescription(pht('New protection setting.'))
@@ -325,8 +333,9 @@ final class DiffusionRepositoryEditEngine
id(new PhabricatorSelectEditField())
->setKey('status')
->setLabel(pht('Status'))
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_ACTIVATE)
->setIsConduitOnly(true)
->setTransactionType(
PhabricatorRepositoryActivateTransaction::TRANSACTIONTYPE)
->setIsFormField(false)
->setOptions(PhabricatorRepository::getStatusNameMap())
->setDescription(pht('Active or inactive status.'))
->setConduitDescription(pht('Active or deactivate the repository.'))
@@ -336,7 +345,7 @@ final class DiffusionRepositoryEditEngine
->setKey('defaultBranch')
->setLabel(pht('Default Branch'))
->setTransactionType(
PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH)
PhabricatorRepositoryDefaultBranchTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setDescription(pht('Default branch name.'))
->setConduitDescription(pht('Set the default branch name.'))
@@ -347,7 +356,7 @@ final class DiffusionRepositoryEditEngine
->setKey('trackOnly')
->setLabel(pht('Track Only'))
->setTransactionType(
PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY)
PhabricatorRepositoryTrackOnlyTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setDescription(pht('Track only these branches.'))
->setConduitDescription(pht('Set the tracked branches.'))
@@ -358,7 +367,7 @@ final class DiffusionRepositoryEditEngine
->setKey('autocloseOnly')
->setLabel(pht('Autoclose Only'))
->setTransactionType(
PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY)
PhabricatorRepositoryAutocloseOnlyTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setDescription(pht('Autoclose commits on only these branches.'))
->setConduitDescription(pht('Set the autoclose branches.'))
@@ -368,7 +377,7 @@ final class DiffusionRepositoryEditEngine
->setKey('importOnly')
->setLabel(pht('Import Only'))
->setTransactionType(
PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH)
PhabricatorRepositorySVNSubpathTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setDescription(pht('Subpath to selectively import.'))
->setConduitDescription(pht('Set the subpath to import.'))
@@ -379,7 +388,7 @@ final class DiffusionRepositoryEditEngine
->setKey('stagingAreaURI')
->setLabel(pht('Staging Area URI'))
->setTransactionType(
PhabricatorRepositoryTransaction::TYPE_STAGING_URI)
PhabricatorRepositoryStagingURITransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setDescription(pht('Staging area URI.'))
->setConduitDescription(pht('Set the staging area URI.'))
@@ -390,7 +399,7 @@ final class DiffusionRepositoryEditEngine
->setKey('automationBlueprintPHIDs')
->setLabel(pht('Use Blueprints'))
->setTransactionType(
PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS)
PhabricatorRepositoryBlueprintsTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setDatasource(new DrydockBlueprintDatasource())
->setDescription(pht('Automation blueprints.'))
@@ -402,7 +411,7 @@ final class DiffusionRepositoryEditEngine
->setKey('symbolLanguages')
->setLabel(pht('Languages'))
->setTransactionType(
PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE)
PhabricatorRepositorySymbolLanguagesTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setDescription(
pht('Languages which define symbols in this repository.'))
@@ -415,7 +424,7 @@ final class DiffusionRepositoryEditEngine
->setKey('symbolRepositoryPHIDs')
->setLabel(pht('Uses Symbols From'))
->setTransactionType(
PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES)
PhabricatorRepositorySymbolSourcesTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setDatasource(new DiffusionRepositoryDatasource())
->setDescription(pht('Repositories to link symbols from.'))
@@ -426,7 +435,7 @@ final class DiffusionRepositoryEditEngine
->setKey('publish')
->setLabel(pht('Publish/Notify'))
->setTransactionType(
PhabricatorRepositoryTransaction::TYPE_NOTIFY)
PhabricatorRepositoryNotifyTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setOptions(
pht('Disable Notifications, Feed, and Herald'),
@@ -439,7 +448,7 @@ final class DiffusionRepositoryEditEngine
->setKey('autoclose')
->setLabel(pht('Autoclose'))
->setTransactionType(
PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE)
PhabricatorRepositoryAutocloseTransaction::TRANSACTIONTYPE)
->setIsCopyable(true)
->setOptions(
pht('Disable Autoclose'),
@@ -455,13 +464,42 @@ final class DiffusionRepositoryEditEngine
->setIsCopyable(true)
->setCapability(DiffusionPushCapability::CAPABILITY)
->setPolicies($policies)
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY)
->setTransactionType(
PhabricatorRepositoryPushPolicyTransaction::TRANSACTIONTYPE)
->setDescription(
pht('Controls who can push changes to the repository.'))
->setConduitDescription(
pht('Change the push policy of the repository.'))
->setConduitTypeDescription(pht('New policy PHID or constant.'))
->setValue($object->getPolicy(DiffusionPushCapability::CAPABILITY)),
id(new PhabricatorTextEditField())
->setKey('filesizeLimit')
->setLabel(pht('Filesize Limit'))
->setTransactionType(
PhabricatorRepositoryFilesizeLimitTransaction::TRANSACTIONTYPE)
->setDescription(pht('Maximum permitted file size.'))
->setConduitDescription(pht('Change the filesize limit.'))
->setConduitTypeDescription(pht('New repository filesize limit.'))
->setValue($object->getFilesizeLimit()),
id(new PhabricatorTextEditField())
->setKey('copyTimeLimit')
->setLabel(pht('Clone/Fetch Timeout'))
->setTransactionType(
PhabricatorRepositoryCopyTimeLimitTransaction::TRANSACTIONTYPE)
->setDescription(
pht('Maximum permitted duration of internal clone/fetch.'))
->setConduitDescription(pht('Change the copy time limit.'))
->setConduitTypeDescription(pht('New repository copy time limit.'))
->setValue($object->getCopyTimeLimit()),
id(new PhabricatorTextEditField())
->setKey('touchLimit')
->setLabel(pht('Touched Paths Limit'))
->setTransactionType(
PhabricatorRepositoryTouchLimitTransaction::TRANSACTIONTYPE)
->setDescription(pht('Maximum permitted paths touched per commit.'))
->setConduitDescription(pht('Change the touch limit.'))
->setConduitTypeDescription(pht('New repository touch limit.'))
->setValue($object->getTouchLimit()),
);
}

View File

@@ -150,7 +150,7 @@ final class DiffusionURIEditEngine
->setAliases(array('repositoryPHID'))
->setLabel(pht('Repository'))
->setIsRequired(true)
->setIsConduitOnly(true)
->setIsFormField(false)
->setTransactionType(
PhabricatorRepositoryURITransaction::TYPE_REPOSITORY)
->setDescription(pht('The repository this URI is associated with.'))
@@ -195,7 +195,7 @@ final class DiffusionURIEditEngine
->setKey('credential')
->setAliases(array('credentialPHID'))
->setLabel(pht('Credential'))
->setIsConduitOnly(true)
->setIsFormField(false)
->setTransactionType(
PhabricatorRepositoryURITransaction::TYPE_CREDENTIAL)
->setDescription(
@@ -206,7 +206,7 @@ final class DiffusionURIEditEngine
id(new PhabricatorBoolEditField())
->setKey('disable')
->setLabel(pht('Disabled'))
->setIsConduitOnly(true)
->setIsFormField(false)
->setTransactionType(PhabricatorRepositoryURITransaction::TYPE_DISABLE)
->setDescription(pht('Active status of the URI.'))
->setConduitDescription(pht('Disable or activate the URI.'))

View File

@@ -31,6 +31,7 @@ final class DiffusionCommitHookEngine extends Phobject {
private $mercurialHook;
private $mercurialCommits = array();
private $gitCommits = array();
private $startTime;
private $heraldViewerProjects;
private $rejectCode = PhabricatorRepositoryPushLog::REJECT_BROKEN;
@@ -38,6 +39,7 @@ final class DiffusionCommitHookEngine extends Phobject {
private $emailPHIDs = array();
private $changesets = array();
private $changesetsSize = 0;
private $filesizeCache = array();
/* -( Config )------------------------------------------------------------- */
@@ -70,6 +72,15 @@ final class DiffusionCommitHookEngine extends Phobject {
return $this->requestIdentifier;
}
public function setStartTime($start_time) {
$this->startTime = $start_time;
return $this;
}
public function getStartTime() {
return $this->startTime;
}
public function setSubversionTransactionInfo($transaction, $repository) {
$this->subversionTransaction = $transaction;
$this->subversionRepository = $repository;
@@ -154,6 +165,25 @@ final class DiffusionCommitHookEngine extends Phobject {
$this->applyHeraldRefRules($ref_updates);
}
try {
if (!$is_initial_import) {
$this->rejectOversizedFiles($content_updates);
}
} catch (DiffusionCommitHookRejectException $ex) {
// If we're rejecting oversized files, flag everything.
$this->rejectCode = PhabricatorRepositoryPushLog::REJECT_OVERSIZED;
throw $ex;
}
try {
if (!$is_initial_import) {
$this->rejectCommitsAffectingTooManyPaths($content_updates);
}
} catch (DiffusionCommitHookRejectException $ex) {
$this->rejectCode = PhabricatorRepositoryPushLog::REJECT_TOUCHES;
throw $ex;
}
try {
if (!$is_initial_import) {
$this->rejectEnormousChanges($content_updates);
@@ -1102,11 +1132,14 @@ final class DiffusionCommitHookEngine extends Phobject {
private function newPushEvent() {
$viewer = $this->getViewer();
$hook_start = $this->getStartTime();
$event = PhabricatorRepositoryPushEvent::initializeNewEvent($viewer)
->setRepositoryPHID($this->getRepository()->getPHID())
->setRemoteAddress($this->getRemoteAddress())
->setRemoteProtocol($this->getRemoteProtocol())
->setEpoch(PhabricatorTime::getNow());
->setEpoch(PhabricatorTime::getNow())
->setHookWait(phutil_microseconds_since($hook_start));
$identifier = $this->getRequestIdentifier();
if (strlen($identifier)) {
@@ -1242,6 +1275,92 @@ final class DiffusionCommitHookEngine extends Phobject {
return $changesets;
}
private function rejectOversizedFiles(array $content_updates) {
$repository = $this->getRepository();
$limit = $repository->getFilesizeLimit();
if (!$limit) {
return;
}
foreach ($content_updates as $update) {
$identifier = $update->getRefNew();
$sizes = $this->getFileSizesForCommit($identifier);
foreach ($sizes as $path => $size) {
if ($size <= $limit) {
continue;
}
$message = pht(
'OVERSIZED FILE'.
"\n".
'This repository ("%s") is configured with a maximum individual '.
'file size limit, but you are pushing a change ("%s") which causes '.
'the size of a file ("%s") to exceed the limit. The commit makes '.
'the file %s bytes long, but the limit for this repository is '.
'%s bytes.',
$repository->getDisplayName(),
$identifier,
$path,
new PhutilNumber($size),
new PhutilNumber($limit));
throw new DiffusionCommitHookRejectException($message);
}
}
}
private function rejectCommitsAffectingTooManyPaths(array $content_updates) {
$repository = $this->getRepository();
$limit = $repository->getTouchLimit();
if (!$limit) {
return;
}
foreach ($content_updates as $update) {
$identifier = $update->getRefNew();
$sizes = $this->getFileSizesForCommit($identifier);
if (count($sizes) > $limit) {
$message = pht(
'COMMIT AFFECTS TOO MANY PATHS'.
"\n".
'This repository ("%s") is configured with a touched files limit '.
'that caps the maximum number of paths any single commit may '.
'affect. You are pushing a change ("%s") which exceeds this '.
'limit: it affects %s paths, but the largest number of paths any '.
'commit may affect is %s paths.',
$repository->getDisplayName(),
$identifier,
phutil_count($sizes),
new PhutilNumber($limit));
throw new DiffusionCommitHookRejectException($message);
}
}
}
public function getFileSizesForCommit($identifier) {
if (!isset($this->filesizeCache[$identifier])) {
$file_sizes = $this->loadFileSizesForCommit($identifier);
$this->filesizeCache[$identifier] = $file_sizes;
}
return $this->filesizeCache[$identifier];
}
private function loadFileSizesForCommit($identifier) {
$repository = $this->getRepository();
return id(new DiffusionLowLevelFilesizeQuery())
->setRepository($repository)
->withIdentifier($identifier)
->execute();
}
public function loadCommitRefForCommit($identifier) {
$repository = $this->getRepository();
$vcs = $repository->getVersionControlSystem();

View File

@@ -14,7 +14,20 @@ final class DiffusionRepositoryActionsManagementPanel
}
public function getManagementPanelIcon() {
return 'fa-flash';
$repository = $this->getRepository();
$has_any =
$repository->getDetail('herald-disabled') ||
$repository->getDetail('disable-autoclose');
// NOTE: Any value here really means something is disabled, so try to
// hint that a little bit with the icon.
if ($has_any) {
return 'fa-flash';
} else {
return 'fa-flash grey';
}
}
protected function getEditEngineFieldKeys() {
@@ -24,6 +37,30 @@ final class DiffusionRepositoryActionsManagementPanel
);
}
public function buildManagementPanelCurtain() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$action_list = $this->newActionList();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$actions_uri = $this->getEditPageURI();
$action_list->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Actions'))
->setHref($actions_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
return $this->newCurtainView()
->setActionList($action_list);
}
public function buildManagementPanelContent() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
@@ -43,22 +80,7 @@ final class DiffusionRepositoryActionsManagementPanel
$autoclose = phutil_tag('em', array(), $autoclose);
$view->addProperty(pht('Autoclose'), $autoclose);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$actions_uri = $this->getEditPageURI();
$button = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-pencil')
->setText(pht('Edit'))
->setHref($actions_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit);
return $this->newBox(pht('Actions'), $view, array($button));
return $this->newBox(pht('Actions'), $view);
}
}

View File

@@ -13,6 +13,10 @@ final class DiffusionRepositoryAutomationManagementPanel
return 800;
}
public function getManagementPanelGroupKey() {
return DiffusionRepositoryManagementBuildsPanelGroup::PANELGROUPKEY;
}
public function shouldEnableForRepository(
PhabricatorRepository $repository) {
return $repository->isGit();
@@ -27,18 +31,60 @@ final class DiffusionRepositoryAutomationManagementPanel
public function getManagementPanelIcon() {
$repository = $this->getRepository();
if (!$repository->canPerformAutomation()) {
return 'fa-truck grey';
}
$blueprint_phids = $repository->getAutomationBlueprintPHIDs();
if (!$blueprint_phids) {
return 'fa-truck grey';
}
$is_authorized = DrydockAuthorizationQuery::isFullyAuthorized(
$repository->getPHID(),
$blueprint_phids);
if (!$is_authorized) {
return 'fa-exclamation-triangle';
return 'fa-exclamation-triangle yellow';
}
return 'fa-truck';
}
public function buildManagementPanelCurtain() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$action_list = $this->newActionList();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$can_test = $can_edit && $repository->canPerformAutomation();
$automation_uri = $this->getEditPageURI();
$test_uri = $repository->getPathURI('edit/testautomation/');
$action_list->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Automation'))
->setHref($automation_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$action_list->addAction(
id(new PhabricatorActionView())
->setIcon('fa-gamepad')
->setName(pht('Test Configuration'))
->setWorkflow(true)
->setDisabled(!$can_test)
->setHref($test_uri));
return $this->newCurtainView()
->setActionList($action_list);
}
public function buildManagementPanelContent() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
@@ -58,33 +104,7 @@ final class DiffusionRepositoryAutomationManagementPanel
$view->addProperty(pht('Automation'), $blueprint_view);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$can_test = $can_edit && $repository->canPerformAutomation();
$automation_uri = $this->getEditPageURI();
$test_uri = $repository->getPathURI('edit/testautomation/');
$edit = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-pencil')
->setText(pht('Edit'))
->setHref($automation_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit);
$test = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-gamepad')
->setText(pht('Test Config'))
->setWorkflow(true)
->setDisabled(!$can_test)
->setHref($test_uri);
return $this->newBox(pht('Automation'), $view, array($edit, $test));
return $this->newBox(pht('Automation'), $view);
}
}

View File

@@ -27,9 +27,10 @@ final class DiffusionRepositoryBasicsManagementPanel
);
}
private function buildActionMenu() {
public function buildManagementPanelCurtain() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$action_list = id(new PhabricatorActionListView())
->setViewer($viewer);
@@ -44,27 +45,34 @@ final class DiffusionRepositoryBasicsManagementPanel
$encoding_uri = $this->getEditPageURI('encoding');
$dangerous_uri = $repository->getPathURI('edit/dangerous/');
$enormous_uri = $repository->getPathURI('edit/enormous/');
$update_uri = $repository->getPathURI('edit/update/');
if ($repository->isTracked()) {
$activate_icon = 'fa-ban';
$activate_label = pht('Deactivate Repository');
} else {
$activate_icon = 'fa-check';
$activate_label = pht('Activate Repository');
}
$should_dangerous = $repository->shouldAllowDangerousChanges();
if ($should_dangerous) {
$dangerous_icon = 'fa-shield';
$dangerous_name = pht('Prevent Dangerous Changes');
$can_dangerous = $can_edit;
} else {
$dangerous_icon = 'fa-exclamation-triangle';
$dangerous_name = pht('Allow Dangerous Changes');
$can_dangerous = ($can_edit && $repository->canAllowDangerousChanges());
}
$should_enormous = $repository->shouldAllowEnormousChanges();
if ($should_enormous) {
$enormous_icon = 'fa-shield';
$enormous_name = pht('Prevent Enormous Changes');
$can_enormous = $can_edit;
} else {
$enormous_icon = 'fa-exclamation-triangle';
$enormous_name = pht('Allow Enormous Changes');
$can_enormous = ($can_edit && $repository->canAllowEnormousChanges());
}
@@ -73,12 +81,14 @@ final class DiffusionRepositoryBasicsManagementPanel
id(new PhabricatorActionView())
->setName(pht('Edit Basic Information'))
->setHref($edit_uri)
->setIcon('fa-pencil')
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$action_list->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Text Encoding'))
->setIcon('fa-text-width')
->setHref($encoding_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
@@ -87,6 +97,7 @@ final class DiffusionRepositoryBasicsManagementPanel
id(new PhabricatorActionView())
->setName($dangerous_name)
->setHref($dangerous_uri)
->setIcon($dangerous_icon)
->setDisabled(!$can_dangerous)
->setWorkflow(true));
@@ -94,16 +105,26 @@ final class DiffusionRepositoryBasicsManagementPanel
id(new PhabricatorActionView())
->setName($enormous_name)
->setHref($enormous_uri)
->setIcon($enormous_icon)
->setDisabled(!$can_enormous)
->setWorkflow(true));
$action_list->addAction(
id(new PhabricatorActionView())
->setHref($activate_uri)
->setName($activate_label)
->setHref($activate_uri)
->setIcon($activate_icon)
->setDisabled(!$can_edit)
->setWorkflow(true));
$action_list->addAction(
id(new PhabricatorActionView())
->setName(pht('Update Now'))
->setHref($update_uri)
->setIcon('fa-refresh')
->setWorkflow(true)
->setDisabled(!$can_edit));
$action_list->addAction(
id(new PhabricatorActionView())
->setType(PhabricatorActionView::TYPE_DIVIDER));
@@ -112,25 +133,18 @@ final class DiffusionRepositoryBasicsManagementPanel
id(new PhabricatorActionView())
->setName(pht('Delete Repository'))
->setHref($delete_uri)
->setIcon('fa-times')
->setColor(PhabricatorActionView::RED)
->setDisabled(true)
->setWorkflow(true));
return $action_list;
return $this->newCurtainView()
->setActionList($action_list);
}
public function buildManagementPanelContent() {
$button = id(new PHUIButtonView())
->setTag('a')
->setText(pht('Actions'))
->setHref('#')
->setIcon('fa-bars')
->addClass('phui-mobile-menu')
->setDropdownMenu($this->buildActionMenu());
$basics = $this->buildBasics();
$basics = $this->newBox(pht('Properties'), $basics, array($button));
$basics = $this->newBox(pht('Properties'), $basics);
$repository = $this->getRepository();
$is_new = $repository->isNewlyInitialized();
@@ -254,7 +268,6 @@ final class DiffusionRepositoryBasicsManagementPanel
private function buildStatus() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$update_uri = $repository->getPathURI('edit/update/');
$view = id(new PHUIPropertyListView())
->setViewer($viewer);
@@ -274,20 +287,7 @@ final class DiffusionRepositoryBasicsManagementPanel
$view->addTextContent($raw_error);
}
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$button = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-refresh')
->setText(pht('Update Now'))
->setWorkflow(true)
->setDisabled(!$can_edit)
->setHref($update_uri);
return $this->newBox(pht('Status'), $view, array($button));
return $this->newBox(pht('Status'), $view);
}
private function buildRepositoryUpdateInterval(

View File

@@ -19,7 +19,18 @@ final class DiffusionRepositoryBranchesManagementPanel
}
public function getManagementPanelIcon() {
return 'fa-code-fork';
$repository = $this->getRepository();
$has_any =
$repository->getDetail('default-branch') ||
$repository->getDetail('branch-filter') ||
$repository->getDetail('close-commits-filter');
if ($has_any) {
return 'fa-code-fork';
} else {
return 'fa-code-fork grey';
}
}
protected function getEditEngineFieldKeys() {
@@ -30,6 +41,30 @@ final class DiffusionRepositoryBranchesManagementPanel
);
}
public function buildManagementPanelCurtain() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$action_list = $this->newActionList();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$branches_uri = $this->getEditPageURI();
$action_list->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Branches'))
->setHref($branches_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
return $this->newCurtainView()
->setActionList($action_list);
}
public function buildManagementPanelContent() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
@@ -61,22 +96,7 @@ final class DiffusionRepositoryBranchesManagementPanel
$view->addProperty(pht('Autoclose Only'), $autoclose_only);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$branches_uri = $this->getEditPageURI();
$button = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-pencil')
->setText(pht('Edit'))
->setHref($branches_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit);
$content[] = $this->newBox(pht('Branches'), $view, array($button));
$content[] = $this->newBox(pht('Branches'), $view);
// Branch Autoclose Table
if (!$repository->isImporting()) {

View File

@@ -0,0 +1,112 @@
<?php
final class DiffusionRepositoryLimitsManagementPanel
extends DiffusionRepositoryManagementPanel {
const PANELKEY = 'limits';
public function getManagementPanelLabel() {
return pht('Limits');
}
public function getManagementPanelOrder() {
return 700;
}
public function shouldEnableForRepository(
PhabricatorRepository $repository) {
return $repository->isGit();
}
public function getManagementPanelIcon() {
$repository = $this->getRepository();
$any_limit = false;
if ($repository->getFilesizeLimit()) {
$any_limit = true;
}
if ($any_limit) {
return 'fa-signal';
} else {
return 'fa-signal grey';
}
}
protected function getEditEngineFieldKeys() {
return array(
'filesizeLimit',
'copyTimeLimit',
'touchLimit',
);
}
public function buildManagementPanelCurtain() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$action_list = $this->newActionList();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$limits_uri = $this->getEditPageURI();
$action_list->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Limits'))
->setHref($limits_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
return $this->newCurtainView()
->setActionList($action_list);
}
public function buildManagementPanelContent() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setViewer($viewer);
$byte_limit = $repository->getFilesizeLimit();
if ($byte_limit) {
$filesize_display = pht('%s Bytes', new PhutilNumber($byte_limit));
} else {
$filesize_display = pht('Unlimited');
$filesize_display = phutil_tag('em', array(), $filesize_display);
}
$view->addProperty(pht('Filesize Limit'), $filesize_display);
$copy_limit = $repository->getCopyTimeLimit();
if ($copy_limit) {
$copy_display = pht('%s Seconds', new PhutilNumber($copy_limit));
} else {
$copy_default = $repository->getDefaultCopyTimeLimit();
$copy_display = pht(
'Default (%s Seconds)',
new PhutilNumber($copy_default));
$copy_display = phutil_tag('em', array(), $copy_display);
}
$view->addProperty(pht('Clone/Fetch Timeout'), $copy_display);
$touch_limit = $repository->getTouchLimit();
if ($touch_limit) {
$touch_display = pht('%s Paths', new PhutilNumber($touch_limit));
} else {
$touch_display = pht('Unlimited');
$touch_display = phutil_tag('em', array(), $touch_display);
}
$view->addProperty(pht('Touched Paths Limit'), $touch_display);
return $this->newBox(pht('Limits'), $view);
}
}

View File

@@ -0,0 +1,16 @@
<?php
final class DiffusionRepositoryManagementBuildsPanelGroup
extends DiffusionRepositoryManagementPanelGroup {
const PANELGROUPKEY = 'builds';
public function getManagementPanelGroupLabel() {
return pht('Builds');
}
public function getManagementPanelGroupOrder() {
return 2000;
}
}

View File

@@ -0,0 +1,16 @@
<?php
final class DiffusionRepositoryManagementIntegrationsPanelGroup
extends DiffusionRepositoryManagementPanelGroup {
const PANELGROUPKEY = 'integrations';
public function getManagementPanelGroupLabel() {
return pht('Integrations');
}
public function getManagementPanelGroupOrder() {
return 4000;
}
}

View File

@@ -0,0 +1,16 @@
<?php
final class DiffusionRepositoryManagementMainPanelGroup
extends DiffusionRepositoryManagementPanelGroup {
const PANELGROUPKEY = 'main';
public function getManagementPanelGroupLabel() {
return null;
}
public function getManagementPanelGroupOrder() {
return 1000;
}
}

View File

@@ -0,0 +1,16 @@
<?php
final class DiffusionRepositoryManagementOtherPanelGroup
extends DiffusionRepositoryManagementPanelGroup {
const PANELGROUPKEY = 'other';
public function getManagementPanelGroupLabel() {
return pht('Other');
}
public function getManagementPanelGroupOrder() {
return 9999;
}
}

View File

@@ -41,13 +41,14 @@ abstract class DiffusionRepositoryManagementPanel
abstract public function getManagementPanelLabel();
abstract public function getManagementPanelOrder();
abstract public function buildManagementPanelContent();
public function buildManagementPanelCurtain() { return null; }
public function getManagementPanelIcon() {
return 'fa-pencil';
}
protected function buildManagementPanelActions() {
return array();
public function getManagementPanelGroupKey() {
return DiffusionRepositoryManagementMainPanelGroup::PANELGROUPKEY;
}
public function shouldEnableForRepository(
@@ -63,22 +64,6 @@ abstract class DiffusionRepositoryManagementPanel
->execute();
}
final protected function newBox($header_text, $body, $button = array()) {
$header = id(new PHUIHeaderView())
->setHeader($header_text);
foreach ($button as $link) {
$header->addActionLink($link);
}
$view = id(new PHUIObjectBoxView())
->setHeader($header)
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
->appendChild($body);
return $view;
}
final protected function newTimeline() {
return $this->controller->newTimeline($this->getRepository());
}
@@ -124,4 +109,36 @@ abstract class DiffusionRepositoryManagementPanel
return $this->getPanelURI();
}
final protected function newActionList() {
$viewer = $this->getViewer();
$action_id = celerity_generate_unique_node_id();
return id(new PhabricatorActionListView())
->setViewer($viewer)
->setID($action_id);
}
final protected function newCurtainView() {
$viewer = $this->getViewer();
return id(new PHUICurtainView())
->setViewer($viewer);
}
final protected function newBox($header_text, $body) {
$viewer = $this->getViewer();
$header = id(new PHUIHeaderView())
->setViewer($viewer)
->setHeader($header_text);
$view = id(new PHUIObjectBoxView())
->setViewer($viewer)
->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($body);
return $view;
}
}

View File

@@ -0,0 +1,21 @@
<?php
abstract class DiffusionRepositoryManagementPanelGroup
extends Phobject {
final public function getManagementPanelGroupKey() {
return $this->getPhobjectClassConstant('PANELGROUPKEY');
}
abstract public function getManagementPanelGroupOrder();
abstract public function getManagementPanelGroupLabel();
public static function getAllPanelGroups() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getManagementPanelGroupKey')
->setSortMethod('getManagementPanelGroupOrder')
->execute();
}
}

View File

@@ -14,7 +14,35 @@ final class DiffusionRepositoryPoliciesManagementPanel
}
public function getManagementPanelIcon() {
return 'fa-lock';
$viewer = $this->getViewer();
$repository = $this->getRepository();
$can_view = PhabricatorPolicyCapability::CAN_VIEW;
$can_edit = PhabricatorPolicyCapability::CAN_EDIT;
$can_push = DiffusionPushCapability::CAPABILITY;
$actual_values = array(
'spacePHID' => $repository->getSpacePHID(),
'view' => $repository->getPolicy($can_view),
'edit' => $repository->getPolicy($can_edit),
'push' => $repository->getPolicy($can_push),
);
$default = PhabricatorRepository::initializeNewRepository(
$viewer);
$default_values = array(
'spacePHID' => $default->getSpacePHID(),
'view' => $default->getPolicy($can_view),
'edit' => $default->getPolicy($can_edit),
'push' => $default->getPolicy($can_push),
);
if ($actual_values === $default_values) {
return 'fa-lock grey';
} else {
return 'fa-lock';
}
}
protected function getEditEngineFieldKeys() {
@@ -26,6 +54,31 @@ final class DiffusionRepositoryPoliciesManagementPanel
);
}
public function buildManagementPanelCurtain() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$action_list = $this->newActionList();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$edit_uri = $this->getEditPageURI();
$action_list->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Policies'))
->setHref($edit_uri)
->setIcon('fa-pencil')
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
return $this->newCurtainView()
->setActionList($action_list);
}
public function buildManagementPanelContent() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
@@ -56,22 +109,7 @@ final class DiffusionRepositoryPoliciesManagementPanel
$pushable = $descriptions[DiffusionPushCapability::CAPABILITY];
$view->addProperty(pht('Pushable By'), $pushable);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$edit_uri = $this->getEditPageURI();
$button = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-pencil')
->setText(pht('Edit'))
->setHref($edit_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit);
return $this->newBox(pht('Policies'), $view, array($button));
return $this->newBox(pht('Policies'), $view);
}
}

View File

@@ -13,14 +13,25 @@ final class DiffusionRepositoryStagingManagementPanel
return 700;
}
public function getManagementPanelGroupKey() {
return DiffusionRepositoryManagementBuildsPanelGroup::PANELGROUPKEY;
}
public function shouldEnableForRepository(
PhabricatorRepository $repository) {
return $repository->isGit();
}
public function getManagementPanelIcon() {
return 'fa-upload';
$repository = $this->getRepository();
$staging_uri = $repository->getStagingURI();
if ($staging_uri) {
return 'fa-upload';
} else {
return 'fa-upload grey';
}
}
protected function getEditEngineFieldKeys() {
@@ -29,6 +40,30 @@ final class DiffusionRepositoryStagingManagementPanel
);
}
public function buildManagementPanelCurtain() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$action_list = $this->newActionList();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$staging_uri = $this->getEditPageURI();
$action_list->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Staging'))
->setHref($staging_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
return $this->newCurtainView()
->setActionList($action_list);
}
public function buildManagementPanelContent() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
@@ -43,22 +78,7 @@ final class DiffusionRepositoryStagingManagementPanel
$view->addProperty(pht('Staging Area URI'), $staging_uri);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$staging_uri = $this->getEditPageURI();
$button = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-pencil')
->setText(pht('Edit'))
->setHref($staging_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit);
return $this->newBox(pht('Staging Area'), $view, array($button));
return $this->newBox(pht('Staging Area'), $view);
}
}

View File

@@ -14,7 +14,32 @@ final class DiffusionRepositoryStorageManagementPanel
}
public function getManagementPanelIcon() {
return 'fa-database';
$repository = $this->getRepository();
if ($repository->getAlmanacServicePHID()) {
return 'fa-sitemap';
} else if ($repository->isHosted()) {
return 'fa-database';
} else {
return 'fa-download';
}
}
public function buildManagementPanelCurtain() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$action_list = $this->newActionList();
$doc_href = PhabricatorEnv::getDoclink('Cluster: Repositories');
$action_list->addAction(
id(new PhabricatorActionView())
->setIcon('fa-book')
->setHref($doc_href)
->setName(pht('Cluster Documentation')));
return $this->newCurtainView()
->setActionList($action_list);
}
public function buildManagementPanelContent() {
@@ -47,15 +72,7 @@ final class DiffusionRepositoryStorageManagementPanel
$view->addProperty(pht('Storage Path'), $storage_path);
$view->addProperty(pht('Storage Cluster'), $storage_service);
$doc_href = PhabricatorEnv::getDoclink('Cluster: Repositories');
$button = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-book')
->setHref($doc_href)
->setText(pht('Help'));
return $this->newBox(pht('Storage'), $view, array($button));
return $this->newBox(pht('Storage'), $view);
}
private function buildClusterStatusPanel() {
@@ -99,15 +116,20 @@ final class DiffusionRepositoryStorageManagementPanel
$versions = mpull($versions, null, 'getDevicePHID');
foreach ($bindings as $binding_group) {
$all_disabled = true;
foreach ($binding_group as $binding) {
if (!$binding->getIsDisabled()) {
$all_disabled = false;
break;
}
}
// List enabled devices first, then sort devices in each group by name.
$sort = array();
foreach ($bindings as $key => $binding_group) {
$all_disabled = $this->isDisabledGroup($binding_group);
$sort[$key] = id(new PhutilSortVector())
->addInt($all_disabled ? 1 : 0)
->addString(head($binding_group)->getDevice()->getName());
}
$sort = msortv($sort, 'getSelf');
$bindings = array_select_keys($bindings, array_keys($sort)) + $bindings;
foreach ($bindings as $binding_group) {
$all_disabled = $this->isDisabledGroup($binding_group);
$any_binding = head($binding_group);
if ($all_disabled) {
@@ -228,4 +250,16 @@ final class DiffusionRepositoryStorageManagementPanel
return $this->newBox(pht('Cluster Status'), $table);
}
private function isDisabledGroup(array $binding_group) {
assert_instances_of($binding_group, 'AlmanacBinding');
foreach ($binding_group as $binding) {
if (!$binding->getIsDisabled()) {
return false;
}
}
return true;
}
}

View File

@@ -19,7 +19,15 @@ final class DiffusionRepositorySubversionManagementPanel
}
public function getManagementPanelIcon() {
return 'fa-folder';
$repository = $this->getRepository();
$has_any = (bool)$repository->getDetail('svn-subpath');
if ($has_any) {
return 'fa-folder';
} else {
return 'fa-folder grey';
}
}
protected function getEditEngineFieldKeys() {
@@ -28,6 +36,30 @@ final class DiffusionRepositorySubversionManagementPanel
);
}
public function buildManagementPanelCurtain() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$action_list = $this->newActionList();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$subversion_uri = $this->getEditPageURI();
$action_list->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Properties'))
->setHref($subversion_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
return $this->newCurtainView($action_list)
->setActionList($action_list);
}
public function buildManagementPanelContent() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
@@ -40,22 +72,7 @@ final class DiffusionRepositorySubversionManagementPanel
phutil_tag('em', array(), pht('Import Entire Repository')));
$view->addProperty(pht('Import Only'), $default_branch);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$subversion_uri = $this->getEditPageURI();
$button = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-pencil')
->setText(pht('Edit'))
->setHref($subversion_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit);
return $this->newBox(pht('Subversion'), $view, array($button));
return $this->newBox(pht('Subversion'), $view);
}
}

View File

@@ -13,8 +13,22 @@ final class DiffusionRepositorySymbolsManagementPanel
return 900;
}
public function getManagementPanelGroupKey() {
return DiffusionRepositoryManagementIntegrationsPanelGroup::PANELGROUPKEY;
}
public function getManagementPanelIcon() {
return 'fa-bullseye';
$repository = $this->getRepository();
$has_any =
$repository->getSymbolLanguages() ||
$repository->getSymbolSources();
if ($has_any) {
return 'fa-link';
} else {
return 'fa-link grey';
}
}
protected function getEditEngineFieldKeys() {
@@ -24,6 +38,30 @@ final class DiffusionRepositorySymbolsManagementPanel
);
}
public function buildManagementPanelCurtain() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$action_list = $this->newActionList();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$symbols_uri = $this->getEditPageURI();
$action_list->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Symbols'))
->setHref($symbols_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
return $this->newCurtainView()
->setActionList($action_list);
}
public function buildManagementPanelContent() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
@@ -47,22 +85,7 @@ final class DiffusionRepositorySymbolsManagementPanel
}
$view->addProperty(pht('Uses Symbols From'), $sources);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$symbols_uri = $this->getEditPageURI();
$button = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-pencil')
->setText(pht('Edit'))
->setHref($symbols_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit);
return $this->newBox(pht('Symbols'), $view, array($button));
return $this->newBox(pht('Symbols'), $view);
}
}

View File

@@ -17,6 +17,36 @@ final class DiffusionRepositoryURIsManagementPanel
return 400;
}
public function buildManagementPanelCurtain() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
$action_list = $this->newActionList();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: URIs');
$add_href = $repository->getPathURI('uri/edit/');
$action_list->addAction(
id(new PhabricatorActionView())
->setIcon('fa-plus')
->setHref($add_href)
->setDisabled(!$can_edit)
->setName(pht('Add New URI')));
$action_list->addAction(
id(new PhabricatorActionView())
->setIcon('fa-book')
->setHref($doc_href)
->setName(pht('URI Documentation')));
return $this->newCurtainView()
->setActionList($action_list);
}
public function buildManagementPanelContent() {
$repository = $this->getRepository();
$viewer = $this->getViewer();
@@ -122,30 +152,9 @@ final class DiffusionRepositoryURIsManagementPanel
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
->setErrors($messages);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$box = $this->newBox(pht('Repository URIs'), $table);
$doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: URIs');
$add_href = $repository->getPathURI('uri/edit/');
$add = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-plus')
->setHref($add_href)
->setDisabled(!$can_edit)
->setText(pht('New URI'));
$help = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-book')
->setHref($doc_href)
->setText(pht('Help'));
$box = $this->newBox(pht('Repository URIs'), $table, array($add, $help));
return array($box, $info_view);
return array($info_view, $box);
}
}

View File

@@ -138,7 +138,8 @@ abstract class DiffusionCommandEngine extends Phobject {
// See T13108. By default, don't let any cluster command run indefinitely
// to try to avoid cases where `git fetch` hangs for some reason and we're
// left sitting with a held lock forever.
$future->setTimeout(phutil_units('15 minutes in seconds'));
$repository = $this->getRepository();
$future->setTimeout($repository->getEffectiveCopyTimeLimit());
return $future;
}

Some files were not shown because too many files have changed in this diff Show More