# Copyright (C) 2008 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
magic='--calling-python-from-/bin/sh--'
"""exec" python -E "$0" "$@" """#$magic"
if __name__ == '__main__':
import sys
if sys.argv[-1] == '#%s' % magic:
del sys.argv[-1]
del magic
# increment this whenever we make important changes to this script
VERSION = (1, 17)
# increment this if the MAINTAINER_KEYS block is modified
KEYRING_VERSION = (1,0)
MAINTAINER_KEYS = """
# Manifest
group = init_optparse.add_option_group('Manifest options')
group.add_option('-u', '--manifest-url',
dest='manifest_url',
help='manifest repository location', metavar='URL')
group.add_option('-b', '--manifest-branch',
dest='manifest_branch',
help='manifest branch or revision', metavar='REVISION')
group.add_option('-m', '--manifest-name',
dest='manifest_name',
help='initial manifest file', metavar='NAME.xml')
group.add_option('--mirror',
dest='mirror', action='store_true',
help='mirror the forrest')
group.add_option('--reference',
dest='reference',
help='location of mirror directory', metavar='DIR')
group.add_option('--depth', type='int', default=None,
dest='depth',
help='create a shallow clone with given depth; see git clone')
group.add_option('-g', '--groups',
dest='groups', default='default',
help='restrict manifest projects to ones with a specified group',
metavar='GROUP')
group.add_option('-p', '--platform',
dest='platform', default="auto",
help='restrict manifest projects to ones with a specified'
'platform group [auto|all|none|linux|darwin|...]',
metavar='PLATFORM')
# Tool
group = init_optparse.add_option_group('repo Version options')
group.add_option('--repo-url',
dest='repo_url',
help='repo repository location', metavar='URL')
group.add_option('--repo-branch',
dest='repo_branch',
help='repo branch or revision', metavar='REVISION')
group.add_option('--no-repo-verify',
dest='no_repo_verify', action='store_true',
help='do not verify repo source code')
# Other
group = init_optparse.add_option_group('Other options')
group.add_option('--config-name',
dest='config_name', action="store_true", default=False,
help='Always prompt for name/e-mail')
class CloneFailure(Exception):
"""Indicate the remote clone of repo itself failed.
"""
def _Init(args):
"""Installs repo by cloning it over the network.
"""
opt, args = init_optparse.parse_args(args)
if args:
init_optparse.print_usage()
sys.exit(1)
url = opt.repo_url
if not url:
url = REPO_URL
extra_args.append('--repo-url=%s' % url)
branch = opt.repo_branch
if not branch:
branch = REPO_REV
extra_args.append('--repo-branch=%s' % branch)
if branch.startswith('refs/heads/'):
branch = branch[len('refs/heads/'):]
if branch.startswith('refs/'):
print >>sys.stderr, "fatal: invalid branch name '%s'" % branch
raise CloneFailure()
if not os.path.isdir(repodir):
try:
os.mkdir(repodir)
except OSError, e:
print >>sys.stderr, \
'fatal: cannot make %s directory: %s' % (
repodir, e.strerror)
# Don't faise CloneFailure; that would delete the
# name. Instead exit immediately.
#
sys.exit(1)
if can_verify and not opt.no_repo_verify:
rev = _Verify(dst, branch, opt.quiet)
else:
rev = 'refs/remotes/origin/%s^0' % branch
_Checkout(dst, branch, rev, opt.quiet)
except CloneFailure:
if opt.quiet:
print >>sys.stderr, \
'fatal: repo init failed; run without --quiet to see why'
raise
def _CheckGitVersion():
cmd = [GIT, '--version']
try:
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
except OSError, e:
print >>sys.stderr
print >>sys.stderr, "fatal: '%s' is not available" % GIT
print >>sys.stderr, 'fatal: %s' % e
print >>sys.stderr
print >>sys.stderr, 'Please make sure %s is installed'\
' and in your path.' % GIT
raise CloneFailure()
def _SetConfig(local, name, value):
"""Set a git configuration option to the specified value.
"""
cmd = [GIT, 'config', name, value]
if subprocess.Popen(cmd, cwd = local).wait() != 0:
raise CloneFailure()
def _InitHttp():
handlers = []
mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
try:
import netrc
n = netrc.netrc()
for host in n.hosts:
p = n.hosts[host]
mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2])
mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2])
except:
pass
handlers.append(urllib2.HTTPBasicAuthHandler(mgr))
handlers.append(urllib2.HTTPDigestAuthHandler(mgr))
if 'http_proxy' in os.environ:
url = os.environ['http_proxy']
handlers.append(urllib2.ProxyHandler({'http': url, 'https': url}))
if 'REPO_CURL_VERBOSE' in os.environ:
handlers.append(urllib2.HTTPHandler(debuglevel=1))
handlers.append(urllib2.HTTPSHandler(debuglevel=1))
urllib2.install_opener(urllib2.build_opener(*handlers))
def _Fetch(url, local, src, quiet):
if not quiet:
print >>sys.stderr, 'Get %s' % url
def _Verify(cwd, branch, quiet):
"""Verify the branch has been signed by a tag.
"""
cmd = [GIT, 'describe', 'origin/%s' % branch]
proc = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd = cwd)
cur = proc.stdout.read().strip()
proc.stdout.close()
proc.stderr.read()
proc.stderr.close()
if proc.wait() != 0 or not cur:
print >>sys.stderr
print >>sys.stderr,\
"fatal: branch '%s' has not been signed" \
% branch
raise CloneFailure()
m = re.compile(r'^(.*)-[0-9]{1,}-g[0-9a-f]{1,}$').match(cur)
if m:
cur = m.group(1)
if not quiet:
print >>sys.stderr
print >>sys.stderr, \
"info: Ignoring branch '%s'; using tagged release '%s'" \
% (branch, cur)
print >>sys.stderr
cmd = [GIT, 'read-tree', '--reset', '-u']
if not quiet:
cmd.append('-v')
cmd.append('HEAD')
if subprocess.Popen(cmd, cwd = cwd).wait() != 0:
raise CloneFailure()
def _FindRepo():
"""Look for a repo installation, starting at the current directory.
"""
dir = os.getcwd()
repo = None
olddir = None
while dir != '/' \
and dir != olddir \
and not repo:
repo = os.path.join(dir, repodir, REPO_MAIN)
if not os.path.isfile(repo):
repo = None
olddir = dir
dir = os.path.dirname(dir)
return (repo, os.path.join(dir, repodir))
repo is not yet installed. Use "repo init" to install it here.
The most commonly used repo commands are:
init Install repo in the current working directory
help Display detailed help on a command
For access to the full online help, install repo ("repo init").
"""
sys.exit(1)
def _Help(args):
if args:
if args[0] == 'init':
init_optparse.print_help()
sys.exit(0)
else:
print >>sys.stderr,\
"error: '%s' is not a bootstrap command.\n"\
' For access to online help, install repo ("repo init").'\
% args[0]
else:
_Usage()
sys.exit(1)
def _NotInstalled():
print >>sys.stderr,\
'error: repo is not installed. Use "repo init" to install it here.'
sys.exit(1)
def _NoCommands(cmd):
print >>sys.stderr,\
"""error: command '%s' requires repo to be installed first.
Use "repo init" to install it here.""" % cmd
sys.exit(1)
if os.path.isfile(my_main) and os.path.isdir(my_git):
for name in ['git_config.py',
'project.py',
'subcmds']:
if not os.path.exists(os.path.join(my_dir, name)):
return None, None
return my_main, my_git
return None, None
def _SetDefaultsTo(gitdir):
global REPO_URL
global REPO_REV
if not main:
if opt.help:
_Usage()
if cmd == 'help':
_Help(args)
if not cmd:
_NotInstalled()
if cmd == 'init':
if my_git:
_SetDefaultsTo(my_git)
try:
_Init(args)
except CloneFailure:
for root, dirs, files in os.walk(repodir, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(repodir)
sys.exit(1)
main, dir = _FindRepo()
else:
_NoCommands(cmd)