diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -4084,8 +4084,13 @@ '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', @@ -4099,10 +4104,15 @@ 'PhabricatorRepositoryCommitTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryCommitTestCase.php', 'PhabricatorRepositoryConfigOptions' => 'applications/repository/config/PhabricatorRepositoryConfigOptions.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', 'PhabricatorRepositoryFulltextEngine' => 'applications/repository/search/PhabricatorRepositoryFulltextEngine.php', 'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php', @@ -4146,6 +4156,8 @@ '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', @@ -4162,6 +4174,7 @@ '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', @@ -4170,18 +4183,26 @@ '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', + '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', @@ -4192,6 +4213,7 @@ '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', @@ -10004,11 +10026,16 @@ 'PhabricatorFulltextInterface', 'PhabricatorFerretInterface', ), + 'PhabricatorRepositoryActivateTransaction' => 'PhabricatorRepositoryTransactionType', 'PhabricatorRepositoryAuditRequest' => array( 'PhabricatorRepositoryDAO', 'PhabricatorPolicyInterface', ), + 'PhabricatorRepositoryAutocloseOnlyTransaction' => 'PhabricatorRepositoryTransactionType', + 'PhabricatorRepositoryAutocloseTransaction' => 'PhabricatorRepositoryTransactionType', + 'PhabricatorRepositoryBlueprintsTransaction' => 'PhabricatorRepositoryTransactionType', 'PhabricatorRepositoryBranch' => 'PhabricatorRepositoryDAO', + 'PhabricatorRepositoryCallsignTransaction' => 'PhabricatorRepositoryTransactionType', 'PhabricatorRepositoryCommit' => array( 'PhabricatorRepositoryDAO', 'PhabricatorPolicyInterface', @@ -10042,10 +10069,15 @@ 'PhabricatorRepositoryCommitTestCase' => 'PhabricatorTestCase', 'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO', + 'PhabricatorRepositoryDangerousTransaction' => 'PhabricatorRepositoryTransactionType', + 'PhabricatorRepositoryDefaultBranchTransaction' => 'PhabricatorRepositoryTransactionType', + 'PhabricatorRepositoryDescriptionTransaction' => 'PhabricatorRepositoryTransactionType', 'PhabricatorRepositoryDestructibleCodex' => 'PhabricatorDestructibleCodex', 'PhabricatorRepositoryDiscoveryEngine' => 'PhabricatorRepositoryEngine', 'PhabricatorRepositoryEditor' => 'PhabricatorApplicationTransactionEditor', + 'PhabricatorRepositoryEncodingTransaction' => 'PhabricatorRepositoryTransactionType', 'PhabricatorRepositoryEngine' => 'Phobject', + 'PhabricatorRepositoryEnormousTransaction' => 'PhabricatorRepositoryTransactionType', 'PhabricatorRepositoryFerretEngine' => 'PhabricatorFerretEngine', 'PhabricatorRepositoryFulltextEngine' => 'PhabricatorFulltextEngine', 'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker', @@ -10097,6 +10129,8 @@ 'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker', 'PhabricatorRepositoryMirror' => 'PhabricatorRepositoryDAO', 'PhabricatorRepositoryMirrorEngine' => 'PhabricatorRepositoryEngine', + 'PhabricatorRepositoryNameTransaction' => 'PhabricatorRepositoryTransactionType', + 'PhabricatorRepositoryNotifyTransaction' => 'PhabricatorRepositoryTransactionType', 'PhabricatorRepositoryOldRef' => array( 'PhabricatorRepositoryDAO', 'PhabricatorPolicyInterface', @@ -10125,6 +10159,7 @@ 'PhabricatorRepositoryPushLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorRepositoryPushLogSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorRepositoryPushMailWorker' => 'PhabricatorWorker', + 'PhabricatorRepositoryPushPolicyTransaction' => 'PhabricatorRepositoryTransactionType', 'PhabricatorRepositoryPushReplyHandler' => 'PhabricatorMailReplyHandler', 'PhabricatorRepositoryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorRepositoryRefCursor' => array( @@ -10136,12 +10171,18 @@ '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', @@ -10149,8 +10190,10 @@ 'PhabricatorRepositorySyncEventPHIDType' => 'PhabricatorPHIDType', 'PhabricatorRepositorySyncEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorRepositoryTestCase' => 'PhabricatorTestCase', - 'PhabricatorRepositoryTransaction' => 'PhabricatorApplicationTransaction', + 'PhabricatorRepositoryTrackOnlyTransaction' => 'PhabricatorRepositoryTransactionType', + 'PhabricatorRepositoryTransaction' => 'PhabricatorModularTransaction', 'PhabricatorRepositoryTransactionQuery' => 'PhabricatorApplicationTransactionQuery', + 'PhabricatorRepositoryTransactionType' => 'PhabricatorModularTransactionType', 'PhabricatorRepositoryType' => 'Phobject', 'PhabricatorRepositoryURI' => array( 'PhabricatorRepositoryDAO', @@ -10167,6 +10210,7 @@ 'PhabricatorRepositoryURITestCase' => 'PhabricatorTestCase', 'PhabricatorRepositoryURITransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorRepositoryURITransactionQuery' => 'PhabricatorApplicationTransactionQuery', + 'PhabricatorRepositoryVCSTransaction' => 'PhabricatorRepositoryTransactionType', 'PhabricatorRepositoryWorkingCopyVersion' => 'PhabricatorRepositoryDAO', 'PhabricatorRequestExceptionHandler' => 'AphrontRequestExceptionHandler', 'PhabricatorResourceSite' => 'PhabricatorSite', diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditActivateController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditActivateController.php --- a/src/applications/diffusion/controller/DiffusionRepositoryEditActivateController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryEditActivateController.php @@ -25,7 +25,8 @@ } $xaction = id(new PhabricatorRepositoryTransaction()) - ->setTransactionType(PhabricatorRepositoryTransaction::TYPE_ACTIVATE) + ->setTransactionType( + PhabricatorRepositoryActivateTransaction::TRANSACTIONTYPE) ->setNewValue($new_status); $editor = id(new PhabricatorRepositoryEditor()) diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditDangerousController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditDangerousController.php --- a/src/applications/diffusion/controller/DiffusionRepositoryEditDangerousController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryEditDangerousController.php @@ -30,7 +30,8 @@ if ($request->isFormPost()) { $xaction = id(new PhabricatorRepositoryTransaction()) - ->setTransactionType(PhabricatorRepositoryTransaction::TYPE_DANGEROUS) + ->setTransactionType( + PhabricatorRepositoryDangerousTransaction::TRANSACTIONTYPE) ->setNewValue(!$repository->shouldAllowDangerousChanges()); $editor = id(new PhabricatorRepositoryEditor()) diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditEnormousController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditEnormousController.php --- a/src/applications/diffusion/controller/DiffusionRepositoryEditEnormousController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryEditEnormousController.php @@ -30,7 +30,8 @@ if ($request->isFormPost()) { $xaction = id(new PhabricatorRepositoryTransaction()) - ->setTransactionType(PhabricatorRepositoryTransaction::TYPE_ENORMOUS) + ->setTransactionType( + PhabricatorRepositoryEnormousTransaction::TRANSACTIONTYPE) ->setNewValue(!$repository->shouldAllowEnormousChanges()); $editor = id(new PhabricatorRepositoryEditor()) diff --git a/src/applications/diffusion/editor/DiffusionRepositoryEditEngine.php b/src/applications/diffusion/editor/DiffusionRepositoryEditEngine.php --- a/src/applications/diffusion/editor/DiffusionRepositoryEditEngine.php +++ b/src/applications/diffusion/editor/DiffusionRepositoryEditEngine.php @@ -243,7 +243,8 @@ id(new PhabricatorSelectEditField()) ->setKey('vcs') ->setLabel(pht('Version Control System')) - ->setTransactionType(PhabricatorRepositoryTransaction::TYPE_VCS) + ->setTransactionType( + PhabricatorRepositoryVCSTransaction::TRANSACTIONTYPE) ->setIsFormField(false) ->setIsCopyable(true) ->setOptions(PhabricatorRepositoryType::getAllRepositoryTypes()) @@ -258,7 +259,8 @@ ->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 @@ 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 @@ 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 @@ 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 @@ ->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.')) @@ -304,7 +310,8 @@ ->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.')) @@ -317,7 +324,8 @@ ->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,7 +333,8 @@ id(new PhabricatorSelectEditField()) ->setKey('status') ->setLabel(pht('Status')) - ->setTransactionType(PhabricatorRepositoryTransaction::TYPE_ACTIVATE) + ->setTransactionType( + PhabricatorRepositoryActivateTransaction::TRANSACTIONTYPE) ->setIsFormField(false) ->setOptions(PhabricatorRepository::getStatusNameMap()) ->setDescription(pht('Active or inactive status.')) @@ -336,7 +345,7 @@ ->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 @@ ->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 @@ ->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 @@ ->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 @@ ->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 @@ ->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 @@ ->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 @@ ->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 @@ ->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 @@ ->setKey('autoclose') ->setLabel(pht('Autoclose')) ->setTransactionType( - PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE) + PhabricatorRepositoryAutocloseTransaction::TRANSACTIONTYPE) ->setIsCopyable(true) ->setOptions( pht('Disable Autoclose'), @@ -455,7 +464,8 @@ ->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( diff --git a/src/applications/meta/xactions/PhabricatorApplicationPolicyChangeTransaction.php b/src/applications/meta/xactions/PhabricatorApplicationPolicyChangeTransaction.php --- a/src/applications/meta/xactions/PhabricatorApplicationPolicyChangeTransaction.php +++ b/src/applications/meta/xactions/PhabricatorApplicationPolicyChangeTransaction.php @@ -52,8 +52,8 @@ } public function getTitle() { - $old = $this->renderPolicy($this->getOldValue()); - $new = $this->renderPolicy($this->getNewValue()); + $old = $this->renderApplicationPolicy($this->getOldValue()); + $new = $this->renderApplicationPolicy($this->getNewValue()); return pht( '%s changed the "%s" policy from "%s" to "%s".', @@ -64,8 +64,8 @@ } public function getTitleForFeed() { - $old = $this->renderPolicy($this->getOldValue()); - $new = $this->renderPolicy($this->getNewValue()); + $old = $this->renderApplicationPolicy($this->getOldValue()); + $new = $this->renderApplicationPolicy($this->getNewValue()); return pht( '%s changed the "%s" policy for application %s from "%s" to "%s".', @@ -165,7 +165,7 @@ return $errors; } - private function renderPolicy($name) { + private function renderApplicationPolicy($name) { $policies = $this->getAllPolicies(); if (empty($policies[$name])) { // Not a standard policy, check for a custom policy. diff --git a/src/applications/repository/editor/PhabricatorRepositoryEditor.php b/src/applications/repository/editor/PhabricatorRepositoryEditor.php --- a/src/applications/repository/editor/PhabricatorRepositoryEditor.php +++ b/src/applications/repository/editor/PhabricatorRepositoryEditor.php @@ -14,28 +14,6 @@ public function getTransactionTypes() { $types = parent::getTransactionTypes(); - $types[] = PhabricatorRepositoryTransaction::TYPE_VCS; - $types[] = PhabricatorRepositoryTransaction::TYPE_ACTIVATE; - $types[] = PhabricatorRepositoryTransaction::TYPE_NAME; - $types[] = PhabricatorRepositoryTransaction::TYPE_DESCRIPTION; - $types[] = PhabricatorRepositoryTransaction::TYPE_ENCODING; - $types[] = PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH; - $types[] = PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY; - $types[] = PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY; - $types[] = PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH; - $types[] = PhabricatorRepositoryTransaction::TYPE_NOTIFY; - $types[] = PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE; - $types[] = PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY; - $types[] = PhabricatorRepositoryTransaction::TYPE_DANGEROUS; - $types[] = PhabricatorRepositoryTransaction::TYPE_ENORMOUS; - $types[] = PhabricatorRepositoryTransaction::TYPE_SLUG; - $types[] = PhabricatorRepositoryTransaction::TYPE_SERVICE; - $types[] = PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE; - $types[] = PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES; - $types[] = PhabricatorRepositoryTransaction::TYPE_STAGING_URI; - $types[] = PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS; - $types[] = PhabricatorRepositoryTransaction::TYPE_CALLSIGN; - $types[] = PhabricatorTransactions::TYPE_EDGE; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; @@ -43,504 +21,6 @@ return $types; } - protected function getCustomTransactionOldValue( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case PhabricatorRepositoryTransaction::TYPE_VCS: - return $object->getVersionControlSystem(); - case PhabricatorRepositoryTransaction::TYPE_ACTIVATE: - return $object->isTracked(); - case PhabricatorRepositoryTransaction::TYPE_NAME: - return $object->getName(); - case PhabricatorRepositoryTransaction::TYPE_DESCRIPTION: - return $object->getDetail('description'); - case PhabricatorRepositoryTransaction::TYPE_ENCODING: - return $object->getDetail('encoding'); - case PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH: - return $object->getDetail('default-branch'); - case PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY: - return array_keys($object->getDetail('branch-filter', array())); - case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY: - return array_keys($object->getDetail('close-commits-filter', array())); - case PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH: - return $object->getDetail('svn-subpath'); - case PhabricatorRepositoryTransaction::TYPE_NOTIFY: - return (int)!$object->getDetail('herald-disabled'); - case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: - return (int)!$object->getDetail('disable-autoclose'); - case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: - return $object->getPushPolicy(); - case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: - return $object->shouldAllowDangerousChanges(); - case PhabricatorRepositoryTransaction::TYPE_ENORMOUS: - return $object->shouldAllowEnormousChanges(); - case PhabricatorRepositoryTransaction::TYPE_SLUG: - return $object->getRepositorySlug(); - case PhabricatorRepositoryTransaction::TYPE_SERVICE: - return $object->getAlmanacServicePHID(); - case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE: - return $object->getSymbolLanguages(); - case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES: - return $object->getSymbolSources(); - case PhabricatorRepositoryTransaction::TYPE_STAGING_URI: - return $object->getDetail('staging-uri'); - case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS: - return $object->getDetail('automation.blueprintPHIDs', array()); - case PhabricatorRepositoryTransaction::TYPE_CALLSIGN: - return $object->getCallsign(); - } - } - - protected function getCustomTransactionNewValue( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case PhabricatorRepositoryTransaction::TYPE_ACTIVATE: - case PhabricatorRepositoryTransaction::TYPE_NAME: - case PhabricatorRepositoryTransaction::TYPE_DESCRIPTION: - case PhabricatorRepositoryTransaction::TYPE_ENCODING: - case PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH: - case PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY: - case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY: - case PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH: - case PhabricatorRepositoryTransaction::TYPE_VCS: - case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: - case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: - case PhabricatorRepositoryTransaction::TYPE_ENORMOUS: - case PhabricatorRepositoryTransaction::TYPE_SERVICE: - case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE: - case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES: - case PhabricatorRepositoryTransaction::TYPE_STAGING_URI: - case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS: - return $xaction->getNewValue(); - case PhabricatorRepositoryTransaction::TYPE_SLUG: - case PhabricatorRepositoryTransaction::TYPE_CALLSIGN: - $name = $xaction->getNewValue(); - if (strlen($name)) { - return $name; - } - return null; - case PhabricatorRepositoryTransaction::TYPE_NOTIFY: - case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: - return (int)$xaction->getNewValue(); - } - } - - protected function applyCustomInternalTransaction( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case PhabricatorRepositoryTransaction::TYPE_VCS: - $object->setVersionControlSystem($xaction->getNewValue()); - break; - case PhabricatorRepositoryTransaction::TYPE_ACTIVATE: - $active = $xaction->getNewValue(); - - // The first time a repository is activated, clear the "new repository" - // flag so we stop showing setup hints. - if ($active) { - $object->setDetail('newly-initialized', false); - } - - $object->setDetail('tracking-enabled', $active); - break; - case PhabricatorRepositoryTransaction::TYPE_NAME: - $object->setName($xaction->getNewValue()); - break; - case PhabricatorRepositoryTransaction::TYPE_DESCRIPTION: - $object->setDetail('description', $xaction->getNewValue()); - break; - case PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH: - $object->setDetail('default-branch', $xaction->getNewValue()); - break; - case PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY: - $object->setDetail( - 'branch-filter', - array_fill_keys($xaction->getNewValue(), true)); - break; - case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY: - $object->setDetail( - 'close-commits-filter', - array_fill_keys($xaction->getNewValue(), true)); - break; - case PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH: - $object->setDetail('svn-subpath', $xaction->getNewValue()); - break; - case PhabricatorRepositoryTransaction::TYPE_NOTIFY: - $object->setDetail('herald-disabled', (int)!$xaction->getNewValue()); - break; - case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: - $object->setDetail('disable-autoclose', (int)!$xaction->getNewValue()); - break; - case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: - return $object->setPushPolicy($xaction->getNewValue()); - case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: - $object->setDetail('allow-dangerous-changes', $xaction->getNewValue()); - return; - case PhabricatorRepositoryTransaction::TYPE_ENORMOUS: - $object->setDetail('allow-enormous-changes', $xaction->getNewValue()); - return; - case PhabricatorRepositoryTransaction::TYPE_SLUG: - $object->setRepositorySlug($xaction->getNewValue()); - return; - case PhabricatorRepositoryTransaction::TYPE_SERVICE: - $object->setAlmanacServicePHID($xaction->getNewValue()); - return; - case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE: - $object->setDetail('symbol-languages', $xaction->getNewValue()); - return; - case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES: - $object->setDetail('symbol-sources', $xaction->getNewValue()); - return; - case PhabricatorRepositoryTransaction::TYPE_STAGING_URI: - $object->setDetail('staging-uri', $xaction->getNewValue()); - return; - case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS: - $object->setDetail( - 'automation.blueprintPHIDs', - $xaction->getNewValue()); - return; - case PhabricatorRepositoryTransaction::TYPE_CALLSIGN: - $object->setCallsign($xaction->getNewValue()); - return; - case PhabricatorRepositoryTransaction::TYPE_ENCODING: - $object->setDetail('encoding', $xaction->getNewValue()); - break; - } - } - - protected function applyCustomExternalTransaction( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS: - DrydockAuthorization::applyAuthorizationChanges( - $this->getActor(), - $object->getPHID(), - $xaction->getOldValue(), - $xaction->getNewValue()); - break; - } - - } - - protected function validateTransaction( - PhabricatorLiskDAO $object, - $type, - array $xactions) { - - $errors = parent::validateTransaction($object, $type, $xactions); - - switch ($type) { - case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY: - case PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY: - foreach ($xactions as $xaction) { - foreach ($xaction->getNewValue() as $pattern) { - // Check for invalid regular expressions. - $regexp = PhabricatorRepository::extractBranchRegexp($pattern); - if ($regexp !== null) { - $ok = @preg_match($regexp, ''); - if ($ok === false) { - $error = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - pht( - 'Expression "%s" is not a valid regular expression. Note '. - 'that you must include delimiters.', - $regexp), - $xaction); - $errors[] = $error; - continue; - } - } - - // Check for formatting mistakes like `regex(...)` instead of - // `regexp(...)`. - $matches = null; - if (preg_match('/^([^(]+)\\(.*\\)\z/', $pattern, $matches)) { - switch ($matches[1]) { - case 'regexp': - break; - default: - $error = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - pht( - 'Matching function "%s(...)" is not recognized. Valid '. - 'functions are: regexp(...).', - $matches[1]), - $xaction); - $errors[] = $error; - break; - } - } - } - } - break; - - case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS: - foreach ($xactions as $xaction) { - $old = nonempty($xaction->getOldValue(), array()); - $new = nonempty($xaction->getNewValue(), array()); - - $add = array_diff($new, $old); - - $invalid = PhabricatorObjectQuery::loadInvalidPHIDsForViewer( - $this->getActor(), - $add); - if ($invalid) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - pht( - 'Some of the selected automation blueprints are invalid '. - 'or restricted: %s.', - implode(', ', $invalid)), - $xaction); - } - } - break; - - case PhabricatorRepositoryTransaction::TYPE_VCS: - $vcs_map = PhabricatorRepositoryType::getAllRepositoryTypes(); - $current_vcs = $object->getVersionControlSystem(); - - if (!$this->getIsNewObject()) { - foreach ($xactions as $xaction) { - if ($xaction->getNewValue() == $current_vcs) { - continue; - } - - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Immutable'), - pht( - 'You can not change the version control system an existing '. - 'repository uses. It can only be set when a repository is '. - 'first created.'), - $xaction); - } - } else { - $value = $object->getVersionControlSystem(); - foreach ($xactions as $xaction) { - $value = $xaction->getNewValue(); - - if (empty($vcs_map[$value])) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - pht( - 'Specified version control system must be a VCS '. - 'recognized by Phabricator: %s.', - implode(', ', array_keys($vcs_map))), - $xaction); - } - } - - if (!strlen($value)) { - $error = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Required'), - pht( - 'When creating a repository, you must specify a valid '. - 'underlying version control system: %s.', - implode(', ', array_keys($vcs_map))), - nonempty(last($xactions), null)); - $error->setIsMissingFieldError(true); - $errors[] = $error; - } - } - break; - - case PhabricatorRepositoryTransaction::TYPE_NAME: - $missing = $this->validateIsEmptyTextField( - $object->getName(), - $xactions); - - if ($missing) { - $error = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Required'), - pht('Repository name is required.'), - nonempty(last($xactions), null)); - - $error->setIsMissingFieldError(true); - $errors[] = $error; - } - break; - - case PhabricatorRepositoryTransaction::TYPE_ACTIVATE: - $status_map = PhabricatorRepository::getStatusMap(); - foreach ($xactions as $xaction) { - $status = $xaction->getNewValue(); - if (empty($status_map[$status])) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - pht( - 'Repository status "%s" is not valid.', - $status), - $xaction); - } - } - break; - - case PhabricatorRepositoryTransaction::TYPE_ENCODING: - foreach ($xactions as $xaction) { - // Make sure the encoding is valid by converting to UTF-8. This tests - // that the user has mbstring installed, and also that they didn't - // type a garbage encoding name. Note that we're converting from - // UTF-8 to the target encoding, because mbstring is fine with - // converting from a nonsense encoding. - $encoding = $xaction->getNewValue(); - if (!strlen($encoding)) { - continue; - } - - try { - phutil_utf8_convert('.', $encoding, 'UTF-8'); - } catch (Exception $ex) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - pht( - 'Repository encoding "%s" is not valid: %s', - $encoding, - $ex->getMessage()), - $xaction); - } - } - break; - - case PhabricatorRepositoryTransaction::TYPE_SLUG: - foreach ($xactions as $xaction) { - $old = $xaction->getOldValue(); - $new = $xaction->getNewValue(); - - if (!strlen($new)) { - continue; - } - - if ($new === $old) { - continue; - } - - try { - PhabricatorRepository::assertValidRepositorySlug($new); - } catch (Exception $ex) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - $ex->getMessage(), - $xaction); - continue; - } - - $other = id(new PhabricatorRepositoryQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withSlugs(array($new)) - ->executeOne(); - if ($other && ($other->getID() !== $object->getID())) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Duplicate'), - pht( - 'The selected repository short name is already in use by '. - 'another repository. Choose a unique short name.'), - $xaction); - continue; - } - } - break; - - case PhabricatorRepositoryTransaction::TYPE_CALLSIGN: - foreach ($xactions as $xaction) { - $old = $xaction->getOldValue(); - $new = $xaction->getNewValue(); - - if (!strlen($new)) { - continue; - } - - if ($new === $old) { - continue; - } - - try { - PhabricatorRepository::assertValidCallsign($new); - } catch (Exception $ex) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - $ex->getMessage(), - $xaction); - continue; - } - - $other = id(new PhabricatorRepositoryQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withCallsigns(array($new)) - ->executeOne(); - if ($other && ($other->getID() !== $object->getID())) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Duplicate'), - pht( - 'The selected callsign ("%s") is already in use by another '. - 'repository. Choose a unique callsign.', - $new), - $xaction); - continue; - } - } - break; - - case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES: - foreach ($xactions as $xaction) { - $old = $object->getSymbolSources(); - $new = $xaction->getNewValue(); - - // If the viewer is adding new repositories, make sure they are - // valid and visible. - $add = array_diff($new, $old); - if (!$add) { - continue; - } - - $repositories = id(new PhabricatorRepositoryQuery()) - ->setViewer($this->getActor()) - ->withPHIDs($add) - ->execute(); - $repositories = mpull($repositories, null, 'getPHID'); - - foreach ($add as $phid) { - if (isset($repositories[$phid])) { - continue; - } - - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - pht( - 'Repository ("%s") does not exist, or you do not have '. - 'permission to see it.', - $phid), - $xaction); - break; - } - } - break; - - } - - return $errors; - } - protected function didCatchDuplicateKeyException( PhabricatorLiskDAO $object, array $xactions, diff --git a/src/applications/repository/management/PhabricatorRepositoryManagementClusterizeWorkflow.php b/src/applications/repository/management/PhabricatorRepositoryManagementClusterizeWorkflow.php --- a/src/applications/repository/management/PhabricatorRepositoryManagementClusterizeWorkflow.php +++ b/src/applications/repository/management/PhabricatorRepositoryManagementClusterizeWorkflow.php @@ -117,7 +117,8 @@ $xactions = array(); $xactions[] = id(new PhabricatorRepositoryTransaction()) - ->setTransactionType(PhabricatorRepositoryTransaction::TYPE_SERVICE) + ->setTransactionType( + PhabricatorRepositoryServiceTransaction::TRANSACTIONTYPE) ->setNewValue($service_phid); id(new PhabricatorRepositoryEditor()) diff --git a/src/applications/repository/storage/PhabricatorRepositoryTransaction.php b/src/applications/repository/storage/PhabricatorRepositoryTransaction.php --- a/src/applications/repository/storage/PhabricatorRepositoryTransaction.php +++ b/src/applications/repository/storage/PhabricatorRepositoryTransaction.php @@ -1,29 +1,7 @@ getOldValue(); - $new = $this->getNewValue(); - - switch ($this->getTransactionType()) { - case self::TYPE_PUSH_POLICY: - case self::TYPE_SERVICE: - if ($old) { - $phids[] = $old; - } - if ($new) { - $phids[] = $new; - } - break; - case self::TYPE_SYMBOLS_SOURCES: - case self::TYPE_AUTOMATION_BLUEPRINTS: - if ($old) { - $phids = array_merge($phids, $old); - } - if ($new) { - $phids = array_merge($phids, $new); - } - break; - } - - return $phids; - } - - public function shouldHide() { - $old = $this->getOldValue(); - $new = $this->getNewValue(); - - switch ($this->getTransactionType()) { - case self::TYPE_NAME: - // Hide these on create, they aren't interesting and we have an - // explicit "create" transaction. - if (!strlen($old)) { - return true; - } - break; - } - - return parent::shouldHide(); - } - - public function getIcon() { - switch ($this->getTransactionType()) { - case self::TYPE_VCS: - return 'fa-plus'; - } - return parent::getIcon(); - } - - public function getColor() { - switch ($this->getTransactionType()) { - case self::TYPE_VCS: - return 'green'; - } - return parent::getIcon(); - } - - public function getTitle() { - $author_phid = $this->getAuthorPHID(); - - $old = $this->getOldValue(); - $new = $this->getNewValue(); - - switch ($this->getTransactionType()) { - case self::TYPE_VCS: - return pht( - '%s created this repository.', - $this->renderHandleLink($author_phid)); - case self::TYPE_ACTIVATE: - // TODO: Old versions of this transaction use a boolean value, but - // should be migrated. - $is_deactivate = - (!$new) || - ($new == PhabricatorRepository::STATUS_INACTIVE); - - if (!$is_deactivate) { - return pht( - '%s activated this repository.', - $this->renderHandleLink($author_phid)); - } else { - return pht( - '%s deactivated this repository.', - $this->renderHandleLink($author_phid)); - } - case self::TYPE_NAME: - return pht( - '%s renamed this repository from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $old, - $new); - case self::TYPE_DESCRIPTION: - return pht( - '%s updated the description of this repository.', - $this->renderHandleLink($author_phid)); - case self::TYPE_ENCODING: - if (strlen($old) && !strlen($new)) { - return pht( - '%s removed the "%s" encoding configured for this repository.', - $this->renderHandleLink($author_phid), - $old); - } else if (strlen($new) && !strlen($old)) { - return pht( - '%s set the encoding for this repository to "%s".', - $this->renderHandleLink($author_phid), - $new); - } else { - return pht( - '%s changed the repository encoding from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $old, - $new); - } - case self::TYPE_DEFAULT_BRANCH: - if (!strlen($new)) { - return pht( - '%s removed "%s" as the default branch.', - $this->renderHandleLink($author_phid), - $old); - } else if (!strlen($old)) { - return pht( - '%s set the default branch to "%s".', - $this->renderHandleLink($author_phid), - $new); - } else { - return pht( - '%s changed the default branch from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $old, - $new); - } - break; - case self::TYPE_TRACK_ONLY: - if (!$new) { - return pht( - '%s set this repository to track all branches.', - $this->renderHandleLink($author_phid)); - } else if (!$old) { - return pht( - '%s set this repository to track branches: %s.', - $this->renderHandleLink($author_phid), - implode(', ', $new)); - } else { - return pht( - '%s changed track branches from "%s" to "%s".', - $this->renderHandleLink($author_phid), - implode(', ', $old), - implode(', ', $new)); - } - break; - case self::TYPE_AUTOCLOSE_ONLY: - if (!$new) { - return pht( - '%s set this repository to autoclose on all branches.', - $this->renderHandleLink($author_phid)); - } else if (!$old) { - return pht( - '%s set this repository to autoclose on branches: %s.', - $this->renderHandleLink($author_phid), - implode(', ', $new)); - } else { - return pht( - '%s changed autoclose branches from "%s" to "%s".', - $this->renderHandleLink($author_phid), - implode(', ', $old), - implode(', ', $new)); - } - break; - case self::TYPE_SVN_SUBPATH: - if (!strlen($new)) { - return pht( - '%s removed "%s" as the Import Only path.', - $this->renderHandleLink($author_phid), - $old); - } else if (!strlen($old)) { - return pht( - '%s set the repository to import only "%s".', - $this->renderHandleLink($author_phid), - $new); - } else { - return pht( - '%s changed the import path from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $old, - $new); - } - break; - case self::TYPE_NOTIFY: - if ($new) { - return pht( - '%s enabled notifications and publishing for this repository.', - $this->renderHandleLink($author_phid)); - } else { - return pht( - '%s disabled notifications and publishing for this repository.', - $this->renderHandleLink($author_phid)); - } - break; - case self::TYPE_AUTOCLOSE: - if ($new) { - return pht( - '%s enabled autoclose for this repository.', - $this->renderHandleLink($author_phid)); - } else { - return pht( - '%s disabled autoclose for this repository.', - $this->renderHandleLink($author_phid)); - } - break; - case self::TYPE_PUSH_POLICY: - return pht( - '%s changed the push policy of this repository from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $this->renderPolicyName($old, 'old'), - $this->renderPolicyName($new, 'new')); - case self::TYPE_DANGEROUS: - if ($new) { - return pht( - '%s disabled protection against dangerous changes.', - $this->renderHandleLink($author_phid)); - } else { - return pht( - '%s enabled protection against dangerous changes.', - $this->renderHandleLink($author_phid)); - } - case self::TYPE_ENORMOUS: - if ($new) { - return pht( - '%s disabled protection against enormous changes.', - $this->renderHandleLink($author_phid)); - } else { - return pht( - '%s enabled protection against enormous changes.', - $this->renderHandleLink($author_phid)); - } - case self::TYPE_SLUG: - if (strlen($old) && !strlen($new)) { - return pht( - '%s removed the short name of this repository.', - $this->renderHandleLink($author_phid)); - } else if (strlen($new) && !strlen($old)) { - return pht( - '%s set the short name of this repository to "%s".', - $this->renderHandleLink($author_phid), - $new); - } else { - return pht( - '%s changed the short name of this repository from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $old, - $new); - } - case self::TYPE_SERVICE: - if (strlen($old) && !strlen($new)) { - return pht( - '%s moved storage for this repository from %s to local.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($old)); - } else if (!strlen($old) && strlen($new)) { - // TODO: Possibly, we should distinguish between automatic assignment - // on creation vs explicit adjustment. - return pht( - '%s set storage for this repository to %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($new)); - } else { - return pht( - '%s moved storage for this repository from %s to %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($old), - $this->renderHandleLink($new)); - } - case self::TYPE_SYMBOLS_SOURCES: - return pht( - '%s changed symbol sources from %s to %s.', - $this->renderHandleLink($author_phid), - empty($old) ? pht('None') : $this->renderHandleList($old), - empty($new) ? pht('None') : $this->renderHandleList($new)); - - case self::TYPE_SYMBOLS_LANGUAGE: - return pht('%s changed indexed languages from %s to %s.', - $this->renderHandleLink($author_phid), - $old ? implode(', ', $old) : pht('Any'), - $new ? implode(', ', $new) : pht('Any')); - - case self::TYPE_STAGING_URI: - if (!$old) { - return pht( - '%s set "%s" as the staging area for this repository.', - $this->renderHandleLink($author_phid), - $new); - } else if (!$new) { - return pht( - '%s removed "%s" as the staging area for this repository.', - $this->renderHandleLink($author_phid), - $old); - } else { - return pht( - '%s changed the staging area for this repository from '. - '"%s" to "%s".', - $this->renderHandleLink($author_phid), - $old, - $new); - } - - case self::TYPE_AUTOMATION_BLUEPRINTS: - $add = array_diff($new, $old); - $rem = array_diff($old, $new); - - if ($add && $rem) { - return pht( - '%s changed %s automation blueprint(s), '. - 'added %s: %s; removed %s: %s.', - $this->renderHandleLink($author_phid), - new PhutilNumber(count($add) + count($rem)), - new PhutilNumber(count($add)), - $this->renderHandleList($add), - new PhutilNumber(count($rem)), - $this->renderHandleList($rem)); - } else if ($add) { - return pht( - '%s added %s automation blueprint(s): %s.', - $this->renderHandleLink($author_phid), - new PhutilNumber(count($add)), - $this->renderHandleList($add)); - } else { - return pht( - '%s removed %s automation blueprint(s): %s.', - $this->renderHandleLink($author_phid), - new PhutilNumber(count($rem)), - $this->renderHandleList($rem)); - } - - case self::TYPE_CALLSIGN: - if ($old === null) { - return pht( - '%s set the callsign for this repository to "%s".', - $this->renderHandleLink($author_phid), - $new); - } else if ($new === null) { - return pht( - '%s removed the callsign ("%s") for this repository.', - $this->renderHandleLink($author_phid), - $old); - } else { - return pht( - '%s changed the callsign for this repository from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $old, - $new); - } - - } - - return parent::getTitle(); - } - - public function hasChangeDetails() { - switch ($this->getTransactionType()) { - case self::TYPE_DESCRIPTION: - return true; - } - return parent::hasChangeDetails(); - } - - public function renderChangeDetails(PhabricatorUser $viewer) { - return $this->renderTextCorpusChangeDetails( - $viewer, - $this->getOldValue(), - $this->getNewValue()); + public function getBaseTransactionClass() { + return 'PhabricatorRepositoryTransactionType'; } } diff --git a/src/applications/repository/xaction/PhabricatorRepositoryActivateTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryActivateTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryActivateTransaction.php @@ -0,0 +1,61 @@ +isTracked(); + } + + public function applyInternalEffects($object, $value) { + // The first time a repository is activated, clear the "new repository" + // flag so we stop showing setup hints. + if ($value) { + $object->setDetail('newly-initialized', false); + } + + $object->setDetail('tracking-enabled', $value); + } + + public function getTitle() { + $new = $this->getNewValue(); + + // TODO: Old versions of this transaction use a boolean value, but + // should be migrated. + $is_deactivate = + (!$new) || + ($new == PhabricatorRepository::STATUS_INACTIVE); + + if (!$is_deactivate) { + return pht( + '%s activated this repository.', + $this->renderAuthor()); + } else { + return pht( + '%s deactivated this repository.', + $this->renderAuthor()); + } + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + $status_map = PhabricatorRepository::getStatusMap(); + foreach ($xactions as $xaction) { + $status = $xaction->getNewValue(); + if (empty($status_map[$status])) { + $errors[] = $this->newInvalidError( + pht( + 'Repository status "%s" is not valid. Valid statuses are: %s.', + $status, + implode(', ', array_keys($status_map))), + $xaction); + } + } + + return $errors; + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryAutocloseOnlyTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryAutocloseOnlyTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryAutocloseOnlyTransaction.php @@ -0,0 +1,42 @@ +getDetail('close-commits-filter', array())); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('close-commits-filter', array_fill_keys($value, true)); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + if (!$new) { + return pht( + '%s set this repository to autoclose on all branches.', + $this->renderAuthor()); + } else if (!$old) { + return pht( + '%s set this repository to autoclose on branches: %s.', + $this->renderAuthor(), + $this->renderValue(implode(', ', $new))); + } else { + return pht( + '%s changed autoclose branches from %s to %s.', + $this->renderAuthor(), + $this->renderValue(implode(', ', $old)), + $this->renderValue(implode(', ', $new))); + } + } + + public function validateTransactions($object, array $xactions) { + return $this->validateRefList($object, $xactions); + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryAutocloseTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryAutocloseTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryAutocloseTransaction.php @@ -0,0 +1,34 @@ +getDetail('disable-autoclose'); + } + + public function generateNewValue($object, $value) { + return (int)$value; + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('disable-autoclose', (int)!$value); + } + + public function getTitle() { + $new = $this->getNewValue(); + + if ($new) { + return pht( + '%s enabled autoclose for this repository.', + $this->renderAuthor()); + } else { + return pht( + '%s disabled autoclose for this repository.', + $this->renderAuthor()); + } + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryBlueprintsTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryBlueprintsTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryBlueprintsTransaction.php @@ -0,0 +1,81 @@ +getDetail('automation.blueprintPHIDs', array()); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('automation.blueprintPHIDs', $value); + } + + public function applyExternalEffects($object, $value) { + DrydockAuthorization::applyAuthorizationChanges( + $this->getActor(), + $object->getPHID(), + $this->getOldValue(), + $this->getNewValue()); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + $add = array_diff($new, $old); + $rem = array_diff($old, $new); + + if ($add && $rem) { + return pht( + '%s changed %s automation blueprint(s), '. + 'added %s: %s; removed %s: %s.', + $this->renderAuthor(), + new PhutilNumber(count($add) + count($rem)), + new PhutilNumber(count($add)), + $this->renderHandleList($add), + new PhutilNumber(count($rem)), + $this->renderHandleList($rem)); + } else if ($add) { + return pht( + '%s added %s automation blueprint(s): %s.', + $this->renderAuthor(), + new PhutilNumber(count($add)), + $this->renderHandleList($add)); + } else { + return pht( + '%s removed %s automation blueprint(s): %s.', + $this->renderAuthor(), + new PhutilNumber(count($rem)), + $this->renderHandleList($rem)); + } + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + foreach ($xactions as $xaction) { + $old = nonempty($xaction->getOldValue(), array()); + $new = nonempty($xaction->getNewValue(), array()); + + $add = array_diff($new, $old); + + $invalid = PhabricatorObjectQuery::loadInvalidPHIDsForViewer( + $this->getActor(), + $add); + if ($invalid) { + $errors[] = $this->newInvalidError( + pht( + 'Some of the selected automation blueprints are invalid '. + 'or restricted: %s.', + implode(', ', $invalid)), + $xaction); + } + } + + return $errors; + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryCallsignTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryCallsignTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryCallsignTransaction.php @@ -0,0 +1,90 @@ +getCallsign(); + } + + public function generateNewValue($object, $value) { + if (strlen($value)) { + return $value; + } + + return null; + } + + public function applyInternalEffects($object, $value) { + $object->setCallsign($value); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + if (!strlen($old)) { + return pht( + '%s set the callsign for this repository to %s.', + $this->renderAuthor(), + $this->renderNewValue()); + } else if (!strlen($new)) { + return pht( + '%s removed the callsign (%s) for this repository.', + $this->renderAuthor(), + $this->renderOldValue()); + } else { + return pht( + '%s changed the callsign for this repository from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + foreach ($xactions as $xaction) { + $old = $xaction->getOldValue(); + $new = $xaction->getNewValue(); + + if (!strlen($new)) { + continue; + } + + if ($new === $old) { + continue; + } + + try { + PhabricatorRepository::assertValidCallsign($new); + } catch (Exception $ex) { + $errors[] = $this->newInvalidError( + $ex->getMessage(), + $xaction); + continue; + } + + $other = id(new PhabricatorRepositoryQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withCallsigns(array($new)) + ->executeOne(); + if ($other && ($other->getID() !== $object->getID())) { + $errors[] = $this->newError( + pht('Duplicate'), + pht( + 'The selected callsign ("%s") is already in use by another '. + 'repository. Choose a unique callsign.', + $new), + $xaction); + continue; + } + } + + return $errors; + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryDangerousTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryDangerousTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryDangerousTransaction.php @@ -0,0 +1,30 @@ +shouldAllowDangerousChanges(); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('allow-dangerous-changes', $value); + } + + public function getTitle() { + $new = $this->getNewValue(); + + if ($new) { + return pht( + '%s disabled protection against dangerous changes.', + $this->renderAuthor()); + } else { + return pht( + '%s enabled protection against dangerous changes.', + $this->renderAuthor()); + } + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryDefaultBranchTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryDefaultBranchTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryDefaultBranchTransaction.php @@ -0,0 +1,39 @@ +getDetail('default-branch'); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('default-branch', $value); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + if (!strlen($new)) { + return pht( + '%s removed %s as the default branch.', + $this->renderAuthor(), + $this->renderOldValue()); + } else if (!strlen($old)) { + return pht( + '%s set the default branch to %s.', + $this->renderAuthor(), + $this->renderNewValue()); + } else { + return pht( + '%s changed the default branch from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryDescriptionTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryDescriptionTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryDescriptionTransaction.php @@ -0,0 +1,49 @@ +getDetail('description'); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('description', $value); + } + + public function getTitle() { + return pht( + '%s updated the description for this repository.', + $this->renderAuthor()); + } + + public function hasChangeDetailView() { + return true; + } + + public function getMailDiffSectionHeader() { + return pht('CHANGES TO REPOSITORY DESCRIPTION'); + } + + public function newChangeDetailView() { + $viewer = $this->getViewer(); + + return id(new PhabricatorApplicationTransactionTextDiffDetailView()) + ->setViewer($viewer) + ->setOldText($this->getOldValue()) + ->setNewText($this->getNewValue()); + } + + public function newRemarkupChanges() { + $changes = array(); + + $changes[] = $this->newRemarkupChange() + ->setOldValue($this->getOldValue()) + ->setNewValue($this->getNewValue()); + + return $changes; + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryEncodingTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryEncodingTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryEncodingTransaction.php @@ -0,0 +1,68 @@ +getDetail('encoding'); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('encoding', $value); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + if (strlen($old) && !strlen($new)) { + return pht( + '%s removed the %s encoding configured for this repository.', + $this->renderAuthor(), + $this->renderOldValue()); + } else if (strlen($new) && !strlen($old)) { + return pht( + '%s set the encoding for this repository to %s.', + $this->renderAuthor(), + $this->renderNewValue()); + } else { + return pht( + '%s changed the repository encoding from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + foreach ($xactions as $xaction) { + // Make sure the encoding is valid by converting to UTF-8. This tests + // that the user has mbstring installed, and also that they didn't + // type a garbage encoding name. Note that we're converting from + // UTF-8 to the target encoding, because mbstring is fine with + // converting from a nonsense encoding. + $encoding = $xaction->getNewValue(); + if (!strlen($encoding)) { + continue; + } + + try { + phutil_utf8_convert('.', $encoding, 'UTF-8'); + } catch (Exception $ex) { + $errors[] = $this->newInvalidError( + pht( + 'Repository encoding "%s" is not valid: %s', + $encoding, + $ex->getMessage()), + $xaction); + } + } + + return $errors; + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryEnormousTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryEnormousTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryEnormousTransaction.php @@ -0,0 +1,30 @@ +shouldAllowEnormousChanges(); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('allow-enormous-changes', $value); + } + + public function getTitle() { + $new = $this->getNewValue(); + + if ($new) { + return pht( + '%s disabled protection against enormous changes.', + $this->renderAuthor()); + } else { + return pht( + '%s enabled protection against enormous changes.', + $this->renderAuthor()); + } + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryNameTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryNameTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryNameTransaction.php @@ -0,0 +1,35 @@ +getName(); + } + + public function applyInternalEffects($object, $value) { + $object->setName($value); + } + + public function getTitle() { + return pht( + '%s renamed this repository from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + if ($this->isEmptyTextTransaction($object->getName(), $xactions)) { + $errors[] = $this->newRequiredError( + pht('Repositories must have a name.')); + } + + return $errors; + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryNotifyTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryNotifyTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryNotifyTransaction.php @@ -0,0 +1,34 @@ +getDetail('herald-disabled'); + } + + public function generateNewValue($object, $value) { + return (int)$value; + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('herald-disabled', (int)!$value); + } + + public function getTitle() { + $new = $this->getNewValue(); + + if ($new) { + return pht( + '%s enabled notifications and publishing for this repository.', + $this->renderAuthor()); + } else { + return pht( + '%s disabled notifications and publishing for this repository.', + $this->renderAuthor()); + } + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryPushPolicyTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryPushPolicyTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryPushPolicyTransaction.php @@ -0,0 +1,24 @@ +getPushPolicy(); + } + + public function applyInternalEffects($object, $value) { + $object->setPushPolicy($value); + } + + public function getTitle() { + return pht( + '%s changed the push policy of this repository from %s to %s.', + $this->renderAuthor(), + $this->renderOldPolicy(), + $this->renderNewPolicy()); + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositorySVNSubpathTransaction.php b/src/applications/repository/xaction/PhabricatorRepositorySVNSubpathTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositorySVNSubpathTransaction.php @@ -0,0 +1,39 @@ +getDetail('svn-subpath'); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('svn-subpath', $value); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + if (!strlen($new)) { + return pht( + '%s removed %s as the "Import Only" path.', + $this->renderAuthor(), + $this->renderOldValue()); + } else if (!strlen($old)) { + return pht( + '%s set the repository "Import Only" path to %s.', + $this->renderAuthor(), + $this->renderNewValue()); + } else { + return pht( + '%s changed the "Import Only" path from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryServiceTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryServiceTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryServiceTransaction.php @@ -0,0 +1,59 @@ +getAlmanacServicePHID(); + } + + public function generateNewValue($object, $value) { + if (strlen($value)) { + return $value; + } + + return null; + } + + public function applyInternalEffects($object, $value) { + $object->setAlmanacServicePHID($value); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getOldValue(); + + if (strlen($old) && !strlen($new)) { + return pht( + '%s moved storage for this repository from %s to local.', + $this->renderAuthor(), + $this->renderOldHandle()); + } else if (!strlen($old) && strlen($new)) { + // TODO: Possibly, we should distinguish between automatic assignment + // on creation vs explicit adjustment. + return pht( + '%s set storage for this repository to %s.', + $this->renderAuthor(), + $this->renderNewHandle()); + } else { + return pht( + '%s moved storage for this repository from %s to %s.', + $this->renderAuthor(), + $this->renderOldHandle(), + $this->renderNewHandle()); + } + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + // TODO: This could use some validation, values should be valid Almanac + // services of appropriate types. It's only reachable via the CLI so it's + // difficult to get wrong in practice. + + return $errors; + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositorySlugTransaction.php b/src/applications/repository/xaction/PhabricatorRepositorySlugTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositorySlugTransaction.php @@ -0,0 +1,88 @@ +getRepositorySlug(); + } + + public function generateNewValue($object, $value) { + if (strlen($value)) { + return $value; + } + + return null; + } + + public function applyInternalEffects($object, $value) { + $object->setRepositorySlug($value); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + if (strlen($old) && !strlen($new)) { + return pht( + '%s removed the short name of this repository.', + $this->renderAuthor()); + } else if (strlen($new) && !strlen($old)) { + return pht( + '%s set the short name of this repository to %s.', + $this->renderAuthor(), + $this->renderNewValue()); + } else { + return pht( + '%s changed the short name of this repository from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + foreach ($xactions as $xaction) { + $old = $xaction->getOldValue(); + $new = $xaction->getNewValue(); + + if (!strlen($new)) { + continue; + } + + if ($new === $old) { + continue; + } + + try { + PhabricatorRepository::assertValidRepositorySlug($new); + } catch (Exception $ex) { + $errors[] = $this->newInvalidError( + $ex->getMessage(), + $xaction); + continue; + } + + $other = id(new PhabricatorRepositoryQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withSlugs(array($new)) + ->executeOne(); + if ($other && ($other->getID() !== $object->getID())) { + $errors[] = $this->newError( + pht('Duplicate'), + pht( + 'The selected repository short name is already in use by '. + 'another repository. Choose a unique short name.'), + $xaction); + continue; + } + } + + return $errors; + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryStagingURITransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryStagingURITransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryStagingURITransaction.php @@ -0,0 +1,68 @@ +getDetail('staging-uri'); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('staging-uri', $value); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + if (!strlen($old)) { + return pht( + '%s set %s as the staging area for this repository.', + $this->renderAuthor(), + $this->renderNewValue()); + } else if (!strlen($new)) { + return pht( + '%s removed %s as the staging area for this repository.', + $this->renderAuthor(), + $this->renderOldValue()); + } else { + return pht( + '%s changed the staging area for this repository from '. + '%s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + $old = $this->generateOldValue($object); + foreach ($xactions as $xaction) { + $new = $xaction->getNewValue(); + + if (!strlen($new)) { + continue; + } + + if ($new === $old) { + continue; + } + + try { + PhabricatorRepository::assertValidRemoteURI($new); + } catch (Exception $ex) { + $errors[] = $this->newInvalidError( + $ex->getMessage(), + $xaction); + continue; + } + } + + return $errors; + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositorySymbolLanguagesTransaction.php b/src/applications/repository/xaction/PhabricatorRepositorySymbolLanguagesTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositorySymbolLanguagesTransaction.php @@ -0,0 +1,39 @@ +getSymbolLanguages(); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('symbol-languages', $value); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + if ($old) { + $display_old = implode(', ', $old); + } else { + $display_old = pht('Any'); + } + + if ($new) { + $display_new = implode(', ', $new); + } else { + $display_new = pht('Any'); + } + + return pht( + '%s changed indexed languages from %s to %s.', + $this->renderAuthor(), + $this->renderValue($display_old), + $this->renderValue($display_new)); + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositorySymbolSourcesTransaction.php b/src/applications/repository/xaction/PhabricatorRepositorySymbolSourcesTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositorySymbolSourcesTransaction.php @@ -0,0 +1,78 @@ +getSymbolSources(); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('symbol-sources', $value); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + if ($old) { + $display_old = $this->renderHandleList($old); + } else { + $display_old = $this->renderValue(pht('None')); + } + + if ($new) { + $display_new = $this->renderHandleList($new); + } else { + $display_new = $this->renderValue(pht('None')); + } + + return pht( + '%s changed symbol sources from %s to %s.', + $this->renderAuthor(), + $display_old, + $display_new); + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + foreach ($xactions as $xaction) { + $old = $object->getSymbolSources(); + $new = $xaction->getNewValue(); + + // If the viewer is adding new repositories, make sure they are + // valid and visible. + $add = array_diff($new, $old); + if (!$add) { + continue; + } + + $repositories = id(new PhabricatorRepositoryQuery()) + ->setViewer($this->getActor()) + ->withPHIDs($add) + ->execute(); + $repositories = mpull($repositories, null, 'getPHID'); + + foreach ($add as $phid) { + if (isset($repositories[$phid])) { + continue; + } + + $errors[] = $this->newInvalidError( + pht( + 'Repository ("%s") does not exist, or you do not have '. + 'permission to see it.', + $phid), + $xaction); + break; + } + } + + return $errors; + } + + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryTrackOnlyTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryTrackOnlyTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryTrackOnlyTransaction.php @@ -0,0 +1,42 @@ +getDetail('branch-filter', array())); + } + + public function applyInternalEffects($object, $value) { + $object->setDetail('branch-filter', array_fill_keys($value, true)); + } + + public function getTitle() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + if (!$new) { + return pht( + '%s set this repository to track all branches.', + $this->renderAuthor()); + } else if (!$old) { + return pht( + '%s set this repository to track branches: %s.', + $this->renderAuthor(), + $this->renderValue(implode(', ', $new))); + } else { + return pht( + '%s changed tracked branches from %s to %s.', + $this->renderAuthor(), + $this->renderValue(implode(', ', $old)), + $this->renderValue(implode(', ', $new))); + } + } + + public function validateTransactions($object, array $xactions) { + return $this->validateRefList($object, $xactions); + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryTransactionType.php b/src/applications/repository/xaction/PhabricatorRepositoryTransactionType.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryTransactionType.php @@ -0,0 +1,49 @@ +getNewValue() as $pattern) { + // Check for invalid regular expressions. + $regexp = PhabricatorRepository::extractBranchRegexp($pattern); + if ($regexp !== null) { + $ok = @preg_match($regexp, ''); + if ($ok === false) { + $errors[] = $this->newInvalidError( + pht( + 'Expression "%s" is not a valid regular expression. Note '. + 'that you must include delimiters.', + $regexp), + $xaction); + continue; + } + } + + // Check for formatting mistakes like `regex(...)` instead of + // `regexp(...)`. + $matches = null; + if (preg_match('/^([^(]+)\\(.*\\)\z/', $pattern, $matches)) { + switch ($matches[1]) { + case 'regexp': + break; + default: + $errors[] = $this->newInvalidError( + pht( + 'Matching function "%s(...)" is not recognized. Valid '. + 'functions are: regexp(...).', + $matches[1]), + $xaction); + break; + } + } + } + } + + return $errors; + } + +} diff --git a/src/applications/repository/xaction/PhabricatorRepositoryVCSTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryVCSTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/xaction/PhabricatorRepositoryVCSTransaction.php @@ -0,0 +1,66 @@ +getVersionControlSystem(); + } + + public function applyInternalEffects($object, $value) { + $object->setVersionControlSystem($value); + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + $vcs_map = PhabricatorRepositoryType::getAllRepositoryTypes(); + $current_vcs = $object->getVersionControlSystem(); + + if (!$this->isNewObject()) { + foreach ($xactions as $xaction) { + if ($xaction->getNewValue() == $current_vcs) { + continue; + } + + $errors[] = $this->newInvalidError( + pht( + 'You can not change the version control system an existing '. + 'repository uses. It can only be set when a repository is '. + 'first created.'), + $xaction); + } + + return $errors; + } + + $value = $object->getVersionControlSystem(); + + foreach ($xactions as $xaction) { + $value = $xaction->getNewValue(); + + if (isset($vcs_map[$value])) { + continue; + } + + $errors[] = $this->newInvalidError( + pht( + 'Specified version control system must be a VCS '. + 'recognized by Phabricator. Valid systems are: %s.', + implode(', ', array_keys($vcs_map))), + $xaction); + } + + if ($value === null) { + $errors[] = $this->newRequiredError( + pht( + 'When creating a repository, you must specify a valid '. + 'underlying version control system. Valid systems are: %s.', + implode(', ', array_keys($vcs_map)))); + } + + return $errors; + } +} diff --git a/src/applications/transactions/controller/PhabricatorApplicationTransactionValueController.php b/src/applications/transactions/controller/PhabricatorApplicationTransactionValueController.php --- a/src/applications/transactions/controller/PhabricatorApplicationTransactionValueController.php +++ b/src/applications/transactions/controller/PhabricatorApplicationTransactionValueController.php @@ -32,7 +32,7 @@ case PhabricatorTransactions::TYPE_VIEW_POLICY: case PhabricatorTransactions::TYPE_EDIT_POLICY: case PhabricatorTransactions::TYPE_JOIN_POLICY: - case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: + case PhabricatorRepositoryPushPolicyTransaction::TRANSACTIONTYPE: break; default: return new Aphront404Response(); diff --git a/src/applications/transactions/storage/PhabricatorModularTransactionType.php b/src/applications/transactions/storage/PhabricatorModularTransactionType.php --- a/src/applications/transactions/storage/PhabricatorModularTransactionType.php +++ b/src/applications/transactions/storage/PhabricatorModularTransactionType.php @@ -199,6 +199,35 @@ return $this->renderHandle($this->getNewValue()); } + final protected function renderOldPolicy() { + return $this->renderPolicy($this->getOldValue(), 'old'); + } + + final protected function renderNewPolicy() { + return $this->renderPolicy($this->getNewValue(), 'new'); + } + + final protected function renderPolicy($phid, $mode) { + $viewer = $this->getViewer(); + $handles = $viewer->loadHandles(array($phid)); + + $policy = PhabricatorPolicy::newFromPolicyAndHandle( + $phid, + $handles[$phid]); + + if ($this->isTextMode()) { + return $this->renderValue($policy->getFullName()); + } + + $storage = $this->getStorage(); + if ($policy->getType() == PhabricatorPolicyType::TYPE_CUSTOM) { + $policy->setHref('/transactions/'.$mode.'/'.$storage->getPHID().'/'); + $policy->setWorkflow(true); + } + + return $this->renderValue($policy->renderDescription()); + } + final protected function renderHandleList(array $phids) { $viewer = $this->getViewer(); $display = $viewer->renderHandleList($phids)