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