blob: 82db359adbcee7b4a2b8964a3c215702fead9790 [file] [log] [blame]
#
# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
import tempfile
from command import Command
from error import GitError, NoSuchProjectError
from git_config import IsId
from import_tar import ImportTar
from import_zip import ImportZip
from project import Project
from remote import Remote
def _ToCommit(project, rev):
return project.bare_git.rev_parse('--verify', '%s^0' % rev)
def _Missing(project, rev):
return project._revlist('--objects', rev, '--not', '--all')
class ComputeSnapshotCheck(Command):
common = False
helpSummary = "Compute the check value for a new snapshot"
helpUsage = """
%prog -p NAME -v VERSION -s FILE [options]
"""
helpDescription = """
%prog computes and then displays the proper check value for a
snapshot, so it can be pasted into the manifest file for a project.
"""
def _Options(self, p):
g = p.add_option_group('Snapshot description options')
g.add_option('-p', '--project',
dest='project', metavar='NAME',
help='destination project name')
g.add_option('-v', '--version',
dest='version', metavar='VERSION',
help='upstream version/revision identifier')
g.add_option('-s', '--snapshot',
dest='snapshot', metavar='PATH',
help='local tarball path')
g.add_option('--new-project',
dest='new_project', action='store_true',
help='destinition is a new project')
g.add_option('--keep',
dest='keep_git', action='store_true',
help='keep the temporary git repository')
g = p.add_option_group('Base revision grafting options')
g.add_option('--prior',
dest='prior', metavar='COMMIT',
help='prior revision checksum')
g = p.add_option_group('Path mangling options')
g.add_option('--strip-prefix',
dest='strip_prefix', metavar='PREFIX',
help='remove prefix from all paths on import')
g.add_option('--insert-prefix',
dest='insert_prefix', metavar='PREFIX',
help='insert prefix before all paths on import')
def _Compute(self, opt):
try:
real_project = self.GetProjects([opt.project])[0]
except NoSuchProjectError:
if opt.new_project:
print >>sys.stderr, \
"warning: project '%s' does not exist" % opt.project
else:
raise NoSuchProjectError(opt.project)
self._tmpdir = tempfile.mkdtemp()
project = Project(manifest = self.manifest,
name = opt.project,
remote = Remote('origin'),
gitdir = os.path.join(self._tmpdir, '.git'),
worktree = self._tmpdir,
relpath = opt.project,
revision = 'refs/heads/master')
project._InitGitDir()
url = 'file://%s' % os.path.abspath(opt.snapshot)
imp = None
for cls in [ImportTar, ImportZip]:
if cls.CanAccept(url):
imp = cls()
break
if not imp:
print >>sys.stderr, 'error: %s unsupported' % opt.snapshot
sys.exit(1)
imp.SetProject(project)
imp.SetVersion(opt.version)
imp.AddUrl(url)
if opt.prior:
if opt.new_project:
if not IsId(opt.prior):
print >>sys.stderr, 'error: --prior=%s not valid' % opt.prior
sys.exit(1)
else:
try:
opt.prior = _ToCommit(real_project, opt.prior)
missing = _Missing(real_project, opt.prior)
except GitError, e:
print >>sys.stderr,\
'error: --prior=%s not valid\n%s' \
% (opt.prior, e)
sys.exit(1)
if missing:
print >>sys.stderr,\
'error: --prior=%s is valid, but is not reachable' \
% opt.prior
sys.exit(1)
imp.SetParent(opt.prior)
src = opt.strip_prefix
dst = opt.insert_prefix
if src or dst:
if src is None:
src = ''
if dst is None:
dst = ''
imp.RemapPath(src, dst)
commitId = imp.Import()
print >>sys.stderr,"%s\t%s" % (commitId, imp.version)
return project
def Execute(self, opt, args):
if args \
or not opt.project \
or not opt.version \
or not opt.snapshot:
self.Usage()
success = False
project = None
try:
self._tmpdir = None
project = self._Compute(opt)
finally:
if project and opt.keep_git:
print 'GIT_DIR = %s' % (project.gitdir)
elif self._tmpdir:
for root, dirs, files in os.walk(self._tmpdir, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(self._tmpdir)