xref: /aosp_15_r20/external/skia/infra/bots/recipe_modules/checkout/api.py (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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.joinpath('work')
19
20  def assert_git_is_from_cipd(self):
21    """Fail if git is not obtained from CIPD."""
22    script = self.resource('assert_git_cipd.py')
23    self.m.run(
24        self.m.step, 'Assert that Git is from CIPD', cmd=['python3', script])
25
26  def git(self, checkout_root):
27    """Run the steps to perform a pure-git checkout without DEPS."""
28    self.assert_git_is_from_cipd()
29    skia_dir = checkout_root.joinpath('skia')
30    self.m.git.checkout(
31        self.m.properties['repository'], dir_path=skia_dir,
32        ref=self.m.properties['revision'], submodules=False)
33    if self.m.vars.is_trybot:
34      self.m.git('fetch', 'origin', self.m.properties['patch_ref'])
35      self.m.git('checkout', 'FETCH_HEAD')
36      self.m.git('rebase', self.m.properties['revision'])
37      return self.m.properties['revision']
38
39  def bot_update(self, checkout_root, gclient_cache=None,
40                 skip_patch=False, override_revision=None):
41    """Run the steps to obtain a checkout using bot_update.
42
43    Args:
44      checkout_root: Root directory where the code will be synced.
45      gclient_cache: Optional, directory of the gclient cache.
46      skip_patch: Ignore changelist/patchset when syncing the Skia repo.
47    """
48    self.assert_git_is_from_cipd()
49    if not gclient_cache:
50      gclient_cache = self.m.vars.cache_dir.joinpath('git')
51
52    cfg_kwargs = {}
53
54    # Use a persistent gclient cache for Swarming.
55    cfg_kwargs['CACHE_DIR'] = gclient_cache
56
57    # Create the checkout path if necessary.
58    # TODO(borenet): 'makedirs checkout_root'
59    self.m.file.ensure_directory('makedirs checkout_path', checkout_root)
60
61    # Initial cleanup.
62    gclient_cfg = self.m.gclient.make_config(**cfg_kwargs)
63
64    main_repo = self.m.properties['repository']
65    main_name = self.m.path.basename(main_repo)
66    if main_name.endswith('.git'):
67      main_name = main_name[:-len('.git')]
68    main = gclient_cfg.solutions.add()
69    main.name = main_name
70    main.managed = False
71    main.url = main_repo
72    main.revision = (override_revision or
73      self.m.properties.get('revision') or 'origin/main')
74    m = gclient_cfg.got_revision_mapping
75    m[main_name] = 'got_revision'
76    patch_root = main_name
77    patch_repo = main.url
78    if self.m.properties.get('patch_repo'):
79      patch_repo = self.m.properties['patch_repo']
80      patch_root = patch_repo.split('/')[-1]
81      if patch_root.endswith('.git'):
82        patch_root = patch_root[:-4]
83
84    # TODO(rmistry): Remove the below block after there is a solution for
85    #                crbug.com/616443
86    entries_file = checkout_root.joinpath('.gclient_entries')
87    if self.m.path.exists(entries_file) or self._test_data.enabled:
88      self.m.file.remove('remove %s' % entries_file,
89                         entries_file)
90
91    # Run bot_update.
92    patch_refs = None
93    patch_ref = self.m.properties.get('patch_ref')
94    if patch_ref and not skip_patch:
95      patch_refs = ['%s@%s:%s' % (self.m.properties['patch_repo'],
96                                  self.m.properties['revision'],
97                                  patch_ref)]
98
99    self.m.gclient.c = gclient_cfg
100    with self.m.context(cwd=checkout_root):
101      # https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/dca14bc463857bd2a0fee59c86ffa289b535d5d3/recipes/recipe_modules/bot_update/api.py#105
102      update_step = self.m.bot_update.ensure_checkout(
103          patch_root=patch_root,
104          # The logic in ensure_checkout for this arg is fairly naive, so if
105          # patch=False, we'll see "... (without patch)" in the step names, even
106          # for non-trybot runs, which is misleading and confusing. Therefore,
107          # always specify patch=True.
108          patch=True,
109          patch_refs=patch_refs,
110          # Download the patches of all changes with the same Gerrit topic.
111          # For context see go/sk-topics.
112          download_topics=True,
113      )
114
115    return update_step.presentation.properties['got_revision']
116