aboutsummaryrefslogtreecommitdiffhomepage
path: root/git-dch
blob: d2dda69e2df3d0bc090ef3398bdda960478efc26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/python
# vim: set fileencoding=utf-8 :
#
# (C) 2007 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 changelogs"""

import sys
import os
import re
import subprocess
import gbp.command_wrappers as gbpc
from gbp.git_utils import (GitRepositoryError, GitRepository, build_tag)
from gbp.config import GbpOptionParser
from gbp.errors import GbpError
from gbp.deb_utils import parse_changelog


def get_log(start, end):
    """Get the shortlog from commit start to commit end"""
    try:
        p1 = subprocess.Popen(["git-log", "--no-merges", "%s...%s" % (start, end)], 
                              stdout=subprocess.PIPE)
        p2 = subprocess.Popen(["git-shortlog"], stdin=p1.stdout, stdout=subprocess.PIPE)
        changes = p2.communicate()[0].split('\n')
    except OSError, err:
        raise GbpError, "Cannot get changes: %s" % err
    except ValueError, err:
        raise GbpError, "Cannot get changes: %s" % err
    if p1.wait() or p2.wait():
        raise GbpError, "Cannot get changes, pipe failed."
    return changes


def add_changelog_entry(msg, author):
    cmd = 'DEBFULLNAME="%s" dch "%s"' % (author, msg.replace('"','\"'))
    ret = os.system(cmd)
    if ret:
        raise GbpError, "Error executing %s: %d" % (cmd, ret)


def add_changelog_section(msg, distribution):
    ret = os.system("dch --distribution=%s -i %s" % (distribution, msg))
    if ret:
        raise GbpError, "Error executing %s: %d" % (cmd, ret)


def shortlog_to_dch(changes):
    """convert the changes in git shortlog format to debian changelog format"""    
    commit_re = re.compile('\s+(?P<msg>.*)')
    author_re = re.compile('(?P<author>.*) \([0-9]+\)')
    author = 'Unknown'
    ret = 0

    for line in changes:
        r = commit_re.match(line)
        msg = ''
        if r:
            msg = r.group('msg')
        else:
            r = author_re.match(line)
            if r:
                author = r.group('author')
            elif line:
                print >>sys.stderr, "Unknown changelog line: %s" % line
        if msg:
            add_changelog_entry(msg, author)


def main(argv):
    ret = 0

    parser = GbpOptionParser(command=os.path.basename(argv[0]), prefix='')

    parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
                      help="verbose command execution")
    parser.add_config_file_option(option_name="debian-branch", dest='debian',
                      help="branch the debian patch is being developed on, default is '%(debian-branch)s'")
    parser.add_option("-s", "--since", dest="from_commit", help="commit to start from")
    parser.add_config_file_option(option_name="debian-tag", dest="debian_tag",
                      help="Format string for debian tags, default is '%(debian-tag)s'")
    (options, args) = parser.parse_args(argv[1:])

    try:
        if options.verbose:
            gbpc.Command.verbose = True

        if args:
            parser.print_help()
            raise GbpError

        try:
            GitRepository('.')
        except GitRepositoryError:
            raise GbpError, "%s is not a git repository" % (os.path.abspath('.'))

        cp = parse_changelog('debian/changelog')
        if options.from_commit:
            start = options.from_commit
        else:
            start = build_tag(options.debian_tag, cp['Version'])

        changes = get_log(start, options.debian)
        if changes:
            # FIXME: need a way to force a new verison anyway:
            if cp['Distribution'] != "UNRELEASED":
                add_changelog_section(distribution="UNRELEASED", msg="UNRELEASED")
            shortlog_to_dch(changes)
        else:
            print "No changes detected from %s to %s." % (start, options.debian)

    except GbpError, 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\:·: