From 71d209fa202b3828a1eb7e8518a127a7a0a08596 Mon Sep 17 00:00:00 2001 From: Guido Guenther Date: Fri, 29 Feb 2008 16:08:00 +0100 Subject: make dsc import repeatable (Closes: #468120) --- TODO | 2 -- gbp/command_wrappers.py | 5 +-- gbp/deb_utils.py | 14 ++++++++ gbp/git_utils.py | 26 ++++++++++++-- git-import-dsc | 96 +++++++++++++++++++++++++++++++------------------ git-import-orig | 37 ++++++------------- 6 files changed, 113 insertions(+), 67 deletions(-) diff --git a/TODO b/TODO index 9f99e086..7450855f 100644 --- a/TODO +++ b/TODO @@ -3,8 +3,6 @@ - add --git-overlay as discussed in #448357 - git-import-orig: - show untracked files using 'git-ls-files -o' after import -- git-import-dsc: - - allow to import into a git repository for backports - git-dch - make format of log messages more flexible - don't forcibly start a new version diff --git a/gbp/command_wrappers.py b/gbp/command_wrappers.py index f11d4860..c71d7437 100644 --- a/gbp/command_wrappers.py +++ b/gbp/command_wrappers.py @@ -205,8 +205,9 @@ class GitAdd(GitCommand): class GitRm(GitCommand): """Wrap git rm to remove files""" - def __init__(self): - GitCommand.__init__(self, 'rm') + def __init__(self, verbose=False): + args = [ ['-q'], [] ][verbose] + GitCommand.__init__(self, cmd='rm', args=args) self.run_error = "Couldn't remove files" diff --git a/gbp/deb_utils.py b/gbp/deb_utils.py index e826c06c..2e7b7078 100644 --- a/gbp/deb_utils.py +++ b/gbp/deb_utils.py @@ -7,6 +7,7 @@ import email import commands import os import shutil +import command_wrappers as gbpc # When trying to parse a version-number from a dsc or changes file, these are # the valid characters. @@ -72,4 +73,17 @@ def copy_orig(cp, orig_dir, output_dir): return False return True +def unpack_orig(archive, tmpdir, filters): + """ + unpack a .orig.tar.gz to tmpdir, leave the cleanup to the caller in case of + an error + """ + try: + unpackArchive = gbpc.UnpackTarArchive(archive, tmpdir, filters) + unpackArchive() + except gbpc.CommandExecFailed: + print >>sys.stderr, "Unpacking of %s failed" % archive + raise GbpError + return unpackArchive.dir + # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/git_utils.py b/gbp/git_utils.py index fffa3f64..90802cc3 100644 --- a/gbp/git_utils.py +++ b/gbp/git_utils.py @@ -5,6 +5,7 @@ import subprocess import os.path +from command_wrappers import (GitAdd, GitRm, copy_from) class GitRepositoryError(Exception): """Exception thrown by GitRepository""" @@ -21,7 +22,7 @@ class GitRepository(object): raise GitRepositoryError self.path = os.path.abspath(path) - + def __check_path(self): if os.getcwd() != self.path: raise GitRepositoryError @@ -53,6 +54,12 @@ class GitRepository(object): out, ret = self.__git_getoutput('ls-tree', [ treeish ]) return [ True, False ][ret != 0] + def has_tag(self, tag): + """check if the repository has the given tag""" + self.__check_path() + out, ret = self.__git_getoutput('tag', [ '-l', tag ]) + return [ False, True ][len(out)] + def get_branch(self): """on what branch is the current working copy""" @@ -98,4 +105,19 @@ def sanitize_version(version): version = version.split(':', 1)[1] return version.replace('~', '.') -# vim:et:ts=4:sw=4: + +def replace_source_tree(repo, src_dir, filters, verbose=False): + """ + make the current wc match what's in src_dir + @return: True if wc was modified + @rtype: boolean + """ + old = set(repo.index_files()) + new = set(copy_from(src_dir, filters)) + GitAdd()(['.']) + files = [ obj for obj in old - new if not os.path.isdir(obj)] + if files: + GitRm(verbose=verbose)(files) + return not repo.is_clean()[0] + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/git-import-dsc b/git-import-dsc index 222af646..b94879f5 100755 --- a/git-import-dsc +++ b/git-import-dsc @@ -24,8 +24,8 @@ import tempfile import glob import pipes import gbp.command_wrappers as gbpc -from gbp.deb_utils import debian_version_chars -from gbp.git_utils import build_tag, GitRepository +from gbp.deb_utils import debian_version_chars, unpack_orig +from gbp.git_utils import build_tag, GitRepository, GitRepositoryError, replace_source_tree from gbp.config import GbpOptionParser from gbp.errors import GbpError @@ -88,40 +88,25 @@ def parse_dsc(dscfile): return dsc -def import_initial(src, dirs, options, tagger, filters): +def import_initial(src, dirs, options): """ import the intial version and (in the case of a non native package) create the 'upstream' branch. Tag everything appropriately. """ try: - unpackTGZ = gbpc.UnpackTarArchive(src.tgz, dirs['tmp'], filters=filters) - unpackTGZ() - except gbpc.CommandExecFailed: - print >>sys.stderr, "Unpacking of %s failed" % src.tgz - gbpc.RemoveTree(dirs['tmp'])() - return False - - try: - dirs['git'] = glob.glob('%s/*' % unpackTGZ.dir)[0] os.chdir(dirs['git']) gbpc.GitInitDB()() gbpc.GitAdd()(['.']) gbpc.GitCommitAll()( - msg="Imported %s version %s" % (['upstream', 'Debian'][src.native], + msg="Imported %s version %s" % (['Upstream', 'Debian'][src.native], src.upstream_version)) - format = [options.upstream_tag, options.debian_tag][src.native] - tagger(build_tag(format, src.upstream_version), - msg="Upstream version %s" % src.upstream_version) - if not src.native: gbpc.GitBranch()(options.upstream_branch) if options.pristine_tar: gbpc.PristineTar().commit(os.path.join(dirs['top'], src.tgz), options.upstream_branch) - except gbpc.CommandExecFailed: print >>sys.stderr, "Creation of git repository failed" - gbpc.RemoveTree(unpackTGZ.dir)() return False return True @@ -142,9 +127,10 @@ def git_apply_patch(diff): return True -def apply_debian_patch(src, dirs, options, tagger): +def apply_debian_patch(src, dirs, options): """apply the debian patch and tag appropriately""" version = "%s-%s" % (src.upstream_version, src.debian_version) + gitTag = gbpc.GitTag(options.sign_tags, options.keyid) try: os.chdir(dirs['git']) repo = GitRepository('.') @@ -155,7 +141,7 @@ def apply_debian_patch(src, dirs, options, tagger): gbpc.GitCommitAll()(msg="Imported Debian patch %s" % version) else: print "Nothing to commit, nothing imported." - tagger(build_tag(options.debian_tag, version), + gitTag(build_tag(options.debian_tag, version), msg="Debian release %s" % version) except gbpc.CommandExecFailed: print >>sys.stderr, "Failed to import Debian package" @@ -170,12 +156,11 @@ def move_tree(src, dirs): print >>sys.stderr, "Cannot move git repository '%s' to it's final location '%s': %s" % (dirs['git'], os.path.abspath(src.pkg), err) return False - else: - gbpc.RemoveTree(dirs['tmp'])() return True def create_debian_branch(debian_branch, dirs): + """create the debian branch if necessary""" os.chdir(dirs['git']) repo = GitRepository('.') if repo.get_branch() != debian_branch: @@ -228,22 +213,65 @@ def main(argv): if not src: raise GbpError - dirs['tmp'] = os.path.abspath(tempfile.mkdtemp(dir='.')) - if not import_initial(src, dirs, options, gitTag, options.filters): - raise GbpError + try: + repo = GitRepository('.') + (clean, out) = repo.is_clean() + if not clean: + print >>sys.stderr, "Repository has uncommitted changes, commit these first: " + raise GbpError, out + dirs['tmp'] = os.path.abspath(tempfile.mkdtemp(dir='..')) + initial = False + except GitRepositoryError: + # The initial import is different: + print "No git repository found, creating one." + dirs['tmp'] = os.path.abspath(tempfile.mkdtemp(dir='.')) + initial = True - os.chdir(dirs['top']) - if not src.native: - apply_debian_patch(src, dirs, options, gitTag) - create_debian_branch(options.debian_branch, dirs) - os.chdir(dirs['top']) - if not move_tree(src, dirs): - raise GbpError + unpack_dir = unpack_orig(src.tgz, dirs['tmp'], options.filters) + + format = [(options.upstream_tag, "Upstream"), (options.debian_tag, "Debian")][src.native] + tag = build_tag(format[0], src.upstream_version) + msg = "%s version %s" % (format[1], src.upstream_version) + + if initial: + dirs['git'] = glob.glob('%s/*' % unpack_dir)[0] + if not import_initial(src, dirs, options): + raise GbpError + gitTag(tag, msg=msg) + os.chdir(dirs['top']) + if not src.native: + apply_debian_patch(src, dirs, options) + create_debian_branch(options.debian_branch, dirs) + os.chdir(dirs['top']) + if not move_tree(src, dirs): + raise GbpError + else: # not the initial import + dirs['git'] = dirs['top'] + unpack_dir = glob.glob('%s/*' % unpack_dir)[0] + if not repo.has_tag(tag): + print "tag %s not found, importing %s tarball" % (tag, format[1]) + # FIXME: this is what import-orig does - merge + if not src.native: + gbpc.GitCheckoutBranch(options.upstream_branch)() + replace_source_tree(repo, unpack_dir, options.filters, verbose=True) + gbpc.GitCommitAll()(msg="Imported %s" % msg) + gitTag(tag, msg=msg) + if options.pristine_tar and not src.native: + gbpc.PristineTar().commit(src.tgz, options.upstream_branch) + if not src.native: + gbpc.GitCheckoutBranch(options.debian_branch)() + replace_source_tree(repo, unpack_dir, options.filters) + apply_debian_patch(src, dirs, options) + except gbpc.CommandExecFailed: + raise GbpError except GbpError, err: if len(err.__str__()): print >>sys.stderr, err - ret = 1 os.chdir(dirs['top']) + ret = 1 + + if dirs.has_key('tmp'): + gbpc.RemoveTree(dirs['tmp'])() if not ret: print 'Everything imported under %s' % src.pkg diff --git a/git-import-orig b/git-import-orig index 25a0ea7a..fbc2fd1e 100755 --- a/git-import-orig +++ b/git-import-orig @@ -25,7 +25,8 @@ import re import glob import subprocess import gbp.command_wrappers as gbpc -from gbp.git_utils import (GitRepositoryError, GitRepository, build_tag) +from gbp.deb_utils import unpack_orig +from gbp.git_utils import (GitRepositoryError, GitRepository, build_tag, replace_source_tree) from gbp.config import GbpOptionParser from gbp.errors import GbpError @@ -38,28 +39,10 @@ def cleanup_tmp_tree(tree): print >>sys.stderr, "Removal of tmptree %s failed." % tree -def unpack_orig(archive, tmpdir): - """unpack a .orig.tar.gz""" +def import_upstream_tree(repo, src_dir, version, filters, verbose): + """import the source uptream tree to the current branch""" try: - unpackArchive = gbpc.UnpackTarArchive(archive, tmpdir) - unpackArchive() - except gbpc.CommandExecFailed: - print "Unpacking of %s failed" % archive - cleanup_tmp_tree(unpackArchive.dir) - raise GbpError - return unpackArchive.dir - - -def import_source_tree(repo, orig_dir, version, filters, verbose): - """import source tree to the current branch""" - try: - old = set(repo.index_files()) - new = set(gbpc.copy_from(orig_dir, filters)) - gbpc.GitAdd()(['.']) - files = [ obj for obj in old - new if not os.path.isdir(obj)] - if files: - gbpc.GitRm()(files) - if not repo.is_clean()[0]: + if replace_source_tree(repo, src_dir, filters, verbose=True): gbpc.GitCommitAll(verbose=verbose)(msg="Imported upstream version %s" % version) else: raise GbpError, "Nothing to commit, nothing imported." @@ -117,14 +100,14 @@ def main(argv): help="run pristine-tar to import the tarball", action="store_true") (options, args) = parser.parse_args(argv[1:]) + if options.verbose: + gbpc.Command.verbose = True + gitCheckoutMaster = gbpc.GitCheckoutBranch(options.debian_branch) gitShowBranch = gbpc.GitShowBranch() gitPullUpstream = gbpc.GitPull('.', options.upstream_branch) try: - if options.verbose: - gbpc.Command.verbose = True - if len(args) != 1: parser.print_help() raise GbpError @@ -171,7 +154,7 @@ on howto create it otherwise use --upstream-branch to specify it. orig_dir = archive else: tmpdir = tempfile.mkdtemp(dir='../') - unpack_orig(archive, tmpdir) + unpack_orig(archive, tmpdir, options.filters) if options.verbose: print "Unpacked %s to '%s'" % (archive , tmpdir) unpacked = glob.glob(tmpdir+'/*') @@ -190,7 +173,7 @@ on howto create it otherwise use --upstream-branch to specify it. else: print "Initial import of '%s' %s..." % (archive, filter_msg) - import_source_tree(repo, orig_dir, version, options.filters, verbose=not is_empty) + import_upstream_tree(repo, orig_dir, version, options.filters, verbose=not is_empty) if options.pristine_tar: gbpc.PristineTar().commit(archive, options.upstream_branch) gbpc.GitTag(options.sign_tags, options.keyid)(build_tag(options.upstream_tag, version), -- cgit v1.2.3