| Index: presubmit_support.py
|
| diff --git a/presubmit_support.py b/presubmit_support.py
|
| index dabfbf0bac2e7bbf253aaa29245fca5378ed58eb..513b29f7cb9b532fda4082e616c7d5fc04c3d1b5 100755
|
| --- a/presubmit_support.py
|
| +++ b/presubmit_support.py
|
| @@ -19,6 +19,7 @@ import contextlib
|
| import fnmatch
|
| import glob
|
| import inspect
|
| +import itertools
|
| import json # Exposed through the API.
|
| import logging
|
| import marshal # Exposed through the API.
|
| @@ -1007,6 +1008,8 @@ class GetTrySlavesExecuter(object):
|
| @staticmethod
|
| def ExecPresubmitScript(script_text, presubmit_path, project, change):
|
| """Executes GetPreferredTrySlaves() from a single presubmit script.
|
| +
|
| + This will soon be deprecated and replaced by GetPreferredTryMasters().
|
|
|
| Args:
|
| script_text: The text of the presubmit script.
|
| @@ -1074,6 +1077,36 @@ class GetTrySlavesExecuter(object):
|
| return result
|
|
|
|
|
| +class GetTryMastersExecuter(object):
|
| + @staticmethod
|
| + def ExecPresubmitScript(script_text, presubmit_path, project, change):
|
| + """Executes GetPreferredTryMasters() from a single presubmit script.
|
| +
|
| + Args:
|
| + script_text: The text of the presubmit script.
|
| + presubmit_path: Project script to run.
|
| + project: Project name to pass to presubmit script for bot selection.
|
| +
|
| + Return:
|
| + A map of try masters to map of builders to set of tests.
|
| + """
|
| + context = {}
|
| + try:
|
| + exec script_text in context
|
| + except Exception, e:
|
| + raise PresubmitFailure('"%s" had an exception.\n%s'
|
| + % (presubmit_path, e))
|
| +
|
| + function_name = 'GetPreferredTryMasters'
|
| + if function_name not in context:
|
| + return {}
|
| + get_preferred_try_masters = context[function_name]
|
| + if not len(inspect.getargspec(get_preferred_try_masters)[0]) == 2:
|
| + raise PresubmitFailure(
|
| + 'Expected function "GetPreferredTryMasters" to take two arguments.')
|
| + return get_preferred_try_masters(project, change)
|
| +
|
| +
|
| def DoGetTrySlaves(change,
|
| changed_files,
|
| repository_root,
|
| @@ -1081,7 +1114,7 @@ def DoGetTrySlaves(change,
|
| project,
|
| verbose,
|
| output_stream):
|
| - """Get the list of try servers from the presubmit scripts.
|
| + """Get the list of try servers from the presubmit scripts (deprecated).
|
|
|
| Args:
|
| changed_files: List of modified files.
|
| @@ -1132,6 +1165,68 @@ def DoGetTrySlaves(change,
|
| return slaves
|
|
|
|
|
| +def _MergeMasters(masters1, masters2):
|
| + """Merges two master maps. Merges also the tests of each builder."""
|
| + result = {}
|
| + for (master, builders) in itertools.chain(masters1.iteritems(),
|
| + masters2.iteritems()):
|
| + new_builders = result.setdefault(master, {})
|
| + for (builder, tests) in builders.iteritems():
|
| + new_builders.setdefault(builder, set([])).update(tests)
|
| + return result
|
| +
|
| +
|
| +def DoGetTryMasters(change,
|
| + changed_files,
|
| + repository_root,
|
| + default_presubmit,
|
| + project,
|
| + verbose,
|
| + output_stream):
|
| + """Get the list of try masters from the presubmit scripts.
|
| +
|
| + Args:
|
| + changed_files: List of modified files.
|
| + repository_root: The repository root.
|
| + default_presubmit: A default presubmit script to execute in any case.
|
| + project: Optional name of a project used in selecting trybots.
|
| + verbose: Prints debug info.
|
| + output_stream: A stream to write debug output to.
|
| +
|
| + Return:
|
| + Map of try masters to map of builders to set of tests.
|
| + """
|
| + presubmit_files = ListRelevantPresubmitFiles(changed_files, repository_root)
|
| + if not presubmit_files and verbose:
|
| + output_stream.write("Warning, no PRESUBMIT.py found.\n")
|
| + results = {}
|
| + executer = GetTryMastersExecuter()
|
| +
|
| + if default_presubmit:
|
| + if verbose:
|
| + output_stream.write("Running default presubmit script.\n")
|
| + fake_path = os.path.join(repository_root, 'PRESUBMIT.py')
|
| + results = _MergeMasters(results, executer.ExecPresubmitScript(
|
| + default_presubmit, fake_path, project, change))
|
| + for filename in presubmit_files:
|
| + filename = os.path.abspath(filename)
|
| + if verbose:
|
| + output_stream.write("Running %s\n" % filename)
|
| + # Accept CRLF presubmit script.
|
| + presubmit_script = gclient_utils.FileRead(filename, 'rU')
|
| + results = _MergeMasters(results, executer.ExecPresubmitScript(
|
| + presubmit_script, filename, project, change))
|
| +
|
| + # Make sets to lists again for later JSON serialization.
|
| + for builders in results.itervalues():
|
| + for builder in builders:
|
| + builders[builder] = list(builders[builder])
|
| +
|
| + if results and verbose:
|
| + output_stream.write('%s\n' % str(results))
|
| + return results
|
| +
|
| +
|
| class PresubmitExecuter(object):
|
| def __init__(self, change, committing, rietveld_obj, verbose):
|
| """
|
|
|