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