2011-12-02 01:57:06 +01:00
|
|
|
<?php
|
|
|
|
|
Rename Conduit classes
Summary: Ref T5655. Rename Conduit classes and provide a `getAPIMethodName` method to declare the API method.
Test Plan:
```
> echo '{}' | arc --conduit-uri='http://phabricator.joshuaspence.com' call-conduit user.whoami
Waiting for JSON parameters on stdin...
{"error":null,"errorMessage":null,"response":{"phid":"PHID-USER-lioqffnwn6y475mu5ndb","userName":"josh","realName":"Joshua Spence","image":"http:\/\/phabricator.joshuaspence.com\/res\/1404425321T\/phabricator\/3eb28cd9\/rsrc\/image\/avatar.png","uri":"http:\/\/phabricator.joshuaspence.com\/p\/josh\/","roles":["admin","verified","approved","activated"]}}
```
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: epriestley, Korvin, hach-que
Maniphest Tasks: T5655
Differential Revision: https://secure.phabricator.com/D9991
2014-07-25 02:54:15 +02:00
|
|
|
final class DifferentialQueryConduitAPIMethod
|
|
|
|
extends DifferentialConduitAPIMethod {
|
|
|
|
|
|
|
|
public function getAPIMethodName() {
|
|
|
|
return 'differential.query';
|
|
|
|
}
|
2011-12-02 01:57:06 +01:00
|
|
|
|
|
|
|
public function getMethodDescription() {
|
2015-05-22 09:27:56 +02:00
|
|
|
return pht('Query Differential revisions which match certain criteria.');
|
2011-12-02 01:57:06 +01:00
|
|
|
}
|
|
|
|
|
2017-01-08 21:54:39 +01:00
|
|
|
public function getMethodStatus() {
|
|
|
|
return self::METHOD_STATUS_FROZEN;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getMethodStatusDescription() {
|
|
|
|
return pht(
|
|
|
|
'This method is frozen and will eventually be deprecated. New code '.
|
|
|
|
'should use "differential.revision.search" instead.');
|
|
|
|
}
|
|
|
|
|
2015-04-13 00:59:07 +02:00
|
|
|
protected function defineParamTypes() {
|
2012-01-10 20:39:11 +01:00
|
|
|
$hash_types = ArcanistDifferentialRevisionHash::getTypes();
|
2014-05-15 06:59:03 +02:00
|
|
|
$hash_const = $this->formatStringConstants($hash_types);
|
2012-01-04 06:08:12 +01:00
|
|
|
|
Pull legacy revision query status filters out of the main Query class
Summary:
Ref T2543. Currently, Differential uses a set of hard-coded query filters (like "open" and "closed") to query revisions by status (for example, "open" means any of "review, revision, changes planned, accepted [usually]").
In other applications, like Maniphest, we've replaced this with a low level list of the actual statuses, plus higher level convenience UI through tokenizer functions. This basically has all of the benefits of the hard-coded filters with none of the drawbacks, and is generally more flexible.
I'd like to do that in Differential, too, although we'll need to keep the legacy maps around for a while because they're used by `differential.find` and `differential.getrevision`. To prepare for this, pull all the legacy stuff out into a separate class. Then I'll modernize where I can, and we can get rid of this junk some day.
Test Plan: Grepped for `RevisionQuery::STATUS`. Ran queries via Differential UI.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T2543
Differential Revision: https://secure.phabricator.com/D18343
2017-08-04 19:19:28 +02:00
|
|
|
$status_types = DifferentialLegacyQuery::getAllConstants();
|
2014-05-15 06:59:03 +02:00
|
|
|
$status_const = $this->formatStringConstants($status_types);
|
2011-12-02 01:57:06 +01:00
|
|
|
|
|
|
|
$order_types = array(
|
|
|
|
DifferentialRevisionQuery::ORDER_MODIFIED,
|
|
|
|
DifferentialRevisionQuery::ORDER_CREATED,
|
|
|
|
);
|
2014-05-15 06:59:03 +02:00
|
|
|
$order_const = $this->formatStringConstants($order_types);
|
2011-12-02 01:57:06 +01:00
|
|
|
|
|
|
|
return array(
|
2011-12-07 17:30:49 +01:00
|
|
|
'authors' => 'optional list<phid>',
|
|
|
|
'ccs' => 'optional list<phid>',
|
|
|
|
'reviewers' => 'optional list<phid>',
|
2012-06-19 02:43:22 +02:00
|
|
|
'paths' => 'optional list<pair<callsign, path>>',
|
2014-05-15 06:59:03 +02:00
|
|
|
'commitHashes' => 'optional list<pair<'.$hash_const.', string>>',
|
|
|
|
'status' => 'optional '.$status_const,
|
|
|
|
'order' => 'optional '.$order_const,
|
2011-12-07 17:30:49 +01:00
|
|
|
'limit' => 'optional uint',
|
|
|
|
'offset' => 'optional uint',
|
|
|
|
'ids' => 'optional list<uint>',
|
|
|
|
'phids' => 'optional list<phid>',
|
|
|
|
'subscribers' => 'optional list<phid>',
|
|
|
|
'responsibleUsers' => 'optional list<phid>',
|
2012-01-24 17:31:45 +01:00
|
|
|
'branches' => 'optional list<string>',
|
2011-12-02 01:57:06 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2015-04-13 00:59:07 +02:00
|
|
|
protected function defineReturnType() {
|
2011-12-02 01:57:06 +01:00
|
|
|
return 'list<dict>';
|
|
|
|
}
|
|
|
|
|
2015-04-13 00:59:07 +02:00
|
|
|
protected function defineErrorTypes() {
|
2011-12-02 01:57:06 +01:00
|
|
|
return array(
|
2015-05-22 09:27:56 +02:00
|
|
|
'ERR-INVALID-PARAMETER' => pht('Missing or malformed parameter.'),
|
2011-12-02 01:57:06 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function execute(ConduitAPIRequest $request) {
|
2011-12-07 17:30:49 +01:00
|
|
|
$authors = $request->getValue('authors');
|
|
|
|
$ccs = $request->getValue('ccs');
|
|
|
|
$reviewers = $request->getValue('reviewers');
|
|
|
|
$status = $request->getValue('status');
|
|
|
|
$order = $request->getValue('order');
|
2012-06-19 02:43:22 +02:00
|
|
|
$path_pairs = $request->getValue('paths');
|
2012-01-04 06:08:12 +01:00
|
|
|
$commit_hashes = $request->getValue('commitHashes');
|
2011-12-07 17:30:49 +01:00
|
|
|
$limit = $request->getValue('limit');
|
|
|
|
$offset = $request->getValue('offset');
|
|
|
|
$ids = $request->getValue('ids');
|
|
|
|
$phids = $request->getValue('phids');
|
|
|
|
$subscribers = $request->getValue('subscribers');
|
|
|
|
$responsible_users = $request->getValue('responsibleUsers');
|
2012-01-24 17:31:45 +01:00
|
|
|
$branches = $request->getValue('branches');
|
2011-12-02 01:57:06 +01:00
|
|
|
|
2013-07-01 21:38:27 +02:00
|
|
|
$query = id(new DifferentialRevisionQuery())
|
|
|
|
->setViewer($request->getUser());
|
|
|
|
|
2011-12-07 17:30:49 +01:00
|
|
|
if ($authors) {
|
|
|
|
$query->withAuthors($authors);
|
|
|
|
}
|
2011-12-02 01:57:06 +01:00
|
|
|
if ($ccs) {
|
|
|
|
$query->withCCs($ccs);
|
|
|
|
}
|
|
|
|
if ($reviewers) {
|
|
|
|
$query->withReviewers($reviewers);
|
|
|
|
}
|
2011-12-07 17:30:49 +01:00
|
|
|
|
2012-06-19 02:43:22 +02:00
|
|
|
if ($path_pairs) {
|
|
|
|
$paths = array();
|
|
|
|
foreach ($path_pairs as $pair) {
|
|
|
|
list($callsign, $path) = $pair;
|
|
|
|
$paths[] = $path;
|
|
|
|
}
|
2011-12-07 17:30:49 +01:00
|
|
|
|
2012-06-19 02:43:22 +02:00
|
|
|
$path_map = id(new DiffusionPathIDQuery($paths))->loadPathIDs();
|
|
|
|
if (count($path_map) != count($paths)) {
|
|
|
|
$unknown_paths = array();
|
|
|
|
foreach ($paths as $p) {
|
|
|
|
if (!idx($path_map, $p)) {
|
|
|
|
$unknown_paths[] = $p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw id(new ConduitException('ERR-INVALID-PARAMETER'))
|
|
|
|
->setErrorDescription(
|
2015-05-22 09:27:56 +02:00
|
|
|
pht(
|
|
|
|
'Unknown paths: %s',
|
|
|
|
implode(', ', $unknown_paths)));
|
2012-06-19 02:43:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$repos = array();
|
|
|
|
foreach ($path_pairs as $pair) {
|
|
|
|
list($callsign, $path) = $pair;
|
|
|
|
if (!idx($repos, $callsign)) {
|
2013-09-26 01:54:48 +02:00
|
|
|
$repos[$callsign] = id(new PhabricatorRepositoryQuery())
|
|
|
|
->setViewer($request->getUser())
|
|
|
|
->withCallsigns(array($callsign))
|
|
|
|
->executeOne();
|
2012-06-19 02:43:22 +02:00
|
|
|
|
|
|
|
if (!$repos[$callsign]) {
|
|
|
|
throw id(new ConduitException('ERR-INVALID-PARAMETER'))
|
|
|
|
->setErrorDescription(
|
2015-05-22 09:27:56 +02:00
|
|
|
pht(
|
|
|
|
'Unknown repo callsign: %s',
|
|
|
|
$callsign));
|
2012-06-19 02:43:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
$repo = $repos[$callsign];
|
|
|
|
|
|
|
|
$query->withPath($repo->getID(), idx($path_map, $path));
|
2011-12-02 01:57:06 +01:00
|
|
|
}
|
|
|
|
}
|
2012-06-19 02:43:22 +02:00
|
|
|
|
2012-01-04 06:08:12 +01:00
|
|
|
if ($commit_hashes) {
|
2012-01-10 20:39:11 +01:00
|
|
|
$hash_types = ArcanistDifferentialRevisionHash::getTypes();
|
2012-01-04 06:08:12 +01:00
|
|
|
foreach ($commit_hashes as $info) {
|
|
|
|
list($type, $hash) = $info;
|
|
|
|
if (empty($type) ||
|
|
|
|
!in_array($type, $hash_types) ||
|
|
|
|
empty($hash)) {
|
|
|
|
throw new ConduitException('ERR-INVALID-PARAMETER');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$query->withCommitHashes($commit_hashes);
|
|
|
|
}
|
|
|
|
|
2011-12-02 01:57:06 +01:00
|
|
|
if ($status) {
|
|
|
|
$query->withStatus($status);
|
|
|
|
}
|
|
|
|
if ($order) {
|
|
|
|
$query->setOrder($order);
|
|
|
|
}
|
|
|
|
if ($limit) {
|
|
|
|
$query->setLimit($limit);
|
|
|
|
}
|
|
|
|
if ($offset) {
|
|
|
|
$query->setOffset($offset);
|
|
|
|
}
|
|
|
|
if ($ids) {
|
|
|
|
$query->withIDs($ids);
|
|
|
|
}
|
|
|
|
if ($phids) {
|
|
|
|
$query->withPHIDs($phids);
|
|
|
|
}
|
2011-12-07 17:30:49 +01:00
|
|
|
if ($responsible_users) {
|
|
|
|
$query->withResponsibleUsers($responsible_users);
|
|
|
|
}
|
|
|
|
if ($subscribers) {
|
2014-02-12 17:53:40 +01:00
|
|
|
$query->withCCs($subscribers);
|
2011-12-07 17:30:49 +01:00
|
|
|
}
|
2012-01-24 17:31:45 +01:00
|
|
|
if ($branches) {
|
|
|
|
$query->withBranches($branches);
|
|
|
|
}
|
2011-12-02 01:57:06 +01:00
|
|
|
|
2017-03-20 22:37:24 +01:00
|
|
|
$query->needReviewers(true);
|
2011-12-21 02:05:52 +01:00
|
|
|
$query->needCommitPHIDs(true);
|
|
|
|
$query->needDiffIDs(true);
|
|
|
|
$query->needActiveDiffs(true);
|
2012-06-26 18:07:52 +02:00
|
|
|
$query->needHashes(true);
|
2011-12-21 02:05:52 +01:00
|
|
|
|
2011-12-02 01:57:06 +01:00
|
|
|
$revisions = $query->execute();
|
|
|
|
|
2014-03-09 19:23:55 +01:00
|
|
|
$field_data = $this->loadCustomFieldsForRevisions(
|
|
|
|
$request->getUser(),
|
|
|
|
$revisions);
|
|
|
|
|
Remove obsolete "relationships" code from Differential
Summary:
Ref T10967. There have been two different ways to load reviewers for a while: `needReviewerStatus()` and `needRelationships()`.
The `needRelationships()` stuff was a false start along time ago that didn't really go anywhere. I believe the idea was that we might want to load several different types of edges (subscribers, reviewers, etc) on lots of different types of objects. However, all that stuff pretty much ended up modularizing so that main `Query` classes did not need to know about it, so `needRelationships()` never got generalized or went anywhere.
A handful of things still use it, but get rid of them: they should either `needReviewerStatus()` to get reviewer info, or the ~3 callsites that care about subscribers can just load them directly.
Test Plan:
- Grepped for removed methods (`needRelationships()`, `getReviewers()`, `getCCPHIDs()`, etc).
- Browsed Diffusion, Differential.
- Called `differential.query`.
It's possible I missed some stuff, but it should mostly show up as super obvious fatals ("call needReviewerStatus() before getReviewerStatus()!").
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T10967
Differential Revision: https://secure.phabricator.com/D17518
2017-03-20 22:02:08 +01:00
|
|
|
if ($revisions) {
|
|
|
|
$ccs = id(new PhabricatorSubscribersQuery())
|
|
|
|
->withObjectPHIDs(mpull($revisions, 'getPHID'))
|
|
|
|
->execute();
|
|
|
|
} else {
|
|
|
|
$ccs = array();
|
|
|
|
}
|
|
|
|
|
2011-12-02 01:57:06 +01:00
|
|
|
$results = array();
|
|
|
|
foreach ($revisions as $revision) {
|
2011-12-21 02:05:52 +01:00
|
|
|
$diff = $revision->getActiveDiff();
|
2011-12-02 01:57:06 +01:00
|
|
|
if (!$diff) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$id = $revision->getID();
|
2014-03-09 19:23:55 +01:00
|
|
|
$phid = $revision->getPHID();
|
|
|
|
|
2012-02-06 21:14:07 +01:00
|
|
|
$result = array(
|
2013-11-12 00:01:21 +01:00
|
|
|
'id' => $id,
|
2014-03-09 19:23:55 +01:00
|
|
|
'phid' => $phid,
|
2013-11-12 00:01:21 +01:00
|
|
|
'title' => $revision->getTitle(),
|
|
|
|
'uri' => PhabricatorEnv::getProductionURI('/D'.$id),
|
|
|
|
'dateCreated' => $revision->getDateCreated(),
|
|
|
|
'dateModified' => $revision->getDateModified(),
|
|
|
|
'authorPHID' => $revision->getAuthorPHID(),
|
|
|
|
'status' => $revision->getStatus(),
|
2017-08-04 14:29:49 +02:00
|
|
|
'statusName' => $revision->getStatusDisplayName(),
|
2016-06-27 22:29:47 +02:00
|
|
|
'properties' => $revision->getProperties(),
|
2013-11-12 00:01:21 +01:00
|
|
|
'branch' => $diff->getBranch(),
|
|
|
|
'summary' => $revision->getSummary(),
|
|
|
|
'testPlan' => $revision->getTestPlan(),
|
|
|
|
'lineCount' => $revision->getLineCount(),
|
2014-04-18 01:01:27 +02:00
|
|
|
'activeDiffPHID' => $diff->getPHID(),
|
2013-11-12 00:01:21 +01:00
|
|
|
'diffs' => $revision->getDiffIDs(),
|
|
|
|
'commits' => $revision->getCommitPHIDs(),
|
Remove obsolete "relationships" code from Differential
Summary:
Ref T10967. There have been two different ways to load reviewers for a while: `needReviewerStatus()` and `needRelationships()`.
The `needRelationships()` stuff was a false start along time ago that didn't really go anywhere. I believe the idea was that we might want to load several different types of edges (subscribers, reviewers, etc) on lots of different types of objects. However, all that stuff pretty much ended up modularizing so that main `Query` classes did not need to know about it, so `needRelationships()` never got generalized or went anywhere.
A handful of things still use it, but get rid of them: they should either `needReviewerStatus()` to get reviewer info, or the ~3 callsites that care about subscribers can just load them directly.
Test Plan:
- Grepped for removed methods (`needRelationships()`, `getReviewers()`, `getCCPHIDs()`, etc).
- Browsed Diffusion, Differential.
- Called `differential.query`.
It's possible I missed some stuff, but it should mostly show up as super obvious fatals ("call needReviewerStatus() before getReviewerStatus()!").
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T10967
Differential Revision: https://secure.phabricator.com/D17518
2017-03-20 22:02:08 +01:00
|
|
|
'reviewers' => $revision->getReviewerPHIDs(),
|
|
|
|
'ccs' => idx($ccs, $phid, array()),
|
2013-11-12 00:01:21 +01:00
|
|
|
'hashes' => $revision->getHashes(),
|
2014-03-09 19:23:55 +01:00
|
|
|
'auxiliary' => idx($field_data, $phid, array()),
|
2014-07-15 00:00:02 +02:00
|
|
|
'repositoryPHID' => $diff->getRepositoryPHID(),
|
2011-12-02 01:57:06 +01:00
|
|
|
);
|
2012-02-06 21:14:07 +01:00
|
|
|
|
|
|
|
// TODO: This is a hacky way to put permissions on this field until we
|
|
|
|
// have first-class support, see T838.
|
|
|
|
if ($revision->getAuthorPHID() == $request->getUser()->getPHID()) {
|
|
|
|
$result['sourcePath'] = $diff->getSourcePath();
|
|
|
|
}
|
|
|
|
|
|
|
|
$results[] = $result;
|
2011-12-02 01:57:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $results;
|
|
|
|
}
|
2013-03-05 14:58:04 +01:00
|
|
|
|
2011-12-02 01:57:06 +01:00
|
|
|
}
|