|
|
|
@ -147,7 +147,7 @@ if not REPO_REV:
|
|
|
|
|
REPO_REV = 'stable'
|
|
|
|
|
|
|
|
|
|
# increment this whenever we make important changes to this script
|
|
|
|
|
VERSION = (2, 11)
|
|
|
|
|
VERSION = (2, 12)
|
|
|
|
|
|
|
|
|
|
# increment this if the MAINTAINER_KEYS block is modified
|
|
|
|
|
KEYRING_VERSION = (2, 3)
|
|
|
|
@ -246,6 +246,7 @@ GITC_FS_ROOT_DIR = '/gitc/manifest-rw/'
|
|
|
|
|
|
|
|
|
|
import collections
|
|
|
|
|
import errno
|
|
|
|
|
import json
|
|
|
|
|
import optparse
|
|
|
|
|
import re
|
|
|
|
|
import shutil
|
|
|
|
@ -269,9 +270,9 @@ gpg_dir = os.path.join(home_dot_repo, 'gnupg')
|
|
|
|
|
def GetParser(gitc_init=False):
|
|
|
|
|
"""Setup the CLI parser."""
|
|
|
|
|
if gitc_init:
|
|
|
|
|
usage = 'repo gitc-init -u url -c client [options]'
|
|
|
|
|
usage = 'repo gitc-init -c client [options] [-u] url'
|
|
|
|
|
else:
|
|
|
|
|
usage = 'repo init -u url [options]'
|
|
|
|
|
usage = 'repo init [options] [-u] url'
|
|
|
|
|
|
|
|
|
|
parser = optparse.OptionParser(usage=usage)
|
|
|
|
|
|
|
|
|
@ -288,8 +289,8 @@ def GetParser(gitc_init=False):
|
|
|
|
|
group = parser.add_option_group('Manifest options')
|
|
|
|
|
group.add_option('-u', '--manifest-url',
|
|
|
|
|
help='manifest repository location', metavar='URL')
|
|
|
|
|
group.add_option('-b', '--manifest-branch',
|
|
|
|
|
help='manifest branch or revision', metavar='REVISION')
|
|
|
|
|
group.add_option('-b', '--manifest-branch', metavar='REVISION',
|
|
|
|
|
help='manifest branch or revision (use HEAD for default)')
|
|
|
|
|
group.add_option('-m', '--manifest-name',
|
|
|
|
|
help='initial manifest file', metavar='NAME.xml')
|
|
|
|
|
cbr_opts = ['--current-branch']
|
|
|
|
@ -323,6 +324,11 @@ def GetParser(gitc_init=False):
|
|
|
|
|
'each project. See git archive.')
|
|
|
|
|
group.add_option('--submodules', action='store_true',
|
|
|
|
|
help='sync any submodules associated with the manifest repo')
|
|
|
|
|
group.add_option('--use-superproject', action='store_true', default=None,
|
|
|
|
|
help='use the manifest superproject to sync projects')
|
|
|
|
|
group.add_option('--no-use-superproject', action='store_false',
|
|
|
|
|
dest='use_superproject',
|
|
|
|
|
help='disable use of manifest superprojects')
|
|
|
|
|
group.add_option('-g', '--groups', default='default',
|
|
|
|
|
help='restrict manifest projects to ones with specified '
|
|
|
|
|
'group(s) [default|all|G1,G2,G3|G4,-G5,-G6]',
|
|
|
|
@ -332,7 +338,8 @@ def GetParser(gitc_init=False):
|
|
|
|
|
'platform group [auto|all|none|linux|darwin|...]',
|
|
|
|
|
metavar='PLATFORM')
|
|
|
|
|
group.add_option('--clone-bundle', action='store_true',
|
|
|
|
|
help='enable use of /clone.bundle on HTTP/HTTPS (default if not --partial-clone)')
|
|
|
|
|
help='enable use of /clone.bundle on HTTP/HTTPS '
|
|
|
|
|
'(default if not --partial-clone)')
|
|
|
|
|
group.add_option('--no-clone-bundle',
|
|
|
|
|
dest='clone_bundle', action='store_false',
|
|
|
|
|
help='disable use of /clone.bundle on HTTP/HTTPS (default if --partial-clone)')
|
|
|
|
@ -515,8 +522,11 @@ def _Init(args, gitc_init=False):
|
|
|
|
|
parser = GetParser(gitc_init=gitc_init)
|
|
|
|
|
opt, args = parser.parse_args(args)
|
|
|
|
|
if args:
|
|
|
|
|
parser.print_usage()
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
if not opt.manifest_url:
|
|
|
|
|
opt.manifest_url = args.pop(0)
|
|
|
|
|
if args:
|
|
|
|
|
parser.print_usage()
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
opt.quiet = opt.output_mode is False
|
|
|
|
|
opt.verbose = opt.output_mode is True
|
|
|
|
|
|
|
|
|
@ -1035,6 +1045,90 @@ def _ParseArguments(args):
|
|
|
|
|
return cmd, opt, arg
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Requirements(object):
|
|
|
|
|
"""Helper for checking repo's system requirements."""
|
|
|
|
|
|
|
|
|
|
REQUIREMENTS_NAME = 'requirements.json'
|
|
|
|
|
|
|
|
|
|
def __init__(self, requirements):
|
|
|
|
|
"""Initialize.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
requirements: A dictionary of settings.
|
|
|
|
|
"""
|
|
|
|
|
self.requirements = requirements
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def from_dir(cls, path):
|
|
|
|
|
return cls.from_file(os.path.join(path, cls.REQUIREMENTS_NAME))
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def from_file(cls, path):
|
|
|
|
|
try:
|
|
|
|
|
with open(path, 'rb') as f:
|
|
|
|
|
data = f.read()
|
|
|
|
|
except EnvironmentError:
|
|
|
|
|
# NB: EnvironmentError is used for Python 2 & 3 compatibility.
|
|
|
|
|
# If we couldn't open the file, assume it's an old source tree.
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
return cls.from_data(data)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def from_data(cls, data):
|
|
|
|
|
comment_line = re.compile(br'^ *#')
|
|
|
|
|
strip_data = b''.join(x for x in data.splitlines() if not comment_line.match(x))
|
|
|
|
|
try:
|
|
|
|
|
json_data = json.loads(strip_data)
|
|
|
|
|
except Exception: # pylint: disable=broad-except
|
|
|
|
|
# If we couldn't parse it, assume it's incompatible.
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
return cls(json_data)
|
|
|
|
|
|
|
|
|
|
def _get_soft_ver(self, pkg):
|
|
|
|
|
"""Return the soft version for |pkg| if it exists."""
|
|
|
|
|
return self.requirements.get(pkg, {}).get('soft', ())
|
|
|
|
|
|
|
|
|
|
def _get_hard_ver(self, pkg):
|
|
|
|
|
"""Return the hard version for |pkg| if it exists."""
|
|
|
|
|
return self.requirements.get(pkg, {}).get('hard', ())
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _format_ver(ver):
|
|
|
|
|
"""Return a dotted version from |ver|."""
|
|
|
|
|
return '.'.join(str(x) for x in ver)
|
|
|
|
|
|
|
|
|
|
def assert_ver(self, pkg, curr_ver):
|
|
|
|
|
"""Verify |pkg|'s |curr_ver| is new enough."""
|
|
|
|
|
curr_ver = tuple(curr_ver)
|
|
|
|
|
soft_ver = tuple(self._get_soft_ver(pkg))
|
|
|
|
|
hard_ver = tuple(self._get_hard_ver(pkg))
|
|
|
|
|
if curr_ver < hard_ver:
|
|
|
|
|
print('repo: error: Your version of "%s" (%s) is unsupported; '
|
|
|
|
|
'Please upgrade to at least version %s to continue.' %
|
|
|
|
|
(pkg, self._format_ver(curr_ver), self._format_ver(soft_ver)),
|
|
|
|
|
file=sys.stderr)
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
if curr_ver < soft_ver:
|
|
|
|
|
print('repo: warning: Your version of "%s" (%s) is no longer supported; '
|
|
|
|
|
'Please upgrade to at least version %s to avoid breakage.' %
|
|
|
|
|
(pkg, self._format_ver(curr_ver), self._format_ver(soft_ver)),
|
|
|
|
|
file=sys.stderr)
|
|
|
|
|
|
|
|
|
|
def assert_all(self):
|
|
|
|
|
"""Assert all of the requirements are satisified."""
|
|
|
|
|
# See if we need a repo launcher upgrade first.
|
|
|
|
|
self.assert_ver('repo', VERSION)
|
|
|
|
|
|
|
|
|
|
# Check python before we try to import the repo code.
|
|
|
|
|
self.assert_ver('python', sys.version_info)
|
|
|
|
|
|
|
|
|
|
# Check git while we're at it.
|
|
|
|
|
self.assert_ver('git', ParseGitVersion())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _Usage():
|
|
|
|
|
gitc_usage = ""
|
|
|
|
|
if get_gitc_manifest_dir():
|
|
|
|
@ -1192,6 +1286,10 @@ def main(orig_args):
|
|
|
|
|
print("fatal: unable to find repo entry point", file=sys.stderr)
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
reqs = Requirements.from_dir(os.path.dirname(repo_main))
|
|
|
|
|
if reqs:
|
|
|
|
|
reqs.assert_all()
|
|
|
|
|
|
|
|
|
|
ver_str = '.'.join(map(str, VERSION))
|
|
|
|
|
me = [sys.executable, repo_main,
|
|
|
|
|
'--repo-dir=%s' % rel_repo_dir,
|
|
|
|
|