blob: 649c4e480249d4c7988ab7823a2ed094aa9131de [file] [log] [blame]
David Pursehouse8898e2f2012-11-14 07:51:03 +09001#!/usr/bin/env python
Mike Frysingerf6013762019-06-13 02:30:51 -04002# -*- coding:utf-8 -*-
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -07003
Mike Frysinger87fb5a12019-06-13 01:54:46 -04004"""Repo launcher.
5
6This is a standalone tool that people may copy to anywhere in their system.
7It is used to get an initial repo client checkout, and after that it runs the
8copy of repo in the checkout.
9"""
10
Mike Frysingerc92ce5c2019-06-13 01:14:23 -040011from __future__ import print_function
12
Mark E. Hamilton4088eb42016-02-10 10:44:30 -070013# repo default configuration
14#
Mark E. Hamilton55536282016-02-03 15:49:43 -070015import os
16REPO_URL = os.environ.get('REPO_URL', None)
17if not REPO_URL:
18 REPO_URL = 'https://gerrit.googlesource.com/git-repo'
David Pursehouse8f62fb72012-11-14 12:09:38 +090019REPO_REV = 'stable'
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070020
21# Copyright (C) 2008 Google Inc.
22#
23# Licensed under the Apache License, Version 2.0 (the "License");
24# you may not use this file except in compliance with the License.
25# You may obtain a copy of the License at
26#
27# http://www.apache.org/licenses/LICENSE-2.0
28#
29# Unless required by applicable law or agreed to in writing, software
30# distributed under the License is distributed on an "AS IS" BASIS,
31# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32# See the License for the specific language governing permissions and
33# limitations under the License.
34
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070035# increment this whenever we make important changes to this script
Ereth McKnight-MacNeil12ee5442018-12-19 21:28:35 -080036VERSION = (1, 25)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070037
38# increment this if the MAINTAINER_KEYS block is modified
Conley Owensbc030842013-07-01 11:05:32 -070039KEYRING_VERSION = (1, 2)
Mike Frysingere4433652016-09-13 18:06:07 -040040
41# Each individual key entry is created by using:
42# gpg --armor --export keyid
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070043MAINTAINER_KEYS = """
44
45 Repo Maintainer <repo@android.kernel.org>
46-----BEGIN PGP PUBLIC KEY BLOCK-----
47Version: GnuPG v1.4.2.2 (GNU/Linux)
48
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
84=CMiZ
85-----END PGP PUBLIC KEY BLOCK-----
Conley Owens55e4d462012-10-01 16:12:28 -070086
87 Conley Owens <cco3@android.com>
88-----BEGIN PGP PUBLIC KEY BLOCK-----
89Version: GnuPG v1.4.11 (GNU/Linux)
90
Conley Owensbc030842013-07-01 11:05:32 -070091mQENBFHRvc8BCADFg45Xx/y6QDC+T7Y/gGc7vx0ww7qfOwIKlAZ9xG3qKunMxo+S
92hPCnzEl3cq+6I1Ww/ndop/HB3N3toPXRCoN8Vs4/Hc7by+SnaLFnacrm+tV5/OgT
93V37Lzt8lhay1Kl+YfpFwHYYpIEBLFV9knyfRXS/428W2qhdzYfvB15/AasRmwmor
94py4NIzSs8UD/SPr1ihqNCdZM76+MQyN5HMYXW/ALZXUFG0pwluHFA7hrfPG74i8C
95zMiP7qvMWIl/r/jtzHioH1dRKgbod+LZsrDJ8mBaqsZaDmNJMhss9g76XvfMyLra
969DI9/iFuBpGzeqBv0hwOGQspLRrEoyTeR6n1ABEBAAG0H0NvbmxleSBPd2VucyA8
97Y2NvM0BhbmRyb2lkLmNvbT6JATgEEwECACIFAlHRvc8CGwMGCwkIBwMCBhUIAgkK
98CwQWAgMBAh4BAheAAAoJEGe35EhpKzgsP6AIAJKJmNtn4l7hkYHKHFSo3egb6RjQ
99zEIP3MFTcu8HFX1kF1ZFbrp7xqurLaE53kEkKuAAvjJDAgI8mcZHP1JyplubqjQA
100xvv84gK+OGP3Xk+QK1ZjUQSbjOpjEiSZpRhWcHci3dgOUH4blJfByHw25hlgHowd
101a/2PrNKZVcJ92YienaxxGjcXEUcd0uYEG2+rwllQigFcnMFDhr9B71MfalRHjFKE
102fmdoypqLrri61YBc59P88Rw2/WUpTQjgNubSqa3A2+CKdaRyaRw+2fdF4TdR0h8W
103zbg+lbaPtJHsV+3mJC7fq26MiJDRJa5ZztpMn8su20gbLgi2ShBOaHAYDDi5AQ0E
104UdG9zwEIAMoOBq+QLNozAhxOOl5GL3StTStGRgPRXINfmViTsihrqGCWBBUfXlUE
105OytC0mYcrDUQev/8ToVoyqw+iGSwDkcSXkrEUCKFtHV/GECWtk1keyHgR10YKI1R
106mquSXoubWGqPeG1PAI74XWaRx8UrL8uCXUtmD8Q5J7mDjKR5NpxaXrwlA0bKsf2E
107Gp9tu1kKauuToZhWHMRMqYSOGikQJwWSFYKT1KdNcOXLQF6+bfoJ6sjVYdwfmNQL
108Ixn8QVhoTDedcqClSWB17VDEFDFa7MmqXZz2qtM3X1R/MUMHqPtegQzBGNhRdnI2
109V45+1Nnx/uuCxDbeI4RbHzujnxDiq70AEQEAAYkBHwQYAQIACQUCUdG9zwIbDAAK
110CRBnt+RIaSs4LNVeB/0Y2pZ8I7gAAcEM0Xw8drr4omg2fUoK1J33ozlA/RxeA/lJ
111I3KnyCDTpXuIeBKPGkdL8uMATC9Z8DnBBajRlftNDVZS3Hz4G09G9QpMojvJkFJV
112By+01Flw/X+eeN8NpqSuLV4W+AjEO8at/VvgKr1AFvBRdZ7GkpI1o6DgPe7ZqX+1
113dzQZt3e13W0rVBb/bUgx9iSLoeWP3aq/k+/GRGOR+S6F6BBSl0SQ2EF2+dIywb1x
114JuinEP+AwLAUZ1Bsx9ISC0Agpk2VeHXPL3FGhroEmoMvBzO0kTFGyoeT7PR/BfKv
115+H/g3HsL2LOB9uoIm8/5p2TTU5ttYCXMHhQZ81AY
116=AUp4
Conley Owens55e4d462012-10-01 16:12:28 -0700117-----END PGP PUBLIC KEY BLOCK-----
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700118"""
119
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700120GIT = 'git' # our git command
121MIN_GIT_VERSION = (1, 7, 2) # minimum supported git version
122repodir = '.repo' # name of repo's private directory
123S_repo = 'repo' # special repo repository
124S_manifests = 'manifests' # special manifest repository
125REPO_MAIN = S_repo + '/main.py' # main script
Eli Ribbled4b13c22018-12-18 21:21:12 -0800126MIN_PYTHON_VERSION = (2, 7) # minimum supported python version
Simran Basi8ce50412015-08-28 14:25:44 -0700127GITC_CONFIG_FILE = '/gitc/.config'
Dan Willemsen745b4ad2015-10-06 15:23:19 -0700128GITC_FS_ROOT_DIR = '/gitc/manifest-rw/'
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700129
130
Mike Frysinger6db1b9e2019-07-10 15:32:36 -0400131import collections
David Jamesbf79c662013-12-26 14:20:13 -0800132import errno
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700133import optparse
Renaud Paquay35d22212016-11-01 11:24:52 -0700134import platform
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700135import re
Mitchel Humpheryseb5acc92014-03-12 10:48:15 -0700136import shutil
Sarah Owens60798a32012-10-25 17:53:09 -0700137import stat
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700138import subprocess
139import sys
David Pursehouse59bbb582013-05-17 10:49:33 +0900140
141if sys.version_info[0] == 3:
Sarah Owens1f7627f2012-10-31 09:21:55 -0700142 import urllib.request
143 import urllib.error
144else:
Sarah Owens1f7627f2012-10-31 09:21:55 -0700145 import imp
David Pursehouse59bbb582013-05-17 10:49:33 +0900146 import urllib2
Sarah Owens1f7627f2012-10-31 09:21:55 -0700147 urllib = imp.new_module('urllib')
148 urllib.request = urllib2
149 urllib.error = urllib2
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700150
Conley Owens5e0ee142013-09-26 15:50:49 -0700151
Chirayu Desai51813df2013-04-16 19:36:09 +0530152# Python version check
153ver = sys.version_info
Chirayu Desai51813df2013-04-16 19:36:09 +0530154if (ver[0], ver[1]) < MIN_PYTHON_VERSION:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400155 print('error: Python version {} unsupported.\n'
156 'Please use Python {}.{} instead.'.format(
157 sys.version.split(' ')[0],
158 MIN_PYTHON_VERSION[0],
159 MIN_PYTHON_VERSION[1],
160 ), file=sys.stderr)
Chirayu Desai51813df2013-04-16 19:36:09 +0530161 sys.exit(1)
162
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700163home_dot_repo = os.path.expanduser('~/.repoconfig')
164gpg_dir = os.path.join(home_dot_repo, 'gnupg')
165
166extra_args = []
167init_optparse = optparse.OptionParser(usage="repo init -u url [options]")
168
169# Logging
170group = init_optparse.add_option_group('Logging options')
171group.add_option('-q', '--quiet',
172 dest="quiet", action="store_true", default=False,
173 help="be quiet")
174
175# Manifest
176group = init_optparse.add_option_group('Manifest options')
177group.add_option('-u', '--manifest-url',
178 dest='manifest_url',
179 help='manifest repository location', metavar='URL')
180group.add_option('-b', '--manifest-branch',
181 dest='manifest_branch',
182 help='manifest branch or revision', metavar='REVISION')
183group.add_option('-m', '--manifest-name',
184 dest='manifest_name',
185 help='initial manifest file', metavar='NAME.xml')
Ereth McKnight-MacNeil12ee5442018-12-19 21:28:35 -0800186group.add_option('--current-branch',
Naseer Ahmedf4dda9a2016-12-01 18:49:54 -0500187 dest='current_branch_only', action='store_true',
188 help='fetch only current manifest branch from server')
Shawn O. Pearcee284ad12008-11-04 07:37:10 -0800189group.add_option('--mirror',
190 dest='mirror', action='store_true',
David Pursehouse3794a782012-11-15 06:17:30 +0900191 help='create a replica of the remote repositories '
192 'rather than a client working directory')
Shawn O. Pearce88443382010-10-08 10:02:09 +0200193group.add_option('--reference',
194 dest='reference',
195 help='location of mirror directory', metavar='DIR')
Nikolai Merinov09f0abb2018-10-19 15:07:05 +0500196group.add_option('--dissociate',
197 dest='dissociate', action='store_true',
198 help='dissociate from reference mirrors after clone')
Doug Anderson49cd59b2011-06-13 21:42:06 -0700199group.add_option('--depth', type='int', default=None,
200 dest='depth',
201 help='create a shallow clone with given depth; see git clone')
Xin Li745be2e2019-06-03 11:24:30 -0700202group.add_option('--partial-clone', action='store_true',
203 dest='partial_clone',
204 help='perform partial clone (https://git-scm.com/'
205 'docs/gitrepository-layout#_code_partialclone_code)')
206group.add_option('--clone-filter', action='store', default='blob:none',
207 dest='clone_filter',
208 help='filter for use with --partial-clone [default: %default]')
Julien Campergue335f5ef2013-10-16 11:02:35 +0200209group.add_option('--archive',
210 dest='archive', action='store_true',
211 help='checkout an archive instead of a git repository for '
212 'each project. See git archive.')
Martin Kellye4e94d22017-03-21 16:05:12 -0700213group.add_option('--submodules',
214 dest='submodules', action='store_true',
215 help='sync any submodules associated with the manifest repo')
Colin Cross5acde752012-03-28 20:15:45 -0700216group.add_option('-g', '--groups',
Conley Owens971de8e2012-04-16 10:36:08 -0700217 dest='groups', default='default',
David Holmer0a1c6a12012-11-14 19:19:00 -0500218 help='restrict manifest projects to ones with specified '
219 'group(s) [default|all|G1,G2,G3|G4,-G5,-G6]',
Colin Cross5acde752012-03-28 20:15:45 -0700220 metavar='GROUP')
Conley Owensd21720d2012-04-16 11:02:21 -0700221group.add_option('-p', '--platform',
222 dest='platform', default="auto",
Conley Owensc9129d92012-10-01 16:12:28 -0700223 help='restrict manifest projects to ones with a specified '
Conley Owensd21720d2012-04-16 11:02:21 -0700224 'platform group [auto|all|none|linux|darwin|...]',
225 metavar='PLATFORM')
Hu xiuyun9711a982015-12-11 11:16:41 +0800226group.add_option('--no-clone-bundle',
227 dest='no_clone_bundle', action='store_true',
228 help='disable use of /clone.bundle on HTTP/HTTPS')
Naseer Ahmedf4dda9a2016-12-01 18:49:54 -0500229group.add_option('--no-tags',
230 dest='no_tags', action='store_true',
231 help="don't fetch tags in the manifest")
Doug Anderson49cd59b2011-06-13 21:42:06 -0700232
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700233
234# Tool
Shawn O. Pearcefd89b672009-04-18 11:28:57 -0700235group = init_optparse.add_option_group('repo Version options')
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700236group.add_option('--repo-url',
237 dest='repo_url',
238 help='repo repository location', metavar='URL')
239group.add_option('--repo-branch',
240 dest='repo_branch',
241 help='repo branch or revision', metavar='REVISION')
242group.add_option('--no-repo-verify',
243 dest='no_repo_verify', action='store_true',
244 help='do not verify repo source code')
245
Victor Boivie841be342011-04-05 11:31:10 +0200246# Other
247group = init_optparse.add_option_group('Other options')
248group.add_option('--config-name',
249 dest='config_name', action="store_true", default=False,
250 help='Always prompt for name/e-mail')
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700251
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700252
253def _GitcInitOptions(init_optparse_arg):
254 init_optparse_arg.set_usage("repo gitc-init -u url -c client [options]")
255 g = init_optparse_arg.add_option_group('GITC options')
Simran Basi1efc2b42015-08-05 15:04:22 -0700256 g.add_option('-f', '--manifest-file',
257 dest='manifest_file',
258 help='Optional manifest file to use for this GITC client.')
259 g.add_option('-c', '--gitc-client',
260 dest='gitc_client',
Dan Willemsen745b4ad2015-10-06 15:23:19 -0700261 help='The name of the gitc_client instance to create or modify.')
Simran Basi1efc2b42015-08-05 15:04:22 -0700262
Simran Basi8ce50412015-08-28 14:25:44 -0700263_gitc_manifest_dir = None
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700264
265
Simran Basi8ce50412015-08-28 14:25:44 -0700266def get_gitc_manifest_dir():
267 global _gitc_manifest_dir
268 if _gitc_manifest_dir is None:
Dan Willemsen2487cb72015-08-31 15:45:06 -0700269 _gitc_manifest_dir = ''
Simran Basi8ce50412015-08-28 14:25:44 -0700270 try:
271 with open(GITC_CONFIG_FILE, 'r') as gitc_config:
272 for line in gitc_config:
273 match = re.match('gitc_dir=(?P<gitc_manifest_dir>.*)', line)
274 if match:
275 _gitc_manifest_dir = match.group('gitc_manifest_dir')
276 except IOError:
Dan Willemsen2487cb72015-08-31 15:45:06 -0700277 pass
Simran Basi8ce50412015-08-28 14:25:44 -0700278 return _gitc_manifest_dir
279
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700280
Dan Willemsen745b4ad2015-10-06 15:23:19 -0700281def gitc_parse_clientdir(gitc_fs_path):
282 """Parse a path in the GITC FS and return its client name.
283
284 @param gitc_fs_path: A subdirectory path within the GITC_FS_ROOT_DIR.
285
286 @returns: The GITC client name
287 """
288 if gitc_fs_path == GITC_FS_ROOT_DIR:
289 return None
290 if not gitc_fs_path.startswith(GITC_FS_ROOT_DIR):
291 manifest_dir = get_gitc_manifest_dir()
292 if manifest_dir == '':
293 return None
294 if manifest_dir[-1] != '/':
295 manifest_dir += '/'
296 if gitc_fs_path == manifest_dir:
297 return None
298 if not gitc_fs_path.startswith(manifest_dir):
299 return None
300 return gitc_fs_path.split(manifest_dir)[1].split('/')[0]
301 return gitc_fs_path.split(GITC_FS_ROOT_DIR)[1].split('/')[0]
302
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700303
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700304class CloneFailure(Exception):
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700305
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700306 """Indicate the remote clone of repo itself failed.
307 """
308
309
Simran Basi1efc2b42015-08-05 15:04:22 -0700310def _Init(args, gitc_init=False):
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700311 """Installs repo by cloning it over the network.
312 """
Simran Basi1efc2b42015-08-05 15:04:22 -0700313 if gitc_init:
314 _GitcInitOptions(init_optparse)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700315 opt, args = init_optparse.parse_args(args)
Xiaodong Xuae0a36c2012-01-31 11:10:09 +0800316 if args:
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700317 init_optparse.print_usage()
318 sys.exit(1)
319
320 url = opt.repo_url
321 if not url:
322 url = REPO_URL
323 extra_args.append('--repo-url=%s' % url)
324
325 branch = opt.repo_branch
326 if not branch:
327 branch = REPO_REV
328 extra_args.append('--repo-branch=%s' % branch)
329
330 if branch.startswith('refs/heads/'):
331 branch = branch[len('refs/heads/'):]
332 if branch.startswith('refs/'):
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400333 print("fatal: invalid branch name '%s'" % branch, file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700334 raise CloneFailure()
335
David Jamesbf79c662013-12-26 14:20:13 -0800336 try:
Simran Basi1efc2b42015-08-05 15:04:22 -0700337 if gitc_init:
Simran Basi8ce50412015-08-28 14:25:44 -0700338 gitc_manifest_dir = get_gitc_manifest_dir()
339 if not gitc_manifest_dir:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400340 print('fatal: GITC filesystem is not available. Exiting...',
341 file=sys.stderr)
Simran Basi8ce50412015-08-28 14:25:44 -0700342 sys.exit(1)
Dan Willemsen745b4ad2015-10-06 15:23:19 -0700343 gitc_client = opt.gitc_client
344 if not gitc_client:
345 gitc_client = gitc_parse_clientdir(os.getcwd())
346 if not gitc_client:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400347 print('fatal: GITC client (-c) is required.', file=sys.stderr)
Dan Willemsen9ff2ece2015-08-31 15:45:06 -0700348 sys.exit(1)
Dan Willemsen745b4ad2015-10-06 15:23:19 -0700349 client_dir = os.path.join(gitc_manifest_dir, gitc_client)
Simran Basi1efc2b42015-08-05 15:04:22 -0700350 if not os.path.exists(client_dir):
351 os.makedirs(client_dir)
352 os.chdir(client_dir)
353 if os.path.exists(repodir):
354 # This GITC Client has already initialized repo so continue.
355 return
356
David Jamesbf79c662013-12-26 14:20:13 -0800357 os.mkdir(repodir)
358 except OSError as e:
359 if e.errno != errno.EEXIST:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400360 print('fatal: cannot make %s directory: %s'
361 % (repodir, e.strerror), file=sys.stderr)
David Pursehouse3794a782012-11-15 06:17:30 +0900362 # Don't raise CloneFailure; that would delete the
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700363 # name. Instead exit immediately.
364 #
365 sys.exit(1)
366
367 _CheckGitVersion()
368 try:
Conley Owensc9129d92012-10-01 16:12:28 -0700369 if NeedSetupGnuPG():
370 can_verify = SetupGnuPG(opt.quiet)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700371 else:
372 can_verify = True
373
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700374 dst = os.path.abspath(os.path.join(repodir, S_repo))
Hu xiuyun9711a982015-12-11 11:16:41 +0800375 _Clone(url, dst, opt.quiet, not opt.no_clone_bundle)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700376
377 if can_verify and not opt.no_repo_verify:
378 rev = _Verify(dst, branch, opt.quiet)
379 else:
380 rev = 'refs/remotes/origin/%s^0' % branch
381
382 _Checkout(dst, branch, rev, opt.quiet)
Sebastian Schuberth993dcac2018-07-13 10:25:52 +0200383
384 if not os.path.isfile(os.path.join(dst, 'repo')):
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400385 print("warning: '%s' does not look like a git-repo repository, is "
386 "REPO_URL set correctly?" % url, file=sys.stderr)
Sebastian Schuberth993dcac2018-07-13 10:25:52 +0200387
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700388 except CloneFailure:
389 if opt.quiet:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400390 print('fatal: repo init failed; run without --quiet to see why',
391 file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700392 raise
393
394
Mike Frysinger6db1b9e2019-07-10 15:32:36 -0400395# The git version info broken down into components for easy analysis.
396# Similar to Python's sys.version_info.
397GitVersion = collections.namedtuple(
398 'GitVersion', ('major', 'minor', 'micro', 'full'))
399
Mike Frysingerf88b2fe2019-07-10 15:37:43 -0400400def ParseGitVersion(ver_str=None):
401 if ver_str is None:
402 # Load the version ourselves.
403 ver_str = _GetGitVersion()
404
Conley Owensff0a3c82014-01-30 14:46:03 -0800405 if not ver_str.startswith('git version '):
406 return None
407
Mike Frysinger6db1b9e2019-07-10 15:32:36 -0400408 full_version = ver_str[len('git version '):].strip()
409 num_ver_str = full_version.split('-')[0]
Conley Owensff0a3c82014-01-30 14:46:03 -0800410 to_tuple = []
411 for num_str in num_ver_str.split('.')[:3]:
412 if num_str.isdigit():
413 to_tuple.append(int(num_str))
414 else:
415 to_tuple.append(0)
Mike Frysinger6db1b9e2019-07-10 15:32:36 -0400416 to_tuple.append(full_version)
417 return GitVersion(*to_tuple)
Conley Owensff0a3c82014-01-30 14:46:03 -0800418
419
Mike Frysingerf88b2fe2019-07-10 15:37:43 -0400420def _GetGitVersion():
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700421 cmd = [GIT, '--version']
Shawn O. Pearce4fd38ec2012-06-05 07:55:07 -0700422 try:
423 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
Sarah Owensa5be53f2012-09-09 15:37:57 -0700424 except OSError as e:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400425 print(file=sys.stderr)
426 print("fatal: '%s' is not available" % GIT, file=sys.stderr)
427 print('fatal: %s' % e, file=sys.stderr)
428 print(file=sys.stderr)
429 print('Please make sure %s is installed and in your path.' % GIT,
430 file=sys.stderr)
Mike Frysingerf88b2fe2019-07-10 15:37:43 -0400431 raise
Shawn O. Pearce4fd38ec2012-06-05 07:55:07 -0700432
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700433 ver_str = proc.stdout.read().strip()
434 proc.stdout.close()
Shawn O. Pearce16191342008-10-28 08:33:34 -0700435 proc.wait()
Mike Frysingerf88b2fe2019-07-10 15:37:43 -0400436 return ver_str.decode('utf-8')
437
438
439def _CheckGitVersion():
440 try:
441 ver_act = ParseGitVersion()
442 except OSError:
443 raise CloneFailure()
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700444
Conley Owensff0a3c82014-01-30 14:46:03 -0800445 if ver_act is None:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400446 print('error: "%s" unsupported' % ver_str, file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700447 raise CloneFailure()
448
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700449 if ver_act < MIN_GIT_VERSION:
David Pursehouse685f0802012-11-14 08:34:39 +0900450 need = '.'.join(map(str, MIN_GIT_VERSION))
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400451 print('fatal: git %s or later required' % need, file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700452 raise CloneFailure()
453
454
Conley Owensc9129d92012-10-01 16:12:28 -0700455def NeedSetupGnuPG():
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700456 if not os.path.isdir(home_dot_repo):
457 return True
458
459 kv = os.path.join(home_dot_repo, 'keyring-version')
460 if not os.path.exists(kv):
461 return True
462
463 kv = open(kv).read()
464 if not kv:
465 return True
466
David Pursehouse685f0802012-11-14 08:34:39 +0900467 kv = tuple(map(int, kv.split('.')))
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700468 if kv < KEYRING_VERSION:
469 return True
470 return False
471
472
Conley Owensc9129d92012-10-01 16:12:28 -0700473def SetupGnuPG(quiet):
David Jamesbf79c662013-12-26 14:20:13 -0800474 try:
475 os.mkdir(home_dot_repo)
476 except OSError as e:
477 if e.errno != errno.EEXIST:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400478 print('fatal: cannot make %s directory: %s'
479 % (home_dot_repo, e.strerror), file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700480 sys.exit(1)
481
David Jamesbf79c662013-12-26 14:20:13 -0800482 try:
483 os.mkdir(gpg_dir, stat.S_IRWXU)
484 except OSError as e:
485 if e.errno != errno.EEXIST:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400486 print('fatal: cannot make %s directory: %s' % (gpg_dir, e.strerror),
487 file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700488 sys.exit(1)
489
Shawn O. Pearcef18cb762010-12-07 11:41:05 -0800490 env = os.environ.copy()
Dāvis Mosāns631d0ec2016-07-16 21:11:11 +0300491 try:
492 env['GNUPGHOME'] = gpg_dir
493 except UnicodeEncodeError:
494 env['GNUPGHOME'] = gpg_dir.encode()
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700495
496 cmd = ['gpg', '--import']
497 try:
498 proc = subprocess.Popen(cmd,
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700499 env=env,
500 stdin=subprocess.PIPE)
Sarah Owensa5be53f2012-09-09 15:37:57 -0700501 except OSError as e:
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700502 if not quiet:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400503 print('warning: gpg (GnuPG) is not available.', file=sys.stderr)
504 print('warning: Installing it is strongly encouraged.', file=sys.stderr)
505 print(file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700506 return False
507
508 proc.stdin.write(MAINTAINER_KEYS)
509 proc.stdin.close()
510
511 if proc.wait() != 0:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400512 print('fatal: registering repo maintainer keys failed', file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700513 sys.exit(1)
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400514 print()
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700515
516 fd = open(os.path.join(home_dot_repo, 'keyring-version'), 'w')
David Pursehouse685f0802012-11-14 08:34:39 +0900517 fd.write('.'.join(map(str, KEYRING_VERSION)) + '\n')
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700518 fd.close()
519 return True
520
521
522def _SetConfig(local, name, value):
523 """Set a git configuration option to the specified value.
524 """
525 cmd = [GIT, 'config', name, value]
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700526 if subprocess.Popen(cmd, cwd=local).wait() != 0:
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700527 raise CloneFailure()
528
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700529
530def _InitHttp():
531 handlers = []
532
Sarah Owens1f7627f2012-10-31 09:21:55 -0700533 mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700534 try:
535 import netrc
536 n = netrc.netrc()
537 for host in n.hosts:
538 p = n.hosts[host]
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700539 mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2])
Xiaodong Xuae0a36c2012-01-31 11:10:09 +0800540 mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2])
David Pursehouse65b0ba52018-06-24 16:21:51 +0900541 except:
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700542 pass
Sarah Owens1f7627f2012-10-31 09:21:55 -0700543 handlers.append(urllib.request.HTTPBasicAuthHandler(mgr))
544 handlers.append(urllib.request.HTTPDigestAuthHandler(mgr))
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700545
546 if 'http_proxy' in os.environ:
547 url = os.environ['http_proxy']
Sarah Owens1f7627f2012-10-31 09:21:55 -0700548 handlers.append(urllib.request.ProxyHandler({'http': url, 'https': url}))
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700549 if 'REPO_CURL_VERBOSE' in os.environ:
Sarah Owens1f7627f2012-10-31 09:21:55 -0700550 handlers.append(urllib.request.HTTPHandler(debuglevel=1))
551 handlers.append(urllib.request.HTTPSHandler(debuglevel=1))
552 urllib.request.install_opener(urllib.request.build_opener(*handlers))
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700553
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700554
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700555def _Fetch(url, local, src, quiet):
556 if not quiet:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400557 print('Get %s' % url, file=sys.stderr)
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700558
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700559 cmd = [GIT, 'fetch']
560 if quiet:
561 cmd.append('--quiet')
562 err = subprocess.PIPE
563 else:
564 err = None
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700565 cmd.append(src)
566 cmd.append('+refs/heads/*:refs/remotes/origin/*')
Xin Li6e538442018-12-10 11:33:16 -0800567 cmd.append('+refs/tags/*:refs/tags/*')
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700568
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700569 proc = subprocess.Popen(cmd, cwd=local, stderr=err)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700570 if err:
571 proc.stderr.read()
572 proc.stderr.close()
573 if proc.wait() != 0:
574 raise CloneFailure()
575
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700576
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700577def _DownloadBundle(url, local, quiet):
578 if not url.endswith('/'):
579 url += '/'
580 url += 'clone.bundle'
581
582 proc = subprocess.Popen(
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700583 [GIT, 'config', '--get-regexp', 'url.*.insteadof'],
584 cwd=local,
585 stdout=subprocess.PIPE)
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700586 for line in proc.stdout:
587 m = re.compile(r'^url\.(.*)\.insteadof (.*)$').match(line)
588 if m:
589 new_url = m.group(1)
590 old_url = m.group(2)
591 if url.startswith(old_url):
592 url = new_url + url[len(old_url):]
593 break
594 proc.stdout.close()
595 proc.wait()
596
597 if not url.startswith('http:') and not url.startswith('https:'):
598 return False
599
600 dest = open(os.path.join(local, '.git', 'clone.bundle'), 'w+b')
601 try:
602 try:
Sarah Owens1f7627f2012-10-31 09:21:55 -0700603 r = urllib.request.urlopen(url)
604 except urllib.error.HTTPError as e:
John Törnblomd3ddcdb2015-08-12 20:12:51 +0200605 if e.code in [401, 403, 404, 501]:
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700606 return False
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400607 print('fatal: Cannot get %s' % url, file=sys.stderr)
608 print('fatal: HTTP error %s' % e.code, file=sys.stderr)
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700609 raise CloneFailure()
Sarah Owens1f7627f2012-10-31 09:21:55 -0700610 except urllib.error.URLError as e:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400611 print('fatal: Cannot get %s' % url, file=sys.stderr)
612 print('fatal: error %s' % e.reason, file=sys.stderr)
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700613 raise CloneFailure()
614 try:
615 if not quiet:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400616 print('Get %s' % url, file=sys.stderr)
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700617 while True:
618 buf = r.read(8192)
Mike Frysinger1b9adab2019-07-04 17:54:54 -0400619 if not buf:
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700620 return True
621 dest.write(buf)
622 finally:
623 r.close()
624 finally:
625 dest.close()
626
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700627
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700628def _ImportBundle(local):
629 path = os.path.join(local, '.git', 'clone.bundle')
630 try:
631 _Fetch(local, local, path, True)
632 finally:
633 os.remove(path)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700634
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700635
Hu xiuyun9711a982015-12-11 11:16:41 +0800636def _Clone(url, local, quiet, clone_bundle):
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700637 """Clones a git repository to a new subdirectory of repodir
638 """
639 try:
640 os.mkdir(local)
Sarah Owensa5be53f2012-09-09 15:37:57 -0700641 except OSError as e:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400642 print('fatal: cannot make %s directory: %s' % (local, e.strerror),
643 file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700644 raise CloneFailure()
645
646 cmd = [GIT, 'init', '--quiet']
647 try:
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700648 proc = subprocess.Popen(cmd, cwd=local)
Sarah Owensa5be53f2012-09-09 15:37:57 -0700649 except OSError as e:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400650 print(file=sys.stderr)
651 print("fatal: '%s' is not available" % GIT, file=sys.stderr)
652 print('fatal: %s' % e, file=sys.stderr)
653 print(file=sys.stderr)
654 print('Please make sure %s is installed and in your path.' % GIT,
655 file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700656 raise CloneFailure()
657 if proc.wait() != 0:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400658 print('fatal: could not create %s' % local, file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700659 raise CloneFailure()
660
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700661 _InitHttp()
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700662 _SetConfig(local, 'remote.origin.url', url)
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700663 _SetConfig(local,
664 'remote.origin.fetch',
665 '+refs/heads/*:refs/remotes/origin/*')
Hu xiuyun9711a982015-12-11 11:16:41 +0800666 if clone_bundle and _DownloadBundle(url, local, quiet):
Shawn O. Pearcef322b9a2011-09-19 14:50:58 -0700667 _ImportBundle(local)
Dan Willemsenfee390e2015-09-02 12:36:30 -0700668 _Fetch(url, local, 'origin', quiet)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700669
670
671def _Verify(cwd, branch, quiet):
672 """Verify the branch has been signed by a tag.
673 """
674 cmd = [GIT, 'describe', 'origin/%s' % branch]
675 proc = subprocess.Popen(cmd,
676 stdout=subprocess.PIPE,
677 stderr=subprocess.PIPE,
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700678 cwd=cwd)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700679 cur = proc.stdout.read().strip()
680 proc.stdout.close()
681
682 proc.stderr.read()
683 proc.stderr.close()
684
685 if proc.wait() != 0 or not cur:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400686 print(file=sys.stderr)
687 print("fatal: branch '%s' has not been signed" % branch, file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700688 raise CloneFailure()
689
690 m = re.compile(r'^(.*)-[0-9]{1,}-g[0-9a-f]{1,}$').match(cur)
691 if m:
692 cur = m.group(1)
693 if not quiet:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400694 print(file=sys.stderr)
695 print("info: Ignoring branch '%s'; using tagged release '%s'"
696 % (branch, cur), file=sys.stderr)
697 print(file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700698
Shawn O. Pearcef18cb762010-12-07 11:41:05 -0800699 env = os.environ.copy()
Dāvis Mosāns631d0ec2016-07-16 21:11:11 +0300700 try:
701 env['GNUPGHOME'] = gpg_dir
702 except UnicodeEncodeError:
703 env['GNUPGHOME'] = gpg_dir.encode()
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700704
705 cmd = [GIT, 'tag', '-v', cur]
706 proc = subprocess.Popen(cmd,
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700707 stdout=subprocess.PIPE,
708 stderr=subprocess.PIPE,
709 cwd=cwd,
710 env=env)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700711 out = proc.stdout.read()
712 proc.stdout.close()
713
714 err = proc.stderr.read()
715 proc.stderr.close()
716
717 if proc.wait() != 0:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400718 print(file=sys.stderr)
719 print(out, file=sys.stderr)
720 print(err, file=sys.stderr)
721 print(file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700722 raise CloneFailure()
723 return '%s^0' % cur
724
725
726def _Checkout(cwd, branch, rev, quiet):
727 """Checkout an upstream branch into the repository and track it.
728 """
729 cmd = [GIT, 'update-ref', 'refs/heads/default', rev]
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700730 if subprocess.Popen(cmd, cwd=cwd).wait() != 0:
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700731 raise CloneFailure()
732
733 _SetConfig(cwd, 'branch.default.remote', 'origin')
734 _SetConfig(cwd, 'branch.default.merge', 'refs/heads/%s' % branch)
735
736 cmd = [GIT, 'symbolic-ref', 'HEAD', 'refs/heads/default']
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700737 if subprocess.Popen(cmd, cwd=cwd).wait() != 0:
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700738 raise CloneFailure()
739
740 cmd = [GIT, 'read-tree', '--reset', '-u']
741 if not quiet:
742 cmd.append('-v')
743 cmd.append('HEAD')
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700744 if subprocess.Popen(cmd, cwd=cwd).wait() != 0:
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700745 raise CloneFailure()
746
747
748def _FindRepo():
749 """Look for a repo installation, starting at the current directory.
750 """
Mickaël Salaün2f6ab7f2012-09-30 00:37:55 +0200751 curdir = os.getcwd()
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700752 repo = None
753
Anthony Newnamdf14a702011-01-09 17:31:57 -0800754 olddir = None
Mickaël Salaün2f6ab7f2012-09-30 00:37:55 +0200755 while curdir != '/' \
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700756 and curdir != olddir \
757 and not repo:
Mickaël Salaün2f6ab7f2012-09-30 00:37:55 +0200758 repo = os.path.join(curdir, repodir, REPO_MAIN)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700759 if not os.path.isfile(repo):
760 repo = None
Mickaël Salaün2f6ab7f2012-09-30 00:37:55 +0200761 olddir = curdir
762 curdir = os.path.dirname(curdir)
763 return (repo, os.path.join(curdir, repodir))
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700764
765
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700766class _Options(object):
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700767 help = False
768
769
770def _ParseArguments(args):
771 cmd = None
772 opt = _Options()
773 arg = []
774
Sarah Owensa6053d52012-11-01 13:36:50 -0700775 for i in range(len(args)):
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700776 a = args[i]
777 if a == '-h' or a == '--help':
778 opt.help = True
779
780 elif not a.startswith('-'):
781 cmd = a
782 arg = args[i + 1:]
783 break
784 return cmd, opt, arg
785
786
787def _Usage():
Dan Willemsen9ff2ece2015-08-31 15:45:06 -0700788 gitc_usage = ""
789 if get_gitc_manifest_dir():
790 gitc_usage = " gitc-init Initialize a GITC Client.\n"
791
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400792 print(
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700793 """usage: repo COMMAND [ARGS]
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700794
795repo is not yet installed. Use "repo init" to install it here.
796
797The most commonly used repo commands are:
798
799 init Install repo in the current working directory
Dan Willemsen9ff2ece2015-08-31 15:45:06 -0700800""" + gitc_usage +
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700801 """ help Display detailed help on a command
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700802
803For access to the full online help, install repo ("repo init").
Mike Frysinger35159ab2019-06-13 00:07:13 -0400804""")
805 sys.exit(0)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700806
807
808def _Help(args):
809 if args:
810 if args[0] == 'init':
811 init_optparse.print_help()
Trond Norbyed3fd5372011-01-03 11:35:15 +0100812 sys.exit(0)
Dan Willemsen9ff2ece2015-08-31 15:45:06 -0700813 elif args[0] == 'gitc-init':
814 _GitcInitOptions(init_optparse)
815 init_optparse.print_help()
816 sys.exit(0)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700817 else:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400818 print("error: '%s' is not a bootstrap command.\n"
819 ' For access to online help, install repo ("repo init").'
820 % args[0], file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700821 else:
822 _Usage()
823 sys.exit(1)
824
825
826def _NotInstalled():
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400827 print('error: repo is not installed. Use "repo init" to install it here.',
828 file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700829 sys.exit(1)
830
831
832def _NoCommands(cmd):
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400833 print("""error: command '%s' requires repo to be installed first.
834 Use "repo init" to install it here.""" % cmd, file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700835 sys.exit(1)
836
837
838def _RunSelf(wrapper_path):
839 my_dir = os.path.dirname(wrapper_path)
840 my_main = os.path.join(my_dir, 'main.py')
841 my_git = os.path.join(my_dir, '.git')
842
843 if os.path.isfile(my_main) and os.path.isdir(my_git):
Shawn O. Pearcec8a300f2009-05-18 13:19:57 -0700844 for name in ['git_config.py',
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700845 'project.py',
846 'subcmds']:
847 if not os.path.exists(os.path.join(my_dir, name)):
848 return None, None
849 return my_main, my_git
850 return None, None
851
852
853def _SetDefaultsTo(gitdir):
854 global REPO_URL
855 global REPO_REV
856
857 REPO_URL = gitdir
858 proc = subprocess.Popen([GIT,
859 '--git-dir=%s' % gitdir,
860 'symbolic-ref',
861 'HEAD'],
Mark E. Hamilton4088eb42016-02-10 10:44:30 -0700862 stdout=subprocess.PIPE,
863 stderr=subprocess.PIPE)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700864 REPO_REV = proc.stdout.read().strip()
865 proc.stdout.close()
866
867 proc.stderr.read()
868 proc.stderr.close()
869
870 if proc.wait() != 0:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400871 print('fatal: %s has no current branch' % gitdir, file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700872 sys.exit(1)
873
874
875def main(orig_args):
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700876 cmd, opt, args = _ParseArguments(orig_args)
877
Dan Willemsen745b4ad2015-10-06 15:23:19 -0700878 repo_main, rel_repo_dir = None, None
879 # Don't use the local repo copy, make sure to switch to the gitc client first.
880 if cmd != 'gitc-init':
881 repo_main, rel_repo_dir = _FindRepo()
882
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700883 wrapper_path = os.path.abspath(__file__)
884 my_main, my_git = _RunSelf(wrapper_path)
885
Simran Basi8ce50412015-08-28 14:25:44 -0700886 cwd = os.getcwd()
Dan Willemsen2487cb72015-08-31 15:45:06 -0700887 if get_gitc_manifest_dir() and cwd.startswith(get_gitc_manifest_dir()):
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400888 print('error: repo cannot be used in the GITC local manifest directory.'
889 '\nIf you want to work on this GITC client please rerun this '
890 'command from the corresponding client under /gitc/',
891 file=sys.stderr)
Simran Basi8ce50412015-08-28 14:25:44 -0700892 sys.exit(1)
Mickaël Salaün2f6ab7f2012-09-30 00:37:55 +0200893 if not repo_main:
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700894 if opt.help:
895 _Usage()
896 if cmd == 'help':
897 _Help(args)
898 if not cmd:
899 _NotInstalled()
Simran Basi1efc2b42015-08-05 15:04:22 -0700900 if cmd == 'init' or cmd == 'gitc-init':
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700901 if my_git:
902 _SetDefaultsTo(my_git)
903 try:
Simran Basi1efc2b42015-08-05 15:04:22 -0700904 _Init(args, gitc_init=(cmd == 'gitc-init'))
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700905 except CloneFailure:
Sebastian Schuberth27226e72016-10-28 14:27:43 +0200906 path = os.path.join(repodir, S_repo)
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400907 print("fatal: cloning the git-repo repository failed, will remove "
908 "'%s' " % path, file=sys.stderr)
Sebastian Schuberth27226e72016-10-28 14:27:43 +0200909 shutil.rmtree(path, ignore_errors=True)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700910 sys.exit(1)
Mickaël Salaün2f6ab7f2012-09-30 00:37:55 +0200911 repo_main, rel_repo_dir = _FindRepo()
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700912 else:
913 _NoCommands(cmd)
914
915 if my_main:
Mickaël Salaün2f6ab7f2012-09-30 00:37:55 +0200916 repo_main = my_main
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700917
David Pursehouse685f0802012-11-14 08:34:39 +0900918 ver_str = '.'.join(map(str, VERSION))
anatoly techtonik3a2a59e2013-09-21 19:29:10 +0300919 me = [sys.executable, repo_main,
Mickaël Salaün2f6ab7f2012-09-30 00:37:55 +0200920 '--repo-dir=%s' % rel_repo_dir,
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700921 '--wrapper-version=%s' % ver_str,
922 '--wrapper-path=%s' % wrapper_path,
923 '--']
924 me.extend(orig_args)
925 me.extend(extra_args)
926 try:
Renaud Paquay35d22212016-11-01 11:24:52 -0700927 if platform.system() == "Windows":
928 sys.exit(subprocess.call(me))
929 else:
930 os.execv(sys.executable, me)
Sarah Owensa5be53f2012-09-09 15:37:57 -0700931 except OSError as e:
Mike Frysingerc92ce5c2019-06-13 01:14:23 -0400932 print("fatal: unable to start %s" % repo_main, file=sys.stderr)
933 print("fatal: %s" % e, file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700934 sys.exit(148)
935
936
937if __name__ == '__main__':
938 main(sys.argv[1:])