diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | cf31fe9b4fb650b27e19f5d7ee7297e383660caf (patch) | |
tree | d04ca6a45d579dca5e5469606c48c405aee68f4b /repo | |
download | git-repo-1.0.tar.gz |
Initial Contributionv1.0
Diffstat (limited to 'repo')
-rwxr-xr-x | repo | 587 |
1 files changed, 587 insertions, 0 deletions
@@ -0,0 +1,587 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | ## repo default configuration | ||
4 | ## | ||
5 | REPO_URL='git://android.kernel.org/tools/repo.git' | ||
6 | REPO_REV='stable' | ||
7 | |||
8 | # Copyright (C) 2008 Google Inc. | ||
9 | # | ||
10 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
11 | # you may not use this file except in compliance with the License. | ||
12 | # You may obtain a copy of the License at | ||
13 | # | ||
14 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
15 | # | ||
16 | # Unless required by applicable law or agreed to in writing, software | ||
17 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
18 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
19 | # See the License for the specific language governing permissions and | ||
20 | # limitations under the License. | ||
21 | |||
22 | magic='--calling-python-from-/bin/sh--' | ||
23 | """exec" python2.4 -E "$0" "$@" """#$magic" | ||
24 | if __name__ == '__main__': | ||
25 | import sys | ||
26 | if sys.argv[-1] == '#%s' % magic: | ||
27 | del sys.argv[-1] | ||
28 | del magic | ||
29 | |||
30 | # increment this whenever we make important changes to this script | ||
31 | VERSION = (1, 4) | ||
32 | |||
33 | # increment this if the MAINTAINER_KEYS block is modified | ||
34 | KEYRING_VERSION = (1,0) | ||
35 | MAINTAINER_KEYS = """ | ||
36 | |||
37 | Repo Maintainer <repo@android.kernel.org> | ||
38 | -----BEGIN PGP PUBLIC KEY BLOCK----- | ||
39 | Version: GnuPG v1.4.2.2 (GNU/Linux) | ||
40 | |||
41 | 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 | ||
76 | =CMiZ | ||
77 | -----END PGP PUBLIC KEY BLOCK----- | ||
78 | """ | ||
79 | |||
80 | GIT = 'git' # our git command | ||
81 | MIN_GIT_VERSION = (1, 5, 4) # minimum supported git version | ||
82 | repodir = '.repo' # name of repo's private directory | ||
83 | S_repo = 'repo' # special repo reposiory | ||
84 | S_manifests = 'manifests' # special manifest repository | ||
85 | REPO_MAIN = S_repo + '/main.py' # main script | ||
86 | |||
87 | |||
88 | import optparse | ||
89 | import os | ||
90 | import re | ||
91 | import readline | ||
92 | import subprocess | ||
93 | import sys | ||
94 | |||
95 | home_dot_repo = os.path.expanduser('~/.repoconfig') | ||
96 | gpg_dir = os.path.join(home_dot_repo, 'gnupg') | ||
97 | |||
98 | extra_args = [] | ||
99 | init_optparse = optparse.OptionParser(usage="repo init -u url [options]") | ||
100 | |||
101 | # Logging | ||
102 | group = init_optparse.add_option_group('Logging options') | ||
103 | group.add_option('-q', '--quiet', | ||
104 | dest="quiet", action="store_true", default=False, | ||
105 | help="be quiet") | ||
106 | |||
107 | # Manifest | ||
108 | group = init_optparse.add_option_group('Manifest options') | ||
109 | group.add_option('-u', '--manifest-url', | ||
110 | dest='manifest_url', | ||
111 | help='manifest repository location', metavar='URL') | ||
112 | group.add_option('-b', '--manifest-branch', | ||
113 | dest='manifest_branch', | ||
114 | help='manifest branch or revision', metavar='REVISION') | ||
115 | group.add_option('-m', '--manifest-name', | ||
116 | dest='manifest_name', | ||
117 | help='initial manifest file', metavar='NAME.xml') | ||
118 | |||
119 | # Tool | ||
120 | group = init_optparse.add_option_group('Version options') | ||
121 | group.add_option('--repo-url', | ||
122 | dest='repo_url', | ||
123 | help='repo repository location', metavar='URL') | ||
124 | group.add_option('--repo-branch', | ||
125 | dest='repo_branch', | ||
126 | help='repo branch or revision', metavar='REVISION') | ||
127 | group.add_option('--no-repo-verify', | ||
128 | dest='no_repo_verify', action='store_true', | ||
129 | help='do not verify repo source code') | ||
130 | |||
131 | |||
132 | class CloneFailure(Exception): | ||
133 | """Indicate the remote clone of repo itself failed. | ||
134 | """ | ||
135 | |||
136 | |||
137 | def _Init(args): | ||
138 | """Installs repo by cloning it over the network. | ||
139 | """ | ||
140 | opt, args = init_optparse.parse_args(args) | ||
141 | if args or not opt.manifest_url: | ||
142 | init_optparse.print_usage() | ||
143 | sys.exit(1) | ||
144 | |||
145 | url = opt.repo_url | ||
146 | if not url: | ||
147 | url = REPO_URL | ||
148 | extra_args.append('--repo-url=%s' % url) | ||
149 | |||
150 | branch = opt.repo_branch | ||
151 | if not branch: | ||
152 | branch = REPO_REV | ||
153 | extra_args.append('--repo-branch=%s' % branch) | ||
154 | |||
155 | if branch.startswith('refs/heads/'): | ||
156 | branch = branch[len('refs/heads/'):] | ||
157 | if branch.startswith('refs/'): | ||
158 | print >>sys.stderr, "fatal: invalid branch name '%s'" % branch | ||
159 | raise CloneFailure() | ||
160 | |||
161 | if not os.path.isdir(repodir): | ||
162 | try: | ||
163 | os.mkdir(repodir) | ||
164 | except OSError, e: | ||
165 | print >>sys.stderr, \ | ||
166 | 'fatal: cannot make %s directory: %s' % ( | ||
167 | repodir, e.strerror) | ||
168 | # Don't faise CloneFailure; that would delete the | ||
169 | # name. Instead exit immediately. | ||
170 | # | ||
171 | sys.exit(1) | ||
172 | |||
173 | _CheckGitVersion() | ||
174 | try: | ||
175 | if _NeedSetupGnuPG(): | ||
176 | can_verify = _SetupGnuPG(opt.quiet) | ||
177 | else: | ||
178 | can_verify = True | ||
179 | |||
180 | if not opt.quiet: | ||
181 | print >>sys.stderr, 'Getting repo ...' | ||
182 | print >>sys.stderr, ' from %s' % url | ||
183 | |||
184 | dst = os.path.abspath(os.path.join(repodir, S_repo)) | ||
185 | _Clone(url, dst, opt.quiet) | ||
186 | |||
187 | if can_verify and not opt.no_repo_verify: | ||
188 | rev = _Verify(dst, branch, opt.quiet) | ||
189 | else: | ||
190 | rev = 'refs/remotes/origin/%s^0' % branch | ||
191 | |||
192 | _Checkout(dst, branch, rev, opt.quiet) | ||
193 | except CloneFailure: | ||
194 | if opt.quiet: | ||
195 | print >>sys.stderr, \ | ||
196 | 'fatal: repo init failed; run without --quiet to see why' | ||
197 | raise | ||
198 | |||
199 | |||
200 | def _CheckGitVersion(): | ||
201 | cmd = [GIT, '--version'] | ||
202 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) | ||
203 | ver_str = proc.stdout.read().strip() | ||
204 | proc.stdout.close() | ||
205 | |||
206 | if not ver_str.startswith('git version '): | ||
207 | print >>sys.stderr, 'error: "%s" unsupported' % ver_str | ||
208 | raise CloneFailure() | ||
209 | |||
210 | ver_str = ver_str[len('git version '):].strip() | ||
211 | ver_act = tuple(map(lambda x: int(x), ver_str.split('.')[0:3])) | ||
212 | if ver_act < MIN_GIT_VERSION: | ||
213 | need = '.'.join(map(lambda x: str(x), MIN_GIT_VERSION)) | ||
214 | print >>sys.stderr, 'fatal: git %s or later required' % need | ||
215 | raise CloneFailure() | ||
216 | |||
217 | |||
218 | def _NeedSetupGnuPG(): | ||
219 | if not os.path.isdir(home_dot_repo): | ||
220 | return True | ||
221 | |||
222 | kv = os.path.join(home_dot_repo, 'keyring-version') | ||
223 | if not os.path.exists(kv): | ||
224 | return True | ||
225 | |||
226 | kv = open(kv).read() | ||
227 | if not kv: | ||
228 | return True | ||
229 | |||
230 | kv = tuple(map(lambda x: int(x), kv.split('.'))) | ||
231 | if kv < KEYRING_VERSION: | ||
232 | return True | ||
233 | return False | ||
234 | |||
235 | |||
236 | def _SetupGnuPG(quiet): | ||
237 | if not os.path.isdir(home_dot_repo): | ||
238 | try: | ||
239 | os.mkdir(home_dot_repo) | ||
240 | except OSError, e: | ||
241 | print >>sys.stderr, \ | ||
242 | 'fatal: cannot make %s directory: %s' % ( | ||
243 | home_dot_repo, e.strerror) | ||
244 | sys.exit(1) | ||
245 | |||
246 | if not os.path.isdir(gpg_dir): | ||
247 | try: | ||
248 | os.mkdir(gpg_dir, 0700) | ||
249 | except OSError, e: | ||
250 | print >>sys.stderr, \ | ||
251 | 'fatal: cannot make %s directory: %s' % ( | ||
252 | gpg_dir, e.strerror) | ||
253 | sys.exit(1) | ||
254 | |||
255 | env = dict(os.environ) | ||
256 | env['GNUPGHOME'] = gpg_dir | ||
257 | |||
258 | cmd = ['gpg', '--import'] | ||
259 | try: | ||
260 | proc = subprocess.Popen(cmd, | ||
261 | env = env, | ||
262 | stdin = subprocess.PIPE) | ||
263 | except OSError, e: | ||
264 | if not quiet: | ||
265 | print >>sys.stderr, 'warning: gpg (GnuPG) is not available.' | ||
266 | print >>sys.stderr, 'warning: Installing it is strongly encouraged.' | ||
267 | print >>sys.stderr | ||
268 | return False | ||
269 | |||
270 | proc.stdin.write(MAINTAINER_KEYS) | ||
271 | proc.stdin.close() | ||
272 | |||
273 | if proc.wait() != 0: | ||
274 | print >>sys.stderr, 'fatal: registering repo maintainer keys failed' | ||
275 | sys.exit(1) | ||
276 | |||
277 | |||
278 | fd = open(os.path.join(home_dot_repo, 'keyring-version'), 'w') | ||
279 | fd.write('.'.join(map(lambda x: str(x), KEYRING_VERSION)) + '\n') | ||
280 | fd.close() | ||
281 | return True | ||
282 | |||
283 | |||
284 | def _SetConfig(local, name, value): | ||
285 | """Set a git configuration option to the specified value. | ||
286 | """ | ||
287 | cmd = [GIT, 'config', name, value] | ||
288 | if subprocess.Popen(cmd, cwd = local).wait() != 0: | ||
289 | raise CloneFailure() | ||
290 | |||
291 | |||
292 | def _Fetch(local, quiet, *args): | ||
293 | cmd = [GIT, 'fetch'] | ||
294 | if quiet: | ||
295 | cmd.append('--quiet') | ||
296 | err = subprocess.PIPE | ||
297 | else: | ||
298 | err = None | ||
299 | cmd.extend(args) | ||
300 | cmd.append('origin') | ||
301 | |||
302 | proc = subprocess.Popen(cmd, cwd = local, stderr = err) | ||
303 | if err: | ||
304 | proc.stderr.read() | ||
305 | proc.stderr.close() | ||
306 | if proc.wait() != 0: | ||
307 | raise CloneFailure() | ||
308 | |||
309 | |||
310 | def _Clone(url, local, quiet): | ||
311 | """Clones a git repository to a new subdirectory of repodir | ||
312 | """ | ||
313 | try: | ||
314 | os.mkdir(local) | ||
315 | except OSError, e: | ||
316 | print >>sys.stderr, \ | ||
317 | 'fatal: cannot make %s directory: %s' \ | ||
318 | % (local, e.strerror) | ||
319 | raise CloneFailure() | ||
320 | |||
321 | cmd = [GIT, 'init', '--quiet'] | ||
322 | try: | ||
323 | proc = subprocess.Popen(cmd, cwd = local) | ||
324 | except OSError, e: | ||
325 | print >>sys.stderr | ||
326 | print >>sys.stderr, "fatal: '%s' is not available" % GIT | ||
327 | print >>sys.stderr, 'fatal: %s' % e | ||
328 | print >>sys.stderr | ||
329 | print >>sys.stderr, 'Please make sure %s is installed'\ | ||
330 | ' and in your path.' % GIT | ||
331 | raise CloneFailure() | ||
332 | if proc.wait() != 0: | ||
333 | print >>sys.stderr, 'fatal: could not create %s' % local | ||
334 | raise CloneFailure() | ||
335 | |||
336 | _SetConfig(local, 'remote.origin.url', url) | ||
337 | _SetConfig(local, 'remote.origin.fetch', | ||
338 | '+refs/heads/*:refs/remotes/origin/*') | ||
339 | _Fetch(local, quiet) | ||
340 | _Fetch(local, quiet, '--tags') | ||
341 | |||
342 | |||
343 | def _Verify(cwd, branch, quiet): | ||
344 | """Verify the branch has been signed by a tag. | ||
345 | """ | ||
346 | cmd = [GIT, 'describe', 'origin/%s' % branch] | ||
347 | proc = subprocess.Popen(cmd, | ||
348 | stdout=subprocess.PIPE, | ||
349 | stderr=subprocess.PIPE, | ||
350 | cwd = cwd) | ||
351 | cur = proc.stdout.read().strip() | ||
352 | proc.stdout.close() | ||
353 | |||
354 | proc.stderr.read() | ||
355 | proc.stderr.close() | ||
356 | |||
357 | if proc.wait() != 0 or not cur: | ||
358 | print >>sys.stderr | ||
359 | print >>sys.stderr,\ | ||
360 | "fatal: branch '%s' has not been signed" \ | ||
361 | % branch | ||
362 | raise CloneFailure() | ||
363 | |||
364 | m = re.compile(r'^(.*)-[0-9]{1,}-g[0-9a-f]{1,}$').match(cur) | ||
365 | if m: | ||
366 | cur = m.group(1) | ||
367 | if not quiet: | ||
368 | print >>sys.stderr | ||
369 | print >>sys.stderr, \ | ||
370 | "info: Ignoring branch '%s'; using tagged release '%s'" \ | ||
371 | % (branch, cur) | ||
372 | print >>sys.stderr | ||
373 | |||
374 | env = dict(os.environ) | ||
375 | env['GNUPGHOME'] = gpg_dir | ||
376 | |||
377 | cmd = [GIT, 'tag', '-v', cur] | ||
378 | proc = subprocess.Popen(cmd, | ||
379 | stdout = subprocess.PIPE, | ||
380 | stderr = subprocess.PIPE, | ||
381 | cwd = cwd, | ||
382 | env = env) | ||
383 | out = proc.stdout.read() | ||
384 | proc.stdout.close() | ||
385 | |||
386 | err = proc.stderr.read() | ||
387 | proc.stderr.close() | ||
388 | |||
389 | if proc.wait() != 0: | ||
390 | print >>sys.stderr | ||
391 | print >>sys.stderr, out | ||
392 | print >>sys.stderr, err | ||
393 | print >>sys.stderr | ||
394 | raise CloneFailure() | ||
395 | return '%s^0' % cur | ||
396 | |||
397 | |||
398 | def _Checkout(cwd, branch, rev, quiet): | ||
399 | """Checkout an upstream branch into the repository and track it. | ||
400 | """ | ||
401 | cmd = [GIT, 'update-ref', 'refs/heads/default', rev] | ||
402 | if subprocess.Popen(cmd, cwd = cwd).wait() != 0: | ||
403 | raise CloneFailure() | ||
404 | |||
405 | _SetConfig(cwd, 'branch.default.remote', 'origin') | ||
406 | _SetConfig(cwd, 'branch.default.merge', 'refs/heads/%s' % branch) | ||
407 | |||
408 | cmd = [GIT, 'symbolic-ref', 'HEAD', 'refs/heads/default'] | ||
409 | if subprocess.Popen(cmd, cwd = cwd).wait() != 0: | ||
410 | raise CloneFailure() | ||
411 | |||
412 | cmd = [GIT, 'read-tree', '--reset', '-u'] | ||
413 | if not quiet: | ||
414 | cmd.append('-v') | ||
415 | cmd.append('HEAD') | ||
416 | if subprocess.Popen(cmd, cwd = cwd).wait() != 0: | ||
417 | raise CloneFailure() | ||
418 | |||
419 | |||
420 | def _FindRepo(): | ||
421 | """Look for a repo installation, starting at the current directory. | ||
422 | """ | ||
423 | dir = os.getcwd() | ||
424 | repo = None | ||
425 | |||
426 | while dir != '/' and not repo: | ||
427 | repo = os.path.join(dir, repodir, REPO_MAIN) | ||
428 | if not os.path.isfile(repo): | ||
429 | repo = None | ||
430 | dir = os.path.dirname(dir) | ||
431 | return (repo, os.path.join(dir, repodir)) | ||
432 | |||
433 | |||
434 | class _Options: | ||
435 | help = False | ||
436 | |||
437 | |||
438 | def _ParseArguments(args): | ||
439 | cmd = None | ||
440 | opt = _Options() | ||
441 | arg = [] | ||
442 | |||
443 | for i in xrange(0, len(args)): | ||
444 | a = args[i] | ||
445 | if a == '-h' or a == '--help': | ||
446 | opt.help = True | ||
447 | |||
448 | elif not a.startswith('-'): | ||
449 | cmd = a | ||
450 | arg = args[i + 1:] | ||
451 | break | ||
452 | return cmd, opt, arg | ||
453 | |||
454 | |||
455 | def _Usage(): | ||
456 | print >>sys.stderr,\ | ||
457 | """usage: repo COMMAND [ARGS] | ||
458 | |||
459 | repo is not yet installed. Use "repo init" to install it here. | ||
460 | |||
461 | The most commonly used repo commands are: | ||
462 | |||
463 | init Install repo in the current working directory | ||
464 | help Display detailed help on a command | ||
465 | |||
466 | For access to the full online help, install repo ("repo init"). | ||
467 | """ | ||
468 | sys.exit(1) | ||
469 | |||
470 | |||
471 | def _Help(args): | ||
472 | if args: | ||
473 | if args[0] == 'init': | ||
474 | init_optparse.print_help() | ||
475 | else: | ||
476 | print >>sys.stderr,\ | ||
477 | "error: '%s' is not a bootstrap command.\n"\ | ||
478 | ' For access to online help, install repo ("repo init").'\ | ||
479 | % args[0] | ||
480 | else: | ||
481 | _Usage() | ||
482 | sys.exit(1) | ||
483 | |||
484 | |||
485 | def _NotInstalled(): | ||
486 | print >>sys.stderr,\ | ||
487 | 'error: repo is not installed. Use "repo init" to install it here.' | ||
488 | sys.exit(1) | ||
489 | |||
490 | |||
491 | def _NoCommands(cmd): | ||
492 | print >>sys.stderr,\ | ||
493 | """error: command '%s' requires repo to be installed first. | ||
494 | Use "repo init" to install it here.""" % cmd | ||
495 | sys.exit(1) | ||
496 | |||
497 | |||
498 | def _RunSelf(wrapper_path): | ||
499 | my_dir = os.path.dirname(wrapper_path) | ||
500 | my_main = os.path.join(my_dir, 'main.py') | ||
501 | my_git = os.path.join(my_dir, '.git') | ||
502 | |||
503 | if os.path.isfile(my_main) and os.path.isdir(my_git): | ||
504 | for name in ['manifest.py', | ||
505 | 'project.py', | ||
506 | 'subcmds']: | ||
507 | if not os.path.exists(os.path.join(my_dir, name)): | ||
508 | return None, None | ||
509 | return my_main, my_git | ||
510 | return None, None | ||
511 | |||
512 | |||
513 | def _SetDefaultsTo(gitdir): | ||
514 | global REPO_URL | ||
515 | global REPO_REV | ||
516 | |||
517 | REPO_URL = gitdir | ||
518 | proc = subprocess.Popen([GIT, | ||
519 | '--git-dir=%s' % gitdir, | ||
520 | 'symbolic-ref', | ||
521 | 'HEAD'], | ||
522 | stdout = subprocess.PIPE, | ||
523 | stderr = subprocess.PIPE) | ||
524 | REPO_REV = proc.stdout.read().strip() | ||
525 | proc.stdout.close() | ||
526 | |||
527 | proc.stderr.read() | ||
528 | proc.stderr.close() | ||
529 | |||
530 | if proc.wait() != 0: | ||
531 | print >>sys.stderr, 'fatal: %s has no current branch' % gitdir | ||
532 | sys.exit(1) | ||
533 | |||
534 | |||
535 | def main(orig_args): | ||
536 | main, dir = _FindRepo() | ||
537 | cmd, opt, args = _ParseArguments(orig_args) | ||
538 | |||
539 | wrapper_path = os.path.abspath(__file__) | ||
540 | my_main, my_git = _RunSelf(wrapper_path) | ||
541 | |||
542 | if not main: | ||
543 | if opt.help: | ||
544 | _Usage() | ||
545 | if cmd == 'help': | ||
546 | _Help(args) | ||
547 | if not cmd: | ||
548 | _NotInstalled() | ||
549 | if cmd == 'init': | ||
550 | if my_git: | ||
551 | _SetDefaultsTo(my_git) | ||
552 | try: | ||
553 | _Init(args) | ||
554 | except CloneFailure: | ||
555 | for root, dirs, files in os.walk(repodir, topdown=False): | ||
556 | for name in files: | ||
557 | os.remove(os.path.join(root, name)) | ||
558 | for name in dirs: | ||
559 | os.rmdir(os.path.join(root, name)) | ||
560 | os.rmdir(repodir) | ||
561 | sys.exit(1) | ||
562 | main, dir = _FindRepo() | ||
563 | else: | ||
564 | _NoCommands(cmd) | ||
565 | |||
566 | if my_main: | ||
567 | main = my_main | ||
568 | |||
569 | ver_str = '.'.join(map(lambda x: str(x), VERSION)) | ||
570 | me = [main, | ||
571 | '--repo-dir=%s' % dir, | ||
572 | '--wrapper-version=%s' % ver_str, | ||
573 | '--wrapper-path=%s' % wrapper_path, | ||
574 | '--'] | ||
575 | me.extend(orig_args) | ||
576 | me.extend(extra_args) | ||
577 | try: | ||
578 | os.execv(main, me) | ||
579 | except OSError, e: | ||
580 | print >>sys.stderr, "fatal: unable to start %s" % main | ||
581 | print >>sys.stderr, "fatal: %s" % e | ||
582 | sys.exit(148) | ||
583 | |||
584 | |||
585 | if __name__ == '__main__': | ||
586 | main(sys.argv[1:]) | ||
587 | |||