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 |