blob: dfdd0aac05f7afa0b64d7573294720fa64111e4d [file] [log] [blame]
Lann Martin10f3ee92018-08-22 15:48:10 -06001# -*- coding: utf-8 -*-
2# Copyright 2018 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
Don Garrett903fedc2018-11-02 17:04:26 -07006"""Sync a git repository to a given manifest.
7
8This script is intended to define all of the ways that a source checkout can be
9defined for a Chrome OS builder.
10
11If a sync completes successfully, the checked out code will exactly match
12whatever manifest is defined, and no local git branches will remain. Extraneous
13files not under version management will be ignored.
14
15It is NOT safe to assume that the checkout can be further updated with
16a simple "repo sync", instead you should call this script again with
17the same options.
18"""
Lann Martin10f3ee92018-08-22 15:48:10 -060019
20from __future__ import print_function
21
Don Garrett903fedc2018-11-02 17:04:26 -070022from chromite.cbuildbot import manifest_version
23from 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 cros_logging as logging
26from chromite.lib import config_lib
27from chromite.lib import osutils
Lann Martin10f3ee92018-08-22 15:48:10 -060028
29
30def GetParser():
31 """Creates the argparse parser."""
32 parser = commandline.ArgumentParser(description=__doc__)
Don Garrett903fedc2018-11-02 17:04:26 -070033
Lann Martin10f3ee92018-08-22 15:48:10 -060034 parser.add_argument('--repo-root', type='path', default='.',
35 help='Path to the repo root to sync.')
Don Garrett903fedc2018-11-02 17:04:26 -070036
37 manifest_group = parser.add_argument_group(
38 'Manifest',
39 description='What manifest do we sync?')
40
41 manifest_ex = manifest_group.add_mutually_exclusive_group()
42 manifest_ex.add_argument(
43 '--branch',
44 default='master',
45 help='Sync to top of given branch.')
46 manifest_ex.add_argument(
47 '--buildspec',
48 help='Path to manifest, relative to manifest-versions root.')
49 manifest_ex.add_argument(
50 '--version',
51 help='Shorthand for an official release buildspec. e.g. 9799.0.0')
52 manifest_ex.add_argument(
53 '--manifest-file', type='path',
54 help='Sync to an existing local manifest file.')
55
56 manifest_group.add_argument(
57 '--external', action='store_true', default=False,
58 help='Sync to the external version of a manifest. Switch from '
59 'manifest-versions-internal to manifest-versions for buildspecs. '
60 'Not usable with --manifest.')
61
62 resources_group = parser.add_argument_group(
63 'Resources',
64 description='External resources that might be needed.')
65
66 resources_group.add_argument(
67 '--manifest-versions-int', type='path',
68 help='Directory for internal manifest versions checkout. '
69 'May be refreshed.')
70
71 resources_group.add_argument(
72 '--manifest-versions-ext', type='path',
73 help='Directory for internal manifest versions checkout. '
74 'May be refreshed.')
75
76 optimization_group = parser.add_argument_group(
77 'Optimization',
78 description='Hints provided to possibly speed up initial sync.')
79
80 optimization_group.add_argument(
81 '--copy-repo', type='path',
82 help='Path to an existing repo root. Used to preload the local '
83 "checkout if the local checkout doesn't exist.")
84 optimization_group.add_argument(
85 '--git-cache-dir', type='path',
86 help='Git cache directory to use.')
87
Lann Martin10f3ee92018-08-22 15:48:10 -060088 return parser
89
90
Don Garrett903fedc2018-11-02 17:04:26 -070091def PrepareManifestVersions(options):
92 """Select manifest-versions checkout to use, and update it.
93
94 Looks at command line options to decide which manifest-versions checkout to
95 use, and updates (or creates) it as needed.
96
97 Args:
98 options: Parsed command line options.
99
100 Returns:
101 Full path to manifest-versions directory to use for this sync.
102
103 Raises:
104 AssertionError: If the needed manifest-versions path wasn't con the
105 command line.
106 """
107 site_params = config_lib.GetSiteParams()
108
109 if options.external:
110 assert options.manifest_versions_ext, '--manifest-versions-ext required.'
111 manifest_versions_url = site_params.MANIFEST_VERSIONS_GOB_URL
112 manifest_versions_path = options.manifest_versions_ext
113 else:
114 assert options.manifest_versions_int, '--manifest-versions-int required.'
115 manifest_versions_url = site_params.MANIFEST_VERSIONS_INT_GOB_URL
116 manifest_versions_path = options.manifest_versions_int
117
118 # Resolve buildspecs against a current manifest versions value.
119 manifest_version.RefreshManifestCheckout(
120 manifest_versions_path, manifest_versions_url)
121
122 return manifest_versions_path
123
124
125def ResolveLocalManifestPath(options):
126 """Based on command line options, decide what local manifest file to use.
127
128 Args:
129 options: Our parsed command line options.
130
131 Returns:
132 Path to local manifest file to use, or None for no file.
133 """
134 if options.manifest_file:
135 # If the user gives us an explicit local manifest file, use it.
136 return options.manifest_file
137
138 elif options.buildspec:
139 # Buildspec builds use a manifest file from manifest_versions. We do NOT
140 # use manifest_versions as the manifest git repo, because it's so large that
141 # sync time would be a major performance problem.
142 manifest_versions_path = PrepareManifestVersions(options)
143 return manifest_version.ResolveBuildspec(
144 manifest_versions_path, options.buildspec)
145
146 elif options.version:
147 # Versions are a short hand version of a buildspec.
148 manifest_versions_path = PrepareManifestVersions(options)
149 return manifest_version.ResolveBuildspecVersion(
150 manifest_versions_path, options.version)
151
152 elif options.branch:
153 # Branch checkouts use our normal manifest repos, not a local manifest file.
154 return None
155
156 else:
157 assert False, 'No sync options specified. Should not be possible.'
158
159
Lann Martin10f3ee92018-08-22 15:48:10 -0600160def main(argv):
161 parser = GetParser()
162 options = parser.parse_args(argv)
163 options.Freeze()
164
Don Garrett903fedc2018-11-02 17:04:26 -0700165 local_manifest = ResolveLocalManifestPath(options)
166
167 if local_manifest:
168 logging.info('Using local_manifest: %s', local_manifest)
169
170 if options.external:
171 manifest_url = config_lib.GetSiteParams().MANIFEST_URL
172 else:
173 manifest_url = config_lib.GetSiteParams().MANIFEST_INT_URL
174
175 osutils.SafeMakedirs(options.repo_root)
176 repo = repository.RepoRepository(
177 manifest_repo_url=manifest_url,
178 directory=options.repo_root,
179 branch=options.branch,
180 git_cache_dir=options.git_cache_dir)
Lann Martin10f3ee92018-08-22 15:48:10 -0600181
182 if options.copy_repo:
Don Garrett903fedc2018-11-02 17:04:26 -0700183 repo.PreLoad(options.copy_repo)
Lann Martin10f3ee92018-08-22 15:48:10 -0600184
Don Garrett903fedc2018-11-02 17:04:26 -0700185 if repository.IsARepoRoot(options.repo_root):
186 repo.BuildRootGitCleanup(prune_all=True)
Lann Martin10f3ee92018-08-22 15:48:10 -0600187
Don Garrett903fedc2018-11-02 17:04:26 -0700188 repo.Sync(local_manifest=local_manifest, detach=True)
189
190 # TODO: Cherry-pick in changes.