From 9feb7343e662c12e794960905cf3f734cb59c251 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 15 Feb 2021 10:02:27 -0800 Subject: [PATCH] Provide a "differential.changeset.search" Conduit API method Summary: Ref T13605. Support selecting a diff's changesets (to get a list of affected file paths) via the API. Test Plan: Called API with no arguments, diffPHIDs, PHIDs, IDs. Got sensible output. Maniphest Tasks: T13605 Differential Revision: https://secure.phabricator.com/D21558 --- src/__phutil_library_map__.php | 3 ++ ...rentialChangesetSearchConduitAPIMethod.php | 18 +++++++ .../query/DifferentialChangesetQuery.php | 38 +++++++++++++++ .../DifferentialChangesetSearchEngine.php | 14 +++++- .../storage/DifferentialChangeset.php | 47 ++++++++++++++++++- 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 src/applications/differential/conduit/DifferentialChangesetSearchConduitAPIMethod.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 847001dd46..79d318b76d 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -477,6 +477,7 @@ phutil_register_library_map(array( 'DifferentialChangesetParserTestCase' => 'applications/differential/parser/__tests__/DifferentialChangesetParserTestCase.php', 'DifferentialChangesetQuery' => 'applications/differential/query/DifferentialChangesetQuery.php', 'DifferentialChangesetRenderer' => 'applications/differential/render/DifferentialChangesetRenderer.php', + 'DifferentialChangesetSearchConduitAPIMethod' => 'applications/differential/conduit/DifferentialChangesetSearchConduitAPIMethod.php', 'DifferentialChangesetSearchEngine' => 'applications/differential/query/DifferentialChangesetSearchEngine.php', 'DifferentialChangesetTestRenderer' => 'applications/differential/render/DifferentialChangesetTestRenderer.php', 'DifferentialChangesetTwoUpRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpRenderer.php', @@ -6533,6 +6534,7 @@ phutil_register_library_map(array( 'DifferentialDAO', 'PhabricatorPolicyInterface', 'PhabricatorDestructibleInterface', + 'PhabricatorConduitResultInterface', ), 'DifferentialChangesetDetailView' => 'AphrontView', 'DifferentialChangesetEngine' => 'Phobject', @@ -6547,6 +6549,7 @@ phutil_register_library_map(array( 'DifferentialChangesetParserTestCase' => 'PhabricatorTestCase', 'DifferentialChangesetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'DifferentialChangesetRenderer' => 'Phobject', + 'DifferentialChangesetSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', 'DifferentialChangesetSearchEngine' => 'PhabricatorApplicationSearchEngine', 'DifferentialChangesetTestRenderer' => 'DifferentialChangesetRenderer', 'DifferentialChangesetTwoUpRenderer' => 'DifferentialChangesetHTMLRenderer', diff --git a/src/applications/differential/conduit/DifferentialChangesetSearchConduitAPIMethod.php b/src/applications/differential/conduit/DifferentialChangesetSearchConduitAPIMethod.php new file mode 100644 index 0000000000..3ee0f6ccdc --- /dev/null +++ b/src/applications/differential/conduit/DifferentialChangesetSearchConduitAPIMethod.php @@ -0,0 +1,18 @@ +phids = $phids; + return $this; + } + public function withDiffs(array $diffs) { assert_instances_of($diffs, 'DifferentialDiff'); $this->diffs = $diffs; return $this; } + public function withDiffPHIDs(array $phids) { + $this->diffPHIDs = $phids; + return $this; + } + public function needAttachToDiffs($attach) { $this->needAttachToDiffs = $attach; return $this; @@ -134,6 +147,31 @@ final class DifferentialChangesetQuery $this->ids); } + if ($this->phids !== null) { + $where[] = qsprintf( + $conn, + 'phid IN (%Ls)', + $this->phids); + } + + if ($this->diffPHIDs !== null) { + $diff_ids = queryfx_all( + $conn, + 'SELECT id FROM %R WHERE phid IN (%Ls)', + new DifferentialDiff(), + $this->diffPHIDs); + $diff_ids = ipull($diff_ids, 'id', null); + + if (!$diff_ids) { + throw new PhabricatorEmptyQueryException(); + } + + $where[] = qsprintf( + $conn, + 'diffID IN (%Ld)', + $diff_ids); + } + return $where; } diff --git a/src/applications/differential/query/DifferentialChangesetSearchEngine.php b/src/applications/differential/query/DifferentialChangesetSearchEngine.php index 3fe8957971..b6279ec339 100644 --- a/src/applications/differential/query/DifferentialChangesetSearchEngine.php +++ b/src/applications/differential/query/DifferentialChangesetSearchEngine.php @@ -38,11 +38,23 @@ final class DifferentialChangesetSearchEngine protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); + + if ($map['diffPHIDs']) { + $query->withDiffPHIDs($map['diffPHIDs']); + } + return $query; } protected function buildCustomSearchFields() { - return array(); + return array( + id(new PhabricatorPHIDsSearchField()) + ->setLabel(pht('Diffs')) + ->setKey('diffPHIDs') + ->setAliases(array('diff', 'diffs', 'diffPHID')) + ->setDescription( + pht('Find changesets attached to a particular diff.')), + ); } protected function getURI($path) { diff --git a/src/applications/differential/storage/DifferentialChangeset.php b/src/applications/differential/storage/DifferentialChangeset.php index add76cd7bf..770a49e411 100644 --- a/src/applications/differential/storage/DifferentialChangeset.php +++ b/src/applications/differential/storage/DifferentialChangeset.php @@ -4,7 +4,8 @@ final class DifferentialChangeset extends DifferentialDAO implements PhabricatorPolicyInterface, - PhabricatorDestructibleInterface { + PhabricatorDestructibleInterface, + PhabricatorConduitResultInterface { protected $diffID; protected $oldFile; @@ -735,5 +736,49 @@ final class DifferentialChangeset $this->saveTransaction(); } +/* -( PhabricatorConduitResultInterface )---------------------------------- */ + + public function getFieldSpecificationsForConduit() { + return array( + id(new PhabricatorConduitSearchFieldSpecification()) + ->setKey('diffPHID') + ->setType('phid') + ->setDescription(pht('The diff the changeset is attached to.')), + ); + } + + public function getFieldValuesForConduit() { + $diff = $this->getDiff(); + + $repository = null; + if ($diff) { + $revision = $diff->getRevision(); + if ($revision) { + $repository = $revision->getRepository(); + } + } + + $absolute_path = $this->getAbsoluteRepositoryPath($repository, $diff); + if (strlen($absolute_path)) { + $absolute_path = base64_encode($absolute_path); + } else { + $absolute_path = null; + } + + $display_path = $this->getDisplayFilename(); + + return array( + 'diffPHID' => $diff->getPHID(), + 'path' => array( + 'displayPath' => $display_path, + 'absolutePath.base64' => $absolute_path, + ), + ); + } + + public function getConduitSearchAttachments() { + return array(); + } + }