Esempio n. 1
0
    def _GetGerritPatch(self, query):
        """Query the configured helpers looking for a given change.

    Args:
      project: The gerrit project to query.
      query: A cros_patch.PatchQuery object.

    Returns:
      A GerritPatch object.
    """
        helper = self._LookupHelper(query)
        query_text = query.ToGerritQueryText()
        change = helper.QuerySingleRecord(
            query_text, must_match=not git.IsSHA1(query_text))

        if not change:
            return

        # If the query was a gerrit number based query, check the projects/change-id
        # to see if we already have it locally, but couldn't map it since we didn't
        # know the gerrit number at the time of the initial injection.
        existing = self._lookup_cache[change]
        if cros_patch.ParseGerritNumber(query_text) and existing is not None:
            keys = change.LookupAliases()
            self._lookup_cache.InjectCustomKeys(keys, existing)
            return existing

        self.InjectLookupCache([change])
        if change.IsAlreadyMerged():
            self.InjectCommittedPatches([change])
        return change
Esempio n. 2
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
        ]