• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5
6# pylint: disable=W0201
7
8
9from recipe_engine import recipe_api
10
11
12BUILD_PRODUCTS_ISOLATE_WHITELIST = [
13  'bookmaker',
14  'dm',
15  'dm.exe',
16  'dm.app',
17  'nanobench.app',
18  'get_images_from_skps',
19  'get_images_from_skps.exe',
20  'nanobench',
21  'nanobench.exe',
22  'skpbench',
23  '*.so',
24  '*.dll',
25  '*.dylib',
26  'skia_launcher',
27  'skiaserve',
28  'lib/*.so',
29]
30
31
32class SkiaStepApi(recipe_api.RecipeApi):
33
34  def __init__(self, *args, **kwargs):
35    """Initialize the recipe module."""
36    super(SkiaStepApi, self).__init__(*args, **kwargs)
37
38    self._already_ran = {}
39    self._ccache = None
40    self._checked_for_ccache = False
41    self._failed = []
42
43  def check_failure(self):
44    """Raise an exception if any step failed."""
45    if self._failed:
46      raise self.m.step.StepFailure('Failed build steps: %s' %
47                                    ', '.join([f.name for f in self._failed]))
48
49  @property
50  def failed_steps(self):
51    return self._failed[:]
52
53  def run_once(self, fn, *args, **kwargs):
54    if not fn.__name__ in self._already_ran:
55      self._already_ran[fn.__name__] = fn(*args, **kwargs)
56    return self._already_ran[fn.__name__]
57
58  def readfile(self, filename, *args, **kwargs):
59    """Convenience function for reading files."""
60    name = kwargs.pop('name', 'read %s' % self.m.path.basename(filename))
61    return self.m.file.read_text(name, filename, *args, **kwargs)
62
63  def writefile(self, filename, contents):
64    """Convenience function for writing files."""
65    return self.m.file.write_text('write %s' % self.m.path.basename(filename),
66                                  filename, contents)
67
68  def rmtree(self, path):
69    """Wrapper around api.file.rmtree."""
70    self.m.file.rmtree('rmtree %s' % self.m.path.basename(path), path)
71
72  def __call__(self, steptype, name, abort_on_failure=True,
73               fail_build_on_failure=True, **kwargs):
74    """Run a step. If it fails, keep going but mark the build status failed."""
75    try:
76      with self.m.env(self.m.vars.default_env):
77        return steptype(name=name, **kwargs)
78    except self.m.step.StepFailure as e:
79      if fail_build_on_failure:
80        self._failed.append(e)
81      if abort_on_failure:
82        raise
83
84  def copy_build_products(self, src, dst):
85    """Copy whitelisted build products from src to dst."""
86    self.m.python.inline(
87        name='copy build products',
88        program='''import errno
89import glob
90import os
91import shutil
92import sys
93
94src = sys.argv[1]
95dst = sys.argv[2]
96build_products_whitelist = %s
97
98try:
99  os.makedirs(dst)
100except OSError as e:
101  if e.errno != errno.EEXIST:
102    raise
103
104for pattern in build_products_whitelist:
105  path = os.path.join(src, pattern)
106  for f in glob.glob(path):
107    dst_path = os.path.join(dst, os.path.relpath(f, src))
108    if not os.path.isdir(os.path.dirname(dst_path)):
109      os.makedirs(os.path.dirname(dst_path))
110    print 'Copying build product %%s to %%s' %% (f, dst_path)
111    shutil.move(f, dst_path)
112''' % str(BUILD_PRODUCTS_ISOLATE_WHITELIST),
113        args=[src, dst],
114        infra_step=True)
115
116  def with_retry(self, steptype, name, attempts, between_attempts_fn=None,
117                 abort_on_failure=True, fail_build_on_failure=True, **kwargs):
118    for attempt in xrange(attempts):
119      step_name = name
120      if attempt > 0:
121        step_name += ' (attempt %d)' % (attempt + 1)
122      try:
123        res = self(steptype, name=step_name, abort_on_failure=True,
124                   fail_build_on_failure=fail_build_on_failure, **kwargs)
125        if attempt > 0 and fail_build_on_failure:
126          del self._failed[-attempt:]
127        return res
128      except self.m.step.StepFailure:
129        if attempt == attempts - 1:
130          if abort_on_failure:
131            raise
132        elif between_attempts_fn:
133          between_attempts_fn(attempt+1)
134