From 8385e4c6557e0e3be5e77335bc474c6d144042a8 Mon Sep 17 00:00:00 2001 From: Guido Guenther Date: Tue, 26 Dec 2006 01:28:01 +0100 Subject: add GitRepository class git-buildpackage: check if upstream branch exists git-import-dsc: improve error handling --- debian/changelog | 7 ++- git-buildpackage | 20 +++++-- git-import-dsc | 124 ++++++++++++++++++++++++++---------------- git-import-orig | 41 ++++++++------ git_buildpackage/__init__.py | 1 + git_buildpackage/git_utils.py | 96 ++++++++++++++++++-------------- 6 files changed, 176 insertions(+), 113 deletions(-) diff --git a/debian/changelog b/debian/changelog index d93cd1f..b147996 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,12 @@ git-buildpackage (0.2.22) unstable; urgency=low - * UNRELEASED + * git-buildpackage: check if upstream branch exists + * git-import-dsc: improve error handling + * add GitRepository class + * make pylint a bit happier * update manpages - -- Guido Guenther Mon, 25 Dec 2006 18:03:05 +0100 + -- Guido Guenther Tue, 26 Dec 2006 00:27:44 +0100 git-buildpackage (0.2.21) unstable; urgency=low diff --git a/git-buildpackage b/git-buildpackage index 86baee7..2852d25 100755 --- a/git-buildpackage +++ b/git-buildpackage @@ -20,8 +20,13 @@ import sys,os,os.path,pipes from git_buildpackage import GitTag, Command, CommandExecFailed -from git_buildpackage.git_utils import * -from git_buildpackage.deb_utils import * +from git_buildpackage.git_utils import (GitRepositoryError, + GitRepository, + sanitize_version) +from git_buildpackage.deb_utils import (parse_changelog, + is_native, + orig_file, + has_orig) from git_buildpackage.config import GBPOptionParser output_dir = '../' @@ -78,20 +83,22 @@ def main(argv): if options.verbose: Command.verbose = True - if not is_repository('.'): + try: + repo=GitRepository('.') + except GitRepositoryError: print >>sys.stderr,"%s is not a git repository" % (os.path.abspath('.')) return 1 try: if not options.ignore_new: Command(options.clean_cmd)() - (ret, out) = is_repository_clean() + (ret, out) = repo.is_clean() if not ret: print >>sys.stderr, "You have uncommitted changes in your source tree:" print >>sys.stderr, out print >>sys.stderr, "Use --git-ignore-new to ignore." return 1 - branch=get_repository_branch() + branch = repo.get_branch() if branch != options.debian_branch and not options.ignore_new: print >>sys.stderr, "You are not on branch '%s' but on '%s'" % (options.debian_branch, branch) print >>sys.stderr, "Use --git-ignore-new to ignore or --git-debian-branch to set the branch name." @@ -100,6 +107,9 @@ def main(argv): cp = parse_changelog('debian/changelog') if not is_native(cp) and not has_orig(cp, output_dir): print "%s does not exist, creating from branch %s" % (orig_file(cp), options.upstream_branch) + if not repo.has_branch(options.upstream_branch): + print >>sys.stderr,"Upstream branch '%s' does not exist" % options.upstream + return 1 if not create_orig(cp, output_dir, options.upstream_branch): return 1 diff --git a/git-import-dsc b/git-import-dsc index ba185d9..b1e8b97 100755 --- a/git-import-dsc +++ b/git-import-dsc @@ -23,44 +23,37 @@ import re import os import tempfile import glob -from optparse import OptionParser -from git_buildpackage import * -from git_buildpackage.git_utils import * -from git_buildpackage.deb_utils import * +import git_buildpackage +from git_buildpackage.deb_utils import debian_version_chars +from git_buildpackage.git_utils import sanitize_version from git_buildpackage.config import GBPOptionParser -gitAdd = GitAdd() -gitCommitAll = GitCommitAll() -class DscPackage(object): - """Parse the dsc file for verions, package names, etc""" - pkgre = re.compile('Source:\s+(?P.+)\s*') - versionre = re.compile("Version:\s(\d+\:)?(?P[%s]+)\s*$" % (debian_version_chars,)) - tarre = re.compile('^\s\w+\s\d+\s+(?P[^_]+_[^_]+(\.orig)?\.tar\.(gz|bz2))') +class DscFile(object): + """Keeps all needed data read from a dscfile""" + pkg_re = re.compile('Source:\s+(?P.+)\s*') + version_re = re.compile("Version:\s(\d+\:)?(?P[%s]+)\s*$" % debian_version_chars) + tar_re = re.compile('^\s\w+\s\d+\s+(?P[^_]+_[^_]+(\.orig)?\.tar\.(gz|bz2))') def __init__(self, dscfile): self.dscfile = os.path.abspath(dscfile) f = file(self.dscfile) for line in f: - m = self.versionre.match(line) + m = self.version_re.match(line) if m: if '-' in m.group('version'): self.debian_version = m.group('version').split("-")[-1] self.upstream_version = "-".join(m.group('version').split("-")[0:-1]) self.native = False - print "Upstream version:", self.upstream_version - print "Debian version:", self.debian_version else: - print "Debian Native Package" self.native = True # Debian native package self.upstream_version = m.group('version') - print "Version:", self.upstream_version continue - m = self.pkgre.match(line) + m = self.pkg_re.match(line) if m: self.pkg = m.group('pkg') continue - m = self.tarre.match(line) + m = self.tar_re.match(line) if m: fromdir = os.path.dirname(dscfile) self.tgz = os.path.join(fromdir, m.group('tar')) @@ -68,46 +61,82 @@ class DscPackage(object): f.close() +def parse_dsc(dscfile): + """parse dsc by creating a DscFile object""" + try: + dsc = DscFile(dscfile) + except IOError, err: + print >>sys.stderr, "Error reading dsc file: %s" % err + dsc = None + else: + try: + if dsc.native: + print "Debian Native Package" + print "Version:", dsc.upstream_version + else: + print "Upstream version:", dsc.upstream_version + print "Debian version:", dsc.debian_version + except AttributeError: + print >>sys.stderr, "Error parsing dsc file %s" % dscfile + dsc = None + return dsc + + def import_upstream(src, dirs, upstream_branch, tagger): + """ + import a new upstream version on the upstream branch and tag + appropriately + """ try: - unpackTGZ = UnpackTGZ(src.tgz, dirs['tmp']) + unpackTGZ = git_buildpackage.UnpackTGZ(src.tgz, dirs['tmp']) unpackTGZ() - except CommandExecFailed: - print >>sys.stderr,"Unpacking of %s failed" % (src.tgz,) - RemoveTree(dirs['tmp'])() - return 1 + except git_buildpackage.CommandExecFailed: + print >>sys.stderr,"Unpacking of %s failed" % src.tgz + git_buildpackage.RemoveTree(dirs['tmp'])() + return False try: - dirs['git'] = glob.glob('%s/*' % (unpackTGZ.dir, ))[0] + dirs['git'] = glob.glob('%s/*' % unpackTGZ.dir)[0] os.chdir(dirs['git']) - GitInitDB()() - gitAdd(['.']) - gitCommitAll(msg="Imported %s version %s" % (['upstream','Debian'][src.native],src.upstream_version,)) + git_buildpackage.GitInitDB()() + git_buildpackage.GitAdd()(['.']) + git_buildpackage.GitCommitAll()( + msg="Imported %s version %s" % (['upstream', 'Debian'][src.native], + src.upstream_version)) tagger(sanitize_version(src.upstream_version)) if not src.native: - GitBranch()(upstream_branch) - except CommandExecFailed: + git_buildpackage.GitBranch()(upstream_branch) + except git_buildpackage.CommandExecFailed: print >>sys.stderr,"Creation of git repository failed" - RemoveTree(unpackTGZ.dir)() - return 1 - return 0 + git_buildpackage.RemoveTree(unpackTGZ.dir)() + return False + return True def apply_debian_patch(src, dirs, tagger): + """apply the debian patch and tag appropriately""" try: - DpkgSourceExtract()(src.dscfile, dirs['dpkg-src']) + git_buildpackage.DpkgSourceExtract()(src.dscfile, dirs['dpkg-src']) os.chdir(dirs['git']) - GitLoadDirs()(dirs['dpkg-src'], 'Imported Debian patch') + git_buildpackage.GitLoadDirs()(dirs['dpkg-src'], 'Imported Debian patch') tagger(sanitize_version('%s-%s' % (src.upstream_version, src.debian_version))) - except CommandExecFailed: + except git_buildpackage.CommandExecFailed: print >>sys.stderr,"Failed to import Debian package" - return 1 - return 0 + return False + return True def move_tree(src, dirs): - os.rename(dirs['git'], src.pkg) - RemoveTree(dirs['tmp'])() + """rename the temporary unpack directory to it's final name""" + try: + os.rename(dirs['git'], src.pkg) + except OSError, err: + 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: + git_buildpackage.RemoveTree(dirs['tmp'])() + return True def main(argv): @@ -127,18 +156,20 @@ def main(argv): (options, args) = parser.parse_args(argv[1:]) if options.verbose: - Command.verbose = True + git_buildpackage.Command.verbose = True - gitTag = GitTag(options.sign_tags, options.keyid) + gitTag = git_buildpackage.GitTag(options.sign_tags, options.keyid) if len(args) != 1: parser.print_help() return 1 else: - src = DscPackage(args[0]) + src = parse_dsc(args[0]) + if not src: + return 1 dirs['tmp'] = os.path.abspath(tempfile.mkdtemp(dir='.')) - if import_upstream(src, dirs, options.upstream_branch, gitTag): + if not import_upstream(src, dirs, options.upstream_branch, gitTag): return 1 os.chdir(dirs['top']) if not src.native: @@ -146,11 +177,12 @@ def main(argv): os.mkdir(dirs['unpack']) dirs['dpkg-src'] = os.path.join(dirs['unpack'], "%s-%s-%s" % (src.pkg, src.upstream_version, src.debian_version)) - if apply_debian_patch(src, dirs, gitTag): + if not apply_debian_patch(src, dirs, gitTag): return 1 os.chdir(dirs['top']) - move_tree(src, dirs) - print 'Everything imported under %s' % (src.pkg, ) + if not move_tree(src, dirs): + return 1 + print 'Everything imported under %s' % src.pkg if __name__ == '__main__': sys.exit(main(sys.argv)) diff --git a/git-import-orig b/git-import-orig index 1a187a7..3df6639 100755 --- a/git-import-orig +++ b/git-import-orig @@ -23,21 +23,24 @@ import os import tempfile import re import glob -from git_buildpackage import * -from git_buildpackage.git_utils import * +import git_buildpackage +from git_buildpackage.git_utils import (GitRepositoryError, + GitRepository, + sanitize_version) from git_buildpackage.config import GBPOptionParser def cleanupTmpTree(tree): - RemoveTree(tree)() + """remove a tree of temporary files""" + git_buildpackage.RemoveTree(tree)() def unpackOrig(tgz): """unpack a .orig.tar.gz""" try: - unpackTGZ = UnpackTGZ(tgz, tempfile.mkdtemp(dir='../')) + unpackTGZ = git_buildpackage.UnpackTGZ(tgz, tempfile.mkdtemp(dir='../')) unpackTGZ() - except CommandExecFailed: + except git_buildpackage.CommandExecFailed: print "Unpacking of %s failed" % (tgz,) cleanupTmpTree(unpackTGZ.dir) return @@ -71,13 +74,13 @@ def main(argv): help="GPG keyid to sign tags with") (options, args) = parser.parse_args(argv[1:]) - gitCheckoutUpstream = GitCheckoutBranch(options.upstream) - gitCheckoutMaster = GitCheckoutBranch(options.debian) - gitShowBranch = GitShowBranch() - gitPullUpstream = GitPull('.', options.upstream) + gitCheckoutUpstream = git_buildpackage.GitCheckoutBranch(options.upstream) + gitCheckoutMaster = git_buildpackage.GitCheckoutBranch(options.debian) + gitShowBranch = git_buildpackage.GitShowBranch() + gitPullUpstream = git_buildpackage.GitPull('.', options.upstream) if options.verbose: - Command.verbose = True + git_buildpackage.Command.verbose = True if len(args) != 1: parser.print_help() @@ -85,11 +88,13 @@ def main(argv): else: tgz = args[0] - if not is_repository('.'): - print >>sys.stderr,"%s is not a git repository" % (os.path.abspath('.'),) + try: + repo=GitRepository('.') + except GitRepositoryError: + print >>sys.stderr,"%s is not a git repository" % (os.path.abspath('.')) return 1 - if not has_branch(options.upstream): + if not repo.has_branch(options.upstream): print >>sys.stderr, """ Repository does not have branch '%s' for upstream sources. If there is none see /usr/share/doc/git-buildpackage/manual-html/gbp.import.convert.html on howto @@ -108,7 +113,7 @@ create it otherwise use --upstream-branch to specify it. parser.print_help() return 1 - (ret, out) = is_repository_clean() + (ret, out) = repo.is_clean() if not ret: print >>sys.stderr, "Repository has uncommitted changes, commit them first: " print >>sys.stderr, out @@ -126,16 +131,16 @@ create it otherwise use --upstream-branch to specify it. print "Importing %s to upstream branch..." % tgz gitCheckoutUpstream() gitShowBranch() - GitLoadDirs()(origdir) - GitTag(options.sign_tags, options.keyid)(sanitize_version(version)) + git_buildpackage.GitLoadDirs()(origdir) + git_buildpackage.GitTag(options.sign_tags, options.keyid)(sanitize_version(version)) if options.merge: print "Merging to %s" % (options.debian,) gitCheckoutMaster() gitShowBranch() gitPullUpstream() - Dch("%s-1" % (version,), 'New Upstream Version')() - except CommandExecFailed: + git_buildpackage.Dch("%s-1" % (version,), 'New Upstream Version')() + except git_buildpackage.CommandExecFailed: print >>sys.stderr, "Import of %s failed" % (tgz,) cleanupTmpTree(tmpdir) return 1 diff --git a/git_buildpackage/__init__.py b/git_buildpackage/__init__.py index 189f5e9..74814bd 100644 --- a/git_buildpackage/__init__.py +++ b/git_buildpackage/__init__.py @@ -11,6 +11,7 @@ class CommandExecFailed(Exception): """Exception raised by the Command class""" pass + class Command(object): """ Wraps a shell command, so we don't have to store any kind of command line options in diff --git a/git_buildpackage/git_utils.py b/git_buildpackage/git_utils.py index 3e68b2d..fa7fe38 100644 --- a/git_buildpackage/git_utils.py +++ b/git_buildpackage/git_utils.py @@ -7,50 +7,62 @@ import subprocess import os.path import re +class GitRepositoryError(Exception): + pass -def is_repository_clean(): - """Does the repository contain any uncommitted modifications""" - clean_msg='nothing to commit' - popen = subprocess.Popen(['git','status'], stdout=subprocess.PIPE) - popen.wait() - out=popen.stdout.readlines() - if out[0].strip() == clean_msg: - ret=True - elif out[0].startswith('#') and out[1].strip() == clean_msg: - ret=True - else: - ret=False - return (ret, "".join(out)) - - -def get_repository_branch(): - """on what branch is the repository""" - popen = subprocess.Popen(['git','branch'], stdout=subprocess.PIPE) - popen.wait() - for line in popen.stdout: - if line.startswith('*'): - return line.split(' ',1)[1].strip() - - -def has_branch(branch): - """check if the repository has branch branch""" - popen = subprocess.Popen(['git','branch'], stdout=subprocess.PIPE) - popen.wait() - for line in popen.stdout: - if line.split(' ',1)[1].strip() == branch: - return True - return False - - -def is_repository(path): - """Is there a git repository at path""" - if not path: - return False - try: - os.stat(path+'/.git') - except: + +class GitRepository(object): + """Represents a git repository at path""" + + def __init__(self, path): + try: + os.stat(os.path.join(path,'.git')) + except: + raise GitRepositoryError + self.path=os.path.abspath(path) + + + def __check_path(self): + if os.getcwd() != self.path: + raise GitRepositoryError + + + def __git_getoutput(self, command): + """Exec a git command and return the output""" + popen = subprocess.Popen(['git',command], stdout=subprocess.PIPE) + popen.wait() + return popen.stdout.readlines() + + + def has_branch(self, branch): + """check if the repository has branch 'branch'""" + self.__check_path() + for line in self.__git_getoutput('branch'): + if line.split(' ',1)[1].strip() == branch: + return True return False - return True + + + def get_branch(self): + """on what branch is the current working copy""" + self.__check_path() + for line in self.__git_getoutput('branch'): + if line.startswith('*'): + return line.split(' ',1)[1].strip() + + + def is_clean(self): + """does the repository contain any uncommitted modifications""" + self.__check_path() + clean_msg='nothing to commit' + out = self.__git_getoutput('status') + if out[0].strip() == clean_msg: + ret=True + elif out[0].startswith('#') and out[1].strip() == clean_msg: + ret=True + else: + ret=False + return (ret, "".join(out)) def sanitize_version(version): -- cgit v1.2.3