예제 #1
0
 def _CheckPaladin(self, repo, master_id, ids, extra):
     patch = self.CommitChangeIdFile(repo,
                                     master_id,
                                     extra=extra,
                                     filename='paladincheck',
                                     content=str(_GetNumber()))
     deps = patch.PaladinDependencies(repo)
     # Assert that are parsing unique'ifies the results.
     self.assertEqual(len(deps), len(set(deps)))
     deps = set(deps)
     ids = set(ids)
     self.assertEqual(ids, deps)
     self.assertEqual(set(cros_patch.FormatPatchDep(x) for x in deps),
                      set(cros_patch.FormatPatchDep(x) for x in ids))
     return patch
예제 #2
0
def GetGerritPatchInfo(patches):
    """Query Gerrit server for patch information.

  Args:
    patches: a list of patch IDs to query.  Internal patches start with a '*'.

  Returns:
    A list of GerritPatch objects describing each patch.  Only the first
    instance of a requested patch is returned.

  Raises:
    PatchException if a patch can't be found.
  """
    parsed_patches = {}

    # First, standardize 'em.
    patches = [
        cros_patch.FormatPatchDep(x, sha1=False, allow_CL=True)
        for x in patches
    ]

    # Next, split on internal vs external.
    internal_patches = [x for x in patches if x.startswith('*')]
    external_patches = [x for x in patches if not x.startswith('*')]

    if internal_patches:
        # feed it id's w/ * stripped off, but bind them back
        # so that we can return patches in the supplied ordering.
        # while this may seem silly, we do this to preclude the potential
        # of a conflict between gerrit instances.  Since change-id is
        # effectively user controlled, better safe than sorry.
        helper = GetGerritHelper(constants.INTERNAL_REMOTE)
        raw_ids = [x[1:] for x in internal_patches]
        parsed_patches.update(
            ('*' + k, v)
            for k, v in helper.QueryMultipleCurrentPatchset(raw_ids))

    if external_patches:
        helper = GetGerritHelper(constants.EXTERNAL_REMOTE)
        parsed_patches.update(
            helper.QueryMultipleCurrentPatchset(external_patches))

    seen = set()
    results = []
    for query in patches:
        # return a unique list, while maintaining the ordering of the first
        # seen instance of each patch.  Do this to ensure whatever ordering
        # the user is trying to enforce, we honor; lest it break on cherry-picking
        gpatch = parsed_patches[query]
        if gpatch.change_id not in seen:
            results.append(gpatch)
            seen.add(gpatch.change_id)

    return results
예제 #3
0
    def QueryMultipleCurrentPatchset(self, queries):
        """Query chromeos gerrit servers for the current patch for given changes

    Args:
     queries: sequence of Change-IDs (Ic04g2ab, 6 characters to 40),
       or change numbers (12345 for example).
       A change number can refer to the same change as a Change ID,
       but Change IDs given should be unique, and the same goes for Change
       Numbers.

    Returns:
     an unordered sequence of GerritPatches for each requested query.

    Raises:
     GerritException: if a query fails to match, or isn't specific enough,
      or a query is malformed.
     RunCommandException: if for whatever reason, the ssh invocation to
      gerrit fails.
    """

        if not queries:
            return

        # process the queries in two seperate streams; this is done so that
        # we can identify exactly which patchset returned no results; it's
        # basically impossible to do it if you query with mixed numeric/ID

        numeric_queries = [x for x in queries if x.isdigit()]

        if numeric_queries:
            query = ' OR '.join('change:%s' % x for x in numeric_queries)
            results = self.Query(query, sort='number')

            # Sort via alpha comparison, rather than integer; Query sorts via the
            # raw textual field, thus we need to match that.
            numeric_queries = sorted(numeric_queries, key=str)

            for query, result in itertools.izip_longest(
                    numeric_queries, results):
                if result is None or result.gerrit_number != query:
                    raise GerritException(
                        'Change number %s not found on server %s.' %
                        (query, self.host))

                yield query, result

        id_queries = sorted(
            cros_patch.FormatPatchDep(x, sha1=False) for x in queries
            if not x.isdigit())

        if not id_queries:
            return

        results = self.Query(' OR '.join('change:%s' % x for x in id_queries),
                             sort='id')

        last_patch_id = None
        for query, result in itertools.izip_longest(id_queries, results):
            # case insensitivity to ensure that if someone queries for IABC
            # and gerrit returns Iabc, we still properly match.
            result_id = ''
            if result:
                result_id = cros_patch.FormatChangeId(result.change_id)

            if result is None or (query and not result_id.startswith(query)):
                if last_patch_id and result_id.startswith(last_patch_id):
                    raise GerritException(
                        'While querying for change %s, we received '
                        'back multiple results.  Please be more specific.  Server=%s'
                        % (last_patch_id, self.host))

                raise GerritException('Change-ID %s not found on server %s.' %
                                      (query, self.host))

            if query is None:
                raise GerritException(
                    'While querying for change %s, we received '
                    'back multiple results.  Please be more specific.  Server=%s'
                    % (last_patch_id, self.host))

            yield query, result
            last_patch_id = query