diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 5afb2b104f..a564ba0f3b 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -149,6 +149,7 @@ phutil_register_library_map(array( 'ConduitAPI_diffusion_browsequery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_browsequery_Method.php', 'ConduitAPI_diffusion_diffquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_diffquery_Method.php', 'ConduitAPI_diffusion_existsquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_existsquery_Method.php', + 'ConduitAPI_diffusion_expandshortcommitquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_expandshortcommitquery_Method.php', 'ConduitAPI_diffusion_filecontentquery_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_filecontentquery_Method.php', 'ConduitAPI_diffusion_findsymbols_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_findsymbols_Method.php', 'ConduitAPI_diffusion_getcommits_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_getcommits_Method.php', @@ -429,6 +430,8 @@ phutil_register_library_map(array( 'DiffusionController' => 'applications/diffusion/controller/DiffusionController.php', 'DiffusionDiffController' => 'applications/diffusion/controller/DiffusionDiffController.php', 'DiffusionEmptyResultView' => 'applications/diffusion/view/DiffusionEmptyResultView.php', + 'DiffusionExpandCommitQueryException' => 'applications/diffusion/exception/DiffusionExpandCommitQueryException.php', + 'DiffusionExpandShortNameQuery' => 'applications/diffusion/query/expandshortname/DiffusionExpandShortNameQuery.php', 'DiffusionExternalController' => 'applications/diffusion/controller/DiffusionExternalController.php', 'DiffusionFileContent' => 'applications/diffusion/data/DiffusionFileContent.php', 'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionFileContentQuery.php', @@ -436,6 +439,7 @@ phutil_register_library_map(array( 'DiffusionGitBranchTestCase' => 'applications/diffusion/data/__tests__/DiffusionGitBranchTestCase.php', 'DiffusionGitCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionGitCommitParentsQuery.php', 'DiffusionGitContainsQuery' => 'applications/diffusion/query/contains/DiffusionGitContainsQuery.php', + 'DiffusionGitExpandShortNameQuery' => 'applications/diffusion/query/expandshortname/DiffusionGitExpandShortNameQuery.php', 'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php', 'DiffusionGitHistoryQuery' => 'applications/diffusion/query/history/DiffusionGitHistoryQuery.php', 'DiffusionGitMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/DiffusionGitMergedCommitsQuery.php', @@ -454,6 +458,7 @@ phutil_register_library_map(array( 'DiffusionLintSaveRunner' => 'applications/diffusion/DiffusionLintSaveRunner.php', 'DiffusionMercurialCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionMercurialCommitParentsQuery.php', 'DiffusionMercurialContainsQuery' => 'applications/diffusion/query/contains/DiffusionMercurialContainsQuery.php', + 'DiffusionMercurialExpandShortNameQuery' => 'applications/diffusion/query/expandshortname/DiffusionMercurialExpandShortNameQuery.php', 'DiffusionMercurialFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php', 'DiffusionMercurialHistoryQuery' => 'applications/diffusion/query/history/DiffusionMercurialHistoryQuery.php', 'DiffusionMercurialMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/DiffusionMercurialMergedCommitsQuery.php', @@ -1940,6 +1945,7 @@ phutil_register_library_map(array( 'ConduitAPI_diffusion_browsequery_Method' => 'ConduitAPI_diffusion_abstractquery_Method', 'ConduitAPI_diffusion_diffquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method', 'ConduitAPI_diffusion_existsquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method', + 'ConduitAPI_diffusion_expandshortcommitquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method', 'ConduitAPI_diffusion_filecontentquery_Method' => 'ConduitAPI_diffusion_abstractquery_Method', 'ConduitAPI_diffusion_findsymbols_Method' => 'ConduitAPI_diffusion_Method', 'ConduitAPI_diffusion_getcommits_Method' => 'ConduitAPI_diffusion_Method', @@ -2210,11 +2216,14 @@ phutil_register_library_map(array( 'DiffusionController' => 'PhabricatorController', 'DiffusionDiffController' => 'DiffusionController', 'DiffusionEmptyResultView' => 'DiffusionView', + 'DiffusionExpandCommitQueryException' => 'Exception', + 'DiffusionExpandShortNameQuery' => 'DiffusionQuery', 'DiffusionExternalController' => 'DiffusionController', 'DiffusionFileContentQuery' => 'DiffusionQuery', 'DiffusionGitBranchTestCase' => 'PhabricatorTestCase', 'DiffusionGitCommitParentsQuery' => 'DiffusionCommitParentsQuery', 'DiffusionGitContainsQuery' => 'DiffusionContainsQuery', + 'DiffusionGitExpandShortNameQuery' => 'DiffusionExpandShortNameQuery', 'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery', 'DiffusionGitHistoryQuery' => 'DiffusionHistoryQuery', 'DiffusionGitMergedCommitsQuery' => 'DiffusionMergedCommitsQuery', @@ -2232,6 +2241,7 @@ phutil_register_library_map(array( 'DiffusionLintDetailsController' => 'DiffusionController', 'DiffusionMercurialCommitParentsQuery' => 'DiffusionCommitParentsQuery', 'DiffusionMercurialContainsQuery' => 'DiffusionContainsQuery', + 'DiffusionMercurialExpandShortNameQuery' => 'DiffusionExpandShortNameQuery', 'DiffusionMercurialFileContentQuery' => 'DiffusionFileContentQuery', 'DiffusionMercurialHistoryQuery' => 'DiffusionHistoryQuery', 'DiffusionMercurialMergedCommitsQuery' => 'DiffusionMergedCommitsQuery', diff --git a/src/applications/differential/view/DifferentialChangesetListView.php b/src/applications/differential/view/DifferentialChangesetListView.php index dcd080dfe8..e10fe8bf2f 100644 --- a/src/applications/differential/view/DifferentialChangesetListView.php +++ b/src/applications/differential/view/DifferentialChangesetListView.php @@ -263,6 +263,7 @@ final class DifferentialChangesetListView extends AphrontView { try { $meta['diffusionURI'] = (string)$repository->getDiffusionBrowseURIForPath( + $this->user, $changeset->getAbsoluteRepositoryPath($repository, $this->diff), idx($changeset->getMetadata(), 'line:first'), $this->getBranch()); diff --git a/src/applications/diffusion/DiffusionLintSaveRunner.php b/src/applications/diffusion/DiffusionLintSaveRunner.php index 6d2f0b3b4e..39612a88f1 100644 --- a/src/applications/diffusion/DiffusionLintSaveRunner.php +++ b/src/applications/diffusion/DiffusionLintSaveRunner.php @@ -235,6 +235,8 @@ final class DiffusionLintSaveRunner { $futures = array(); foreach ($this->blame as $path => $lines) { $drequest = DiffusionRequest::newFromDictionary(array( + 'user' => PhabricatorUser::getOmnipotentUser(), + 'initFromConduit' => false, 'repository' => $repository, 'branch' => $this->branch->getName(), 'path' => $path, diff --git a/src/applications/diffusion/conduit/ConduitAPI_diffusion_abstractquery_Method.php b/src/applications/diffusion/conduit/ConduitAPI_diffusion_abstractquery_Method.php index 09727976c4..1da13b9b4c 100644 --- a/src/applications/diffusion/conduit/ConduitAPI_diffusion_abstractquery_Method.php +++ b/src/applications/diffusion/conduit/ConduitAPI_diffusion_abstractquery_Method.php @@ -17,6 +17,9 @@ abstract class ConduitAPI_diffusion_abstractquery_Method } private $diffusionRequest; + private $repository; + private $shouldCreateDiffusionRequest = true; + protected function setDiffusionRequest(DiffusionRequest $request) { $this->diffusionRequest = $request; return $this; @@ -25,10 +28,54 @@ abstract class ConduitAPI_diffusion_abstractquery_Method return $this->diffusionRequest; } + /** + * A wee bit of magic here. If @{method:shouldCreateDiffusionRequest} + * returns false, this function grabs a repository object based on the + * callsign directly. Otherwise, the repository was loaded when we created a + * @{class:DiffusionRequest}, so this function just pulls it out of the + * @{class:DiffusionRequest}. + * + * @return @{class:PhabricatorRepository} $repository + */ + protected function getRepository(ConduitAPIRequest $request) { + if (!$this->repository) { + if ($this->shouldCreateDiffusionRequest()) { + $this->repository = $this->getDiffusionRequest()->getRepository(); + } else { + $callsign = $request->getValue('callsign'); + $repository = id(new PhabricatorRepository())->loadOneWhere( + 'callsign = %s', + $callsign); + if (!$repository) { + throw new ConduitException('ERR-UNKNOWN-REPOSITORY'); + } + $this->repository = $repository; + } + } + return $this->repository; + } + + /** + * You should probably not mess with this unless your conduit method is + * involved with the creation / validation / etc. of + * @{class:DiffusionRequest}s. If you are dealing with + * @{class:DiffusionRequest}, setting this to false should help avoid + * infinite loops. + */ + protected function setShouldCreateDiffusionRequest($should) { + $this->shouldCreateDiffusionRequest = $should; + return $this; + } + private function shouldCreateDiffusionRequest() { + return $this->shouldCreateDiffusionRequest; + } + final public function defineErrorTypes() { return $this->defineCustomErrorTypes() + array( - 'ERR-UNKNOWN-REPOSITORY-VCS' => + 'ERR-UNKNOWN-REPOSITORY' => + pht('There is no repository with that callsign.'), + 'ERR-UNKNOWN-VCS-TYPE' => pht('Unknown repository VCS type.'), 'ERR-UNSUPPORTED-VCS' => pht('VCS is not supported for this method.')); @@ -70,29 +117,39 @@ abstract class ConduitAPI_diffusion_abstractquery_Method } /** - * This method is final because each query will need to construct a + * This method is final because most queries will need to construct a * @{class:DiffusionRequest} and use it. Consolidating this codepath and * enforcing @{method:getDiffusionRequest} works when we need it is good. * * @{method:getResult} should be overridden by subclasses as necessary, e.g. * there is a common operation across all version control systems that * should occur after @{method:getResult}, like formatting a timestamp. + * + * In the rare cases where one does not want to create a + * @{class:DiffusionRequest} - suppose to avoid infinite loops in the + * creation of a @{class:DiffusionRequest} - make sure to call + * + * $this->setShouldCreateDiffusionRequest(false); + * + * in the constructor of the pertinent Conduit method. */ final protected function execute(ConduitAPIRequest $request) { - $drequest = DiffusionRequest::newFromDictionary( - array( - 'callsign' => $request->getValue('callsign'), - 'path' => $request->getValue('path'), - 'commit' => $request->getValue('commit'), - )); - $this->setDiffusionRequest($drequest); + if ($this->shouldCreateDiffusionRequest()) { + $drequest = DiffusionRequest::newFromDictionary( + array( + 'user' => $request->getUser(), + 'callsign' => $request->getValue('callsign'), + 'path' => $request->getValue('path'), + 'commit' => $request->getValue('commit'), + )); + $this->setDiffusionRequest($drequest); + } return $this->getResult($request); } protected function getResult(ConduitAPIRequest $request) { - $drequest = $this->getDiffusionRequest(); - $repository = $drequest->getRepository(); + $repository = $this->getRepository($request); $result = null; switch ($repository->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: @@ -105,7 +162,7 @@ abstract class ConduitAPI_diffusion_abstractquery_Method $result = $this->getSVNResult($request); break; default: - throw new ConduitException('ERR-UNKNOWN-REPOSITORY-VCS'); + throw new ConduitException('ERR-UNKNOWN-VCS-TYPE'); break; } return $result; diff --git a/src/applications/diffusion/conduit/ConduitAPI_diffusion_browsequery_Method.php b/src/applications/diffusion/conduit/ConduitAPI_diffusion_browsequery_Method.php index 3163b25990..b1ebcf9c53 100644 --- a/src/applications/diffusion/conduit/ConduitAPI_diffusion_browsequery_Method.php +++ b/src/applications/diffusion/conduit/ConduitAPI_diffusion_browsequery_Method.php @@ -61,9 +61,10 @@ final class ConduitAPI_diffusion_browsequery_Method $readme_request = DiffusionRequest::newFromDictionary( array( - 'repository' => $drequest->getRepository(), - 'commit' => $drequest->getStableCommitName(), - 'path' => $readme->getFullPath(), + 'user' => $request->getUser(), + 'repository' => $drequest->getRepository(), + 'commit' => $drequest->getStableCommitName(), + 'path' => $readme->getFullPath(), )); $file_content = DiffusionFileContent::newFromConduit( diff --git a/src/applications/diffusion/conduit/ConduitAPI_diffusion_expandshortcommitquery_Method.php b/src/applications/diffusion/conduit/ConduitAPI_diffusion_expandshortcommitquery_Method.php new file mode 100644 index 0000000000..0a97f94247 --- /dev/null +++ b/src/applications/diffusion/conduit/ConduitAPI_diffusion_expandshortcommitquery_Method.php @@ -0,0 +1,70 @@ +setShouldCreateDiffusionRequest(false); + } + + public function getMethodDescription() { + return + 'Expands a short commit name to its full glory.'; + } + + public function defineReturnType() { + return 'array'; + } + + protected function defineCustomParamTypes() { + return array( + 'commit' => 'required string', + ); + } + + protected function defineCustomErrorTypes() { + return array( + 'ERR-MISSING-COMMIT' => pht( + 'Bad commit.'), + 'ERR-INVALID-COMMIT' => pht( + 'Invalid object name.'), + 'ERR-UNPARSEABLE-OUTPUT' => pht( + 'Unparseable output from cat-file.') + ); + } + + protected function getGitResult(ConduitAPIRequest $request) { + return $this->getGitOrMercurialResult($request); + } + protected function getMercurialResult(ConduitAPIRequest $request) { + return $this->getGitOrMercurialResult($request); + } + + private function getGitOrMercurialResult(ConduitAPIRequest $request) { + $repository = $this->getRepository($request); + $query = DiffusionExpandShortNameQuery::newFromRepository($repository); + $query->setCommit($request->getValue('commit')); + try { + $result = $query->expand(); + return $result; + } catch (DiffusionExpandCommitQueryException $e) { + switch ($e->getStatusCode()) { + case DiffusionExpandCommitQueryException::CODE_INVALID: + throw id(new ConduitException('ERR-INVALID-COMMIT')) + ->setErrorDescription($e->getMessage()); + break; + case DiffusionExpandCommitQueryException::CODE_MISSING: + throw id(new ConduitException('ERR-MISSING-COMMIT')) + ->setErrorDescription($e->getMessage()); + break; + case DiffusionExpandCommitQueryException::CODE_UNPARSEABLE: + throw id(new ConduitException('ERR-UNPARSEABLE-OUTPUT')) + ->setErrorDescription($e->getMessage()); + break; + } + } + } +} diff --git a/src/applications/diffusion/conduit/ConduitAPI_diffusion_getrecentcommitsbypath_Method.php b/src/applications/diffusion/conduit/ConduitAPI_diffusion_getrecentcommitsbypath_Method.php index fa21056597..d6c3e95ab1 100644 --- a/src/applications/diffusion/conduit/ConduitAPI_diffusion_getrecentcommitsbypath_Method.php +++ b/src/applications/diffusion/conduit/ConduitAPI_diffusion_getrecentcommitsbypath_Method.php @@ -32,8 +32,9 @@ final class ConduitAPI_diffusion_getrecentcommitsbypath_Method protected function execute(ConduitAPIRequest $request) { $drequest = DiffusionRequest::newFromDictionary( array( - 'callsign' => $request->getValue('callsign'), - 'path' => $request->getValue('path'), + 'user' => $request->getUser(), + 'callsign' => $request->getValue('callsign'), + 'path' => $request->getValue('path'), )); $limit = nonempty( diff --git a/src/applications/diffusion/controller/DiffusionBrowseFileController.php b/src/applications/diffusion/controller/DiffusionBrowseFileController.php index f43cf6a76c..c177f4918f 100644 --- a/src/applications/diffusion/controller/DiffusionBrowseFileController.php +++ b/src/applications/diffusion/controller/DiffusionBrowseFileController.php @@ -957,6 +957,7 @@ final class DiffusionBrowseFileController extends DiffusionController { $before_req = DiffusionRequest::newFromDictionary( array( + 'user' => $this->getRequest()->getUser(), 'repository' => $drequest->getRepository(), 'commit' => $commit, )); diff --git a/src/applications/diffusion/controller/DiffusionCommitBranchesController.php b/src/applications/diffusion/controller/DiffusionCommitBranchesController.php index 4b306f5b10..9453f9fe44 100644 --- a/src/applications/diffusion/controller/DiffusionCommitBranchesController.php +++ b/src/applications/diffusion/controller/DiffusionCommitBranchesController.php @@ -3,6 +3,7 @@ final class DiffusionCommitBranchesController extends DiffusionController { public function willProcessRequest(array $data) { + $data['user'] = $this->getRequest()->getUser(); $this->diffusionRequest = DiffusionRequest::newFromDictionary($data); } diff --git a/src/applications/diffusion/controller/DiffusionCommitController.php b/src/applications/diffusion/controller/DiffusionCommitController.php index 641690b627..24c8bc0d8c 100644 --- a/src/applications/diffusion/controller/DiffusionCommitController.php +++ b/src/applications/diffusion/controller/DiffusionCommitController.php @@ -10,6 +10,7 @@ final class DiffusionCommitController extends DiffusionController { public function willProcessRequest(array $data) { // This controller doesn't use blob/path stuff, just pass the dictionary // in directly instead of using the AphrontRequest parsing mechanism. + $data['user'] = $this->getRequest()->getUser(); $drequest = DiffusionRequest::newFromDictionary($data); $this->diffusionRequest = $drequest; } diff --git a/src/applications/diffusion/controller/DiffusionCommitEditController.php b/src/applications/diffusion/controller/DiffusionCommitEditController.php index d893dabd91..8345a6eedd 100644 --- a/src/applications/diffusion/controller/DiffusionCommitEditController.php +++ b/src/applications/diffusion/controller/DiffusionCommitEditController.php @@ -3,6 +3,7 @@ final class DiffusionCommitEditController extends DiffusionController { public function willProcessRequest(array $data) { + $data['user'] = $this->getRequest()->getUser(); $this->diffusionRequest = DiffusionRequest::newFromDictionary($data); } diff --git a/src/applications/diffusion/controller/DiffusionCommitTagsController.php b/src/applications/diffusion/controller/DiffusionCommitTagsController.php index 9ac8077dfd..cac70f616e 100644 --- a/src/applications/diffusion/controller/DiffusionCommitTagsController.php +++ b/src/applications/diffusion/controller/DiffusionCommitTagsController.php @@ -3,6 +3,7 @@ final class DiffusionCommitTagsController extends DiffusionController { public function willProcessRequest(array $data) { + $data['user'] = $this->getRequest()->getUser(); $this->diffusionRequest = DiffusionRequest::newFromDictionary($data); } diff --git a/src/applications/diffusion/controller/DiffusionLintController.php b/src/applications/diffusion/controller/DiffusionLintController.php index 22fb166ec8..604041c45a 100644 --- a/src/applications/diffusion/controller/DiffusionLintController.php +++ b/src/applications/diffusion/controller/DiffusionLintController.php @@ -40,6 +40,7 @@ final class DiffusionLintController extends DiffusionController { $drequests = array(); foreach ($branches as $id => $branch) { $drequests[$id] = DiffusionRequest::newFromDictionary(array( + 'user' => $user, 'repository' => $repositories[$branch->getRepositoryID()], 'branch' => $branch->getName(), )); diff --git a/src/applications/diffusion/controller/DiffusionPathCompleteController.php b/src/applications/diffusion/controller/DiffusionPathCompleteController.php index fbba21b953..b9dd4f117c 100644 --- a/src/applications/diffusion/controller/DiffusionPathCompleteController.php +++ b/src/applications/diffusion/controller/DiffusionPathCompleteController.php @@ -27,8 +27,9 @@ final class DiffusionPathCompleteController extends DiffusionController { $drequest = DiffusionRequest::newFromDictionary( array( - 'repository' => $repository, - 'path' => $query_dir, + 'user' => $request->getUser(), + 'repository' => $repository, + 'path' => $query_dir, )); $this->setDiffusionRequest($drequest); diff --git a/src/applications/diffusion/controller/DiffusionPathValidateController.php b/src/applications/diffusion/controller/DiffusionPathValidateController.php index 9a2c2625c3..980b1bcb2f 100644 --- a/src/applications/diffusion/controller/DiffusionPathValidateController.php +++ b/src/applications/diffusion/controller/DiffusionPathValidateController.php @@ -22,8 +22,9 @@ final class DiffusionPathValidateController extends DiffusionController { $drequest = DiffusionRequest::newFromDictionary( array( - 'repository' => $repository, - 'path' => $path, + 'user' => $request->getUser(), + 'repository' => $repository, + 'path' => $path, )); $this->setDiffusionRequest($drequest); diff --git a/src/applications/diffusion/exception/DiffusionExpandCommitQueryException.php b/src/applications/diffusion/exception/DiffusionExpandCommitQueryException.php new file mode 100644 index 0000000000..fab33a6f98 --- /dev/null +++ b/src/applications/diffusion/exception/DiffusionExpandCommitQueryException.php @@ -0,0 +1,21 @@ +statusCode; + } + + public function __construct($status_code /* ... */) { + $args = func_get_args(); + $this->statusCode = $args[0]; + + $args = array_slice($args, 1); + call_user_func_array(array('parent', '__construct'), $args); + } + +} diff --git a/src/applications/diffusion/query/DiffusionQuery.php b/src/applications/diffusion/query/DiffusionQuery.php index 7846730ef3..40292db927 100644 --- a/src/applications/diffusion/query/DiffusionQuery.php +++ b/src/applications/diffusion/query/DiffusionQuery.php @@ -14,6 +14,16 @@ abstract class DiffusionQuery extends PhabricatorQuery { $repository = $request->getRepository(); + $obj = self::initQueryObject($base_class, $repository); + $obj->request = $request; + + return $obj; + } + + final protected static function initQueryObject( + $base_class, + PhabricatorRepository $repository) { + $map = array( PhabricatorRepositoryType::REPOSITORY_TYPE_GIT => 'Git', PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL => 'Mercurial', @@ -27,8 +37,6 @@ abstract class DiffusionQuery extends PhabricatorQuery { $class = str_replace('Diffusion', 'Diffusion'.$name, $base_class); $obj = new $class(); - $obj->request = $request; - return $obj; } diff --git a/src/applications/diffusion/query/expandshortname/DiffusionExpandShortNameQuery.php b/src/applications/diffusion/query/expandshortname/DiffusionExpandShortNameQuery.php new file mode 100644 index 0000000000..1413d6450f --- /dev/null +++ b/src/applications/diffusion/query/expandshortname/DiffusionExpandShortNameQuery.php @@ -0,0 +1,42 @@ +commit = $commit; + } + public function getCommit() { + return $this->commit; + } + + public function setRepository(PhabricatorRepository $repository) { + $this->repository = $repository; + return $this; + } + public function getRepository() { + return $this->repository; + } + + final public static function newFromRepository( + PhabricatorRepository $repository) { + + $obj = parent::initQueryObject(__CLASS__, $repository); + $obj->setRepository($repository); + return $obj; + } + + final public function expand() { + $this->executeQuery(); + + return array( + 'commit' => $this->commit, + 'commitType' => $this->commitType, + 'tagContent' => $this->tagContent); + } + +} diff --git a/src/applications/diffusion/query/expandshortname/DiffusionGitExpandShortNameQuery.php b/src/applications/diffusion/query/expandshortname/DiffusionGitExpandShortNameQuery.php new file mode 100644 index 0000000000..96694e613f --- /dev/null +++ b/src/applications/diffusion/query/expandshortname/DiffusionGitExpandShortNameQuery.php @@ -0,0 +1,52 @@ +getRepository(); + $commit = $this->getCommit(); + + $future = $repository->getLocalCommandFuture( + 'cat-file --batch'); + $future->write($commit); + list($stdout) = $future->resolvex(); + + list($hash, $type) = explode(' ', $stdout); + if ($type == 'missing') { + throw new DiffusionExpandCommitQueryException( + DiffusionExpandCommitQueryException::CODE_MISSING, + "Bad commit '{$this->commit}'."); + } + + switch ($type) { + case 'tag': + $this->commitType = 'tag'; + + $matches = null; + $ok = preg_match( + '/^object ([a-f0-9]+)$.*?\n\n(.*)$/sm', + $stdout, + $matches); + if (!$ok) { + throw new DiffusionExpandCommitQueryException( + DiffusionExpandCommitQueryException::CODE_UNPARSEABLE, + "Unparseable output from cat-file: {$stdout}"); + } + + $hash = $matches[1]; + $this->tagContent = trim($matches[2]); + break; + case 'commit': + break; + default: + throw new DiffusionExpandCommitQueryException( + DiffusionExpandCommitQueryException::CODE_INVALID, + "The reference '{$this->commit}' does not name a valid ". + 'commit or a tag in this repository.'); + break; + } + + $this->commit = $hash; + } +} diff --git a/src/applications/diffusion/query/expandshortname/DiffusionMercurialExpandShortNameQuery.php b/src/applications/diffusion/query/expandshortname/DiffusionMercurialExpandShortNameQuery.php new file mode 100644 index 0000000000..6d1d5ed404 --- /dev/null +++ b/src/applications/diffusion/query/expandshortname/DiffusionMercurialExpandShortNameQuery.php @@ -0,0 +1,23 @@ +getRepository(); + $commit = $this->getCommit(); + + list($full_hash) = $repository->execxLocalCommand( + 'log --template=%s --rev %s', + '{node}', + $commit); + + $full_hash = explode("\n", trim($full_hash)); + + // TODO: Show "multiple matching commits" if count is larger than 1. For + // now, pick the first one. + + $this->commit = head($full_hash); + } + +} diff --git a/src/applications/diffusion/request/DiffusionGitRequest.php b/src/applications/diffusion/request/DiffusionGitRequest.php index 8cc99b600d..268bc29fe2 100644 --- a/src/applications/diffusion/request/DiffusionGitRequest.php +++ b/src/applications/diffusion/request/DiffusionGitRequest.php @@ -10,54 +10,11 @@ final class DiffusionGitRequest extends DiffusionRequest { } protected function didInitialize() { - $repository = $this->getRepository(); - - $this->validateWorkingCopy($repository->getLocalPath()); - if (!$this->commit) { return; } - // Expand short commit names and verify - - $future = $repository->getLocalCommandFuture( - 'cat-file --batch'); - $future->write($this->commit); - list($stdout) = $future->resolvex(); - - list($hash, $type) = explode(' ', $stdout); - if ($type == 'missing') { - throw new Exception("Bad commit '{$this->commit}'."); - } - - switch ($type) { - case 'tag': - $this->commitType = 'tag'; - - $matches = null; - $ok = preg_match( - '/^object ([a-f0-9]+)$.*?\n\n(.*)$/sm', - $stdout, - $matches); - if (!$ok) { - throw new Exception( - "Unparseable output from cat-file: {$stdout}"); - } - - $hash = $matches[1]; - $this->tagContent = trim($matches[2]); - break; - case 'commit': - break; - default: - throw new AphrontUsageException( - "Invalid Object Name", - "The reference '{$this->commit}' does not name a valid ". - "commit or a tag in this repository."); - break; - } - - $this->commit = $hash; + $this->expandCommitName(); } public function getBranch() { diff --git a/src/applications/diffusion/request/DiffusionMercurialRequest.php b/src/applications/diffusion/request/DiffusionMercurialRequest.php index 79a828ee3f..3f630401e7 100644 --- a/src/applications/diffusion/request/DiffusionMercurialRequest.php +++ b/src/applications/diffusion/request/DiffusionMercurialRequest.php @@ -10,10 +10,6 @@ final class DiffusionMercurialRequest extends DiffusionRequest { } protected function didInitialize() { - $repository = $this->getRepository(); - - $this->validateWorkingCopy($repository->getLocalPath()); - // Expand abbreviated hashes to full hashes so "/rXnnnn" (i.e., fewer than // 40 characters) works correctly. if (!$this->commit) { @@ -24,21 +20,8 @@ final class DiffusionMercurialRequest extends DiffusionRequest { return; } - list($full_hash) = $this->repository->execxLocalCommand( - 'log --template=%s --rev %s', - '{node}', - $this->commit); - - $full_hash = explode("\n", trim($full_hash)); - - // TODO: Show "multiple matching commits" if count is larger than 1. For - // now, pick the first one. - - $this->commit = head($full_hash); - - - return; - } + $this->expandCommitName(); + } public function getBranch() { if ($this->branch) { diff --git a/src/applications/diffusion/request/DiffusionRequest.php b/src/applications/diffusion/request/DiffusionRequest.php index e7f5005fe0..632ab6965b 100644 --- a/src/applications/diffusion/request/DiffusionRequest.php +++ b/src/applications/diffusion/request/DiffusionRequest.php @@ -17,9 +17,9 @@ abstract class DiffusionRequest { protected $line; protected $symbolicCommit; protected $commit; - protected $branch; protected $commitType = 'commit'; protected $tagContent; + protected $branch; protected $lint; protected $repository; @@ -28,6 +28,9 @@ abstract class DiffusionRequest { protected $stableCommitName; protected $arcanistProjects; + private $initFromConduit = true; + private $user; + abstract protected function getSupportsBranches(); abstract protected function didInitialize(); @@ -91,6 +94,7 @@ abstract class DiffusionRequest { $use_branches = $object->getSupportsBranches(); $parsed = self::parseRequestBlob(idx($data, 'dblob'), $use_branches); + $object->setUser($request->getUser()); $object->initializeFromDictionary($parsed); $object->lint = $request->getStr('lint'); return $object; @@ -167,18 +171,39 @@ abstract class DiffusionRequest { * @task new */ final private function initializeFromDictionary(array $data) { - $this->path = idx($data, 'path'); - $this->symbolicCommit = idx($data, 'commit'); - $this->commit = idx($data, 'commit'); - $this->line = idx($data, 'line'); + $this->path = idx($data, 'path'); + $this->symbolicCommit = idx($data, 'commit'); + $this->commit = idx($data, 'commit'); + $this->line = idx($data, 'line'); + $this->initFromConduit = idx($data, 'initFromConduit', true); if ($this->getSupportsBranches()) { $this->branch = idx($data, 'branch'); } + if (!$this->getUser()) { + $user = idx($data, 'user'); + if (!$user) { + throw new Exception( + 'You must provide a PhabricatorUser in the dictionary!'); + } + $this->setUser($user); + } + $this->didInitialize(); } + final protected function shouldInitFromConduit() { + return $this->initFromConduit; + } + + final public function setUser(PhabricatorUser $user) { + $this->user = $user; + return $this; + } + final public function getUser() { + return $this->user; + } public function getRepository() { return $this->repository; @@ -580,4 +605,27 @@ abstract class DiffusionRequest { "Guide' in the documentation for help setting up repositories."); } + final protected function expandCommitName() { + if ($this->shouldInitFromConduit()) { + $commit_data = DiffusionQuery::callConduitWithDiffusionRequest( + $this->getUser(), + $this, + 'diffusion.expandshortcommitquery', + array( + 'commit' => $this->commit + )); + } else { + $repository = $this->getRepository(); + $this->validateWorkingCopy($repository->getLocalPath()); + $query = DiffusionExpandShortNameQuery::newFromRepository( + $repository); + $query->setCommit($this->commit); + $commit_data = $query->expand(); + } + + $this->commit = $commit_data['commit']; + $this->commitType = $commit_data['commitType']; + $this->tagContent = $commit_data['tagContent']; + } + } diff --git a/src/applications/herald/adapter/HeraldCommitAdapter.php b/src/applications/herald/adapter/HeraldCommitAdapter.php index 543221eb63..a73eeb875e 100644 --- a/src/applications/herald/adapter/HeraldCommitAdapter.php +++ b/src/applications/herald/adapter/HeraldCommitAdapter.php @@ -106,6 +106,7 @@ final class HeraldCommitAdapter extends HeraldObjectAdapter { private function loadCommitDiff() { $drequest = DiffusionRequest::newFromDictionary( array( + 'user' => PhabricatorUser::getOmnipotentUser(), 'repository' => $this->repository, 'commit' => $this->commit->getCommitIdentifier(), )); diff --git a/src/applications/owners/storage/PhabricatorOwnersPackage.php b/src/applications/owners/storage/PhabricatorOwnersPackage.php index f625aa6355..f3e644cb6f 100644 --- a/src/applications/owners/storage/PhabricatorOwnersPackage.php +++ b/src/applications/owners/storage/PhabricatorOwnersPackage.php @@ -309,6 +309,7 @@ final class PhabricatorOwnersPackage extends PhabricatorOwnersDAO // build query to validate path $drequest = DiffusionRequest::newFromDictionary( array( + 'user' => $this->getActor(), 'repository' => $repository, 'path' => $path, )); diff --git a/src/applications/releeph/commitfinder/ReleephCommitFinder.php b/src/applications/releeph/commitfinder/ReleephCommitFinder.php index 3212944419..71e4b2c301 100644 --- a/src/applications/releeph/commitfinder/ReleephCommitFinder.php +++ b/src/applications/releeph/commitfinder/ReleephCommitFinder.php @@ -3,6 +3,15 @@ final class ReleephCommitFinder { private $releephProject; + private $user; + + public function setUser(PhabricatorUser $user) { + $this->user = $user; + return $this; + } + public function getUser() { + return $this->user; + } public function setReleephProject(ReleephProject $rp) { $this->releephProject = $rp; @@ -55,6 +64,7 @@ final class ReleephCommitFinder { } try { + $dr_data['user'] = $this->getUser(); $dr = DiffusionRequest::newFromDictionary($dr_data); } catch (Exception $ex) { $message = "No commit matches {$partial_string}: ".$ex->getMessage(); diff --git a/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php b/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php index e0275e476d..ec7f924519 100644 --- a/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php +++ b/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php @@ -43,6 +43,7 @@ final class ConduitAPI_releeph_request_Method $requested_commits = array(); $things = $request->getValue('things'); $finder = id(new ReleephCommitFinder()) + ->setUser($user) ->setReleephProject($releeph_project); foreach ($things as $thing) { try { diff --git a/src/applications/releeph/controller/branch/ReleephBranchCreateController.php b/src/applications/releeph/controller/branch/ReleephBranchCreateController.php index 01c9923379..ecee3d481a 100644 --- a/src/applications/releeph/controller/branch/ReleephBranchCreateController.php +++ b/src/applications/releeph/controller/branch/ReleephBranchCreateController.php @@ -41,6 +41,7 @@ final class ReleephBranchCreateController extends ReleephController { } else { try { $finder = id(new ReleephCommitFinder()) + ->setUser($request->getUser()) ->setReleephProject($releeph_project); $cut_commit = $finder->fromPartial($cut_point); } catch (Exception $e) { diff --git a/src/applications/releeph/controller/request/ReleephRequestEditController.php b/src/applications/releeph/controller/request/ReleephRequestEditController.php index a458aab3f9..95775d2bcd 100644 --- a/src/applications/releeph/controller/request/ReleephRequestEditController.php +++ b/src/applications/releeph/controller/request/ReleephRequestEditController.php @@ -71,6 +71,7 @@ final class ReleephRequestEditController extends ReleephController { } else { $pr_commit = null; $finder = id(new ReleephCommitFinder()) + ->setUser($user) ->setReleephProject($releeph_project); try { $pr_commit = $finder->fromPartial($request_identifier); @@ -186,7 +187,7 @@ final class ReleephRequestEditController extends ReleephController { } $form = id(new AphrontFormView()) - ->setUser($request->getUser()); + ->setUser($user); if ($is_edit) { $form diff --git a/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php b/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php index e568646797..982c166a14 100644 --- a/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php +++ b/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php @@ -327,8 +327,9 @@ final class DifferentialReleephRequestFieldSpecification case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $change_query = DiffusionPathChangeQuery::newFromDiffusionRequest( DiffusionRequest::newFromDictionary(array( - 'repository' => $repo, - 'commit' => $commit->getCommitIdentifier(), + 'user' => $this->getUser(), + 'repository' => $repo, + 'commit' => $commit->getCommitIdentifier(), ))); $path_changes = $change_query->loadChanges(); $commit_paths = mpull($path_changes, 'getPath'); diff --git a/src/applications/releeph/view/branch/ReleephBranchBoxView.php b/src/applications/releeph/view/branch/ReleephBranchBoxView.php index 7a5acde4c3..8161c4c42a 100644 --- a/src/applications/releeph/view/branch/ReleephBranchBoxView.php +++ b/src/applications/releeph/view/branch/ReleephBranchBoxView.php @@ -167,6 +167,7 @@ final class ReleephBranchBoxView extends AphrontView { "Diffusion \xE2\x86\x97"); } else { $diffusion_request = DiffusionRequest::newFromDictionary(array( + 'user' => $this->getUser(), 'repository' => $repo, )); $diffusion_branch_uri = $diffusion_request->generateURI(array( diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php index 94cb122fb1..bd4d85f675 100644 --- a/src/applications/repository/storage/PhabricatorRepository.php +++ b/src/applications/repository/storage/PhabricatorRepository.php @@ -69,14 +69,18 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO return $this; } - public function getDiffusionBrowseURIForPath($path, - $line = null, - $branch = null) { + public function getDiffusionBrowseURIForPath( + PhabricatorUser $user, + $path, + $line = null, + $branch = null) { + $drequest = DiffusionRequest::newFromDictionary( array( + 'user' => $user, 'repository' => $this, - 'path' => $path, - 'branch' => $branch, + 'path' => $path, + 'branch' => $branch, )); return $drequest->generateURI( diff --git a/src/applications/repository/storage/PhabricatorRepositorySymbol.php b/src/applications/repository/storage/PhabricatorRepositorySymbol.php index e74a27fe08..fb24bb215a 100644 --- a/src/applications/repository/storage/PhabricatorRepositorySymbol.php +++ b/src/applications/repository/storage/PhabricatorRepositorySymbol.php @@ -39,7 +39,8 @@ final class PhabricatorRepositorySymbol extends PhabricatorRepositoryDAO { $request = DiffusionRequest::newFromDictionary( array( - 'repository' => $this->getRepository(), + 'user' => PhabricatorUser::getOmnipotentUser(), + 'repository' => $this->getRepository(), )); return $request->generateURI( array( diff --git a/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php b/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php index 5baa23443d..64803aed7a 100644 --- a/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php +++ b/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php @@ -363,8 +363,10 @@ final class PhabricatorRepositoryCommitHeraldWorker $drequest = DiffusionRequest::newFromDictionary( array( - 'repository' => $repository, - 'commit' => $commit->getCommitIdentifier(), + 'user' => PhabricatorUser::getOmnipotentUser(), + 'initFromConduit' => false, + 'repository' => $repository, + 'commit' => $commit->getCommitIdentifier(), )); $raw_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest); diff --git a/src/applications/repository/worker/commitchangeparser/PhabricatorOwnersPackagePathValidator.php b/src/applications/repository/worker/commitchangeparser/PhabricatorOwnersPackagePathValidator.php index e3f5d590ba..3a62f07656 100644 --- a/src/applications/repository/worker/commitchangeparser/PhabricatorOwnersPackagePathValidator.php +++ b/src/applications/repository/worker/commitchangeparser/PhabricatorOwnersPackagePathValidator.php @@ -85,8 +85,10 @@ final class PhabricatorOwnersPackagePathValidator { $repository = id(new PhabricatorRepository())->load($commit->getRepositoryID()); $data = array( - 'repository'=>$repository, - 'commit'=>$commit->getCommitIdentifier() + 'user' => PhabricatorUser::getOmnipotentUser(), + 'initFromConduit' => false, + 'repository' => $repository, + 'commit' => $commit->getCommitIdentifier() ); $drequest = DiffusionRequest::newFromDictionary($data); $change_query = diff --git a/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php b/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php index dd48746d87..b8faffbaf6 100644 --- a/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php +++ b/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php @@ -230,6 +230,8 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker $actor_phid) { $drequest = DiffusionRequest::newFromDictionary(array( + 'user' => PhabricatorUser::getOmnipotentUser(), + 'initFromConduit' => false, 'repository' => $this->repository, 'commit' => $this->commit->getCommitIdentifier(), )); @@ -333,6 +335,8 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker return $vs_diff; } $drequest = DiffusionRequest::newFromDictionary(array( + 'user' => PhabricatorUser::getOmnipotentUser(), + 'initFromConduit' => false, 'repository' => $this->repository, 'commit' => $this->commit->getCommitIdentifier(), 'path' => $path,