diff options
Diffstat (limited to 'subcmds/init.py')
| -rw-r--r-- | subcmds/init.py | 173 |
1 files changed, 112 insertions, 61 deletions
diff --git a/subcmds/init.py b/subcmds/init.py index 2ca4e163..a758fbb1 100644 --- a/subcmds/init.py +++ b/subcmds/init.py | |||
| @@ -14,16 +14,17 @@ | |||
| 14 | # limitations under the License. | 14 | # limitations under the License. |
| 15 | 15 | ||
| 16 | import os | 16 | import os |
| 17 | import platform | ||
| 18 | import re | ||
| 19 | import shutil | ||
| 17 | import sys | 20 | import sys |
| 18 | 21 | ||
| 19 | from color import Coloring | 22 | from color import Coloring |
| 20 | from command import InteractiveCommand, MirrorSafeCommand | 23 | from command import InteractiveCommand, MirrorSafeCommand |
| 21 | from error import ManifestParseError | 24 | from error import ManifestParseError |
| 22 | from project import SyncBuffer | 25 | from project import SyncBuffer |
| 26 | from git_config import GitConfig | ||
| 23 | from git_command import git_require, MIN_GIT_VERSION | 27 | from git_command import git_require, MIN_GIT_VERSION |
| 24 | from manifest_submodule import SubmoduleManifest | ||
| 25 | from manifest_xml import XmlManifest | ||
| 26 | from subcmds.sync import _ReloadManifest | ||
| 27 | 28 | ||
| 28 | class Init(InteractiveCommand, MirrorSafeCommand): | 29 | class Init(InteractiveCommand, MirrorSafeCommand): |
| 29 | common = True | 30 | common = True |
| @@ -75,21 +76,27 @@ to update the working directory files. | |||
| 75 | g.add_option('-b', '--manifest-branch', | 76 | g.add_option('-b', '--manifest-branch', |
| 76 | dest='manifest_branch', | 77 | dest='manifest_branch', |
| 77 | help='manifest branch or revision', metavar='REVISION') | 78 | help='manifest branch or revision', metavar='REVISION') |
| 78 | g.add_option('-o', '--origin', | 79 | g.add_option('-m', '--manifest-name', |
| 79 | dest='manifest_origin', | 80 | dest='manifest_name', default='default.xml', |
| 80 | help="use REMOTE instead of 'origin' to track upstream", | 81 | help='initial manifest file', metavar='NAME.xml') |
| 81 | metavar='REMOTE') | ||
| 82 | if isinstance(self.manifest, XmlManifest) \ | ||
| 83 | or not self.manifest.manifestProject.Exists: | ||
| 84 | g.add_option('-m', '--manifest-name', | ||
| 85 | dest='manifest_name', default='default.xml', | ||
| 86 | help='initial manifest file', metavar='NAME.xml') | ||
| 87 | g.add_option('--mirror', | 82 | g.add_option('--mirror', |
| 88 | dest='mirror', action='store_true', | 83 | dest='mirror', action='store_true', |
| 89 | help='mirror the forrest') | 84 | help='mirror the forrest') |
| 90 | g.add_option('--reference', | 85 | g.add_option('--reference', |
| 91 | dest='reference', | 86 | dest='reference', |
| 92 | help='location of mirror directory', metavar='DIR') | 87 | help='location of mirror directory', metavar='DIR') |
| 88 | g.add_option('--depth', type='int', default=None, | ||
| 89 | dest='depth', | ||
| 90 | help='create a shallow clone with given depth; see git clone') | ||
| 91 | g.add_option('-g', '--groups', | ||
| 92 | dest='groups', default='default', | ||
| 93 | help='restrict manifest projects to ones with a specified group', | ||
| 94 | metavar='GROUP') | ||
| 95 | g.add_option('-p', '--platform', | ||
| 96 | dest='platform', default='auto', | ||
| 97 | help='restrict manifest projects to ones with a specified' | ||
| 98 | 'platform group [auto|all|none|linux|darwin|...]', | ||
| 99 | metavar='PLATFORM') | ||
| 93 | 100 | ||
| 94 | # Tool | 101 | # Tool |
| 95 | g = p.add_option_group('repo Version options') | 102 | g = p.add_option_group('repo Version options') |
| @@ -103,91 +110,94 @@ to update the working directory files. | |||
| 103 | dest='no_repo_verify', action='store_true', | 110 | dest='no_repo_verify', action='store_true', |
| 104 | help='do not verify repo source code') | 111 | help='do not verify repo source code') |
| 105 | 112 | ||
| 106 | def _ApplyOptions(self, opt, is_new): | 113 | # Other |
| 114 | g = p.add_option_group('Other options') | ||
| 115 | g.add_option('--config-name', | ||
| 116 | dest='config_name', action="store_true", default=False, | ||
| 117 | help='Always prompt for name/e-mail') | ||
| 118 | |||
| 119 | def _SyncManifest(self, opt): | ||
| 107 | m = self.manifest.manifestProject | 120 | m = self.manifest.manifestProject |
| 121 | is_new = not m.Exists | ||
| 108 | 122 | ||
| 109 | if is_new: | 123 | if is_new: |
| 110 | if opt.manifest_origin: | 124 | if not opt.manifest_url: |
| 111 | m.remote.name = opt.manifest_origin | 125 | print >>sys.stderr, 'fatal: manifest url (-u) is required.' |
| 126 | sys.exit(1) | ||
| 127 | |||
| 128 | if not opt.quiet: | ||
| 129 | print >>sys.stderr, 'Get %s' \ | ||
| 130 | % GitConfig.ForUser().UrlInsteadOf(opt.manifest_url) | ||
| 131 | m._InitGitDir() | ||
| 112 | 132 | ||
| 113 | if opt.manifest_branch: | 133 | if opt.manifest_branch: |
| 114 | m.revisionExpr = opt.manifest_branch | 134 | m.revisionExpr = opt.manifest_branch |
| 115 | else: | 135 | else: |
| 116 | m.revisionExpr = 'refs/heads/master' | 136 | m.revisionExpr = 'refs/heads/master' |
| 117 | else: | 137 | else: |
| 118 | if opt.manifest_origin: | ||
| 119 | print >>sys.stderr, 'fatal: cannot change origin name' | ||
| 120 | sys.exit(1) | ||
| 121 | |||
| 122 | if opt.manifest_branch: | 138 | if opt.manifest_branch: |
| 123 | m.revisionExpr = opt.manifest_branch | 139 | m.revisionExpr = opt.manifest_branch |
| 124 | else: | 140 | else: |
| 125 | m.PreSync() | 141 | m.PreSync() |
| 126 | 142 | ||
| 127 | def _SyncManifest(self, opt): | ||
| 128 | m = self.manifest.manifestProject | ||
| 129 | is_new = not m.Exists | ||
| 130 | |||
| 131 | if is_new: | ||
| 132 | if not opt.manifest_url: | ||
| 133 | print >>sys.stderr, 'fatal: manifest url (-u) is required.' | ||
| 134 | sys.exit(1) | ||
| 135 | |||
| 136 | if not opt.quiet: | ||
| 137 | print >>sys.stderr, 'Getting manifest ...' | ||
| 138 | print >>sys.stderr, ' from %s' % opt.manifest_url | ||
| 139 | m._InitGitDir() | ||
| 140 | |||
| 141 | self._ApplyOptions(opt, is_new) | ||
| 142 | if opt.manifest_url: | 143 | if opt.manifest_url: |
| 143 | r = m.GetRemote(m.remote.name) | 144 | r = m.GetRemote(m.remote.name) |
| 144 | r.url = opt.manifest_url | 145 | r.url = opt.manifest_url |
| 145 | r.ResetFetch() | 146 | r.ResetFetch() |
| 146 | r.Save() | 147 | r.Save() |
| 147 | 148 | ||
| 149 | groups = re.split('[,\s]+', opt.groups) | ||
| 150 | all_platforms = ['linux', 'darwin'] | ||
| 151 | platformize = lambda x: 'platform-' + x | ||
| 152 | if opt.platform == 'auto': | ||
| 153 | if (not opt.mirror and | ||
| 154 | not m.config.GetString('repo.mirror') == 'true'): | ||
| 155 | groups.append(platformize(platform.system().lower())) | ||
| 156 | elif opt.platform == 'all': | ||
| 157 | groups.extend(map(platformize, all_platforms)) | ||
| 158 | elif opt.platform in all_platforms: | ||
| 159 | groups.extend(platformize(opt.platform)) | ||
| 160 | elif opt.platform != 'none': | ||
| 161 | print >>sys.stderr, 'fatal: invalid platform flag' | ||
| 162 | sys.exit(1) | ||
| 163 | |||
| 164 | groups = [x for x in groups if x] | ||
| 165 | groupstr = ','.join(groups) | ||
| 166 | if opt.platform == 'auto' and groupstr == 'default,platform-' + platform.system().lower(): | ||
| 167 | groupstr = None | ||
| 168 | m.config.SetString('manifest.groups', groupstr) | ||
| 169 | |||
| 148 | if opt.reference: | 170 | if opt.reference: |
| 149 | m.config.SetString('repo.reference', opt.reference) | 171 | m.config.SetString('repo.reference', opt.reference) |
| 150 | 172 | ||
| 151 | if opt.mirror: | 173 | if opt.mirror: |
| 152 | if is_new: | 174 | if is_new: |
| 153 | m.config.SetString('repo.mirror', 'true') | 175 | m.config.SetString('repo.mirror', 'true') |
| 154 | m.config.ClearCache() | ||
| 155 | else: | 176 | else: |
| 156 | print >>sys.stderr, 'fatal: --mirror not supported on existing client' | 177 | print >>sys.stderr, 'fatal: --mirror not supported on existing client' |
| 157 | sys.exit(1) | 178 | sys.exit(1) |
| 158 | 179 | ||
| 159 | if not m.Sync_NetworkHalf(): | 180 | if not m.Sync_NetworkHalf(is_new=is_new): |
| 160 | r = m.GetRemote(m.remote.name) | 181 | r = m.GetRemote(m.remote.name) |
| 161 | print >>sys.stderr, 'fatal: cannot obtain manifest %s' % r.url | 182 | print >>sys.stderr, 'fatal: cannot obtain manifest %s' % r.url |
| 162 | sys.exit(1) | ||
| 163 | 183 | ||
| 164 | if is_new and SubmoduleManifest.IsBare(m): | 184 | # Better delete the manifest git dir if we created it; otherwise next |
| 165 | new = self.GetManifest(reparse=True, type=SubmoduleManifest) | 185 | # time (when user fixes problems) we won't go through the "is_new" logic. |
| 166 | if m.gitdir != new.manifestProject.gitdir: | 186 | if is_new: |
| 167 | os.rename(m.gitdir, new.manifestProject.gitdir) | 187 | shutil.rmtree(m.gitdir) |
| 168 | new = self.GetManifest(reparse=True, type=SubmoduleManifest) | 188 | sys.exit(1) |
| 169 | m = new.manifestProject | ||
| 170 | self._ApplyOptions(opt, is_new) | ||
| 171 | 189 | ||
| 172 | if not is_new: | 190 | if opt.manifest_branch: |
| 173 | # Force the manifest to load if it exists, the old graph | 191 | m.MetaBranchSwitch(opt.manifest_branch) |
| 174 | # may be needed inside of _ReloadManifest(). | ||
| 175 | # | ||
| 176 | self.manifest.projects | ||
| 177 | 192 | ||
| 178 | syncbuf = SyncBuffer(m.config) | 193 | syncbuf = SyncBuffer(m.config) |
| 179 | m.Sync_LocalHalf(syncbuf) | 194 | m.Sync_LocalHalf(syncbuf) |
| 180 | syncbuf.Finish() | 195 | syncbuf.Finish() |
| 181 | 196 | ||
| 182 | if isinstance(self.manifest, XmlManifest): | 197 | if is_new or m.CurrentBranch is None: |
| 183 | self._LinkManifest(opt.manifest_name) | 198 | if not m.StartBranch('default'): |
| 184 | _ReloadManifest(self) | 199 | print >>sys.stderr, 'fatal: cannot create default in manifest' |
| 185 | 200 | sys.exit(1) | |
| 186 | self._ApplyOptions(opt, is_new) | ||
| 187 | |||
| 188 | if not self.manifest.InitBranch(): | ||
| 189 | print >>sys.stderr, 'fatal: cannot create branch in manifest' | ||
| 190 | sys.exit(1) | ||
| 191 | 201 | ||
| 192 | def _LinkManifest(self, name): | 202 | def _LinkManifest(self, name): |
| 193 | if not name: | 203 | if not name: |
| @@ -210,6 +220,24 @@ to update the working directory files. | |||
| 210 | return value | 220 | return value |
| 211 | return a | 221 | return a |
| 212 | 222 | ||
| 223 | def _ShouldConfigureUser(self): | ||
| 224 | gc = self.manifest.globalConfig | ||
| 225 | mp = self.manifest.manifestProject | ||
| 226 | |||
| 227 | # If we don't have local settings, get from global. | ||
| 228 | if not mp.config.Has('user.name') or not mp.config.Has('user.email'): | ||
| 229 | if not gc.Has('user.name') or not gc.Has('user.email'): | ||
| 230 | return True | ||
| 231 | |||
| 232 | mp.config.SetString('user.name', gc.GetString('user.name')) | ||
| 233 | mp.config.SetString('user.email', gc.GetString('user.email')) | ||
| 234 | |||
| 235 | print '' | ||
| 236 | print 'Your identity is: %s <%s>' % (mp.config.GetString('user.name'), | ||
| 237 | mp.config.GetString('user.email')) | ||
| 238 | print 'If you want to change this, please re-run \'repo init\' with --config-name' | ||
| 239 | return False | ||
| 240 | |||
| 213 | def _ConfigureUser(self): | 241 | def _ConfigureUser(self): |
| 214 | mp = self.manifest.manifestProject | 242 | mp = self.manifest.manifestProject |
| 215 | 243 | ||
| @@ -220,7 +248,7 @@ to update the working directory files. | |||
| 220 | 248 | ||
| 221 | print '' | 249 | print '' |
| 222 | print 'Your identity is: %s <%s>' % (name, email) | 250 | print 'Your identity is: %s <%s>' % (name, email) |
| 223 | sys.stdout.write('is this correct [y/n]? ') | 251 | sys.stdout.write('is this correct [y/N]? ') |
| 224 | a = sys.stdin.readline().strip() | 252 | a = sys.stdin.readline().strip() |
| 225 | if a in ('yes', 'y', 't', 'true'): | 253 | if a in ('yes', 'y', 't', 'true'): |
| 226 | break | 254 | break |
| @@ -262,19 +290,42 @@ to update the working directory files. | |||
| 262 | out.printer(fg='black', attr=c)(' %-6s ', c) | 290 | out.printer(fg='black', attr=c)(' %-6s ', c) |
| 263 | out.nl() | 291 | out.nl() |
| 264 | 292 | ||
| 265 | sys.stdout.write('Enable color display in this user account (y/n)? ') | 293 | sys.stdout.write('Enable color display in this user account (y/N)? ') |
| 266 | a = sys.stdin.readline().strip().lower() | 294 | a = sys.stdin.readline().strip().lower() |
| 267 | if a in ('y', 'yes', 't', 'true', 'on'): | 295 | if a in ('y', 'yes', 't', 'true', 'on'): |
| 268 | gc.SetString('color.ui', 'auto') | 296 | gc.SetString('color.ui', 'auto') |
| 269 | 297 | ||
| 298 | def _ConfigureDepth(self, opt): | ||
| 299 | """Configure the depth we'll sync down. | ||
| 300 | |||
| 301 | Args: | ||
| 302 | opt: Options from optparse. We care about opt.depth. | ||
| 303 | """ | ||
| 304 | # Opt.depth will be non-None if user actually passed --depth to repo init. | ||
| 305 | if opt.depth is not None: | ||
| 306 | if opt.depth > 0: | ||
| 307 | # Positive values will set the depth. | ||
| 308 | depth = str(opt.depth) | ||
| 309 | else: | ||
| 310 | # Negative numbers will clear the depth; passing None to SetString | ||
| 311 | # will do that. | ||
| 312 | depth = None | ||
| 313 | |||
| 314 | # We store the depth in the main manifest project. | ||
| 315 | self.manifest.manifestProject.config.SetString('repo.depth', depth) | ||
| 316 | |||
| 270 | def Execute(self, opt, args): | 317 | def Execute(self, opt, args): |
| 271 | git_require(MIN_GIT_VERSION, fail=True) | 318 | git_require(MIN_GIT_VERSION, fail=True) |
| 272 | self._SyncManifest(opt) | 319 | self._SyncManifest(opt) |
| 320 | self._LinkManifest(opt.manifest_name) | ||
| 273 | 321 | ||
| 274 | if os.isatty(0) and os.isatty(1) and not self.manifest.IsMirror: | 322 | if os.isatty(0) and os.isatty(1) and not self.manifest.IsMirror: |
| 275 | self._ConfigureUser() | 323 | if opt.config_name or self._ShouldConfigureUser(): |
| 324 | self._ConfigureUser() | ||
| 276 | self._ConfigureColor() | 325 | self._ConfigureColor() |
| 277 | 326 | ||
| 327 | self._ConfigureDepth(opt) | ||
| 328 | |||
| 278 | if self.manifest.IsMirror: | 329 | if self.manifest.IsMirror: |
| 279 | type = 'mirror ' | 330 | type = 'mirror ' |
| 280 | else: | 331 | else: |
