Patchwork [05,of,22] buildrpm: simpler and better versioning scheme and changelog

login
register
mail settings
Submitter Mads Kiilerich
Date May 20, 2014, 2:10 a.m.
Message ID <2259d306178fe5cce7f5.1400551800@mk-desktop>
Download mbox | patch
Permalink /patch/4827/
State Changes Requested
Headers show

Comments

Mads Kiilerich - May 20, 2014, 2:10 a.m.
# HG changeset patch
# User Mads Kiilerich <madski@unity3d.com>
# Date 1400111317 -7200
#      Thu May 15 01:48:37 2014 +0200
# Node ID 2259d306178fe5cce7f57cda30241d7a991f0b8d
# Parent  d92c61a619e5e350da6d7c192a91dc3ccd743efb
buildrpm: simpler and better versioning scheme and changelog

Replace a long and hairy mix of hg and shell script and python with a short and
hairy use of revsets and templating.

This will introduce a new versioning scheme where
* revisions are monotonically increasing so nightly builds will be upgrades
* stable and development branches can be distinguished

Builds not on the stable branch is given a 0.next prefix to make clear we don't
have a good approximation of a version number.
The version number on released (and tagged) revisions is "{latesttag}-1", where
1 can be seen as indicating that it is build 1.0 of that version.
Tags with only two numbers / digits (and perhaps a -rc suffix) (such as 3.0 and
3.0-rc) are padded with an extra .0 to make it 3 digits (such as 3.0.0).
Tags with -rc are named X.X.X-0.rc instead of X.X.X-rc - that makes sure that
the final -1.x cames after -0.rc.x (so 3.0.0-1.7 comes after 3.0.0-0.rc.7).

An example of full version numbers:
3.0.0-1.0.2195ac506c6a
          ^^^^^^^^^^^^ node
        ^ latesttagdistance
      ^ the real thing, higher than rc which is 0.rc  \
    ^ padding to 3 numbers (when necessary)            } from latesttag
^^^ release number                                    /

Note: latesttag and latesttagdistance works fine for changesets on the same
branch as the tags. The result is more confusing for changesets on the
development branch.

The changelog in the rpm spec will go back to the previous tagged release and
look like:

* Sat May 03 2014 Mads Kiilerich <madski@unity3d.com> 3.0.0-1.4.75aaae8ad660
- color: don't fail on error messages when no curses (issue4237)

* Fri May 02 2014 Matt Mackall <mpm@selenic.com> 3.0.0-1.2.cadad384c97c
- Added signature for changeset 2195ac506c6a

* Fri May 02 2014 Matt Mackall <mpm@selenic.com> 3.0.0-1.1.95671eead199
- Added tag 3.0 for changeset 2195ac506c6a

* Thu May 01 2014 Pierre-Yves David <pierre-yves.david@fb.com> 3.0.0-1.0.2195ac506c6a
- 3.0
- revset: directly use __contains__ instead of a lambda

Note: The changelog entries has to be sorted by date - that can make entries
show up in a confusing order.
Mads Kiilerich - May 20, 2014, 7:18 p.m.
It would be nice if we had better support and "best practice 
documentation" for automatic versioning of builds from repositories, 
both if they used "semantic versioning" and other numbering schemes.

latesttag and latesttagdistance brings us a bit of the way ... but 
setup.py shows that it still requires a lot of scaffolding.

The scheme I use here is mostly compliant with 
http://fedoraproject.org/wiki/Packaging:NamingGuidelines#Package_Versioning 
.

/Mads

Patch

diff --git a/contrib/buildrpm b/contrib/buildrpm
--- a/contrib/buildrpm
+++ b/contrib/buildrpm
@@ -31,69 +31,39 @@  rpmdir="$PWD/rpmbuild"
 rm -rf $rpmdir
 mkdir -p $rpmdir/SOURCES $rpmdir/SPECS $rpmdir/RPMS $rpmdir/SRPMS $rpmdir/BUILD
 
-hgversion=`$HG version | sed -ne 's/.*(version \(.*\))$/\1/p'`
+# Builds not on the stable branch is given a 0.next prefix to make clear we don't
+# have a good approximation of a version number.
+# The version number on released (and tagged) revisions is "{latesttag}-1", where
+# 1 can be seen as indicating that it is build 1.0 of that version.
+# Tags with only two numbers / digits (and perhaps a -rc suffix) (such as 3.0 and
+# 3.0-rc) are padded with an extra .0 to make it 3 digits (such as 3.0.0).
+# Tags with -rc are named X.X.X-0.rc instead of X.X.X-rc - that makes sure that
+# the final -1.x cames after -0.rc.x (so 3.0.0-1.7 comes after 3.0.0-0.rc.7).
 
-if echo $hgversion | grep -- '-' > /dev/null 2>&1; then
-    # nightly build case, version is like 1.3.1+250-20b91f91f9ca
-    version=`echo $hgversion | cut -d- -f1`
-    release=`echo $hgversion | cut -d- -f2 | sed -e 's/+.*//'`
-else
-    # official tag, version is like 1.3.1
-    version=`echo $hgversion | sed -e 's/+.*//'`
-    release='0'
-fi
+hgversion=`$HG par -T '{ifeq(branch, "stable", "", "0.next.")}{sub("-rc-1$", "-0.rc", sub(r"(?<=^\d\.\d)(?=(-rc)?-1$)", ".0", "{latesttag}-1"))}.{latesttagdistance}.{node|short}\n'`
+
+# An example of full version numbers:
+# 3.0.0-1.0.2195ac506c6a
+#           ^^^^^^^^^^^^ node
+#         ^ latesttagdistance
+#       ^ the real thing, higher than rc which is 0.rc  \
+#     ^ padding to 3 numbers (when necessary)            } from latesttag
+# ^^^ release number                                    /
+
+version=${hgversion%-*}
+release=${hgversion#*-}
 
 $HG archive -t tgz $rpmdir/SOURCES/mercurial-$version-$release.tar.gz
 rpmspec=$rpmdir/SPECS/mercurial.spec
 
-sed -e "s,^Version:.*,Version: $version," \
+(
+sed \
+    -e "s,^Version:.*,Version: $version," \
     -e "s,^Release:.*,Release: $release," \
-    $specfile > $rpmspec
-
-echo >> $rpmspec
-echo "%changelog" >> $rpmspec
-
-if echo $version | grep '+' > /dev/null 2>&1; then
-    latesttag="`echo $version | sed -e 's/+.*//'`"
-    $HG log -r .:"$latesttag" -fM \
-        --template '{date|hgdate}\t{author}\t{desc|firstline}\n' | python -c '
-import sys, time
-
-def datestr(date, format):
-    return time.strftime(format, time.gmtime(float(date[0]) - date[1]))
-
-changelog = []
-for l in sys.stdin.readlines():
-    tok = l.split("\t")
-    hgdate = tuple(int(v) for v in tok[0].split())
-    changelog.append((datestr(hgdate, "%F"), tok[1], hgdate, tok[2]))
-prevtitle = ""
-for l in sorted(changelog, reverse=True):
-    title = "* %s %s" % (datestr(l[2], "%a %b %d %Y"), l[1])
-    if prevtitle != title:
-        prevtitle = title
-        print
-        print title
-    print "- %s" % l[3].strip()
-' >> $rpmspec
-
-else
-
-    $HG log \
-         --template '{date|hgdate}\t{author}\t{desc|firstline}\n' \
-         .hgtags | python -c '
-import sys, time
-
-def datestr(date, format):
-    return time.strftime(format, time.gmtime(float(date[0]) - date[1]))
-
-for l in sys.stdin.readlines():
-    tok = l.split("\t")
-    hgdate = tuple(int(v) for v in tok[0].split())
-    print "* %s %s\n- %s" % (datestr(hgdate, "%a %b %d %Y"), tok[1], tok[2])
-' >> $rpmspec
-
-fi
+    $specfile
+$HG log -r "sort(::.-::parents(tagged('re:^[0-9.]*$')&::parents(.)),-date)" \
+    -T '* {date(date|localdate, "%a %b %d %Y")} {author} {sub("-rc-1$", "-0.rc", sub(r"(?<=^\d\.\d)(?=(-rc)?-1$)", ".0", "{latesttag}-1"))}.{latesttagdistance}.{node|short}\n{if(tags,"- {tags}\n")}- {desc|firstline}\n\n'
+) > $rpmspec
 
 rpmbuild --define "_topdir $rpmdir" -ba $rpmspec --clean
 if [ $? = 0 ]; then
diff --git a/contrib/mercurial.spec b/contrib/mercurial.spec
--- a/contrib/mercurial.spec
+++ b/contrib/mercurial.spec
@@ -76,3 +76,5 @@  rm -rf $RPM_BUILD_ROOT
 %endif
 %{_libdir}/python%{pythonver}/site-packages/%{name}
 %{_libdir}/python%{pythonver}/site-packages/hgext
+
+%changelog