blob: 0cb8633a924425164719a7e2415873bce0b41382 [file] [log] [blame]
Lann Martin10f3ee92018-08-22 15:48:10 -06001# Copyright 2018 The Chromium OS 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
Don Garrett903fedc2018-11-02 17:04:26 -07005"""Sync a git repository to a given manifest.
6
7This script is intended to define all of the ways that a source checkout can be
8defined for a Chrome OS builder.
9
10If a sync completes successfully, the checked out code will exactly match
11whatever manifest is defined, and no local git branches will remain. Extraneous
12files not under version management will be ignored.
13
14It is NOT safe to assume that the checkout can be further updated with
15a simple "repo sync", instead you should call this script again with
16the same options.
17"""
Lann Martin10f3ee92018-08-22 15:48:10 -060018
Chris McDonald59650c32021-07-20 15:29:28 -060019import logging
20
Don Garrett903fedc2018-11-02 17:04:26 -070021from chromite.cbuildbot import manifest_version
Don Garrett115df402018-11-09 14:43:42 -080022from chromite.cbuildbot import patch_series
Don Garrett903fedc2018-11-02 17:04:26 -070023from chromite.cbuildbot import repository
Lann Martin10f3ee92018-08-22 15:48:10 -060024from chromite.lib import commandline
Don Garrett903fedc2018-11-02 17:04:26 -070025from chromite.lib import config_lib
Don Garrett115df402018-11-09 14:43:42 -080026from chromite.lib import gerrit
Don Garrett903fedc2018-11-02 17:04:26 -070027from chromite.lib import osutils
Lann Martin10f3ee92018-08-22 15:48:10 -060028
29
30def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -060031 """Creates the argparse parser."""
32 parser = commandline.ArgumentParser(description=__doc__)
Don Garrett903fedc2018-11-02 17:04:26 -070033
Alex Klein1699fab2022-09-08 08:46:06 -060034 parser.add_argument(
35 "--repo-root",
36 type="path",
37 default=".",
38 help="Path to the repo root to sync.",
39 )
Don Garrett903fedc2018-11-02 17:04:26 -070040
Alex Klein1699fab2022-09-08 08:46:06 -060041 manifest_group = parser.add_argument_group(
42 "Manifest", description="What manifest do we sync?"
43 )
Don Garrett903fedc2018-11-02 17:04:26 -070044
Alex Klein1699fab2022-09-08 08:46:06 -060045 manifest_ex = manifest_group.add_mutually_exclusive_group()
46 manifest_ex.add_argument(
47 "--branch", default="master", help="Sync to top of given branch."
48 )
49 manifest_ex.add_argument(
50 "--buildspec",
51 help="Path to manifest, relative to manifest-versions root.",
52 )
53 manifest_ex.add_argument(
54 "--version",
55 help="Shorthand for an official release buildspec. e.g. 9799.0.0",
56 )
57 manifest_ex.add_argument(
58 "--manifest-file",
59 type="path",
60 help="Sync to an existing local manifest file.",
61 )
Don Garrett903fedc2018-11-02 17:04:26 -070062
Alex Klein1699fab2022-09-08 08:46:06 -060063 manifest_group.add_argument("--groups", help="manifest groups to sync.")
Raul E Rangel5a7c5002019-11-08 09:18:32 -070064
Alex Klein1699fab2022-09-08 08:46:06 -060065 manifest_url_ex = manifest_group.add_mutually_exclusive_group()
66 manifest_url_ex.add_argument(
67 "--external",
68 action="store_true",
69 default=False,
70 help="Sync to the external version of a manifest. Switch from "
71 "manifest-versions-internal to manifest-versions for buildspecs. "
72 "Not usable with --manifest.",
73 )
74 manifest_url_ex.add_argument(
75 "--manifest-url", help="Manually set URL to fetch repo manifest from."
76 )
Don Garrett903fedc2018-11-02 17:04:26 -070077
Alex Klein1699fab2022-09-08 08:46:06 -060078 patch_group = parser.add_argument_group(
79 "Patch", description="Which patches should be included with the build?"
80 )
81 patch_group.add_argument(
82 "-g",
83 "--gerrit-patches",
84 action="split_extend",
85 default=[],
86 metavar="Id1 *int_Id2...IdN",
87 help="Space-separated list of short-form Gerrit "
88 "Change-Id's or change numbers to patch. "
89 "Please prepend '*' to internal Change-Id's",
90 )
Don Garrett115df402018-11-09 14:43:42 -080091
Alex Klein1699fab2022-09-08 08:46:06 -060092 resources_group = parser.add_argument_group(
93 "Resources", description="External resources that might be needed."
94 )
Don Garrett903fedc2018-11-02 17:04:26 -070095
Alex Klein1699fab2022-09-08 08:46:06 -060096 resources_group.add_argument(
97 "--manifest-versions-int",
98 type="path",
99 help="Directory for internal manifest versions checkout. "
100 "May be refreshed.",
101 )
Don Garrett903fedc2018-11-02 17:04:26 -0700102
Alex Klein1699fab2022-09-08 08:46:06 -0600103 resources_group.add_argument(
104 "--manifest-versions-ext",
105 type="path",
106 help="Directory for internal manifest versions checkout. "
107 "May be refreshed.",
108 )
Don Garrett903fedc2018-11-02 17:04:26 -0700109
Alex Klein1699fab2022-09-08 08:46:06 -0600110 optimization_group = parser.add_argument_group(
111 "Optimization",
112 description="Hints provided to possibly speed up initial sync.",
113 )
Don Garrett903fedc2018-11-02 17:04:26 -0700114
Alex Klein1699fab2022-09-08 08:46:06 -0600115 optimization_group.add_argument(
116 "--copy-repo",
117 type="path",
118 help="Path to an existing repo root. Used to preload the local "
119 "checkout if the local checkout doesn't exist.",
120 )
121 optimization_group.add_argument(
122 "--git-cache-dir", type="path", help="Git cache directory to use."
123 )
124 optimization_group.add_argument(
125 "--repo-url", help="Repo repository location."
126 )
Don Garrett903fedc2018-11-02 17:04:26 -0700127
Alex Klein1699fab2022-09-08 08:46:06 -0600128 return parser
Lann Martin10f3ee92018-08-22 15:48:10 -0600129
130
Don Garrett903fedc2018-11-02 17:04:26 -0700131def PrepareManifestVersions(options):
Alex Klein1699fab2022-09-08 08:46:06 -0600132 """Select manifest-versions checkout to use, and update it.
Don Garrett903fedc2018-11-02 17:04:26 -0700133
Alex Klein1699fab2022-09-08 08:46:06 -0600134 Looks at command line options to decide which manifest-versions checkout to
135 use, and updates (or creates) it as needed.
Don Garrett903fedc2018-11-02 17:04:26 -0700136
Alex Klein1699fab2022-09-08 08:46:06 -0600137 Args:
138 options: Parsed command line options.
Don Garrett903fedc2018-11-02 17:04:26 -0700139
Alex Klein1699fab2022-09-08 08:46:06 -0600140 Returns:
141 Full path to manifest-versions directory to use for this sync.
Don Garrett903fedc2018-11-02 17:04:26 -0700142
Alex Klein1699fab2022-09-08 08:46:06 -0600143 Raises:
144 AssertionError: If the needed manifest-versions path wasn't con the
145 command line.
146 """
147 site_params = config_lib.GetSiteParams()
Don Garrett903fedc2018-11-02 17:04:26 -0700148
Alex Klein1699fab2022-09-08 08:46:06 -0600149 if options.external:
150 assert (
151 options.manifest_versions_ext
152 ), "--manifest-versions-ext required."
153 manifest_versions_url = site_params.MANIFEST_VERSIONS_GOB_URL
154 manifest_versions_path = options.manifest_versions_ext
155 else:
156 assert (
157 options.manifest_versions_int
158 ), "--manifest-versions-int required."
159 manifest_versions_url = site_params.MANIFEST_VERSIONS_INT_GOB_URL
160 manifest_versions_path = options.manifest_versions_int
Don Garrett903fedc2018-11-02 17:04:26 -0700161
Alex Klein1699fab2022-09-08 08:46:06 -0600162 # Resolve buildspecs against a current manifest versions value.
163 manifest_version.RefreshManifestCheckout(
164 manifest_versions_path, manifest_versions_url
165 )
Don Garrett903fedc2018-11-02 17:04:26 -0700166
Alex Klein1699fab2022-09-08 08:46:06 -0600167 return manifest_versions_path
Don Garrett903fedc2018-11-02 17:04:26 -0700168
169
170def ResolveLocalManifestPath(options):
Alex Klein1699fab2022-09-08 08:46:06 -0600171 """Based on command line options, decide what local manifest file to use.
Don Garrett903fedc2018-11-02 17:04:26 -0700172
Alex Klein1699fab2022-09-08 08:46:06 -0600173 Args:
174 options: Our parsed command line options.
Don Garrett903fedc2018-11-02 17:04:26 -0700175
Alex Klein1699fab2022-09-08 08:46:06 -0600176 Returns:
177 Path to local manifest file to use, or None for no file.
178 """
179 if options.manifest_file:
180 # If the user gives us an explicit local manifest file, use it.
181 return options.manifest_file
Don Garrett903fedc2018-11-02 17:04:26 -0700182
Alex Klein1699fab2022-09-08 08:46:06 -0600183 elif options.buildspec:
184 # Buildspec builds use a manifest file from manifest_versions. We do NOT
185 # use manifest_versions as the manifest git repo, because it's so large that
186 # sync time would be a major performance problem.
187 manifest_versions_path = PrepareManifestVersions(options)
188 return manifest_version.ResolveBuildspec(
189 manifest_versions_path, options.buildspec
190 )
Don Garrett903fedc2018-11-02 17:04:26 -0700191
Alex Klein1699fab2022-09-08 08:46:06 -0600192 elif options.version:
193 # Versions are a short hand version of a buildspec.
194 manifest_versions_path = PrepareManifestVersions(options)
195 return manifest_version.ResolveBuildspecVersion(
196 manifest_versions_path, options.version
197 )
Don Garrett903fedc2018-11-02 17:04:26 -0700198
Alex Klein1699fab2022-09-08 08:46:06 -0600199 elif options.branch:
200 # Branch checkouts use our normal manifest repos, not a local manifest file.
201 return None
Don Garrett903fedc2018-11-02 17:04:26 -0700202
Alex Klein1699fab2022-09-08 08:46:06 -0600203 else:
204 assert False, "No sync options specified. Should not be possible."
Don Garrett903fedc2018-11-02 17:04:26 -0700205
206
Lann Martin10f3ee92018-08-22 15:48:10 -0600207def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600208 parser = GetParser()
209 options = parser.parse_args(argv)
210 options.Freeze()
Lann Martin10f3ee92018-08-22 15:48:10 -0600211
Alex Klein1699fab2022-09-08 08:46:06 -0600212 local_manifest = ResolveLocalManifestPath(options)
Don Garrett903fedc2018-11-02 17:04:26 -0700213
Alex Klein1699fab2022-09-08 08:46:06 -0600214 if local_manifest:
215 logging.info("Using local_manifest: %s", local_manifest)
Don Garrett903fedc2018-11-02 17:04:26 -0700216
Alex Klein1699fab2022-09-08 08:46:06 -0600217 if options.manifest_url:
218 manifest_url = options.manifest_url
219 elif options.external:
220 manifest_url = config_lib.GetSiteParams().MANIFEST_URL
221 else:
222 manifest_url = config_lib.GetSiteParams().MANIFEST_INT_URL
Don Garrett903fedc2018-11-02 17:04:26 -0700223
Alex Klein1699fab2022-09-08 08:46:06 -0600224 osutils.SafeMakedirs(options.repo_root)
225 repo = repository.RepoRepository(
226 manifest_repo_url=manifest_url,
227 directory=options.repo_root,
228 branch=options.branch,
229 git_cache_dir=options.git_cache_dir,
230 repo_url=options.repo_url,
231 groups=options.groups,
232 )
Lann Martin10f3ee92018-08-22 15:48:10 -0600233
Alex Klein1699fab2022-09-08 08:46:06 -0600234 if options.copy_repo:
235 repo.PreLoad(options.copy_repo)
Lann Martin10f3ee92018-08-22 15:48:10 -0600236
Alex Klein1699fab2022-09-08 08:46:06 -0600237 repo.Sync(local_manifest=local_manifest, detach=True)
Don Garrett903fedc2018-11-02 17:04:26 -0700238
Alex Klein1699fab2022-09-08 08:46:06 -0600239 if options.gerrit_patches:
240 patches = gerrit.GetGerritPatchInfo(options.gerrit_patches)
241 # TODO: Extract patches from manifest synced.
Don Garrett115df402018-11-09 14:43:42 -0800242
Alex Klein1699fab2022-09-08 08:46:06 -0600243 helper_pool = patch_series.HelperPool.SimpleCreate(
244 cros_internal=not options.external, cros=True
245 )
Don Garrett115df402018-11-09 14:43:42 -0800246
Alex Klein1699fab2022-09-08 08:46:06 -0600247 series = patch_series.PatchSeries(
248 path=options.repo_root,
249 helper_pool=helper_pool,
250 forced_manifest=None,
251 )
Don Garrett115df402018-11-09 14:43:42 -0800252
Alex Klein1699fab2022-09-08 08:46:06 -0600253 _, failed_tot, failed_inflight = series.Apply(patches)
Don Garrettf3976f92018-12-20 12:46:47 -0800254
Alex Klein1699fab2022-09-08 08:46:06 -0600255 failed = failed_tot + failed_inflight
256 if failed:
257 logging.error(
258 "Failed to apply: %s", ", ".join(str(p) for p in failed)
259 )
260 return 1