1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-24 21:48:21 +01:00

(stable) Promote 2018 Week 48

This commit is contained in:
epriestley 2018-12-03 10:56:15 -08:00
commit 8ef2f4086e
245 changed files with 4510 additions and 2466 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' => '2574c199',
'core.pkg.js' => 'b5a949ca',
'core.pkg.css' => 'cff4ff6f',
'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',
@ -207,13 +207,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',
@ -373,7 +373,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',
@ -422,7 +422,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/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',
@ -521,7 +521,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',
@ -574,7 +574,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',
@ -688,13 +688,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',
@ -750,7 +750,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',
@ -821,7 +821,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',
@ -903,15 +903,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',
@ -953,6 +944,10 @@ return array(
'javelin-dom',
'javelin-router',
),
'0a84bcc1' => array(
'javelin-install',
'phuix-button-view',
),
'0f764c35' => array(
'javelin-install',
'javelin-util',
@ -1058,9 +1053,6 @@ return array(
'javelin-install',
'javelin-event',
),
'2ee659ce' => array(
'javelin-install',
),
'31420f77' => array(
'javelin-behavior',
),
@ -1319,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',
@ -2009,10 +2010,6 @@ return array(
'phuix-icon-view',
'phabricator-prefab',
),
'e0b984b5' => array(
'javelin-install',
'phuix-button-view',
),
'e1d25dfb' => array(
'javelin-behavior',
'javelin-stratcom',
@ -2094,6 +2091,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

@ -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);

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

@ -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',
@ -1353,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',
@ -1367,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',
@ -1432,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',
@ -1488,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',
@ -1537,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',
@ -4074,8 +4086,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',
@ -4088,12 +4105,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',
@ -4136,6 +4160,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',
@ -4152,6 +4178,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',
@ -4160,18 +4187,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',
@ -4182,6 +4218,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',
@ -6218,6 +6255,7 @@ phutil_register_library_map(array(
'DiffusionLookSoonConduitAPIMethod' => 'DiffusionConduitAPIMethod',
'DiffusionLowLevelCommitFieldsQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelCommitQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelFilesizeQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelGitRefQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelMercurialBranchesQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelMercurialPathsQuery' => 'DiffusionLowLevelQuery',
@ -6327,10 +6365,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',
@ -6829,9 +6873,11 @@ phutil_register_library_map(array(
'HarbormasterDAO',
'PhabricatorPolicyInterface',
'PhabricatorDestructibleInterface',
'PhabricatorConduitResultInterface',
),
'HarbormasterBuildTargetPHIDType' => 'PhabricatorPHIDType',
'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'HarbormasterBuildTargetSearchEngine' => 'PhabricatorApplicationSearchEngine',
'HarbormasterBuildTransaction' => 'PhabricatorApplicationTransaction',
'HarbormasterBuildTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'HarbormasterBuildTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
@ -6843,6 +6889,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface',
'HarbormasterBuildableInterface',
'PhabricatorConduitResultInterface',
'PhabricatorDestructibleInterface',
),
'HarbormasterBuildableActionController' => 'HarbormasterController',
@ -6850,6 +6897,7 @@ phutil_register_library_map(array(
'HarbormasterBuildableListController' => 'HarbormasterController',
'HarbormasterBuildablePHIDType' => 'PhabricatorPHIDType',
'HarbormasterBuildableQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'HarbormasterBuildableSearchAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'HarbormasterBuildableSearchEngine' => 'PhabricatorApplicationSearchEngine',
'HarbormasterBuildableStatus' => 'Phobject',
'HarbormasterBuildableTransaction' => 'PhabricatorApplicationTransaction',
@ -6913,6 +6961,7 @@ phutil_register_library_map(array(
'HarbormasterStepEditController' => 'HarbormasterPlanController',
'HarbormasterStepViewController' => 'HarbormasterPlanController',
'HarbormasterTargetEngine' => 'Phobject',
'HarbormasterTargetSearchAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'HarbormasterTargetWorker' => 'HarbormasterWorker',
'HarbormasterTestBuildStepGroup' => 'HarbormasterBuildStepGroup',
'HarbormasterThrowExceptionBuildStep' => 'HarbormasterBuildStepImplementation',
@ -6975,6 +7024,7 @@ phutil_register_library_map(array(
'HeraldInvalidConditionException' => 'Exception',
'HeraldMailableState' => 'HeraldState',
'HeraldManageGlobalRulesCapability' => 'PhabricatorPolicyCapability',
'HeraldManagementWorkflow' => 'PhabricatorManagementWorkflow',
'HeraldManiphestTaskAdapter' => 'HeraldAdapter',
'HeraldNewController' => 'HeraldController',
'HeraldNewObjectField' => 'HeraldField',
@ -7031,6 +7081,7 @@ phutil_register_library_map(array(
'HeraldSupportActionGroup' => 'HeraldActionGroup',
'HeraldSupportFieldGroup' => 'HeraldFieldGroup',
'HeraldTestConsoleController' => 'HeraldController',
'HeraldTestManagementWorkflow' => 'HeraldManagementWorkflow',
'HeraldTextFieldValue' => 'HeraldFieldValue',
'HeraldTokenizerFieldValue' => 'HeraldFieldValue',
'HeraldTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
@ -9982,11 +10033,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',
@ -10019,12 +10075,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',
@ -10075,6 +10138,8 @@ phutil_register_library_map(array(
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositoryMirror' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryMirrorEngine' => 'PhabricatorRepositoryEngine',
'PhabricatorRepositoryNameTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryNotifyTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryOldRef' => array(
'PhabricatorRepositoryDAO',
'PhabricatorPolicyInterface',
@ -10103,6 +10168,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryPushLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorRepositoryPushLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorRepositoryPushMailWorker' => 'PhabricatorWorker',
'PhabricatorRepositoryPushPolicyTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryPushReplyHandler' => 'PhabricatorMailReplyHandler',
'PhabricatorRepositoryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorRepositoryRefCursor' => array(
@ -10114,12 +10180,18 @@ 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',
@ -10127,8 +10199,11 @@ phutil_register_library_map(array(
'PhabricatorRepositorySyncEventPHIDType' => 'PhabricatorPHIDType',
'PhabricatorRepositorySyncEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorRepositoryTestCase' => 'PhabricatorTestCase',
'PhabricatorRepositoryTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorRepositoryTouchLimitTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryTrackOnlyTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryTransaction' => 'PhabricatorModularTransaction',
'PhabricatorRepositoryTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorRepositoryTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorRepositoryType' => 'Phobject',
'PhabricatorRepositoryURI' => array(
'PhabricatorRepositoryDAO',
@ -10145,6 +10220,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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -39,6 +39,7 @@ final class DiffusionCommitHookEngine extends Phobject {
private $emailPHIDs = array();
private $changesets = array();
private $changesetsSize = 0;
private $filesizeCache = array();
/* -( Config )------------------------------------------------------------- */
@ -164,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);
@ -1255,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();
@ -58,22 +111,7 @@ final class DiffusionRepositoryPoliciesManagementPanel
: phutil_tag('em', array(), pht('Not a Hosted Repository'));
$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;
}

View file

@ -81,10 +81,10 @@ final class DiffusionCachedResolveRefsQuery
$commits = queryfx_all(
$conn_r,
'SELECT commitIdentifier FROM %T
WHERE repositoryID = %s AND %Q',
WHERE repositoryID = %s AND %LO',
id(new PhabricatorRepositoryCommit())->getTableName(),
$repository->getID(),
implode(' OR ', $prefixes));
$prefixes);
foreach ($commits as $commit) {
$hash = $commit['commitIdentifier'];

View file

@ -696,7 +696,7 @@ final class DiffusionCommitQuery
pht('No commit identifiers.'));
}
$where[] = '('.implode(' OR ', $sql).')';
$where[] = qsprintf($conn, '%LO', $sql);
}
if ($this->auditIDs !== null) {

View file

@ -70,7 +70,7 @@ final class DiffusionLintCountQuery extends PhabricatorQuery {
}
protected function buildCustomWhereClause(
AphrontDatabaseConnection $conn_r,
AphrontDatabaseConnection $conn,
$part) {
$where = array();
@ -79,19 +79,19 @@ final class DiffusionLintCountQuery extends PhabricatorQuery {
if ($this->codes !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'code IN (%Ls)',
$this->codes);
}
if ($this->branchIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'branchID IN (%Ld)',
$this->branchIDs);
}
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
private function processPaths() {

View file

@ -10,12 +10,12 @@ final class DiffusionPathQuery extends Phobject {
}
public function execute() {
$conn_r = id(new PhabricatorRepository())->establishConnection('r');
$conn = id(new PhabricatorRepository())->establishConnection('r');
$where = $this->buildWhereClause($conn_r);
$where = $this->buildWhereClause($conn);
$results = queryfx_all(
$conn_r,
$conn,
'SELECT * FROM %T %Q',
PhabricatorRepository::TABLE_PATH,
$where);
@ -23,20 +23,20 @@ final class DiffusionPathQuery extends Phobject {
return ipull($results, null, 'id');
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->pathIDs) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->pathIDs);
}
if ($where) {
return 'WHERE ('.implode(') AND (', $where).')';
return qsprintf($conn, 'WHERE %LA', $where);
} else {
return '';
return qsprintf($conn, '');
}
}

View file

@ -192,52 +192,52 @@ final class DiffusionSymbolQuery extends PhabricatorOffsetPagedQuery {
/**
* @task internal
*/
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if (isset($this->context)) {
$where[] = qsprintf(
$conn_r,
$conn,
'symbolContext = %s',
$this->context);
}
if ($this->name) {
$where[] = qsprintf(
$conn_r,
$conn,
'symbolName = %s',
$this->name);
}
if ($this->namePrefix) {
$where[] = qsprintf(
$conn_r,
$conn,
'symbolName LIKE %>',
$this->namePrefix);
}
if ($this->repositoryPHIDs) {
$where[] = qsprintf(
$conn_r,
$conn,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
if ($this->language) {
$where[] = qsprintf(
$conn_r,
$conn,
'symbolLanguage = %s',
$this->language);
}
if ($this->type) {
$where[] = qsprintf(
$conn_r,
$conn,
'symbolType = %s',
$this->type);
}
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}

View file

@ -0,0 +1,125 @@
<?php
final class DiffusionLowLevelFilesizeQuery
extends DiffusionLowLevelQuery {
private $identifier;
public function withIdentifier($identifier) {
$this->identifier = $identifier;
return $this;
}
protected function executeQuery() {
if (!strlen($this->identifier)) {
throw new PhutilInvalidStateException('withIdentifier');
}
$type = $this->getRepository()->getVersionControlSystem();
switch ($type) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$result = $this->loadGitFilesizes();
break;
default:
throw new Exception(pht('Unsupported repository type "%s"!', $type));
}
return $result;
}
private function loadGitFilesizes() {
$repository = $this->getRepository();
$identifier = $this->identifier;
$paths_future = $repository->getLocalCommandFuture(
'diff-tree -z -r --no-commit-id %s --',
$identifier);
// With "-z" we get "<fields>\0<filename>\0" for each line. Process the
// delimited text as "<fields>, <filename>" pairs.
$path_lines = id(new LinesOfALargeExecFuture($paths_future))
->setDelimiter("\0");
$paths = array();
$path_pairs = new PhutilChunkedIterator($path_lines, 2);
foreach ($path_pairs as $path_pair) {
if (count($path_pair) != 2) {
throw new Exception(
pht(
'Unexpected number of output lines from "git diff-tree" when '.
'processing commit ("%s"): expected an even number of lines.',
$identifier));
}
list($fields, $pathname) = array_values($path_pair);
$fields = explode(' ', $fields);
// Fields are:
//
// :100644 100644 aaaa bbbb M
//
// [0] Old file mode.
// [1] New file mode.
// [2] Old object hash.
// [3] New object hash.
// [4] Change mode.
$paths[] = array(
'path' => $pathname,
'newHash' => $fields[3],
);
}
$path_sizes = array();
if (!$paths) {
return $path_sizes;
}
$check_paths = array();
foreach ($paths as $path) {
if ($path['newHash'] === DiffusionCommitHookEngine::EMPTY_HASH) {
$path_sizes[$path['path']] = 0;
continue;
}
$check_paths[$path['newHash']][] = $path['path'];
}
if (!$check_paths) {
return $path_sizes;
}
$future = $repository->getLocalCommandFuture(
'cat-file --batch-check=%s',
'%(objectsize)');
$future->write(implode("\n", array_keys($check_paths)));
$size_lines = id(new LinesOfALargeExecFuture($future))
->setDelimiter("\n");
foreach ($size_lines as $line) {
$object_size = (int)$line;
$object_hash = head_key($check_paths);
$path_names = $check_paths[$object_hash];
unset($check_paths[$object_hash]);
foreach ($path_names as $path_name) {
$path_sizes[$path_name] = $object_size;
}
}
if ($check_paths) {
throw new Exception(
pht(
'Unexpected number of output lines from "git cat-file" when '.
'processing commit ("%s").',
$identifier));
}
return $path_sizes;
}
}

View file

@ -101,11 +101,11 @@ final class DivinerLivePublisher extends DivinerPublisher {
$strings[] = qsprintf($conn_w, '%s', $hash);
}
foreach (PhabricatorLiskDAO::chunkSQL($strings, ', ') as $chunk) {
foreach (PhabricatorLiskDAO::chunkSQL($strings) as $chunk) {
queryfx(
$conn_w,
'UPDATE %T SET graphHash = NULL, nodeHash = NULL
WHERE graphHash IN (%Q)',
WHERE graphHash IN (%LQ)',
$symbol_table->getTableName(),
$chunk);
}

View file

@ -299,40 +299,40 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
return $atoms;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->bookPHIDs) {
$where[] = qsprintf(
$conn_r,
$conn,
'bookPHID IN (%Ls)',
$this->bookPHIDs);
}
if ($this->types) {
$where[] = qsprintf(
$conn_r,
$conn,
'type IN (%Ls)',
$this->types);
}
if ($this->names) {
$where[] = qsprintf(
$conn_r,
$conn,
'name IN (%Ls)',
$this->names);
}
@ -347,7 +347,7 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
}
$where[] = qsprintf(
$conn_r,
$conn,
'titleSlugHash in (%Ls)',
$hashes);
}
@ -366,46 +366,46 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
if ($contexts && $with_null) {
$where[] = qsprintf(
$conn_r,
$conn,
'context IN (%Ls) OR context IS NULL',
$contexts);
} else if ($contexts) {
$where[] = qsprintf(
$conn_r,
$conn,
'context IN (%Ls)',
$contexts);
} else if ($with_null) {
$where[] = qsprintf(
$conn_r,
$conn,
'context IS NULL');
}
}
if ($this->indexes) {
$where[] = qsprintf(
$conn_r,
$conn,
'atomIndex IN (%Ld)',
$this->indexes);
}
if ($this->isDocumentable !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'isDocumentable = %d',
(int)$this->isDocumentable);
}
if ($this->isGhost !== null) {
if ($this->isGhost) {
$where[] = qsprintf($conn_r, 'graphHash IS NULL');
$where[] = qsprintf($conn, 'graphHash IS NULL');
} else {
$where[] = qsprintf($conn_r, 'graphHash IS NOT NULL');
$where[] = qsprintf($conn, 'graphHash IS NOT NULL');
}
}
if ($this->nodeHashes) {
$where[] = qsprintf(
$conn_r,
$conn,
'nodeHash IN (%Ls)',
$this->nodeHashes);
}
@ -415,21 +415,21 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
// the column has binary collation. Eventually, this should move into
// fulltext.
$where[] = qsprintf(
$conn_r,
$conn,
'CONVERT(name USING utf8) LIKE %~',
$this->nameContains);
}
if ($this->repositoryPHIDs) {
$where[] = qsprintf(
$conn_r,
$conn,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
/**

View file

@ -116,54 +116,54 @@ final class DivinerBookQuery extends PhabricatorCursorPagedPolicyAwareQuery {
return $books;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
$conn,
'phid IN (%Ls)',
$this->phids);
}
if (strlen($this->nameLike)) {
$where[] = qsprintf(
$conn_r,
$conn,
'name LIKE %~',
$this->nameLike);
}
if ($this->names !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'name IN (%Ls)',
$this->names);
}
if (strlen($this->namePrefix)) {
$where[] = qsprintf(
$conn_r,
$conn,
'name LIKE %>',
$this->namePrefix);
}
if ($this->repositoryPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
return $this->formatWhereClause($conn, $where);
}
public function getQueryApplicationClass() {

View file

@ -173,6 +173,7 @@ final class DrydockWorkingCopyBlueprintImplementation
$map = $resource->getAttribute('repositories.map');
$futures = array();
$repositories = $this->loadRepositories(ipull($map, 'phid'));
foreach ($map as $directory => $spec) {
// TODO: Validate directory isn't goofy like "/etc" or "../../lol"
@ -181,11 +182,18 @@ final class DrydockWorkingCopyBlueprintImplementation
$repository = $repositories[$spec['phid']];
$path = "{$root}/repo/{$directory}/";
// TODO: Run these in parallel?
$interface->execx(
$future = $interface->getExecFuture(
'git clone -- %s %s',
(string)$repository->getCloneURIObject(),
$path);
$future->setTimeout($repository->getEffectiveCopyTimeLimit());
$futures[$directory] = $future;
}
foreach (new FutureIterator($futures) as $key => $future) {
$future->resolvex();
}
$resource
@ -240,8 +248,12 @@ final class DrydockWorkingCopyBlueprintImplementation
$map = $lease->getAttribute('repositories.map');
$root = $resource->getAttribute('workingcopy.root');
$repositories = $this->loadRepositories(ipull($map, 'phid'));
$default = null;
foreach ($map as $directory => $spec) {
$repository = $repositories[$spec['phid']];
$interface->pushWorkingDirectory("{$root}/repo/{$directory}/");
$cmd = array();
@ -271,7 +283,9 @@ final class DrydockWorkingCopyBlueprintImplementation
$arg[] = $branch;
}
$this->execxv($interface, $cmd, $arg);
$this->newExecvFuture($interface, $cmd, $arg)
->setTimeout($repository->getEffectiveCopyTimeLimit())
->resolvex();
if (idx($spec, 'default')) {
$default = $directory;
@ -295,7 +309,9 @@ final class DrydockWorkingCopyBlueprintImplementation
$arg[] = $ref_ref;
try {
$this->execxv($interface, $cmd, $arg);
$this->newExecvFuture($interface, $cmd, $arg)
->setTimeout($repository->getEffectiveCopyTimeLimit())
->resolvex();
} catch (CommandException $ex) {
$display_command = csprintf(
'git fetch %R %R',
@ -509,12 +525,18 @@ final class DrydockWorkingCopyBlueprintImplementation
DrydockCommandInterface $interface,
array $commands,
array $arguments) {
return $this->newExecvFuture($interface, $commands, $arguments)->resolvex();
}
private function newExecvFuture(
DrydockCommandInterface $interface,
array $commands,
array $arguments) {
$commands = implode(' && ', $commands);
$argv = array_merge(array($commands), $arguments);
return call_user_func_array(array($interface, 'execx'), $argv);
return call_user_func_array(array($interface, 'getExecFuture'), $argv);
}
}

View file

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

View file

@ -140,9 +140,9 @@ final class DrydockSlotLock extends DrydockDAO {
try {
queryfx(
$conn_w,
'INSERT INTO %T (ownerPHID, lockIndex, lockKey) VALUES %Q',
'INSERT INTO %T (ownerPHID, lockIndex, lockKey) VALUES %LQ',
$table->getTableName(),
implode(', ', $sql));
$sql);
} catch (AphrontDuplicateKeyQueryException $ex) {
// Try to improve the readability of the exception. We might miss on
// this query if the lock has already been released, but most of the

View file

@ -189,7 +189,7 @@ final class PhabricatorFactDaemon extends PhabricatorDaemon {
$conn,
'INSERT INTO %T
(keyID, objectID, dimensionID, value, epoch)
VALUES %Q',
VALUES %LQ',
$table_name,
$chunk);
}

View file

@ -158,7 +158,7 @@ final class PhabricatorFactDatapointQuery extends Phobject {
$this->dimensionMap);
}
$where = '('.implode(') AND (', $where).')';
$where = qsprintf($conn, '%LA', $where);
if ($this->limit) {
$limit = qsprintf(
@ -166,7 +166,7 @@ final class PhabricatorFactDatapointQuery extends Phobject {
'LIMIT %d',
$this->limit);
} else {
$limit = '';
$limit = qsprintf($conn, '');
}
return queryfx_all(

View file

@ -75,7 +75,7 @@ abstract class PhabricatorFactDimension extends PhabricatorFactDAO {
foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
queryfx(
$conn,
'INSERT IGNORE INTO %T (%C) VALUES %Q',
'INSERT IGNORE INTO %T (%C) VALUES %LQ',
$this->getTableName(),
$column,
$chunk);

View file

@ -133,9 +133,9 @@ final class PhabricatorFeedStoryPublisher extends Phobject {
queryfx(
$conn,
'INSERT INTO %T (objectPHID, chronologicalKey) VALUES %Q',
'INSERT INTO %T (objectPHID, chronologicalKey) VALUES %LQ',
$ref->getTableName(),
implode(', ', $sql));
$sql);
}
$subscribed_phids = $this->subscribedPHIDs;
@ -191,9 +191,9 @@ final class PhabricatorFeedStoryPublisher extends Phobject {
$conn,
'INSERT INTO %T '.
'(primaryObjectPHID, userPHID, chronologicalKey, hasViewed) '.
'VALUES %Q',
'VALUES %LQ',
$notif->getTableName(),
implode(', ', $sql));
$sql);
}
PhabricatorUserCache::clearCaches(

View file

@ -64,22 +64,20 @@ final class PhabricatorFeedQuery
}
if ($this->chronologicalKeys !== null) {
// NOTE: We want to use integers in the query so we can take advantage
// of keys, but can't use %d on 32-bit systems. Make sure all the keys
// are integers and then format them raw.
// NOTE: We can't use "%d" to format these large integers on 32-bit
// systems. Historically, we formatted these into integers in an
// awkward way because MySQL could sometimes (?) fail to use the proper
// keys if the values were formatted as strings instead of integers.
$keys = $this->chronologicalKeys;
foreach ($keys as $key) {
if (!ctype_digit($key)) {
throw new Exception(
pht("Key '%s' is not a valid chronological key!", $key));
}
}
// After the "qsprintf()" update to use PhutilQueryString, we can no
// longer do this in a sneaky way. However, the MySQL key issue also
// no longer appears to reproduce across several systems. So: just use
// strings until problems turn up?
$where[] = qsprintf(
$conn,
'ref.chronologicalKey IN (%Q)',
implode(', ', $keys));
'ref.chronologicalKey IN (%Ls)',
$this->chronologicalKeys);
}
// NOTE: We may not have 64-bit PHP, so do the shifts in MySQL instead.

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