summaryrefslogtreecommitdiffstats
path: root/subcmds/init.py
diff options
context:
space:
mode:
authorGavin Mak <gavinmak@google.com>2023-03-11 06:46:20 +0000
committerLUCI <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-03-22 17:46:28 +0000
commitea2e330e43c182dc16b0111ebc69ee5a71ee4ce1 (patch)
treedc33ba0e56825b3e007d0589891756724725a465 /subcmds/init.py
parent1604cf255f8c1786a23388db6d5277ac7949a24a (diff)
downloadgit-repo-ea2e330e43c182dc16b0111ebc69ee5a71ee4ce1.tar.gz
Format codebase with black and check formatting in CQ
Apply rules set by https://gerrit-review.googlesource.com/c/git-repo/+/362954/ across the codebase and fix any lingering errors caught by flake8. Also check black formatting in run_tests (and CQ). Bug: b/267675342 Change-Id: I972d77649dac351150dcfeb1cd1ad0ea2efc1956 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/363474 Reviewed-by: Mike Frysinger <vapier@google.com> Tested-by: Gavin Mak <gavinmak@google.com> Commit-Queue: Gavin Mak <gavinmak@google.com>
Diffstat (limited to 'subcmds/init.py')
-rw-r--r--subcmds/init.py544
1 files changed, 302 insertions, 242 deletions
diff --git a/subcmds/init.py b/subcmds/init.py
index 813fa590..b5c2e3b5 100644
--- a/subcmds/init.py
+++ b/subcmds/init.py
@@ -22,13 +22,13 @@ from wrapper import Wrapper
22 22
23 23
24class Init(InteractiveCommand, MirrorSafeCommand): 24class Init(InteractiveCommand, MirrorSafeCommand):
25 COMMON = True 25 COMMON = True
26 MULTI_MANIFEST_SUPPORT = True 26 MULTI_MANIFEST_SUPPORT = True
27 helpSummary = "Initialize a repo client checkout in the current directory" 27 helpSummary = "Initialize a repo client checkout in the current directory"
28 helpUsage = """ 28 helpUsage = """
29%prog [options] [manifest url] 29%prog [options] [manifest url]
30""" 30"""
31 helpDescription = """ 31 helpDescription = """
32The '%prog' command is run once to install and initialize repo. 32The '%prog' command is run once to install and initialize repo.
33The latest repo source code and manifest collection is downloaded 33The latest repo source code and manifest collection is downloaded
34from the server and is installed in the .repo/ directory in the 34from the server and is installed in the .repo/ directory in the
@@ -77,243 +77,303 @@ manifest, a subsequent `repo sync` (or `repo sync -d`) is necessary
77to update the working directory files. 77to update the working directory files.
78""" 78"""
79 79
80 def _CommonOptions(self, p): 80 def _CommonOptions(self, p):
81 """Disable due to re-use of Wrapper().""" 81 """Disable due to re-use of Wrapper()."""
82 82
83 def _Options(self, p, gitc_init=False): 83 def _Options(self, p, gitc_init=False):
84 Wrapper().InitParser(p, gitc_init=gitc_init) 84 Wrapper().InitParser(p, gitc_init=gitc_init)
85 m = p.add_option_group('Multi-manifest') 85 m = p.add_option_group("Multi-manifest")
86 m.add_option('--outer-manifest', action='store_true', default=True, 86 m.add_option(
87 help='operate starting at the outermost manifest') 87 "--outer-manifest",
88 m.add_option('--no-outer-manifest', dest='outer_manifest', 88 action="store_true",
89 action='store_false', help='do not operate on outer manifests') 89 default=True,
90 m.add_option('--this-manifest-only', action='store_true', default=None, 90 help="operate starting at the outermost manifest",
91 help='only operate on this (sub)manifest') 91 )
92 m.add_option('--no-this-manifest-only', '--all-manifests', 92 m.add_option(
93 dest='this_manifest_only', action='store_false', 93 "--no-outer-manifest",
94 help='operate on this manifest and its submanifests') 94 dest="outer_manifest",
95 95 action="store_false",
96 def _RegisteredEnvironmentOptions(self): 96 help="do not operate on outer manifests",
97 return {'REPO_MANIFEST_URL': 'manifest_url', 97 )
98 'REPO_MIRROR_LOCATION': 'reference'} 98 m.add_option(
99 99 "--this-manifest-only",
100 def _SyncManifest(self, opt): 100 action="store_true",
101 """Call manifestProject.Sync with arguments from opt. 101 default=None,
102 102 help="only operate on this (sub)manifest",
103 Args: 103 )
104 opt: options from optparse. 104 m.add_option(
105 """ 105 "--no-this-manifest-only",
106 # Normally this value is set when instantiating the project, but the 106 "--all-manifests",
107 # manifest project is special and is created when instantiating the 107 dest="this_manifest_only",
108 # manifest which happens before we parse options. 108 action="store_false",
109 self.manifest.manifestProject.clone_depth = opt.manifest_depth 109 help="operate on this manifest and its submanifests",
110 if not self.manifest.manifestProject.Sync( 110 )
111 manifest_url=opt.manifest_url, 111
112 manifest_branch=opt.manifest_branch, 112 def _RegisteredEnvironmentOptions(self):
113 standalone_manifest=opt.standalone_manifest, 113 return {
114 groups=opt.groups, 114 "REPO_MANIFEST_URL": "manifest_url",
115 platform=opt.platform, 115 "REPO_MIRROR_LOCATION": "reference",
116 mirror=opt.mirror, 116 }
117 dissociate=opt.dissociate, 117
118 reference=opt.reference, 118 def _SyncManifest(self, opt):
119 worktree=opt.worktree, 119 """Call manifestProject.Sync with arguments from opt.
120 submodules=opt.submodules, 120
121 archive=opt.archive, 121 Args:
122 partial_clone=opt.partial_clone, 122 opt: options from optparse.
123 clone_filter=opt.clone_filter, 123 """
124 partial_clone_exclude=opt.partial_clone_exclude, 124 # Normally this value is set when instantiating the project, but the
125 clone_bundle=opt.clone_bundle, 125 # manifest project is special and is created when instantiating the
126 git_lfs=opt.git_lfs, 126 # manifest which happens before we parse options.
127 use_superproject=opt.use_superproject, 127 self.manifest.manifestProject.clone_depth = opt.manifest_depth
128 verbose=opt.verbose, 128 if not self.manifest.manifestProject.Sync(
129 current_branch_only=opt.current_branch_only, 129 manifest_url=opt.manifest_url,
130 tags=opt.tags, 130 manifest_branch=opt.manifest_branch,
131 depth=opt.depth, 131 standalone_manifest=opt.standalone_manifest,
132 git_event_log=self.git_event_log, 132 groups=opt.groups,
133 manifest_name=opt.manifest_name): 133 platform=opt.platform,
134 sys.exit(1) 134 mirror=opt.mirror,
135 135 dissociate=opt.dissociate,
136 def _Prompt(self, prompt, value): 136 reference=opt.reference,
137 print('%-10s [%s]: ' % (prompt, value), end='', flush=True) 137 worktree=opt.worktree,
138 a = sys.stdin.readline().strip() 138 submodules=opt.submodules,
139 if a == '': 139 archive=opt.archive,
140 return value 140 partial_clone=opt.partial_clone,
141 return a 141 clone_filter=opt.clone_filter,
142 142 partial_clone_exclude=opt.partial_clone_exclude,
143 def _ShouldConfigureUser(self, opt, existing_checkout): 143 clone_bundle=opt.clone_bundle,
144 gc = self.client.globalConfig 144 git_lfs=opt.git_lfs,
145 mp = self.manifest.manifestProject 145 use_superproject=opt.use_superproject,
146 146 verbose=opt.verbose,
147 # If we don't have local settings, get from global. 147 current_branch_only=opt.current_branch_only,
148 if not mp.config.Has('user.name') or not mp.config.Has('user.email'): 148 tags=opt.tags,
149 if not gc.Has('user.name') or not gc.Has('user.email'): 149 depth=opt.depth,
150 return True 150 git_event_log=self.git_event_log,
151 151 manifest_name=opt.manifest_name,
152 mp.config.SetString('user.name', gc.GetString('user.name')) 152 ):
153 mp.config.SetString('user.email', gc.GetString('user.email')) 153 sys.exit(1)
154 154
155 if not opt.quiet and not existing_checkout or opt.verbose: 155 def _Prompt(self, prompt, value):
156 print() 156 print("%-10s [%s]: " % (prompt, value), end="", flush=True)
157 print('Your identity is: %s <%s>' % (mp.config.GetString('user.name'), 157 a = sys.stdin.readline().strip()
158 mp.config.GetString('user.email'))) 158 if a == "":
159 print("If you want to change this, please re-run 'repo init' with --config-name") 159 return value
160 return False 160 return a
161 161
162 def _ConfigureUser(self, opt): 162 def _ShouldConfigureUser(self, opt, existing_checkout):
163 mp = self.manifest.manifestProject 163 gc = self.client.globalConfig
164 164 mp = self.manifest.manifestProject
165 while True: 165
166 if not opt.quiet: 166 # If we don't have local settings, get from global.
167 if not mp.config.Has("user.name") or not mp.config.Has("user.email"):
168 if not gc.Has("user.name") or not gc.Has("user.email"):
169 return True
170
171 mp.config.SetString("user.name", gc.GetString("user.name"))
172 mp.config.SetString("user.email", gc.GetString("user.email"))
173
174 if not opt.quiet and not existing_checkout or opt.verbose:
175 print()
176 print(
177 "Your identity is: %s <%s>"
178 % (
179 mp.config.GetString("user.name"),
180 mp.config.GetString("user.email"),
181 )
182 )
183 print(
184 "If you want to change this, please re-run 'repo init' with "
185 "--config-name"
186 )
187 return False
188
189 def _ConfigureUser(self, opt):
190 mp = self.manifest.manifestProject
191
192 while True:
193 if not opt.quiet:
194 print()
195 name = self._Prompt("Your Name", mp.UserName)
196 email = self._Prompt("Your Email", mp.UserEmail)
197
198 if not opt.quiet:
199 print()
200 print("Your identity is: %s <%s>" % (name, email))
201 print("is this correct [y/N]? ", end="", flush=True)
202 a = sys.stdin.readline().strip().lower()
203 if a in ("yes", "y", "t", "true"):
204 break
205
206 if name != mp.UserName:
207 mp.config.SetString("user.name", name)
208 if email != mp.UserEmail:
209 mp.config.SetString("user.email", email)
210
211 def _HasColorSet(self, gc):
212 for n in ["ui", "diff", "status"]:
213 if gc.Has("color.%s" % n):
214 return True
215 return False
216
217 def _ConfigureColor(self):
218 gc = self.client.globalConfig
219 if self._HasColorSet(gc):
220 return
221
222 class _Test(Coloring):
223 def __init__(self):
224 Coloring.__init__(self, gc, "test color display")
225 self._on = True
226
227 out = _Test()
228
167 print() 229 print()
168 name = self._Prompt('Your Name', mp.UserName) 230 print("Testing colorized output (for 'repo diff', 'repo status'):")
169 email = self._Prompt('Your Email', mp.UserEmail) 231
232 for c in ["black", "red", "green", "yellow", "blue", "magenta", "cyan"]:
233 out.write(" ")
234 out.printer(fg=c)(" %-6s ", c)
235 out.write(" ")
236 out.printer(fg="white", bg="black")(" %s " % "white")
237 out.nl()
238
239 for c in ["bold", "dim", "ul", "reverse"]:
240 out.write(" ")
241 out.printer(fg="black", attr=c)(" %-6s ", c)
242 out.nl()
243
244 print(
245 "Enable color display in this user account (y/N)? ",
246 end="",
247 flush=True,
248 )
249 a = sys.stdin.readline().strip().lower()
250 if a in ("y", "yes", "t", "true", "on"):
251 gc.SetString("color.ui", "auto")
252
253 def _DisplayResult(self):
254 if self.manifest.IsMirror:
255 init_type = "mirror "
256 else:
257 init_type = ""
170 258
171 if not opt.quiet:
172 print() 259 print()
173 print('Your identity is: %s <%s>' % (name, email)) 260 print(
174 print('is this correct [y/N]? ', end='', flush=True) 261 "repo %shas been initialized in %s"
175 a = sys.stdin.readline().strip().lower() 262 % (init_type, self.manifest.topdir)
176 if a in ('yes', 'y', 't', 'true'): 263 )
177 break 264
178 265 current_dir = os.getcwd()
179 if name != mp.UserName: 266 if current_dir != self.manifest.topdir:
180 mp.config.SetString('user.name', name) 267 print(
181 if email != mp.UserEmail: 268 "If this is not the directory in which you want to initialize "
182 mp.config.SetString('user.email', email) 269 "repo, please run:"
183 270 )
184 def _HasColorSet(self, gc): 271 print(" rm -r %s" % os.path.join(self.manifest.topdir, ".repo"))
185 for n in ['ui', 'diff', 'status']: 272 print("and try again.")
186 if gc.Has('color.%s' % n): 273
187 return True 274 def ValidateOptions(self, opt, args):
188 return False 275 if opt.reference:
189 276 opt.reference = os.path.expanduser(opt.reference)
190 def _ConfigureColor(self): 277
191 gc = self.client.globalConfig 278 # Check this here, else manifest will be tagged "not new" and init won't
192 if self._HasColorSet(gc): 279 # be possible anymore without removing the .repo/manifests directory.
193 return 280 if opt.mirror:
194 281 if opt.archive:
195 class _Test(Coloring): 282 self.OptionParser.error(
196 def __init__(self): 283 "--mirror and --archive cannot be used " "together."
197 Coloring.__init__(self, gc, 'test color display') 284 )
198 self._on = True 285 if opt.use_superproject is not None:
199 out = _Test() 286 self.OptionParser.error(
200 287 "--mirror and --use-superproject cannot be "
201 print() 288 "used together."
202 print("Testing colorized output (for 'repo diff', 'repo status'):") 289 )
203 290 if opt.archive and opt.use_superproject is not None:
204 for c in ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan']: 291 self.OptionParser.error(
205 out.write(' ') 292 "--archive and --use-superproject cannot be used " "together."
206 out.printer(fg=c)(' %-6s ', c) 293 )
207 out.write(' ') 294
208 out.printer(fg='white', bg='black')(' %s ' % 'white') 295 if opt.standalone_manifest and (
209 out.nl() 296 opt.manifest_branch or opt.manifest_name != "default.xml"
210 297 ):
211 for c in ['bold', 'dim', 'ul', 'reverse']: 298 self.OptionParser.error(
212 out.write(' ') 299 "--manifest-branch and --manifest-name cannot"
213 out.printer(fg='black', attr=c)(' %-6s ', c) 300 " be used with --standalone-manifest."
214 out.nl() 301 )
215 302
216 print('Enable color display in this user account (y/N)? ', end='', flush=True) 303 if args:
217 a = sys.stdin.readline().strip().lower() 304 if opt.manifest_url:
218 if a in ('y', 'yes', 't', 'true', 'on'): 305 self.OptionParser.error(
219 gc.SetString('color.ui', 'auto') 306 "--manifest-url option and URL argument both specified: "
220 307 "only use one to select the manifest URL."
221 def _DisplayResult(self): 308 )
222 if self.manifest.IsMirror: 309
223 init_type = 'mirror ' 310 opt.manifest_url = args.pop(0)
224 else: 311
225 init_type = '' 312 if args:
226 313 self.OptionParser.error("too many arguments to init")
227 print() 314
228 print('repo %shas been initialized in %s' % (init_type, self.manifest.topdir)) 315 def Execute(self, opt, args):
229 316 git_require(MIN_GIT_VERSION_HARD, fail=True)
230 current_dir = os.getcwd() 317 if not git_require(MIN_GIT_VERSION_SOFT):
231 if current_dir != self.manifest.topdir: 318 print(
232 print('If this is not the directory in which you want to initialize ' 319 "repo: warning: git-%s+ will soon be required; please upgrade "
233 'repo, please run:') 320 "your version of git to maintain support."
234 print(' rm -r %s' % os.path.join(self.manifest.topdir, '.repo')) 321 % (".".join(str(x) for x in MIN_GIT_VERSION_SOFT),),
235 print('and try again.') 322 file=sys.stderr,
236 323 )
237 def ValidateOptions(self, opt, args): 324
238 if opt.reference: 325 rp = self.manifest.repoProject
239 opt.reference = os.path.expanduser(opt.reference) 326
240 327 # Handle new --repo-url requests.
241 # Check this here, else manifest will be tagged "not new" and init won't be 328 if opt.repo_url:
242 # possible anymore without removing the .repo/manifests directory. 329 remote = rp.GetRemote("origin")
243 if opt.mirror: 330 remote.url = opt.repo_url
244 if opt.archive: 331 remote.Save()
245 self.OptionParser.error('--mirror and --archive cannot be used ' 332
246 'together.') 333 # Handle new --repo-rev requests.
247 if opt.use_superproject is not None: 334 if opt.repo_rev:
248 self.OptionParser.error('--mirror and --use-superproject cannot be ' 335 wrapper = Wrapper()
249 'used together.') 336 try:
250 if opt.archive and opt.use_superproject is not None: 337 remote_ref, rev = wrapper.check_repo_rev(
251 self.OptionParser.error('--archive and --use-superproject cannot be used ' 338 rp.gitdir,
252 'together.') 339 opt.repo_rev,
253 340 repo_verify=opt.repo_verify,
254 if opt.standalone_manifest and (opt.manifest_branch or 341 quiet=opt.quiet,
255 opt.manifest_name != 'default.xml'): 342 )
256 self.OptionParser.error('--manifest-branch and --manifest-name cannot' 343 except wrapper.CloneFailure:
257 ' be used with --standalone-manifest.') 344 print(
258 345 "fatal: double check your --repo-rev setting.",
259 if args: 346 file=sys.stderr,
260 if opt.manifest_url: 347 )
261 self.OptionParser.error( 348 sys.exit(1)
262 '--manifest-url option and URL argument both specified: only use ' 349 branch = rp.GetBranch("default")
263 'one to select the manifest URL.') 350 branch.merge = remote_ref
264 351 rp.work_git.reset("--hard", rev)
265 opt.manifest_url = args.pop(0) 352 branch.Save()
266 353
267 if args: 354 if opt.worktree:
268 self.OptionParser.error('too many arguments to init') 355 # Older versions of git supported worktree, but had dangerous gc
269 356 # bugs.
270 def Execute(self, opt, args): 357 git_require((2, 15, 0), fail=True, msg="git gc worktree corruption")
271 git_require(MIN_GIT_VERSION_HARD, fail=True) 358
272 if not git_require(MIN_GIT_VERSION_SOFT): 359 # Provide a short notice that we're reinitializing an existing checkout.
273 print('repo: warning: git-%s+ will soon be required; please upgrade your ' 360 # Sometimes developers might not realize that they're in one, or that
274 'version of git to maintain support.' 361 # repo doesn't do nested checkouts.
275 % ('.'.join(str(x) for x in MIN_GIT_VERSION_SOFT),), 362 existing_checkout = self.manifest.manifestProject.Exists
276 file=sys.stderr) 363 if not opt.quiet and existing_checkout:
277 364 print(
278 rp = self.manifest.repoProject 365 "repo: reusing existing repo client checkout in",
279 366 self.manifest.topdir,
280 # Handle new --repo-url requests. 367 )
281 if opt.repo_url: 368
282 remote = rp.GetRemote('origin') 369 self._SyncManifest(opt)
283 remote.url = opt.repo_url 370
284 remote.Save() 371 if os.isatty(0) and os.isatty(1) and not self.manifest.IsMirror:
285 372 if opt.config_name or self._ShouldConfigureUser(
286 # Handle new --repo-rev requests. 373 opt, existing_checkout
287 if opt.repo_rev: 374 ):
288 wrapper = Wrapper() 375 self._ConfigureUser(opt)
289 try: 376 self._ConfigureColor()
290 remote_ref, rev = wrapper.check_repo_rev( 377
291 rp.gitdir, opt.repo_rev, repo_verify=opt.repo_verify, quiet=opt.quiet) 378 if not opt.quiet:
292 except wrapper.CloneFailure: 379 self._DisplayResult()
293 print('fatal: double check your --repo-rev setting.', file=sys.stderr)
294 sys.exit(1)
295 branch = rp.GetBranch('default')
296 branch.merge = remote_ref
297 rp.work_git.reset('--hard', rev)
298 branch.Save()
299
300 if opt.worktree:
301 # Older versions of git supported worktree, but had dangerous gc bugs.
302 git_require((2, 15, 0), fail=True, msg='git gc worktree corruption')
303
304 # Provide a short notice that we're reinitializing an existing checkout.
305 # Sometimes developers might not realize that they're in one, or that
306 # repo doesn't do nested checkouts.
307 existing_checkout = self.manifest.manifestProject.Exists
308 if not opt.quiet and existing_checkout:
309 print('repo: reusing existing repo client checkout in', self.manifest.topdir)
310
311 self._SyncManifest(opt)
312
313 if os.isatty(0) and os.isatty(1) and not self.manifest.IsMirror:
314 if opt.config_name or self._ShouldConfigureUser(opt, existing_checkout):
315 self._ConfigureUser(opt)
316 self._ConfigureColor()
317
318 if not opt.quiet:
319 self._DisplayResult()