Example #1
0
  def QueryMultipleCurrentPatchset(self, changes):
    """Query the gerrit server for multiple changes.

    Args:
      changes: A sequence of gerrit change numbers.

    Returns:
      A list of cros_patch.GerritPatch.
    """
    if not changes:
      return

    url_prefix = gob_util.GetGerritFetchUrl(self.host)
    results = self.GetMultipleChangeDetail(changes)
    for change, change_detail in zip(changes, results):
      if not change_detail:
        raise GerritException('Change %s not found on server %s.'
                              % (change, self.host))
      patch_dict = cros_patch.GerritPatch.ConvertQueryResults(
          change_detail, self.host)
      yield change, cros_patch.GerritPatch(patch_dict, self.remote, url_prefix)
Example #2
0
 def QueryMultipleCurrentPatchset(self, changes):
     if not changes:
         return
     url_prefix = gob_util.GetGerritFetchUrl(self.host)
     o_params = [
         'CURRENT_COMMIT',
         'CURRENT_REVISION',
         'DETAILED_ACCOUNTS',
         'DETAILED_LABELS',
     ]
     moar = gob_util.MultiQueryChanges(self.host, {},
                                       changes,
                                       limit=self._GERRIT_MAX_QUERY_RETURN,
                                       o_params=o_params)
     results = list(moar)
     while moar and '_more_changes' in moar[-1]:
         query_kwds = {'resume_sortkey': moar[-1]['_sortkey']}
         moar = gob_util.MultiQueryChanges(
             self.host,
             query_kwds,
             changes,
             limit=self._GERRIT_MAX_QUERY_RETURN,
             o_params=o_params)
         results.extend(moar)
     for change in changes:
         change_results = [
             x for x in results if (str(x.get('_number')) == change
                                    or x.get('change_id') == change)
         ]
         if not change_results:
             raise GerritException('Change %s not found on server %s.' %
                                   (change, self.host))
         elif len(change_results) > 1:
             logging.warning(json.dumps(change_results, indent=2))
             raise GerritException(
                 'Query for change %s returned multiple results.' % change)
         patch_dict = cros_patch.GerritPatch.ConvertQueryResults(
             change_results[0], self.host)
         yield change, cros_patch.GerritPatch(patch_dict, self.remote,
                                              url_prefix)
Example #3
0
    def Query(self,
              change=None,
              sort=None,
              current_patch=True,
              options=(),
              dryrun=False,
              raw=False,
              _resume_sortkey=None,
              **query_kwds):
        if options:
            raise GerritException(
                '"options" argument unsupported on gerrit-on-borg.')
        url_prefix = gob_util.GetGerritFetchUrl(self.host)
        o_params = ['DETAILED_ACCOUNTS']
        if current_patch:
            o_params.extend(
                ['CURRENT_COMMIT', 'CURRENT_REVISION', 'DETAILED_LABELS'])

        if change and change.isdigit() and not query_kwds:
            if dryrun:
                logging.info(
                    'Would have run gob_util.GetChangeDetail(%s, %s, %s)',
                    self.host, change, o_params)
                return []
            patch_dict = cros_patch.GerritPatch.ConvertQueryResults(
                gob_util.GetChangeDetail(self.host, change, o_params=o_params),
                self.host)
            if raw:
                return [patch_dict]
            return [
                cros_patch.GerritPatch(patch_dict, self.remote, url_prefix)
            ]

        if change and query_kwds.get('change'):
            raise GerritException(
                'Bad query params: provided a change-id-like query,'
                ' and a "change" search parameter')

        if _resume_sortkey:
            query_kwds['resume_sortkey'] = _resume_sortkey

        if dryrun:
            logging.info(
                'Would have run gob_util.QueryChanges(%s, %s, '
                'first_param=%s, limit=%d)', self.host, repr(query_kwds),
                change, self._GERRIT_MAX_QUERY_RETURN)
            return []

        moar = gob_util.QueryChanges(self.host,
                                     query_kwds,
                                     first_param=change,
                                     limit=self._GERRIT_MAX_QUERY_RETURN,
                                     o_params=o_params)
        result = list(moar)
        while moar and moar[-1].get('_more_changes'):
            query_kwds['resume_sortkey'] = result[-1].get['_sortkey']
            moar = gob_util.QueryChanges(self.host,
                                         query_kwds,
                                         first_param=change,
                                         limit=self._GERRIT_MAX_QUERY_RETURN)
            result.extend(moar)
        result = [
            cros_patch.GerritPatch.ConvertQueryResults(x, self.host)
            for x in result
        ]
        if sort:
            result = sorted(result, key=operator.itemgetter(sort))
        if raw:
            return result
        return [
            cros_patch.GerritPatch(x, self.remote, url_prefix) for x in result
        ]
Example #4
0
    def Query(self,
              change=None,
              sort=None,
              current_patch=True,
              options=(),
              dryrun=False,
              raw=False,
              start=None,
              bypass_cache=True,
              **kwargs):
        """Free-form query for gerrit changes.

    Args:
      change: ChangeId, git commit hash, or gerrit number for a change.
      sort: A functor to extract a sort key from a cros_patch.GerritChange
          object, for sorting results..  If this is None, results will not be
          sorted.
      current_patch: If True, ask the gerrit server for extra information about
          the latest uploaded patch.
      options: Deprecated.
      dryrun: If True, don't query the gerrit server; return an empty list.
      raw: If True, return a list of python dict's representing the query
          results.  Otherwise, return a list of cros_patch.GerritPatch.
      start: Offset in the result set to start at.
      bypass_cache: Query each change to make sure data is up to date.
      kwargs: A dict of query parameters, as described here:
        https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes

    Returns:
      A list of python dicts or cros_patch.GerritChange.
    """
        query_kwds = kwargs
        if options:
            raise GerritException(
                '"options" argument unsupported on gerrit-on-borg.')
        url_prefix = gob_util.GetGerritFetchUrl(self.host)
        # All possible params are documented at
        # pylint: disable=C0301
        # https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
        o_params = ['DETAILED_ACCOUNTS', 'ALL_REVISIONS', 'DETAILED_LABELS']
        if current_patch:
            o_params.extend(['CURRENT_COMMIT', 'CURRENT_REVISION'])

        if change and cros_patch.ParseGerritNumber(change) and not query_kwds:
            if dryrun:
                logging.info('Would have run gob_util.GetChangeDetail(%s, %s)',
                             self.host, change)
                return []
            change = self.GetChangeDetail(change)
            if change is None:
                return []
            patch_dict = cros_patch.GerritPatch.ConvertQueryResults(
                change, self.host)
            if raw:
                return [patch_dict]
            return [
                cros_patch.GerritPatch(patch_dict, self.remote, url_prefix)
            ]

        # TODO: We should allow querying using a cros_patch.PatchQuery
        # object directly.
        if change and cros_patch.ParseSHA1(change):
            # Use commit:sha1 for accurate query results (crbug.com/358381).
            kwargs['commit'] = change
            change = None
        elif change and cros_patch.ParseChangeID(change):
            # Use change:change-id for accurate query results (crbug.com/357876).
            kwargs['change'] = change
            change = None
        elif change and cros_patch.ParseFullChangeID(change):
            change = cros_patch.ParseFullChangeID(change)
            kwargs['change'] = change.change_id
            kwargs['project'] = change.project
            kwargs['branch'] = change.branch
            change = None

        if change and query_kwds.get('change'):
            raise GerritException(
                'Bad query params: provided a change-id-like query,'
                ' and a "change" search parameter')

        if dryrun:
            logging.info(
                'Would have run gob_util.QueryChanges(%s, %s, '
                'first_param=%s, limit=%d)', self.host, repr(query_kwds),
                change, self._GERRIT_MAX_QUERY_RETURN)
            return []

        start = 0
        moar = gob_util.QueryChanges(self.host,
                                     query_kwds,
                                     first_param=change,
                                     start=start,
                                     limit=self._GERRIT_MAX_QUERY_RETURN,
                                     o_params=o_params)
        result = list(moar)
        while moar and self.MORE_CHANGES in moar[-1]:
            start += len(moar)
            moar = gob_util.QueryChanges(self.host,
                                         query_kwds,
                                         first_param=change,
                                         start=start,
                                         limit=self._GERRIT_MAX_QUERY_RETURN,
                                         o_params=o_params)
            result.extend(moar)

        # NOTE: Query results are served from the gerrit cache, which may be stale.
        # To make sure the patch information is accurate, re-request each query
        # result directly, circumventing the cache.  For reference:
        #   https://code.google.com/p/chromium/issues/detail?id=302072
        if bypass_cache:
            result = self.GetMultipleChangeDetail(
                [x['_number'] for x in result])

        result = [
            cros_patch.GerritPatch.ConvertQueryResults(x, self.host)
            for x in result
        ]
        if sort:
            result = sorted(result, key=operator.itemgetter(sort))
        if raw:
            return result
        return [
            cros_patch.GerritPatch(x, self.remote, url_prefix) for x in result
        ]