init.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #
  2. # Copyright (C) 2008 The Android Open Source Project
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import os
  16. import sys
  17. from color import Coloring
  18. from command import InteractiveCommand, MirrorSafeCommand
  19. from error import ManifestParseError
  20. from remote import Remote
  21. from project import SyncBuffer
  22. from git_command import git, MIN_GIT_VERSION
  23. class Init(InteractiveCommand, MirrorSafeCommand):
  24. common = True
  25. helpSummary = "Initialize repo in the current directory"
  26. helpUsage = """
  27. %prog [options]
  28. """
  29. helpDescription = """
  30. The '%prog' command is run once to install and initialize repo.
  31. The latest repo source code and manifest collection is downloaded
  32. from the server and is installed in the .repo/ directory in the
  33. current working directory.
  34. The optional <manifest> argument can be used to specify an alternate
  35. manifest to be used. If no manifest is specified, the manifest
  36. default.xml will be used.
  37. """
  38. def _Options(self, p):
  39. # Logging
  40. g = p.add_option_group('Logging options')
  41. g.add_option('-q', '--quiet',
  42. dest="quiet", action="store_true", default=False,
  43. help="be quiet")
  44. # Manifest
  45. g = p.add_option_group('Manifest options')
  46. g.add_option('-u', '--manifest-url',
  47. dest='manifest_url',
  48. help='manifest repository location', metavar='URL')
  49. g.add_option('-b', '--manifest-branch',
  50. dest='manifest_branch',
  51. help='manifest branch or revision', metavar='REVISION')
  52. g.add_option('-m', '--manifest-name',
  53. dest='manifest_name', default='default.xml',
  54. help='initial manifest file', metavar='NAME.xml')
  55. g.add_option('--mirror',
  56. dest='mirror', action='store_true',
  57. help='mirror the forrest')
  58. # Tool
  59. g = p.add_option_group('Version options')
  60. g.add_option('--repo-url',
  61. dest='repo_url',
  62. help='repo repository location', metavar='URL')
  63. g.add_option('--repo-branch',
  64. dest='repo_branch',
  65. help='repo branch or revision', metavar='REVISION')
  66. g.add_option('--no-repo-verify',
  67. dest='no_repo_verify', action='store_true',
  68. help='do not verify repo source code')
  69. def _CheckGitVersion(self):
  70. ver_str = git.version()
  71. if not ver_str.startswith('git version '):
  72. print >>sys.stderr, 'error: "%s" unsupported' % ver_str
  73. sys.exit(1)
  74. ver_str = ver_str[len('git version '):].strip()
  75. ver_act = tuple(map(lambda x: int(x), ver_str.split('.')[0:3]))
  76. if ver_act < MIN_GIT_VERSION:
  77. need = '.'.join(map(lambda x: str(x), MIN_GIT_VERSION))
  78. print >>sys.stderr, 'fatal: git %s or later required' % need
  79. sys.exit(1)
  80. def _SyncManifest(self, opt):
  81. m = self.manifest.manifestProject
  82. is_new = not m.Exists
  83. if is_new:
  84. if not opt.manifest_url:
  85. print >>sys.stderr, 'fatal: manifest url (-u) is required.'
  86. sys.exit(1)
  87. if not opt.quiet:
  88. print >>sys.stderr, 'Getting manifest ...'
  89. print >>sys.stderr, ' from %s' % opt.manifest_url
  90. m._InitGitDir()
  91. if opt.manifest_branch:
  92. m.revision = opt.manifest_branch
  93. else:
  94. m.revision = 'refs/heads/master'
  95. else:
  96. if opt.manifest_branch:
  97. m.revision = opt.manifest_branch
  98. else:
  99. m.PreSync()
  100. if opt.manifest_url:
  101. r = m.GetRemote(m.remote.name)
  102. r.url = opt.manifest_url
  103. r.ResetFetch()
  104. r.Save()
  105. if opt.mirror:
  106. if is_new:
  107. m.config.SetString('repo.mirror', 'true')
  108. else:
  109. print >>sys.stderr, 'fatal: --mirror not supported on existing client'
  110. sys.exit(1)
  111. if not m.Sync_NetworkHalf():
  112. r = m.GetRemote(m.remote.name)
  113. print >>sys.stderr, 'fatal: cannot obtain manifest %s' % r.url
  114. sys.exit(1)
  115. syncbuf = SyncBuffer(m.config)
  116. m.Sync_LocalHalf(syncbuf)
  117. syncbuf.Finish()
  118. if is_new or m.CurrentBranch is None:
  119. if not m.StartBranch('default'):
  120. print >>sys.stderr, 'fatal: cannot create default in manifest'
  121. sys.exit(1)
  122. def _LinkManifest(self, name):
  123. if not name:
  124. print >>sys.stderr, 'fatal: manifest name (-m) is required.'
  125. sys.exit(1)
  126. try:
  127. self.manifest.Link(name)
  128. except ManifestParseError, e:
  129. print >>sys.stderr, "fatal: manifest '%s' not available" % name
  130. print >>sys.stderr, 'fatal: %s' % str(e)
  131. sys.exit(1)
  132. def _PromptKey(self, prompt, key, value):
  133. mp = self.manifest.manifestProject
  134. sys.stdout.write('%-10s [%s]: ' % (prompt, value))
  135. a = sys.stdin.readline().strip()
  136. if a != '' and a != value:
  137. mp.config.SetString(key, a)
  138. def _ConfigureUser(self):
  139. mp = self.manifest.manifestProject
  140. print ''
  141. self._PromptKey('Your Name', 'user.name', mp.UserName)
  142. self._PromptKey('Your Email', 'user.email', mp.UserEmail)
  143. def _HasColorSet(self, gc):
  144. for n in ['ui', 'diff', 'status']:
  145. if gc.Has('color.%s' % n):
  146. return True
  147. return False
  148. def _ConfigureColor(self):
  149. gc = self.manifest.globalConfig
  150. if self._HasColorSet(gc):
  151. return
  152. class _Test(Coloring):
  153. def __init__(self):
  154. Coloring.__init__(self, gc, 'test color display')
  155. self._on = True
  156. out = _Test()
  157. print ''
  158. print "Testing colorized output (for 'repo diff', 'repo status'):"
  159. for c in ['black','red','green','yellow','blue','magenta','cyan']:
  160. out.write(' ')
  161. out.printer(fg=c)(' %-6s ', c)
  162. out.write(' ')
  163. out.printer(fg='white', bg='black')(' %s ' % 'white')
  164. out.nl()
  165. for c in ['bold','dim','ul','reverse']:
  166. out.write(' ')
  167. out.printer(fg='black', attr=c)(' %-6s ', c)
  168. out.nl()
  169. sys.stdout.write('Enable color display in this user account (y/n)? ')
  170. a = sys.stdin.readline().strip().lower()
  171. if a in ('y', 'yes', 't', 'true', 'on'):
  172. gc.SetString('color.ui', 'auto')
  173. def Execute(self, opt, args):
  174. self._CheckGitVersion()
  175. self._SyncManifest(opt)
  176. self._LinkManifest(opt.manifest_name)
  177. if os.isatty(0) and os.isatty(1) and not self.manifest.IsMirror:
  178. self._ConfigureUser()
  179. self._ConfigureColor()
  180. if self.manifest.IsMirror:
  181. type = 'mirror '
  182. else:
  183. type = ''
  184. print ''
  185. print 'repo %sinitialized in %s' % (type, self.manifest.topdir)