| Index: infra/bots/recipe_modules/run/api.py
|
| diff --git a/infra/bots/recipe_modules/run/api.py b/infra/bots/recipe_modules/run/api.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1784254d6e07b5056d58f3810dda2c19c6c3b5f3
|
| --- /dev/null
|
| +++ b/infra/bots/recipe_modules/run/api.py
|
| @@ -0,0 +1,152 @@
|
| +# Copyright 2016 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +
|
| +# pylint: disable=W0201
|
| +
|
| +
|
| +from recipe_engine import recipe_api
|
| +
|
| +
|
| +BUILD_PRODUCTS_ISOLATE_WHITELIST = [
|
| + 'dm',
|
| + 'dm.exe',
|
| + 'nanobench',
|
| + 'nanobench.exe',
|
| + '*.so',
|
| + '*.dll',
|
| + '*.dylib',
|
| + 'skia_launcher',
|
| + 'lib/*.so',
|
| + 'iOSShell.app',
|
| + 'iOSShell.ipa',
|
| + 'visualbench',
|
| + 'visualbench.exe',
|
| + 'vulkan-1.dll',
|
| +]
|
| +
|
| +
|
| +class SkiaStepApi(recipe_api.RecipeApi):
|
| +
|
| + def __init__(self, *args, **kwargs):
|
| + """Initialize the recipe module."""
|
| + super(SkiaStepApi, self).__init__(*args, **kwargs)
|
| +
|
| + self._already_ran = {}
|
| + self._ccache = None
|
| + self._checked_for_ccache = False
|
| + self._failed = []
|
| +
|
| + def check_failure(self):
|
| + """Raise an exception if any step failed."""
|
| + if self._failed:
|
| + raise self.m.step.StepFailure('Failed build steps: %s' %
|
| + ', '.join([f.name for f in self._failed]))
|
| +
|
| + def run_once(self, fn, *args, **kwargs):
|
| + if not fn.__name__ in self._already_ran:
|
| + self._already_ran[fn.__name__] = fn(*args, **kwargs)
|
| + return self._already_ran[fn.__name__]
|
| +
|
| + def readfile(self, filename, *args, **kwargs):
|
| + """Convenience function for reading files."""
|
| + name = kwargs.pop('name') or 'read %s' % self.m.path.basename(filename)
|
| + return self.m.file.read(name, filename, infra_step=True, *args, **kwargs)
|
| +
|
| + def writefile(self, filename, contents):
|
| + """Convenience function for writing files."""
|
| + return self.m.file.write('write %s' % self.m.path.basename(filename),
|
| + filename, contents, infra_step=True)
|
| +
|
| + def rmtree(self, path):
|
| + """Wrapper around api.file.rmtree with environment fix."""
|
| + env = {}
|
| + env['PYTHONPATH'] = str(self.m.path['checkout'].join(
|
| + 'infra', 'bots', '.recipe_deps', 'build', 'scripts'))
|
| + self.m.file.rmtree(self.m.path.basename(path),
|
| + path,
|
| + env=env,
|
| + infra_step=True)
|
| +
|
| + def __call__(self, steptype, name, abort_on_failure=True,
|
| + fail_build_on_failure=True, env=None, **kwargs):
|
| + """Run a step. If it fails, keep going but mark the build status failed."""
|
| + env = dict(env or {})
|
| + env.update(self.m.vars.default_env)
|
| + try:
|
| + return steptype(name=name, env=env, **kwargs)
|
| + except self.m.step.StepFailure as e:
|
| + if abort_on_failure:
|
| + raise # pragma: no cover
|
| + if fail_build_on_failure:
|
| + self._failed.append(e)
|
| +
|
| + def json_from_file(self, filename, cwd, builder_name, test_data):
|
| + """Execute the given script to obtain JSON data."""
|
| + return self.m.python(
|
| + 'exec %s' % self.m.path.basename(filename),
|
| + filename,
|
| + args=[self.m.json.output(), builder_name],
|
| + step_test_data=lambda: self.m.json.test_api.output(test_data),
|
| + cwd=cwd,
|
| + infra_step=True).json.output
|
| +
|
| + def copy_build_products(self, src, dst):
|
| + """Copy whitelisted build products from src to dst."""
|
| + self.m.python.inline(
|
| + name='copy build products',
|
| + program='''import errno
|
| +import glob
|
| +import os
|
| +import shutil
|
| +import sys
|
| +
|
| +src = sys.argv[1]
|
| +dst = sys.argv[2]
|
| +build_products_whitelist = %s
|
| +
|
| +try:
|
| + os.makedirs(dst)
|
| +except OSError as e:
|
| + if e.errno != errno.EEXIST:
|
| + raise
|
| +
|
| +for pattern in build_products_whitelist:
|
| + path = os.path.join(src, pattern)
|
| + for f in glob.glob(path):
|
| + dst_path = os.path.join(dst, os.path.relpath(f, src))
|
| + if not os.path.isdir(os.path.dirname(dst_path)):
|
| + os.makedirs(os.path.dirname(dst_path))
|
| + print 'Copying build product %%s to %%s' %% (f, dst_path)
|
| + shutil.move(f, dst_path)
|
| +''' % str(BUILD_PRODUCTS_ISOLATE_WHITELIST),
|
| + args=[src, dst],
|
| + infra_step=True)
|
| +
|
| + def ccache(self):
|
| + if not self._checked_for_ccache:
|
| + self._checked_for_ccache = True
|
| + if not self.m.platform.is_win:
|
| + result = self(
|
| + self.m.python.inline,
|
| + name='has ccache?',
|
| + program='''import json
|
| +import subprocess
|
| +import sys
|
| +
|
| +ccache = None
|
| +try:
|
| + ccache = subprocess.check_output(['which', 'ccache']).rstrip()
|
| +except:
|
| + pass
|
| +print json.dumps({'ccache': ccache})
|
| +''',
|
| + stdout=self.m.json.output(),
|
| + infra_step=True,
|
| + abort_on_failure=False,
|
| + fail_build_on_failure=False)
|
| + if result and result.stdout and result.stdout.get('ccache'):
|
| + self._ccache = result.stdout['ccache']
|
| +
|
| + return self._ccache
|
|
|