1#!//usr/bin/env python2.7
2
3from __future__ import print_function
4import subprocess
5import re
6import sys
7import datetime
8import os
9import ConfigParser
10
11try:
12    long
13except NameError:
14    long = int
15
16distribution="yakkety"
17
18versionTagRE = re.compile("^v([0-9]+((\.[0-9]+)+))(-(.+))?$")
19
20def processVersionTag(tag):
21    m = versionTagRE.match(tag)
22    if m:
23        return (m.group(1), "release" if m.group(4) is None else "beta")
24    else:
25        return None
26
27def getCommitVersion(commit):
28    major=None
29    minor=None
30    patch=None
31    try:
32        for line in subprocess.check_output(["git", "show",
33                                             commit + ":VERSION.cmake"]).splitlines():
34            m = re.match("set\( MIRALL_VERSION_([A-Z]+) +([0-9]+) *\)", line)
35            if m is not None:
36                kind=m.group(1)
37                version=m.group(2)
38                if kind=="MAJOR":
39                    major=version
40                elif kind=="MINOR":
41                    minor=version
42                elif kind=="PATCH":
43                    patch=version
44        if major and minor and patch:
45            return major + "." + minor + "." + patch
46        else:
47            return None
48    except:
49        return None
50
51def collectEntries(baseCommit, baseVersion, kind, finalBaseVersion, finalRevDate, config):
52
53    newVersionCommit = None
54    newVersionTag = None
55    newVersionOrigTag = None
56
57    if config is not None and config.has_section("versionhack"):
58        if config.has_option("versionhack", "commit") and \
59           config.has_option("versionhack", "tag"):
60            newVersionCommit = config.get("versionhack", "commit")
61            newVersionTag = config.get("versionhack", "tag")
62
63    entries = []
64
65    args = ["git", "log",
66            "--format=%h%x09%an%x09%ae%x09%aD%x09%ad%x09%s",
67            "--date=unix", "--author-date-order", "--reverse"]
68    try:
69        output = subprocess.check_output(args + [baseCommit + ".."])
70    except:
71        output = subprocess.check_output(args)
72
73
74    lastVersionTag = None
75    lastCMAKEVersion = None
76    for line in output.splitlines():
77        words = line.split("\t")
78        (commit, name, email, date, revdate) = words[0:5]
79        subject = "\t".join(words[5:])
80
81        revdate = datetime.datetime.utcfromtimestamp(long(revdate)).strftime("%Y%m%d.%H%M%S")
82        revdate += "." + commit
83
84        kind = "alpha"
85
86        if commit==newVersionCommit:
87            result = processVersionTag(newVersionTag)
88            if result:
89                newVersionOrigTag = lastVersionTag
90                (baseVersion, _kind) = result
91
92        version=getCommitVersion(commit)
93        if version and version!=lastCMAKEVersion:
94            tag = "v" + version
95            if tag!=newVersionOrigTag:
96                result = processVersionTag(tag)
97                if result:
98                    lastVersionTag = tag
99                    lastCMAKEVersion = version
100                    (baseVersion, _kind) = result
101
102        for tag in subprocess.check_output(["git", "tag",
103                                            "--points-at",
104                                            commit]).splitlines():
105            if tag!=newVersionOrigTag:
106                result = processVersionTag(tag)
107                if result:
108                    lastVersionTag = tag
109                    (baseVersion, kind) = result
110
111
112        entries.append((commit, name, email, date, revdate, subject,
113                        baseVersion, kind))
114
115    if entries:
116        (commit, name, email, date, revdate, subject, baseVersion, kind) = entries[-1]
117        if finalRevDate is None:
118            revdate = datetime.datetime.now().strftime("%Y%m%d.%H%M%S")+ "." + commit
119        else:
120            revdate = finalRevDate
121        if finalBaseVersion is not None:
122            baseVersion = finalBaseVersion
123        entries[-1] = (commit, name, email, date, revdate, subject, baseVersion, kind)
124
125    entries.reverse()
126
127    return entries
128
129def genChangeLogEntries(f, entries, distribution):
130    latestBaseVersion = None
131    latestRevDate = None
132    latestKind = None
133    for (commit, name, email, date, revdate, subject, baseVersion, kind) in entries:
134        if latestBaseVersion is None:
135            latestBaseVersion = baseVersion
136            latestRevDate = revdate
137            latestKind = kind
138        upstreamVersion = baseVersion + "-" + revdate
139        if distribution=="stable":
140            version = upstreamVersion
141        else:
142            version = upstreamVersion + "-1.0~" + distribution + "1"
143        print("nextcloud-desktop (%s) %s; urgency=medium" % (version, distribution), file=f)
144        print(file=f)
145        print("  * " + subject, file=f)
146        print(file=f)
147        print(" -- %s <%s>  %s" % (name, email, date), file=f)
148        print(file=f)
149    return (latestBaseVersion, latestRevDate, latestKind)
150
151if __name__ == "__main__":
152    scriptdir = os.path.dirname(__file__)
153    configPath = os.path.join(scriptdir, "git2changelog.cfg")
154
155    baseCommit = "f9b1c724d6ab5431e0cd56b7cd834f2dd48cebb1"
156    baseVersion = "2.4.0"
157
158    config = None
159    if os.path.exists(configPath):
160        config = ConfigParser.SafeConfigParser()
161        config.read(configPath)
162
163        if config.has_section("base"):
164            if config.has_option("base", "commit") and \
165               config.has_option("base", "version"):
166                baseCommit = config.get("base", "commit")
167                baseVersion = config.get("base", "version")
168
169    distribution = sys.argv[2]
170    finalRevDate = sys.argv[3] if len(sys.argv)>3 else None
171    finalBaseVersion = sys.argv[4] if len(sys.argv)>4 else None
172
173    entries = collectEntries(baseCommit, baseVersion, "alpha",
174                             finalBaseVersion, finalRevDate, config)
175
176    with open(sys.argv[1], "wt") as f:
177        (baseVersion, revdate, kind) = genChangeLogEntries(f, entries, distribution)
178        print(baseVersion, revdate, kind)
179