1# Copyright 2014 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
9"""Default flavor utils class, used for desktop builders."""
10
11
12import json
13
14
15WIN_TOOLCHAIN_DIR = 't'
16
17
18class DeviceDirs(object):
19  def __init__(self,
20               dm_dir,
21               perf_data_dir,
22               resource_dir,
23               images_dir,
24               skp_dir,
25               svg_dir,
26               tmp_dir):
27    self._dm_dir = dm_dir
28    self._perf_data_dir = perf_data_dir
29    self._resource_dir = resource_dir
30    self._images_dir = images_dir
31    self._skp_dir = skp_dir
32    self._svg_dir = svg_dir
33    self._tmp_dir = tmp_dir
34
35  @property
36  def dm_dir(self):
37    """Where DM writes."""
38    return self._dm_dir
39
40  @property
41  def perf_data_dir(self):
42    return self._perf_data_dir
43
44  @property
45  def resource_dir(self):
46    return self._resource_dir
47
48  @property
49  def images_dir(self):
50    return self._images_dir
51
52  @property
53  def skp_dir(self):
54    """Holds SKP files that are consumed by RenderSKPs and BenchPictures."""
55    return self._skp_dir
56
57  @property
58  def svg_dir(self):
59    return self._svg_dir
60
61  @property
62  def tmp_dir(self):
63    return self._tmp_dir
64
65
66class DefaultFlavorUtils(object):
67  """Utilities to be used by build steps.
68
69  The methods in this class define how certain high-level functions should
70  work. Each build step flavor should correspond to a subclass of
71  DefaultFlavorUtils which may override any of these functions as appropriate
72  for that flavor.
73
74  For example, the AndroidFlavorUtils will override the functions for
75  copying files between the host and Android device, as well as the
76  'step' function, so that commands may be run through ADB.
77  """
78  def __init__(self, module):
79    # Store a pointer to the parent recipe module (SkiaFlavorApi) so that
80    # FlavorUtils objects can do recipe module-like things, like run steps or
81    # access module-level resources.
82    self.module = module
83
84    # self.m is just a shortcut so that FlavorUtils objects can use the same
85    # syntax as regular recipe modules to run steps, eg: self.m.step(...)
86    self.m = module.m
87    self._chrome_path = None
88    self._win_toolchain_dir = self.m.vars.slave_dir.join(WIN_TOOLCHAIN_DIR)
89    win_toolchain_asset_path = self.m.vars.infrabots_dir.join(
90        'assets', 'win_toolchain', 'VERSION')
91    if not self.m.path.exists(win_toolchain_asset_path):
92      self._win_toolchain_dir = self.m.vars.slave_dir
93
94  def copy_extra_build_products(self, swarming_out_dir):
95    pass
96
97  @property
98  def out_dir(self):
99    """Flavor-specific out directory."""
100    return self.m.vars.skia_out.join(self.m.vars.configuration)
101
102  def device_path_join(self, *args):
103    """Like os.path.join(), but for paths on a connected device."""
104    return self.m.path.join(*args)
105
106  def copy_directory_contents_to_device(self, host_dir, device_dir):
107    """Like shutil.copytree(), but for copying to a connected device."""
108    # For "normal" builders who don't have an attached device, we expect
109    # host_dir and device_dir to be the same.
110    if str(host_dir) != str(device_dir):
111      raise ValueError('For builders who do not have attached devices, copying '
112                       'from host to device is undefined and only allowed if '
113                       'host_path and device_path are the same (%s vs %s).' % (
114                       str(host_dir), str(device_dir)))
115
116  def copy_directory_contents_to_host(self, device_dir, host_dir):
117    """Like shutil.copytree(), but for copying from a connected device."""
118    # For "normal" builders who don't have an attached device, we expect
119    # host_dir and device_dir to be the same.
120    if str(host_dir) != str(device_dir):
121      raise ValueError('For builders who do not have attached devices, copying '
122                       'from device to host is undefined and only allowed if '
123                       'host_path and device_path are the same (%s vs %s).' % (
124                       str(host_dir), str(device_dir)))
125
126  def copy_file_to_device(self, host_path, device_path):
127    """Like shutil.copyfile, but for copying to a connected device."""
128    # For "normal" builders who don't have an attached device, we expect
129    # host_dir and device_dir to be the same.
130    if str(host_path) != str(device_path):
131      raise ValueError('For builders who do not have attached devices, copying '
132                       'from host to device is undefined and only allowed if '
133                       'host_path and device_path are the same (%s vs %s).' % (
134                       str(host_path), str(device_path)))
135
136  def create_clean_device_dir(self, path):
137    """Like shutil.rmtree() + os.makedirs(), but on a connected device."""
138    self.create_clean_host_dir(path)
139
140  def create_clean_host_dir(self, path):
141    """Convenience function for creating a clean directory."""
142    self.m.run.rmtree(path)
143    self.m.file.ensure_directory(
144        'makedirs %s' % self.m.path.basename(path), path)
145
146  def install(self):
147    """Run device-specific installation steps."""
148    self.device_dirs = DeviceDirs(
149        dm_dir=self.m.vars.dm_dir,
150        perf_data_dir=self.m.vars.perf_data_dir,
151        resource_dir=self.m.vars.resource_dir,
152        images_dir=self.m.vars.images_dir,
153        skp_dir=self.m.vars.local_skp_dir,
154        svg_dir=self.m.vars.local_svg_dir,
155        tmp_dir=self.m.vars.tmp_dir)
156
157  def cleanup_steps(self):
158    """Run any device-specific cleanup steps."""
159    pass
160