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
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
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