compute_snapshot_check.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. import tempfile
  18. from command import Command
  19. from error import GitError, NoSuchProjectError
  20. from git_config import IsId
  21. from import_tar import ImportTar
  22. from import_zip import ImportZip
  23. from project import Project
  24. from remote import Remote
  25. def _ToCommit(project, rev):
  26. return project.bare_git.rev_parse('--verify', '%s^0' % rev)
  27. def _Missing(project, rev):
  28. return project._revlist('--objects', rev, '--not', '--all')
  29. class ComputeSnapshotCheck(Command):
  30. common = False
  31. helpSummary = "Compute the check value for a new snapshot"
  32. helpUsage = """
  33. %prog -p NAME -v VERSION -s FILE [options]
  34. """
  35. helpDescription = """
  36. %prog computes and then displays the proper check value for a
  37. snapshot, so it can be pasted into the manifest file for a project.
  38. """
  39. def _Options(self, p):
  40. g = p.add_option_group('Snapshot description options')
  41. g.add_option('-p', '--project',
  42. dest='project', metavar='NAME',
  43. help='destination project name')
  44. g.add_option('-v', '--version',
  45. dest='version', metavar='VERSION',
  46. help='upstream version/revision identifier')
  47. g.add_option('-s', '--snapshot',
  48. dest='snapshot', metavar='PATH',
  49. help='local tarball path')
  50. g.add_option('--new-project',
  51. dest='new_project', action='store_true',
  52. help='destinition is a new project')
  53. g.add_option('--keep',
  54. dest='keep_git', action='store_true',
  55. help='keep the temporary git repository')
  56. g = p.add_option_group('Base revision grafting options')
  57. g.add_option('--prior',
  58. dest='prior', metavar='COMMIT',
  59. help='prior revision checksum')
  60. g = p.add_option_group('Path mangling options')
  61. g.add_option('--strip-prefix',
  62. dest='strip_prefix', metavar='PREFIX',
  63. help='remove prefix from all paths on import')
  64. g.add_option('--insert-prefix',
  65. dest='insert_prefix', metavar='PREFIX',
  66. help='insert prefix before all paths on import')
  67. def _Compute(self, opt):
  68. try:
  69. real_project = self.GetProjects([opt.project])[0]
  70. except NoSuchProjectError:
  71. if opt.new_project:
  72. print >>sys.stderr, \
  73. "warning: project '%s' does not exist" % opt.project
  74. else:
  75. raise NoSuchProjectError(opt.project)
  76. self._tmpdir = tempfile.mkdtemp()
  77. project = Project(manifest = self.manifest,
  78. name = opt.project,
  79. remote = Remote('origin'),
  80. gitdir = os.path.join(self._tmpdir, '.git'),
  81. worktree = self._tmpdir,
  82. relpath = opt.project,
  83. revision = 'refs/heads/master')
  84. project._InitGitDir()
  85. url = 'file://%s' % os.path.abspath(opt.snapshot)
  86. imp = None
  87. for cls in [ImportTar, ImportZip]:
  88. if cls.CanAccept(url):
  89. imp = cls()
  90. break
  91. if not imp:
  92. print >>sys.stderr, 'error: %s unsupported' % opt.snapshot
  93. sys.exit(1)
  94. imp.SetProject(project)
  95. imp.SetVersion(opt.version)
  96. imp.AddUrl(url)
  97. if opt.prior:
  98. if opt.new_project:
  99. if not IsId(opt.prior):
  100. print >>sys.stderr, 'error: --prior=%s not valid' % opt.prior
  101. sys.exit(1)
  102. else:
  103. try:
  104. opt.prior = _ToCommit(real_project, opt.prior)
  105. missing = _Missing(real_project, opt.prior)
  106. except GitError, e:
  107. print >>sys.stderr,\
  108. 'error: --prior=%s not valid\n%s' \
  109. % (opt.prior, e)
  110. sys.exit(1)
  111. if missing:
  112. print >>sys.stderr,\
  113. 'error: --prior=%s is valid, but is not reachable' \
  114. % opt.prior
  115. sys.exit(1)
  116. imp.SetParent(opt.prior)
  117. src = opt.strip_prefix
  118. dst = opt.insert_prefix
  119. if src or dst:
  120. if src is None:
  121. src = ''
  122. if dst is None:
  123. dst = ''
  124. imp.RemapPath(src, dst)
  125. commitId = imp.Import()
  126. print >>sys.stderr,"%s\t%s" % (commitId, imp.version)
  127. return project
  128. def Execute(self, opt, args):
  129. if args \
  130. or not opt.project \
  131. or not opt.version \
  132. or not opt.snapshot:
  133. self.Usage()
  134. success = False
  135. project = None
  136. try:
  137. self._tmpdir = None
  138. project = self._Compute(opt)
  139. finally:
  140. if project and opt.keep_git:
  141. print 'GIT_DIR = %s' % (project.gitdir)
  142. elif self._tmpdir:
  143. for root, dirs, files in os.walk(self._tmpdir, topdown=False):
  144. for name in files:
  145. os.remove(os.path.join(root, name))
  146. for name in dirs:
  147. os.rmdir(os.path.join(root, name))
  148. os.rmdir(self._tmpdir)