• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
9from recipe_engine import recipe_api
10from recipe_engine import config_types
11
12
13class CheckoutApi(recipe_api.RecipeApi):
14
15  @property
16  def default_checkout_root(self):
17    """The default location for cached persistent checkouts."""
18    return self.m.vars.cache_dir.join('work')
19
20  def git(self, checkout_root):
21    """Run the steps to perform a pure-git checkout without DEPS."""
22    skia_dir = checkout_root.join('skia')
23    self.m.git.checkout(
24        self.m.properties['repository'], dir_path=skia_dir,
25        ref=self.m.properties['revision'], submodules=False)
26    if self.m.vars.is_trybot:
27      self.m.git('fetch', 'origin', self.m.properties['patch_ref'])
28      self.m.git('checkout', 'FETCH_HEAD')
29      self.m.git('rebase', self.m.properties['revision'])
30      return self.m.properties['revision']
31
32  def bot_update(self, checkout_root, gclient_cache=None,
33                 checkout_chromium=False, checkout_flutter=False,
34                 extra_gclient_env=None, parent_rev=False,
35                 flutter_android=False):
36    """Run the steps to obtain a checkout using bot_update.
37
38    Args:
39      checkout_root: Root directory where the code will be synced.
40      gclient_cache: Optional, directory of the gclient cache.
41      checkout_chromium: If True, will check out chromium/src.git in addition
42          to the primary repo.
43      checkout_flutter: If True, will checkout flutter in addition to the
44          primary repo.
45      extra_gclient_env: Map of extra environment variable names to their values
46          to supply while running gclient.
47      parent_rev: If True, checks out the parent of the specified revision,
48          rather than the revision itself, ie. HEAD^ for normal jobs and HEAD
49          (no patch) for try jobs.
50      flutter_android: Indicates that we're checking out flutter for Android.
51    """
52    if not gclient_cache:
53      gclient_cache = self.m.vars.cache_dir.join('git')
54    if not extra_gclient_env:
55      extra_gclient_env = {}
56
57    cfg_kwargs = {}
58
59    # Use a persistent gclient cache for Swarming.
60    cfg_kwargs['CACHE_DIR'] = gclient_cache
61
62    # Create the checkout path if necessary.
63    # TODO(borenet): 'makedirs checkout_root'
64    self.m.file.ensure_directory('makedirs checkout_path', checkout_root)
65
66    # Initial cleanup.
67    gclient_cfg = self.m.gclient.make_config(**cfg_kwargs)
68
69    main_repo = self.m.properties['repository']
70    if checkout_flutter:
71      main_repo = 'https://github.com/flutter/engine.git'
72    main_name = self.m.path.basename(main_repo)
73    if main_name.endswith('.git'):
74      main_name = main_name[:-len('.git')]
75      # Special case for flutter because it seems to need a very specific
76      # directory structure to successfully build.
77      if checkout_flutter and main_name == 'engine':
78        main_name = 'src/flutter'
79    main = gclient_cfg.solutions.add()
80    main.name = main_name
81    main.managed = False
82    main.url = main_repo
83    main.revision = self.m.properties.get('revision') or 'origin/master'
84    m = gclient_cfg.got_revision_mapping
85    m[main_name] = 'got_revision'
86    patch_root = main_name
87    patch_repo = main.url
88    if self.m.properties.get('patch_repo'):
89      patch_repo = self.m.properties['patch_repo']
90      patch_root = patch_repo.split('/')[-1]
91      if patch_root.endswith('.git'):
92        patch_root = patch_root[:-4]
93
94    if checkout_flutter:
95      # Skia is a DEP of Flutter; the 'revision' property is a Skia revision,
96      # and any patch should be applied to Skia, not Flutter.
97      main.revision = 'origin/master'
98      main.managed = True
99      m[main_name] = 'got_flutter_revision'
100      if flutter_android:
101        gclient_cfg.target_os.add('android')
102
103      skia_dep_path = 'src/third_party/skia'
104      gclient_cfg.repo_path_map['https://skia.googlesource.com/skia'] = (
105          skia_dep_path, 'HEAD')
106      gclient_cfg.revisions[skia_dep_path] = self.m.properties['revision']
107      m[skia_dep_path] = 'got_revision'
108      patch_root = skia_dep_path
109
110    if checkout_chromium:
111      main.custom_vars['checkout_chromium'] = True
112      extra_gclient_env['GYP_CHROMIUM_NO_ACTION'] = '0'
113
114    # TODO(rmistry): Remove the below block after there is a solution for
115    #                crbug.com/616443
116    entries_file = checkout_root.join('.gclient_entries')
117    if self.m.path.exists(entries_file) or self._test_data.enabled:
118      self.m.file.remove('remove %s' % entries_file,
119                         entries_file)
120
121    # Run bot_update.
122    if not self.m.vars.is_trybot and parent_rev:
123      main.revision = main.revision + '^'
124
125    patch_refs = None
126    patch_ref = self.m.properties.get('patch_ref')
127    if patch_ref:
128      patch_refs = ['%s@%s' % (self.m.properties['patch_repo'], patch_ref)]
129
130    self.m.gclient.c = gclient_cfg
131    with self.m.context(cwd=checkout_root):
132      update_step = self.m.bot_update.ensure_checkout(
133          patch_root=patch_root,
134          # The logic in ensure_checkout for this arg is fairly naive, so if
135          # patch=False, we'll see "... (without patch)" in the step names, even
136          # for non-trybot runs, which is misleading and confusing. Therefore,
137          # always specify patch=True for non-trybot runs.
138          patch=not (self.m.vars.is_trybot and parent_rev),
139          patch_refs=patch_refs,
140      )
141
142    if checkout_chromium or checkout_flutter:
143      gclient_env = {'DEPOT_TOOLS_UPDATE': '0'}
144      if extra_gclient_env:
145        gclient_env.update(extra_gclient_env)
146      with self.m.context(cwd=checkout_root, env=gclient_env):
147        self.m.gclient.runhooks()
148    return update_step.presentation.properties['got_revision']
149