#!/usr/bin/python # vim: set fileencoding=utf-8 : # # (C) 2009,2012,2015 Guido Guenther # # gbp-posttag-push: post tag hook to be called by git-buildpackage to push out # the newly created tag and to forward the remote branch to that position # # it checks for explicit push destinations, if none are found it pushes back to # where the branch got merged from. Before pushing it checks if the tag is # signed. # # use: # [buildpackage] # posttag = gbp-posttag-push # # Options: # -d: dry-run # -u: push upstream branch too, if not on remote already # --verbose: verbose command output from __future__ import print_function import os import subprocess import sys import gbp.log from gbp.config import GbpOptionParser from gbp.deb.git import DebianGitRepository from gbp.errors import GbpError from gbp.scripts.common import ExitCodes class Env(object): pass def get_push_targets(env): """get a list of push targets""" dests = {} cmd = "git config --get-regexp 'remote\..*\.push' '^%s(:.*)?$'" % env.branch for remote in subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).communicate()[0].split("\n"): if not len(remote): continue repo, refspec = remote.split() repo = ".".join(repo.split('.')[1:-1]) # remote..push try: remote = refspec.split(':')[1] # src:dest except IndexError: remote = refspec dests[repo] = remote return dests def get_pull(env): """where did we pull from?""" cmd = 'git config --get branch."%s".remote' % env.branch remote = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).communicate()[0].strip() if not remote: remote = 'origin' return { remote: env.branch } def git_push_sim(*args): print("git push %s" % " ".join(args)) def get_upstream_tag(repo, tag, tag_format): # FIXME: This assumes the debian version is the last part after the slash: version = tag.split('/')[-1] no_epoch = version.split(':')[-1] upstream = version.rsplit('-')[0] tag = tag_format % dict(version=upstream) if repo.has_tag(tag): return tag return None def main(argv): env = Env() upstream_sha1 = None try: parser = GbpOptionParser(command=os.path.basename(argv[0]), prefix='', usage='%prog [options] paths') except GbpError as err: gbp.log.error(err) return ExitCodes.parse_error parser.add_option("-d", "--dry-run", dest="dryrun", default=False, action="store_true", help="dry run, don't push.") parser.add_option("-u", "--push-upstream", dest="push_upstream", default=False, action="store_true", help="also push upstream branch changes") parser.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") parser.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") parser.add_option("--verbose", action="store_true", dest="verbose", default=False, help="verbose command execution") (options, args) = parser.parse_args() gbp.log.setup(False, options.verbose) repo = DebianGitRepository('.') if options.dryrun: print("Dry run mode. Not pushing.") repo.push = git_push_sim repo.push_tag = git_push_sim for envvar in [ "GBP_TAG", "GBP_BRANCH", "GBP_SHA1" ]: var = os.getenv(envvar) if var: env.__dict__.setdefault( "%s" % envvar.split("_")[1].lower(), var) else: print("%s not set." % envvar, file=sys.stderr) return 1 dests = get_push_targets(env) if not dests: dests = get_pull(env) upstream_tag = get_upstream_tag(repo, env.tag, options.upstream_tag) if upstream_tag: upstream_sha1 = repo.rev_parse("%s^{}" % upstream_tag) if not repo.verify_tag(env.tag): print("Not pushing non-existent or unsigned tag '%s'." % env.tag, file=sys.stderr) return 0 for dest in dests: print("Pushing %s to %s" % (env.tag, dest)) repo.push_tag(dest, env.tag) print("Pushing %s to %s %s" % (env.sha1, dest, dests[dest])) repo.push(dest, env.sha1, dests[dest]) if options.push_upstream and upstream_tag: print("Pushing %s to %s" % (upstream_tag, dest)) repo.push_tag(dest, upstream_tag) if not repo.branch_contains("%s/%s" % (dest, options.upstream_branch), upstream_sha1, remote=True): print("Pushing %s to %s %s" % (upstream_sha1, dest, options.upstream_branch)) repo.push(dest, upstream_sha1, options.upstream_branch) print("done.") if __name__ == '__main__': sys.exit(main(sys.argv)) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: