From 47d060a19e5740ea12dda6b1f77537fe2afab38c Mon Sep 17 00:00:00 2001 From: Emmanuel Milou <emilou@emilou-desktop.(none)> Date: Thu, 28 May 2009 15:06:30 -0400 Subject: [PATCH] add files --- AUTHORS | 63 +++++ tools/build-system/bin/git-dch | 404 +++++++++++++++++++++++++++++++++ 2 files changed, 467 insertions(+) create mode 100644 AUTHORS create mode 100755 tools/build-system/bin/git-dch diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000000..26e4e78f59 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,63 @@ +Current authors: + +Emmanuel Milou <emmanuel dot milou at savoirfairelinux dot com> + - ALSA implementation ( replaces portaudio ) + - Dynamic loading of audio codecs ( shared libraries ) + - Debian packages + - GTK client error handling + - Plus many portions of code in sflphoned and sflphone-gtk + - Test and debugging + +Alexandre Bourget <alexandre dot bourget at savoirfairelinux dot com> + - IAX implementation + +Guillaume Carmel-Archambault <guillaume.carmel-archambault at savoirfairelinux dot com> + - Presence + - Contacts +Yun Liu <yun.liu at savoirfairelinux dot com> + - Change sip library to pjsip + - Support multiple accounts registration + - Add chinese translation + - Many portions of test and debugging + +Polytechnic School of Montreal: + - Jean-Francois Blanchard-Dionne <jean-francois.blanchard-dionne at polymtl dot ca> + - Ala Eddine Limame <ala-eddine.limame at polymtl dot ca> + - Alexis S. Bourrelle <bourrelle at polymtl dot ca> + - Marilyne Mercier <marilyne.mercier at polymtl dot ca> + - Jean Tessier <jean.tessier at polymtl dot ca> + - Video layer implementation + - Video conference + +Pierre-Luc Beaudoin <pierre-luc.beaudoin at savoirfairelinux dot com> + - Many portions of code + - GTK client implementation + +Former authors: + +Yan Morin <yan dot morin at savoirfairelinux dot com> + - zeroconf integration + - sflphoned deamon + - add and improve sip core feature + - tests and debugging + +Jerome Oufella <jerome dot oufella at savoirfairelinux dot com> + - Many portions of code and bug fixes + +Julien Plissonneau Duquene <... at savoirfairelinux dot com> + - autotools cleanups + +Jean-Philippe Barrette-LaPierre + - Autotools support and portions of code + +Laurielle Lea + - Implementation of SFLphone + +Sherry Yang <syangs04 at yahoo dot com> + +Imran Akbar <imr at stanford dot edu> + - Working on Win32 port + +Contributors: + +Mikael Magnusson diff --git a/tools/build-system/bin/git-dch b/tools/build-system/bin/git-dch new file mode 100755 index 0000000000..f9ee5bc56f --- /dev/null +++ b/tools/build-system/bin/git-dch @@ -0,0 +1,404 @@ +#!/usr/bin/python -u +# vim: set fileencoding=utf-8 : +# +# (C) 2007,2008 Guido Guenther <agx@sigxcpu.org> +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""Generate Debian changelog entries from git commit messages""" + +import sys +import re +import os.path +import shutil +import subprocess +import gbp.command_wrappers as gbpc +from gbp.git_utils import (GitRepositoryError, GitRepository, build_tag) +from gbp.config import GbpOptionParser, GbpOptionGroup +from gbp.errors import GbpError +from gbp.deb_utils import parse_changelog +from gbp.command_wrappers import (Command, CommandExecFailed) + +snapshot_re = re.compile("\s*\*\* SNAPSHOT build @(?P<commit>[a-z0-9]+)\s+\*\*") +author_re = re.compile('Author: (?P<author>.*) <(?P<email>.*)>') +bug_r = r'(?:bug)?\#?\s?\d+' +bug_re = re.compile(bug_r, re.I) + +def system(cmd): + try: + Command(cmd, shell=True)() + except CommandExecFailed: + raise GbpError + + +def escape_commit(msg): + return msg.replace('"','\\\"').replace("$","\$").replace("`","\`") + + +def spawn_dch(msg='', author=None, email=None, newversion=False, version=None, release=False, distribution=None): + distopt = "" + versionopt = "" + env = "" + + if newversion: + if version: + versionopt = '--newversion=%s' % version + else: + versionopt = '-i' + elif release: + versionopt = "--release" + msg = None + + if author and email: + env = """DEBFULLNAME="%s" DEBEMAIL="%s" """ % (author, email) + + if distribution: + distopt = "--distribution=%s" % distribution + + cmd = '%(env)s dch --no-auto-nmu %(distopt)s %(versionopt)s ' % locals() + if type(msg) == type(''): + cmd += '"%s"' % escape_commit(msg) + system(cmd) + + +def add_changelog_entry(msg, author, email): + "add aa single changelog entry" + spawn_dch(msg=msg, author=author, email=email) + + +def add_changelog_section(msg, distribution, author=None, email=None, version=None): + "add a new changelog section" + spawn_dch(msg=msg, newversion= True, version=version, author=author, email=email, distribution=distribution) + + +def fixup_trailer(repo, git_author=False): + """fixup the changelog trailer's comitter and email address - it might + otherwise point to the last git committer instead of the person creating + the changelog""" + author = email = None + if git_author: + try: author = repo.get_config('user.name') + except KeyError: pass + + try: email = repo.get_config('user.email') + except KeyError: pass + + spawn_dch(msg='', author=author, email=email) + + +def head_commit(): + """get the full sha1 of the last commit on HEAD""" + commit = subprocess.Popen([ 'git', 'log', 'HEAD^..' ], stdout=subprocess.PIPE).stdout + sha = commit.readline().split()[-1] + return sha + + +def snapshot_version(version): + """ + get the current release and snapshot version + Format is <debian-version>~<release>.gbp<short-commit-id> + """ + try: + (release, suffix) = version.rsplit('~', 1) + (snapshot, commit) = suffix.split('.', 1) + if not commit.startswith('gbp'): + raise ValueError + else: + snapshot = int(snapshot) + except ValueError: # not a snapshot release + release = version + snapshot = 0 + return release, snapshot + + +def mangle_changelog(changelog, cp, snapshot=''): + """ + Mangle changelog to either add or remove snapshot markers + + @param snapshot: SHA1 if snapshot header should be added/maintained, empty if it should be removed + @type snapshot: str + """ + try: + tmpfile = '%s.%s' % (changelog, snapshot) + cw = file(tmpfile, 'w') + cr = file(changelog, 'r') + + cr.readline() # skip version and empty line + cr.readline() + print >>cw, "%(Source)s (%(MangledVersion)s) %(Distribution)s; urgency=%(urgency)s\n" % cp + + line = cr.readline() + if snapshot_re.match(line): + cr.readline() # consume the empty line after the snapshot header + line = '' + + if snapshot: + print >>cw, " ** SNAPSHOT build @%s **\n" % snapshot + + if line: + print >>cw, line.rstrip() + shutil.copyfileobj(cr, cw) + cw.close() + cr.close() + os.unlink(changelog) + os.rename(tmpfile, changelog) + except OSError, e: + raise GbpError, "Error mangling changelog %s" % e + + +def do_release(changelog, cp): + "remove the snapshot header and set the distribution" + (release, snapshot) = snapshot_version(cp['Version']) + if snapshot: + cp['MangledVersion'] = release + mangle_changelog(changelog, cp) + # <julien.bonjean@savoirfairelinux.com> + # prevent doing a release + # spawn_dch(release=True) + + +def do_snapshot(changelog, next_snapshot): + """ + Add new snapshot banner to most recent changelog section. The next snapshot + number is calculated by eval()'ing next_snapshot + """ + # commit = head_commit() + + cp = parse_changelog(changelog) + + # <julien.bonjean@savoirfairelinux.com> + # clean version before generate snapshot + version=cp['Version'] + try: + (release, suffix) = version.rsplit('~', 1) + except: + pass + try: + (snapshot, commit) = suffix.split('.', 1) + stripped = str(int(snapshot)) + except: + version=release + commit = head_commit() + + (release, snapshot) = snapshot_version(version) + snapshot = int(eval(next_snapshot)) + + suffix = "%d.gbp%s" % (snapshot, "".join(commit[0:6])) + cp['MangledVersion'] = "%s~%s" % (release, suffix) + + mangle_changelog(changelog, cp, commit) + return snapshot, commit + + +def get_author(commit): + """get the author from a commit message""" + for line in commit: + m = author_re.match(line) + if m: + return m.group('author'), m.group('email') + + +def parse_commit(repo, commitid, options): + """parse a commit and return message and author""" + msg = '' + thanks = '' + closes = '' + bugs = {} + bts_closes = re.compile(r'(?P<bts>%s):\s+%s' % (options.meta_closes, bug_r), re.I) + + commit = repo.show(commitid) + author, email = get_author(commit) + if not author: + raise GbpError, "can't parse author of commit %s" % commit + for line in commit: + if line.startswith(' '): # commit body + line = line[4:] + m = bts_closes.match(line) + if m: + bug_nums = [ bug.strip() for bug in bug_re.findall(line, re.I) ] + try: + bugs[m.group('bts')] += bug_nums + except KeyError: + bugs[m.group('bts')] = bug_nums + elif line.startswith('Thanks: '): + thanks = line.split(' ', 1)[1].strip() + else: # normal commit message + if options.short and msg: + continue + elif line.strip(): # don't add all whitespace lines + msg += line + # start of diff output: + elif line.startswith('diff '): + break + if options.meta: + for bts in bugs: + closes += '(%s: %s) ' % (bts, ', '.join(bugs[bts])) + if thanks: + thanks = '- thanks to %s' % thanks + msg += closes + thanks + if options.idlen: + msg = "[%s] " % commitid[0:options.idlen] + msg + return msg, (author, email) + + +def shortlog_to_dch(repo, commits, options): + """convert the changes in git shortlog format to debian changelog format""" + author = 'Unknown' + + for commit in commits: + msg, (author, email) = parse_commit(repo, commit, options) + add_changelog_entry(msg, author, email) + + +def guess_snapshot_commit(cp): + """guess the last commit documented in the changelog from the snapshot banner""" + sr = re.search(snapshot_re, cp['Changes']) + if sr: + return sr.group('commit') + + +def main(argv): + ret = 0 + changelog = 'debian/changelog' + until = 'HEAD' + found_snapshot_header = False + first_commit = None + + parser = GbpOptionParser(command=os.path.basename(argv[0]), prefix='', + usage='%prog [options] paths') + range_group = GbpOptionGroup(parser, "commit range options", "which commits to add to the changelog") + version_group = GbpOptionGroup(parser, "release & version number options", "what version number and release to use") + commit_group = GbpOptionGroup(parser, "commit message formatting", "howto format the changelog entries") + naming_group = GbpOptionGroup(parser, "branch and tag naming", "branch names and tag formats") + parser.add_option_group(range_group) + parser.add_option_group(version_group) + parser.add_option_group(commit_group) + parser.add_option_group(naming_group) + + naming_group.add_config_file_option(option_name="debian-branch", dest="debian_branch") + naming_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") + naming_group.add_config_file_option(option_name="debian-tag", dest="debian_tag") + naming_group.add_config_file_option(option_name="snapshot-number", dest="snapshot_number", + help="expression to determine the next snapshot number, default is '%(snapshot-number)s'") + parser.add_config_file_option(option_name="git-log", dest="git_log", + help="options to pass to git-log, default is '%(git-log)s'") + parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, + help="verbose command execution") + range_group.add_option("-s", "--since", dest="since", help="commit to start from (e.g. HEAD^^^, debian/0.4.3)") + range_group.add_option("-a", "--auto", action="store_true", dest="auto", default=False, + help="autocomplete changelog from last snapshot or tag") + version_group.add_option("-R", "--release", action="store_true", dest="release", default=False, + help="mark as release") + version_group.add_option("-S", "--snapshot", action="store_true", dest="snapshot", default=False, + help="mark as snapshot build") + version_group.add_option("-N", "--new-version", dest="new_version", + help="use this as base for the new version number") + version_group.add_config_file_option(option_name="git-author", dest="git_author", action="store_true") + version_group.add_config_file_option(option_name="no-git-author", dest="git_author", action="store_false") + commit_group.add_config_file_option(option_name="meta", dest="meta", + help="parse meta tags in commit messages, default is '%(meta)s'", action="store_true") + commit_group.add_config_file_option(option_name="meta-closes", dest="meta_closes", + help="Meta tags for the bts close commands, default is '%(meta-closes)s'") + commit_group.add_option("--full", action="store_false", dest="short", default=True, + help="include the full commit message instead of only the first line") + commit_group.add_config_file_option(option_name="id-length", dest="idlen", + help="include N digits of the commit id in the changelog entry, default is '%(id-length)s'", + type="int", metavar="N") + (options, args) = parser.parse_args(argv[1:]) + + if options.snapshot and options.release: + parser.error("'--snapshot' and '--release' are incompatible options") + + if options.since and options.auto: + parser.error("'--since' and '--auto' are incompatible options") + + try: + if options.verbose: + gbpc.Command.verbose = True + + try: + repo = GitRepository('.') + except GitRepositoryError: + raise GbpError, "%s is not a git repository" % (os.path.abspath('.')) + + branch = repo.get_branch() + if options.debian_branch != branch: + print >>sys.stderr, "You are not on branch '%s' but on '%s'" % (options.debian_branch, branch) + raise GbpError, "Use --debian-branch to set the branch to pick changes from" + + cp = parse_changelog(changelog) + + if options.since: + since = options.since + else: + since = '' + if options.auto: + since = guess_snapshot_commit(cp) + if since: + print "Continuing from commit '%s'" % since + found_snapshot_header = True + else: + print "Couldn't find snapshot header, using version info" + if not since: + since = build_tag(options.debian_tag, cp['Version']) + + if args: + print "Only looking for changes on '%s'" % " ".join(args) + commits = repo.commits(since, until, " ".join(args), options.git_log.split(" ")) + + # add a new changelog section if: + if cp['Distribution'] != "UNRELEASED" and not found_snapshot_header and commits: + # the last version was a release and we have pending commits + add_section = True + elif options.new_version or not found_snapshot_header: + # the user wants to force a new version or switch to snapshot mode + add_section = True + else: + add_section = False + + if add_section: + if commits: + first_commit = commits[0] + commits = commits[1:] + commit_msg, (commit_author, commit_email) = parse_commit(repo, first_commit, options) + else: + commit_msg = "UNRELEASED" + commit_author = None + commit_email = None + add_changelog_section(distribution="UNRELEASED", msg=commit_msg, + version=options.new_version, author=commit_author, + email=commit_email) + + if commits: + shortlog_to_dch(repo, commits, options) + fixup_trailer(repo, git_author=options.git_author) + elif not first_commit: + print "No changes detected from %s to %s." % (since, until) + + if options.release: + do_release(changelog, cp) + elif options.snapshot: + (snap, version) = do_snapshot(changelog, options.snapshot_number) + print "Changelog has been prepared for snapshot #%d at %s" % (snap, version) + + except (GbpError, GitRepositoryError), err: + if len(err.__str__()): + print >>sys.stderr, err + ret = 1 + return ret + +if __name__ == "__main__": + sys.exit(main(sys.argv)) + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- GitLab