Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / releeph / commitfinder / ReleephCommitFinder.php
blob8c1712c802553d6231caf6a52847c795e597778d
1 <?php
3 final class ReleephCommitFinder extends Phobject {
5 private $releephProject;
6 private $user;
7 private $objectPHID;
9 public function setUser(PhabricatorUser $user) {
10 $this->user = $user;
11 return $this;
13 public function getUser() {
14 return $this->user;
17 public function setReleephProject(ReleephProject $rp) {
18 $this->releephProject = $rp;
19 return $this;
22 public function getRequestedObjectPHID() {
23 return $this->objectPHID;
26 public function fromPartial($partial_string) {
27 $this->objectPHID = null;
29 // Look for diffs
30 $matches = array();
31 if (preg_match('/^D([1-9]\d*)$/', $partial_string, $matches)) {
32 $diff_id = $matches[1];
33 $diff_rev = id(new DifferentialRevisionQuery())
34 ->setViewer($this->getUser())
35 ->withIDs(array($diff_id))
36 ->needCommitPHIDs(true)
37 ->executeOne();
38 if (!$diff_rev) {
39 throw new ReleephCommitFinderException(
40 pht(
41 '%s does not refer to an existing diff.',
42 $partial_string));
44 $commit_phids = $diff_rev->getCommitPHIDs();
46 if (!$commit_phids) {
47 throw new ReleephCommitFinderException(
48 pht(
49 '%s has no commits associated with it yet.',
50 $partial_string));
53 $this->objectPHID = $diff_rev->getPHID();
55 $commits = id(new DiffusionCommitQuery())
56 ->setViewer($this->getUser())
57 ->withPHIDs($commit_phids)
58 ->execute();
59 $commits = msort($commits, 'getEpoch');
60 return head($commits);
63 // Look for a raw commit number, or r<callsign><commit-number>.
64 $repository = $this->releephProject->getRepository();
65 $dr_data = null;
66 $matches = array();
67 if (preg_match('/^r(?P<callsign>[A-Z]+)(?P<commit>\w+)$/',
68 $partial_string, $matches)) {
69 $callsign = $matches['callsign'];
70 if ($callsign != $repository->getCallsign()) {
71 throw new ReleephCommitFinderException(
72 pht(
73 '%s is in a different repository to this Releeph project (%s).',
74 $partial_string,
75 $repository->getCallsign()));
76 } else {
77 $dr_data = $matches;
79 } else {
80 $dr_data = array(
81 'callsign' => $repository->getCallsign(),
82 'commit' => $partial_string,
86 try {
87 $dr_data['user'] = $this->getUser();
88 $dr = DiffusionRequest::newFromDictionary($dr_data);
89 } catch (Exception $ex) {
90 $message = pht(
91 'No commit matches %s: %s',
92 $partial_string,
93 $ex->getMessage());
94 throw new ReleephCommitFinderException($message);
97 $phabricator_repository_commit = $dr->loadCommit();
99 if (!$phabricator_repository_commit) {
100 throw new ReleephCommitFinderException(
101 pht(
102 "The commit %s doesn't exist in this repository.",
103 $partial_string));
106 // When requesting a single commit, if it has an associated review we
107 // imply the review was requested instead. This is always correct for now
108 // and consistent with the older behavior, although it might not be the
109 // right rule in the future.
110 $phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
111 $phabricator_repository_commit->getPHID(),
112 DiffusionCommitHasRevisionEdgeType::EDGECONST);
113 if ($phids) {
114 $this->objectPHID = head($phids);
117 return $phabricator_repository_commit;