summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--gbp/config.py14
-rw-r--r--gbp/git_utils.py13
-rwxr-xr-xgit-buildpackage132
4 files changed, 125 insertions, 35 deletions
diff --git a/TODO b/TODO
index 708db757..517aeb25 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,4 @@
- git-buildpackage:
- - allow to export the hole source tree to tmpdir before building
- allow to fetch and build from a signed tag even when it's in a remote repo
- git-import-orig:
- show untracked files using 'git-ls-files -o' after import
diff --git a/gbp/config.py b/gbp/config.py
index 694aceb7..d1686fa6 100644
--- a/gbp/config.py
+++ b/gbp/config.py
@@ -35,6 +35,7 @@ class GbpOptionParser(OptionParser):
'filter' : '',
'snapshot-number' : 'snapshot + 1',
'git-log' : '--no-merges',
+ 'export-dir' : '',
}
config_files=[ '/etc/git-buildpackage/gbp.conf',
os.path.expanduser('~/.gbp.conf'),
@@ -43,19 +44,18 @@ class GbpOptionParser(OptionParser):
def __parse_config_files(self):
"""parse the possible config files and set appropriate values default values"""
- parser=SafeConfigParser(self.defaults)
+ parser = SafeConfigParser(self.defaults)
parser.read(self.config_files)
- self.config=dict(parser.defaults())
+ self.config = dict(parser.defaults())
if parser.has_section(self.command):
- self.config=dict(parser.items(self.command, raw=True))
+ self.config.update(dict(parser.items(self.command, raw=True)))
def __init__(self, command, prefix='', usage=None):
- self.command=command
- self.prefix=prefix
+ self.command = command
+ self.prefix = prefix
self.__parse_config_files()
OptionParser.__init__(self, usage=usage)
-
def add_config_file_option(self, option_name, dest, help, **kwargs):
"""
set a option for the command line parser, the default is read from the config file
@@ -67,7 +67,7 @@ class GbpOptionParser(OptionParser):
@type help: string
"""
OptionParser.add_option(self,"--%s%s" % (self.prefix, option_name), dest=dest,
- default=self.config[option_name],
+ default=self.config[option_name],
help=help % self.config, **kwargs)
# 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 f52550b3..9cfb0ec5 100644
--- a/gbp/git_utils.py
+++ b/gbp/git_utils.py
@@ -27,10 +27,10 @@ class GitRepository(object):
raise GitRepositoryError
- def __git_getoutput(self, command):
- """Exec a git command and return the output"""
+ def __git_getoutput(self, command, args=[]):
+ """exec a git command and return the output"""
output = []
- popen = subprocess.Popen(['git', command], stdout=subprocess.PIPE)
+ popen = subprocess.Popen(['git', command] + args, stdout=subprocess.PIPE)
while popen.poll() == None:
output += popen.stdout.readlines()
ret = popen.poll()
@@ -47,6 +47,13 @@ class GitRepository(object):
return False
+ def has_treeish(self, treeish):
+ """check if the repository has the treeish object treeish"""
+ self.__check_path()
+ out, ret = self.__git_getoutput('ls-tree', [ treeish ])
+ return [ True, False ][ret != 0]
+
+
def get_branch(self):
"""on what branch is the current working copy"""
self.__check_path()
diff --git a/git-buildpackage b/git-buildpackage
index e6c544df..91ce2b3e 100755
--- a/git-buildpackage
+++ b/git-buildpackage
@@ -20,20 +20,19 @@
import sys
import os, os.path
+import errno
import pipes
+import time
from gbp.git_utils import (GitRepositoryError, GitRepository, build_tag)
from gbp.deb_utils import (parse_changelog, is_native, orig_file, has_orig)
-from gbp.command_wrappers import (GitTag, Command, CommandExecFailed)
+from gbp.command_wrappers import (GitTag, Command, CommandExecFailed, RemoveTree)
from gbp.config import GbpOptionParser
from gbp.errors import GbpError
-def create_orig(cp, output_dir, branch):
- "create an orig.tar.gz in output_dir"
- output = os.path.join(output_dir, orig_file(cp))
- pipe = pipes.Template()
- pipe.prepend('git-archive --format=tar --prefix=%s-%s/ %s' % (cp['Source'], cp['Upstream-Version'], branch), '.-')
- pipe.append('gzip -c -9', '--')
+def git_archive_pipe(prefix, pipe, output, treeish):
+ """run the git_archive pipe"""
+ pipe.prepend('git-archive --format=tar --prefix=%s/ %s' % (prefix, treeish), '.-')
try:
ret = pipe.copy('', output)
if ret:
@@ -48,9 +47,52 @@ def create_orig(cp, output_dir, branch):
return True
+def create_orig(cp, output_dir, treeish):
+ "create an orig.tar.gz in output_dir"
+ output = os.path.join(output_dir, orig_file(cp))
+ prefix = "%s-%s" % (cp['Source'], cp['Upstream-Version'])
+
+ pipe = pipes.Template()
+ pipe.append('gzip -c -9', '--')
+ return git_archive_pipe(prefix, pipe, output, treeish)
+
+
+def dump_tree(export_dir, treeish):
+ "dump a tree to output_dir"
+ output_dir = os.path.dirname(export_dir)
+ prefix = os.path.basename(export_dir)
+ pipe = pipes.Template()
+ pipe.append('tar -C %s -xf -' % output_dir, '-.')
+ return git_archive_pipe(prefix, pipe, '', treeish)
+
+
+def move_old_export(target):
+ """move a build tree away if it exists"""
+ try:
+ os.mkdir(target)
+ except OSError, (e, msg):
+ if e == errno.EEXIST:
+ os.rename(target, "%s.obsolete.%s" % (target, time.time()))
+
+
+def prepare_output_dir(dir):
+ output_dir = dir
+ if not dir:
+ output_dir = '..'
+ output_dir = os.path.abspath(output_dir)
+
+ try:
+ os.mkdir(output_dir)
+ except OSError, (e, msg):
+ if e != errno.EEXIST:
+ raise GbpError, "Cannot create output dir %s" % output_dir
+ return output_dir
+
+
def main(argv):
- output_dir = '..'
changelog = 'debian/changelog'
+ default_tree = 'HEAD'
+ retval = 0
args = [ arg for arg in argv[1:] if arg.find('--git-') == 0 ]
dpkg_args = [ arg for arg in argv[1:] if arg.find('--git-') == -1 ]
@@ -77,23 +119,31 @@ def main(argv):
parser.add_config_file_option(option_name="sign-tags", dest="sign_tag",
help="sign git tags", action="store_true")
parser.add_config_file_option(option_name="no-create-orig", dest="no_create_orig",
- help="create orig.tar.gz", action="store_true")
+ help="don't create orig.tar.gz", action="store_true")
parser.add_config_file_option(option_name="posttag", dest="posttag_hook",
help="hook to execute after a successfull tag operation")
parser.add_config_file_option(option_name="keyid", dest="keyid",
help="GPG keyid to sign tags with")
parser.add_config_file_option(option_name="debian-tag", dest="debian_tag",
- help="Format string for debian tags, default is '%(debian-tag)s'")
+ help="format string for debian tags, default is '%(debian-tag)s'")
+ parser.add_config_file_option(option_name="upstream-tag", dest="upstream_tag",
+ help="format string for upstream tags, default is '%(upstream-tag)s'")
+ parser.add_config_file_option(option_name="export-dir", dest="export_dir",
+ help="before building export into EXPORT_DIR")
+ parser.add_option("--git-export", dest="treeish", default=default_tree,
+ help="export treeish object TREEISH, default is '%s'" % default_tree)
(options, args) = parser.parse_args(args)
if options.verbose:
Command.verbose = True
try:
- repo = GitRepository('.')
+ repo = GitRepository(os.path.curdir)
except GitRepositoryError:
print >>sys.stderr, "%s is not a git repository" % (os.path.abspath('.'))
return 1
+ else:
+ repo_dir = os.path.abspath(os.path.curdir)
try:
if not options.ignore_new:
@@ -103,20 +153,48 @@ def main(argv):
print >>sys.stderr, "You have uncommitted changes in your source tree:"
print >>sys.stderr, out
raise GbpError, "Use --git-ignore-new to ignore."
- 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)
- raise GbpError, "Use --git-ignore-new to ignore or --git-debian-branch to set the branch name."
+
+ branch = repo.get_branch()
+ if branch != options.debian_branch:
+ print >>sys.stderr, "You are not on branch '%s' but on '%s'" % (options.debian_branch, branch)
+ raise GbpError, "Use --git-ignore-new to ignore or --git-debian-branch to set the branch name."
cp = parse_changelog(changelog)
if not cp:
raise GbpError,"'%s' does not exist, not a debian package" % changelog
+
+ output_dir = prepare_output_dir(options.export_dir)
+ if not repo.has_treeish(options.treeish):
+ raise GbpError # git-ls-tree printed an error message already
+ # Export to another build dir if requested:
+ if options.export_dir:
+ tmp_dir = os.path.join(output_dir, "%s-tmp" % cp['Source'])
+ print "Exporting '%s' to '%s'" % (options.treeish, tmp_dir)
+ dump_tree(tmp_dir, options.treeish)
+ cp = parse_changelog(os.path.join(tmp_dir, 'debian', 'changelog'))
+ if is_native(cp):
+ version = cp['Debian-Version']
+ else:
+ version = cp['Upstream-Version']
+ export_dir = os.path.join(output_dir, "%s-%s" % (cp['Source'], version))
+ print "Moving '%s' to '%s'" % (tmp_dir, export_dir)
+ move_old_export(export_dir)
+ os.rename(tmp_dir, export_dir)
+
+ # Build the orig.tar.gz if necessary:
if not is_native(cp) and not has_orig(cp, output_dir) and not options.no_create_orig:
- print "%s does not exist, creating from branch '%s'" % (orig_file(cp), options.upstream_branch)
- if not repo.has_branch(options.upstream_branch):
- raise GbpError, "Upstream branch '%s' does not exist" % options.upstream_branch
- if not create_orig(cp, output_dir, options.upstream_branch):
- raise GbpError
+ if options.upstream_branch != GbpOptionParser.defaults['upstream-branch']:
+ upstream_tree = options.upstream_branch
+ else:
+ upstream_tree = build_tag(options.upstream_tag, cp['Upstream-Version'])
+ print "%s does not exist, creating from '%s'" % (orig_file(cp), upstream_tree)
+ if not repo.has_treeish(upstream_tree):
+ raise GbpError # git-ls-tree printed an error message already
+ if not create_orig(cp, output_dir, upstream_tree):
+ raise GbpError, "Cannot create upstream tarball at '%s'" % output_dir
+
+ if options.export_dir:
+ os.chdir(export_dir)
Command(options.build_cmd, dpkg_args, shell=True)()
if options.tag:
@@ -125,18 +203,24 @@ def main(argv):
except KeyError:
raise GbpError, "Can't parse version from changelog"
else:
- print "Tagging", version
+ print "Tagging %s" % version
GitTag(options.sign_tag, options.keyid)(build_tag(options.debian_tag, version),
msg="Debian release %s" % version)
if(options.posttag_hook):
Command(options.posttag_hook, shell=True)()
+
except CommandExecFailed:
- return 1
+ retval = 1
except GbpError, err:
if len(err.__str__()):
print >>sys.stderr, err
- return 1
- return 0
+ retval = 1
+
+ if options.export_dir and not retval:
+ RemoveTree(export_dir)()
+
+ os.chdir(repo_dir)
+ return retval
if __name__ == '__main__':
sys.exit(main(sys.argv))