2017-02-02 14:02:37 +00:00
|
|
|
# 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',
|
|
|
|
'get_images_from_skps',
|
|
|
|
'get_images_from_skps.exe',
|
|
|
|
'nanobench',
|
|
|
|
'nanobench.exe',
|
|
|
|
'skpbench',
|
|
|
|
'*.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]))
|
|
|
|
|
2017-02-09 15:08:13 +00:00
|
|
|
@property
|
|
|
|
def failed_steps(self):
|
|
|
|
return self._failed[:]
|
|
|
|
|
2017-02-02 14:02:37 +00:00
|
|
|
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."""
|
2017-03-21 12:20:33 +00:00
|
|
|
env = self.m.step.get_from_context('env', {})
|
2017-02-02 14:02:37 +00:00
|
|
|
env['PYTHONPATH'] = str(self.m.path['start_dir'].join(
|
|
|
|
'skia', 'infra', 'bots', '.recipe_deps', 'build', 'scripts'))
|
2017-03-20 19:40:12 +00:00
|
|
|
with self.m.step.context({'env': env}):
|
|
|
|
self.m.file.rmtree(self.m.path.basename(path),
|
|
|
|
path,
|
|
|
|
infra_step=True)
|
2017-02-21 12:22:20 +00:00
|
|
|
|
2017-02-02 14:02:37 +00:00
|
|
|
def __call__(self, steptype, name, abort_on_failure=True,
|
2017-03-20 19:40:12 +00:00
|
|
|
fail_build_on_failure=True, **kwargs):
|
2017-02-02 14:02:37 +00:00
|
|
|
"""Run a step. If it fails, keep going but mark the build status failed."""
|
2017-03-21 12:20:33 +00:00
|
|
|
env = self.m.step.get_from_context('env', {})
|
2017-02-02 14:02:37 +00:00
|
|
|
env.update(self.m.vars.default_env)
|
|
|
|
try:
|
2017-03-21 12:20:33 +00:00
|
|
|
with self.m.step.context({'env': env}):
|
|
|
|
return steptype(name=name, **kwargs)
|
2017-02-02 14:02:37 +00:00
|
|
|
except self.m.step.StepFailure as e:
|
2017-02-13 15:35:39 +00:00
|
|
|
if abort_on_failure or fail_build_on_failure:
|
|
|
|
self._failed.append(e)
|
2017-02-02 14:02:37 +00:00
|
|
|
if abort_on_failure:
|
|
|
|
raise # pragma: no cover
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
2017-02-21 12:22:20 +00:00
|
|
|
def with_retry(self, steptype, name, attempts, **kwargs):
|
2017-02-02 14:02:37 +00:00
|
|
|
for attempt in xrange(attempts):
|
|
|
|
step_name = name
|
|
|
|
if attempt > 0:
|
|
|
|
step_name += ' (attempt %d)' % (attempt + 1)
|
|
|
|
try:
|
2017-03-20 19:40:12 +00:00
|
|
|
res = self(steptype, name=step_name, **kwargs)
|
2017-02-21 12:22:20 +00:00
|
|
|
return res
|
2017-02-02 14:02:37 +00:00
|
|
|
except self.m.step.StepFailure:
|
|
|
|
if attempt == attempts - 1:
|
|
|
|
raise
|