2 # -*- coding: utf-8 -*-
4 """Wrapper for syncing CrOS code.
7 depot_tools clone depot_tools tree
8 int switch to internal tree
9 ext switch to external tree
11 Operates on the repo in the cwd.
21 REPO_URL
= 'https://chromium.googlesource.com/external/repo'
22 INT_MANIFEST
= 'https://chrome-internal.googlesource.com/chromeos/manifest-internal'
23 EXT_MANIFEST
= 'https://chromium.googlesource.com/chromiumos/manifest'
26 def run(cmd
, **kwargs
):
27 """Run with command tracing."""
28 # Python 3.6 doesn't support capture_output.
29 if sys
.version_info
< (3, 7):
30 capture_output
= kwargs
.pop('capture_output', None)
32 assert 'stdout' not in kwargs
and 'stderr' not in kwargs
33 kwargs
['stdout'] = subprocess
.PIPE
34 kwargs
['stderr'] = subprocess
.PIPE
36 print(kwargs
.get('cwd', os
.getcwd()))
38 return subprocess
.run(cmd
, **kwargs
)
41 def expand_branch(opts
):
42 """Support branch shortnames."""
43 url
= INT_MANIFEST
if opts
.action
== 'int' else EXT_MANIFEST
44 ret
= run(['git', 'ls-remote', url
, 'refs/heads/*'], capture_output
=True, encoding
='utf-8')
45 branches
= [x
.split()[-1].split('/')[-1] for x
in ret
.stdout
.splitlines()]
47 for branch
in branches
:
48 if fnmatch
.fnmatch(branch
.lower(), f
'*{opts.branch.lower()}*'):
51 print(f
'error: could not match branch {opts.branch}', file=sys
.stderr
)
52 print(f
'Available branches:\n{" ".join(sorted(branches))}', file=sys
.stderr
)
55 print(f
'error: too many branches match {opts.branch}:\n{" ".join(sorted(ret))}',
58 print(f
'Expanded branch {opts.branch} into {ret[0]}')
62 def set_git_config(opts
):
63 """Set .git/config settings in all the repos."""
66 rdir
= os
.path
.join(topdir
, '.repo')
67 if os
.path
.exists(rdir
):
69 topdir
= os
.path
.dirname(topdir
)
72 def gcfg(path
, *args
):
73 cmd
= ['git', f
'--git-dir={path}', 'config', 'user.email'] + list(args
)
74 ret
= run(cmd
, capture_output
=True, encoding
='utf-8')
75 return ret
.stdout
.strip()
77 current_email
= gcfg(os
.path
.join(rdir
, 'manifests.git'))
78 if current_email
== opts
.email
:
81 print(f
'Setting e-mail to {opts.email}')
82 for root
, dirs
, files
in os
.walk(rdir
):
83 if root
.endswith('.git') and not os
.path
.islink(os
.path
.join(root
, 'config')):
84 gcfg(root
, opts
.email
)
89 """Initialize CrOS checkout."""
90 cmd
= ['repo', 'init']
92 if opts
.action
== 'int':
93 cmd
+= ['-u', INT_MANIFEST
]
94 cmd
+= ['--repo-url', REPO_URL
]
95 elif opts
.action
== 'ext':
96 cmd
+= ['-u', EXT_MANIFEST
]
97 cmd
+= ['--repo-url', REPO_URL
]
100 cmd
+= ['--reference', opts
.ref
]
103 cmd
+= ['-m', opts
.manifest
]
106 cmd
+= ['-g', opts
.group
]
109 branch
= expand_branch(opts
)
110 cmd
+= ['-b', branch
]
114 return ret
.returncode
118 print('\ncros-repo: all done')
122 def clone_depot_tools():
123 """Clone depot_tools repo."""
124 ret
= run(['git', 'clone', 'https://chromium.googlesource.com/chromium/tools/depot_tools'])
125 return ret
.returncode
129 """Get command line parser."""
130 parser
= argparse
.ArgumentParser(
132 formatter_class
=argparse
.RawDescriptionHelpFormatter
)
133 parser
.add_argument('-b', '--branch',
134 help='Switch branches (use "master" to get to ToT)')
135 parser
.add_argument('-r', '--ref', '--reference', default
='~/chromiumos/',
136 help='Patch to reference repo (default: %(default)s)')
137 parser
.add_argument('-g', '--group',
138 help='Manifest group to use (e.g. "minilayout")')
139 parser
.add_argument('-m', '--manifest',
140 help='Manifest file name to use (e.g. "full.xml")')
141 parser
.add_argument('-e', '--email', default
='vapier@chromium.org',
142 help='E-mail address to force (default: %(default)s)')
143 parser
.add_argument('action', nargs
='?',
144 choices
={'depot_tools', 'dt', 'int', 'ext'},
151 parser
= get_parser()
152 opts
= parser
.parse_args(argv
)
154 if '/' in opts
.manifest
:
155 parser
.error('manifest should be basename like "full.xml"')
156 if opts
.manifest
.endswith('.xml'):
157 opts
.manifest
= opts
.manifest
[:-4]
158 opts
.manifest
+= '.xml'
160 opts
.ref
= os
.path
.expanduser(opts
.ref
)
162 if opts
.action
in {'depot_tools', 'dt'}:
163 return clone_depot_tools()
165 return init_repo(opts
)
168 if __name__
== '__main__':
169 sys
.exit(main(sys
.argv
[1:]))