Subsume 'harbormaster.querybuilds' with a modern search API method
Summary: We deprecate the existing API method used to access build information from the API, but preserve its response structure after calling through to the new method.  I've cordoned off the fields I needed to define in order to meet the output structure by putting those fields in a search attachment.
Test Plan:
Used the API console and looked at the list view controller for builds.
Old output structure:
```lang=json
{
  "data": [
    {
      "id": "16823",
      "phid": "PHID-HMBD-xghrwfz6luoye5rgc2hq",
      "uri": "https://secure.phabricator.com/harbormaster/build/16823/",
      "name": "Run Core Tests",
      "buildablePHID": "PHID-HMBB-s6ykzm2jzxz4ymduztq3",
      "buildPlanPHID": "PHID-HMCP-pcfxcgyoif67l3buc4zt",
      "buildStatus": "passed",
      "buildStatusName": "Passed"
    }
  ],
  "cursor": {
    "limit": 100,
    "after": "16823",
    "before": null
  }
}
```
New output structure:
```lang=json
{
  "data": [
    {
      "id": 1,
      "type": "HMBD",
      "phid": "PHID-HMBD-qpgcmv67tzaauzayzit5",
      "uri": "http://ec2-54-165-244-168.compute-1.amazonaws.com/harbormaster/build/1/",
      "name": "arc lint + arc unit",
      "buildStatusName": "Passed",
      "buildablePHID": "PHID-HMBB-qdefith5uakkepqpjr2g",
      "buildPlanPHID": "PHID-HMCP-zswbhazb7ipmaf4plygg",
      "buildStatus": "passed",
      "initiatorPHID": "PHID-USER-rihx4366f3aczsvc2wtb",
      "dateCreated": 1450295643,
      "dateModified": 1450295644,
      "policy": {
        "view": "users",
        "edit": "users"
      }
    }
  ],
  "maps": {},
  "query": {
    "queryKey": null
  },
  "cursor": {
    "limit": 100,
    "after": null,
    "before": null,
    "order": null
  }
}
```
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin, epriestley
Differential Revision: https://secure.phabricator.com/D16356
			
			
This commit is contained in:
		| @@ -1131,6 +1131,7 @@ phutil_register_library_map(array( | |||||||
|     'HarbormasterBuildPlanTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildPlanTransactionQuery.php', |     'HarbormasterBuildPlanTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildPlanTransactionQuery.php', | ||||||
|     'HarbormasterBuildQuery' => 'applications/harbormaster/query/HarbormasterBuildQuery.php', |     'HarbormasterBuildQuery' => 'applications/harbormaster/query/HarbormasterBuildQuery.php', | ||||||
|     'HarbormasterBuildRequest' => 'applications/harbormaster/engine/HarbormasterBuildRequest.php', |     'HarbormasterBuildRequest' => 'applications/harbormaster/engine/HarbormasterBuildRequest.php', | ||||||
|  |     'HarbormasterBuildSearchConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterBuildSearchConduitAPIMethod.php', | ||||||
|     'HarbormasterBuildSearchEngine' => 'applications/harbormaster/query/HarbormasterBuildSearchEngine.php', |     'HarbormasterBuildSearchEngine' => 'applications/harbormaster/query/HarbormasterBuildSearchEngine.php', | ||||||
|     'HarbormasterBuildStatus' => 'applications/harbormaster/constants/HarbormasterBuildStatus.php', |     'HarbormasterBuildStatus' => 'applications/harbormaster/constants/HarbormasterBuildStatus.php', | ||||||
|     'HarbormasterBuildStatusDatasource' => 'applications/harbormaster/typeahead/HarbormasterBuildStatusDatasource.php', |     'HarbormasterBuildStatusDatasource' => 'applications/harbormaster/typeahead/HarbormasterBuildStatusDatasource.php', | ||||||
| @@ -1204,6 +1205,7 @@ phutil_register_library_map(array( | |||||||
|     'HarbormasterQueryAutotargetsConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterQueryAutotargetsConduitAPIMethod.php', |     'HarbormasterQueryAutotargetsConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterQueryAutotargetsConduitAPIMethod.php', | ||||||
|     'HarbormasterQueryBuildablesConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterQueryBuildablesConduitAPIMethod.php', |     'HarbormasterQueryBuildablesConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterQueryBuildablesConduitAPIMethod.php', | ||||||
|     'HarbormasterQueryBuildsConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterQueryBuildsConduitAPIMethod.php', |     'HarbormasterQueryBuildsConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterQueryBuildsConduitAPIMethod.php', | ||||||
|  |     'HarbormasterQueryBuildsSearchEngineAttachment' => 'applications/harbormaster/engineextension/HarbormasterQueryBuildsSearchEngineAttachment.php', | ||||||
|     'HarbormasterRemarkupRule' => 'applications/harbormaster/remarkup/HarbormasterRemarkupRule.php', |     'HarbormasterRemarkupRule' => 'applications/harbormaster/remarkup/HarbormasterRemarkupRule.php', | ||||||
|     'HarbormasterRunBuildPlansHeraldAction' => 'applications/harbormaster/herald/HarbormasterRunBuildPlansHeraldAction.php', |     'HarbormasterRunBuildPlansHeraldAction' => 'applications/harbormaster/herald/HarbormasterRunBuildPlansHeraldAction.php', | ||||||
|     'HarbormasterSchemaSpec' => 'applications/harbormaster/storage/HarbormasterSchemaSpec.php', |     'HarbormasterSchemaSpec' => 'applications/harbormaster/storage/HarbormasterSchemaSpec.php', | ||||||
| @@ -5637,6 +5639,7 @@ phutil_register_library_map(array( | |||||||
|       'HarbormasterDAO', |       'HarbormasterDAO', | ||||||
|       'PhabricatorApplicationTransactionInterface', |       'PhabricatorApplicationTransactionInterface', | ||||||
|       'PhabricatorPolicyInterface', |       'PhabricatorPolicyInterface', | ||||||
|  |       'PhabricatorConduitResultInterface', | ||||||
|     ), |     ), | ||||||
|     'HarbormasterBuildAbortedException' => 'Exception', |     'HarbormasterBuildAbortedException' => 'Exception', | ||||||
|     'HarbormasterBuildActionController' => 'HarbormasterController', |     'HarbormasterBuildActionController' => 'HarbormasterController', | ||||||
| @@ -5691,6 +5694,7 @@ phutil_register_library_map(array( | |||||||
|     'HarbormasterBuildPlanTransactionQuery' => 'PhabricatorApplicationTransactionQuery', |     'HarbormasterBuildPlanTransactionQuery' => 'PhabricatorApplicationTransactionQuery', | ||||||
|     'HarbormasterBuildQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', |     'HarbormasterBuildQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', | ||||||
|     'HarbormasterBuildRequest' => 'Phobject', |     'HarbormasterBuildRequest' => 'Phobject', | ||||||
|  |     'HarbormasterBuildSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', | ||||||
|     'HarbormasterBuildSearchEngine' => 'PhabricatorApplicationSearchEngine', |     'HarbormasterBuildSearchEngine' => 'PhabricatorApplicationSearchEngine', | ||||||
|     'HarbormasterBuildStatus' => 'Phobject', |     'HarbormasterBuildStatus' => 'Phobject', | ||||||
|     'HarbormasterBuildStatusDatasource' => 'PhabricatorTypeaheadDatasource', |     'HarbormasterBuildStatusDatasource' => 'PhabricatorTypeaheadDatasource', | ||||||
| @@ -5777,6 +5781,7 @@ phutil_register_library_map(array( | |||||||
|     'HarbormasterQueryAutotargetsConduitAPIMethod' => 'HarbormasterConduitAPIMethod', |     'HarbormasterQueryAutotargetsConduitAPIMethod' => 'HarbormasterConduitAPIMethod', | ||||||
|     'HarbormasterQueryBuildablesConduitAPIMethod' => 'HarbormasterConduitAPIMethod', |     'HarbormasterQueryBuildablesConduitAPIMethod' => 'HarbormasterConduitAPIMethod', | ||||||
|     'HarbormasterQueryBuildsConduitAPIMethod' => 'HarbormasterConduitAPIMethod', |     'HarbormasterQueryBuildsConduitAPIMethod' => 'HarbormasterConduitAPIMethod', | ||||||
|  |     'HarbormasterQueryBuildsSearchEngineAttachment' => 'PhabricatorSearchEngineAttachment', | ||||||
|     'HarbormasterRemarkupRule' => 'PhabricatorObjectRemarkupRule', |     'HarbormasterRemarkupRule' => 'PhabricatorObjectRemarkupRule', | ||||||
|     'HarbormasterRunBuildPlansHeraldAction' => 'HeraldAction', |     'HarbormasterRunBuildPlansHeraldAction' => 'HeraldAction', | ||||||
|     'HarbormasterSchemaSpec' => 'PhabricatorConfigSchemaSpec', |     'HarbormasterSchemaSpec' => 'PhabricatorConfigSchemaSpec', | ||||||
|   | |||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | final class HarbormasterBuildSearchConduitAPIMethod | ||||||
|  |   extends PhabricatorSearchEngineAPIMethod { | ||||||
|  |  | ||||||
|  |   public function getAPIMethodName() { | ||||||
|  |     return 'harbormaster.build.search'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function newSearchEngine() { | ||||||
|  |     return new HarbormasterBuildSearchEngine(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getMethodSummary() { | ||||||
|  |     return pht('Find out information about builds.'); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -11,6 +11,14 @@ final class HarbormasterQueryBuildsConduitAPIMethod | |||||||
|     return pht('Query Harbormaster builds.'); |     return pht('Query Harbormaster builds.'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public function getMethodStatus() { | ||||||
|  |     return self::METHOD_STATUS_DEPRECATED; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getMethodStatusDescription() { | ||||||
|  |     return pht('Use %s instead.', 'harbormaster.build.search'); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   protected function defineParamTypes() { |   protected function defineParamTypes() { | ||||||
|     return array( |     return array( | ||||||
|       'ids' => 'optional list<id>', |       'ids' => 'optional list<id>', | ||||||
| @@ -27,65 +35,39 @@ final class HarbormasterQueryBuildsConduitAPIMethod | |||||||
|  |  | ||||||
|   protected function execute(ConduitAPIRequest $request) { |   protected function execute(ConduitAPIRequest $request) { | ||||||
|     $viewer = $request->getUser(); |     $viewer = $request->getUser(); | ||||||
|  |     $call = new ConduitCall( | ||||||
|  |       'harbormaster.build.search', | ||||||
|  |       array_filter(array( | ||||||
|  |         'constraints' => array_filter(array( | ||||||
|  |           'ids' => $request->getValue('ids'), | ||||||
|  |           'phids' => $request->getValue('phids'), | ||||||
|  |           'statuses' => $request->getValue('buildStatuses'), | ||||||
|  |           'buildables' => $request->getValue('buildablePHIDs'), | ||||||
|  |           'plans' => $request->getValue('buildPlanPHIDs'), | ||||||
|  |         )), | ||||||
|  |         'attachments' => array( | ||||||
|  |           'querybuilds' => true, | ||||||
|  |         ), | ||||||
|  |         'limit' => $request->getValue('limit'), | ||||||
|  |         'before' => $request->getValue('before'), | ||||||
|  |         'after' => $request->getValue('after'), | ||||||
|  |       ))); | ||||||
|  |  | ||||||
|     $query = id(new HarbormasterBuildQuery()) |     $subsumption = $call->setUser($viewer) | ||||||
|       ->setViewer($viewer); |       ->execute(); | ||||||
|  |  | ||||||
|     $ids = $request->getValue('ids'); |     $data = []; | ||||||
|     if ($ids !== null) { |     foreach ($subsumption['data'] as $build_data) { | ||||||
|       $query->withIDs($ids); |       $querybuilds = idxv($build_data, array('attachments', 'querybuilds'), []); | ||||||
|  |       $fields = idx($build_data, 'fields', []); | ||||||
|  |       unset($build_data['fields']); | ||||||
|  |       unset($build_data['attachments']); | ||||||
|  |       $data[] = array_mergev(array($build_data, $querybuilds, $fields)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     $phids = $request->getValue('phids'); |     $subsumption['data'] = $data; | ||||||
|     if ($phids !== null) { |  | ||||||
|       $query->withPHIDs($phids); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $statuses = $request->getValue('buildStatuses'); |     return $subsumption; | ||||||
|     if ($statuses !== null) { |  | ||||||
|       $query->withBuildStatuses($statuses); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $buildable_phids = $request->getValue('buildablePHIDs'); |  | ||||||
|     if ($buildable_phids !== null) { |  | ||||||
|       $query->withBuildablePHIDs($buildable_phids); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $build_plan_phids = $request->getValue('buildPlanPHIDs'); |  | ||||||
|     if ($build_plan_phids !== null) { |  | ||||||
|       $query->withBuildPlanPHIDs($build_plan_phids); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $pager = $this->newPager($request); |  | ||||||
|  |  | ||||||
|     $builds = $query->executeWithCursorPager($pager); |  | ||||||
|  |  | ||||||
|     $data = array(); |  | ||||||
|     foreach ($builds as $build) { |  | ||||||
|  |  | ||||||
|       $id = $build->getID(); |  | ||||||
|       $uri = '/harbormaster/build/'.$id.'/'; |  | ||||||
|       $status = $build->getBuildStatus(); |  | ||||||
|       $status_name = HarbormasterBuildStatus::getBuildStatusName($status); |  | ||||||
|  |  | ||||||
|       $data[] = array( |  | ||||||
|         'id' => $id, |  | ||||||
|         'phid' => $build->getPHID(), |  | ||||||
|         'uri' => PhabricatorEnv::getProductionURI($uri), |  | ||||||
|         'name' => $build->getBuildPlan()->getName(), |  | ||||||
|         'buildablePHID' => $build->getBuildablePHID(), |  | ||||||
|         'buildPlanPHID' => $build->getBuildPlanPHID(), |  | ||||||
|         'buildStatus' => $status, |  | ||||||
|         'buildStatusName' => $status_name, |  | ||||||
|       ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $results = array( |  | ||||||
|       'data' => $data, |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     $results = $this->addPagerResults($results, $pager); |  | ||||||
|     return $results; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,28 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | final class HarbormasterQueryBuildsSearchEngineAttachment | ||||||
|  |   extends PhabricatorSearchEngineAttachment { | ||||||
|  |  | ||||||
|  |   public function getAttachmentName() { | ||||||
|  |     return pht('Harbormaster Query Builds'); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getAttachmentDescription() { | ||||||
|  |     return pht( | ||||||
|  |       'This attachment exists solely to provide compatibility with the '. | ||||||
|  |       'message format returned by an outdated API method. It will be '. | ||||||
|  |       'taken away at some point and you should not rely on these fields '. | ||||||
|  |       'being available.'); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getAttachmentForObject($object, $data, $spec) { | ||||||
|  |     $status_name = HarbormasterBuildStatus::getBuildStatusName( | ||||||
|  |       $object->getBuildStatus()); | ||||||
|  |     return array( | ||||||
|  |       'uri' => PhabricatorEnv::getProductionURI($object->getURI()), | ||||||
|  |       'name' => $object->getName(), | ||||||
|  |       'buildStatusName' => $status_name, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -24,6 +24,12 @@ final class HarbormasterBuildSearchEngine | |||||||
|         ->setDescription( |         ->setDescription( | ||||||
|           pht('Search for builds running a given build plan.')) |           pht('Search for builds running a given build plan.')) | ||||||
|         ->setDatasource(new HarbormasterBuildPlanDatasource()), |         ->setDatasource(new HarbormasterBuildPlanDatasource()), | ||||||
|  |       id(new PhabricatorPHIDsSearchField()) | ||||||
|  |         ->setLabel(pht('Buildables')) | ||||||
|  |         ->setKey('buildables') | ||||||
|  |         ->setAliases(array('buildable')) | ||||||
|  |         ->setDescription( | ||||||
|  |           pht('Search for builds running against particular buildables.')), | ||||||
|       id(new PhabricatorSearchDatasourceField()) |       id(new PhabricatorSearchDatasourceField()) | ||||||
|         ->setLabel(pht('Statuses')) |         ->setLabel(pht('Statuses')) | ||||||
|         ->setKey('statuses') |         ->setKey('statuses') | ||||||
| @@ -42,6 +48,12 @@ final class HarbormasterBuildSearchEngine | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   protected function getHiddenFields() { | ||||||
|  |     return array( | ||||||
|  |       'buildables', | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   protected function buildQueryFromParameters(array $map) { |   protected function buildQueryFromParameters(array $map) { | ||||||
|     $query = $this->newQuery(); |     $query = $this->newQuery(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,7 +3,8 @@ | |||||||
| final class HarbormasterBuild extends HarbormasterDAO | final class HarbormasterBuild extends HarbormasterDAO | ||||||
|   implements |   implements | ||||||
|     PhabricatorApplicationTransactionInterface, |     PhabricatorApplicationTransactionInterface, | ||||||
|     PhabricatorPolicyInterface { |     PhabricatorPolicyInterface, | ||||||
|  |     PhabricatorConduitResultInterface { | ||||||
|  |  | ||||||
|   protected $buildablePHID; |   protected $buildablePHID; | ||||||
|   protected $buildPlanPHID; |   protected $buildPlanPHID; | ||||||
| @@ -397,4 +398,49 @@ final class HarbormasterBuild extends HarbormasterDAO | |||||||
|     return pht('A build inherits policies from its buildable.'); |     return pht('A build inherits policies from its buildable.'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* -(  PhabricatorConduitResultInterface  )---------------------------------- */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   public function getFieldSpecificationsForConduit() { | ||||||
|  |     return array( | ||||||
|  |       id(new PhabricatorConduitSearchFieldSpecification()) | ||||||
|  |         ->setKey('buildablePHID') | ||||||
|  |         ->setType('phid') | ||||||
|  |         ->setDescription(pht('PHID of the object this build is building.')), | ||||||
|  |       id(new PhabricatorConduitSearchFieldSpecification()) | ||||||
|  |         ->setKey('buildPlanPHID') | ||||||
|  |         ->setType('phid') | ||||||
|  |         ->setDescription(pht('PHID of the build plan being run.')), | ||||||
|  |       id(new PhabricatorConduitSearchFieldSpecification()) | ||||||
|  |         ->setKey('buildStatus') | ||||||
|  |         ->setType('map<string, wild>') | ||||||
|  |         ->setDescription(pht('The current status of this build.')), | ||||||
|  |       id(new PhabricatorConduitSearchFieldSpecification()) | ||||||
|  |         ->setKey('initiatorPHID') | ||||||
|  |         ->setType('phid') | ||||||
|  |         ->setDescription(pht('The person (or thing) that started this build.')), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getFieldValuesForConduit() { | ||||||
|  |     $status = $this->getBuildStatus(); | ||||||
|  |     return array( | ||||||
|  |       'buildablePHID' => $this->getBuildablePHID(), | ||||||
|  |       'buildPlanPHID' => $this->getBuildPlanPHID(), | ||||||
|  |       'buildStatus' => array( | ||||||
|  |         'value' => $status, | ||||||
|  |         'name' => HarbormasterBuildStatus::getBuildStatusName($status), | ||||||
|  |       ), | ||||||
|  |       'initiatorPHID' => nonempty($this->getInitiatorPHID(), null), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getConduitSearchAttachments() { | ||||||
|  |     return array( | ||||||
|  |       id(new HarbormasterQueryBuildsSearchEngineAttachment()) | ||||||
|  |         ->setAttachmentKey('querybuilds'), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Mike Riley
					Mike Riley