buildpackage-rpm: add more tagging options
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Wed, 4 Sep 2013 07:33:03 +0000 (10:33 +0300)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Fri, 14 Nov 2014 12:45:07 +0000 (14:45 +0200)
Add new possible keywords to be used in packaging-tag format string:
'nowtime', 'authortime', 'committime', 'nowtimenum', 'authortimenum' and
'committimenum'.

The '*timenum' keyword denote the corresponding '*time' keyword appended
with an additional incremental serial number. E.g. if 'nowtime' would
produce '20120531', 'nowtimenum' would (the first time) produce
'20120531.1'.

What is completely missing is a way to support these new tag keywords in
git-import-srpm tool. So, if you use these tags, git-import-srpm is not
able to reproduce the tags, (and, it is not necessarily able to
correctly tell if you've already imported a certain version of the
package).

Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
gbp/rpm/policy.py
gbp/scripts/buildpackage_rpm.py

index 5818fcd..94b65f2 100644 (file)
@@ -46,6 +46,9 @@ class RpmPkgPolicy(PkgPolicy):
                            "and can only containg alphanumerics or characters "
                            "in %s" % list(version_whitelist_chars))
 
+    # Time stamp format to be used in tagging
+    tag_timestamp_format = "%Y%m%d"
+
     @classmethod
     def is_valid_orig_archive(cls, filename):
         """
index 562e135..bef4623 100755 (executable)
@@ -25,6 +25,7 @@ import sys
 import tempfile
 import shutil
 import re
+from datetime import datetime
 
 import gbp.rpm as rpm
 from gbp.rpm.policy import RpmPkgPolicy
@@ -220,6 +221,55 @@ def setup_builder(options, builder_args):
         options.spec_dir = ''
 
 
+def update_tag_str_fields(fields, tag_format_str, repo, commit_info):
+    """Update string format fields for packaging tag"""
+    fields['nowtime'] = datetime.now().strftime(RpmPkgPolicy.tag_timestamp_format)
+
+    fields['authortime'] = datetime.fromtimestamp(int(commit_info['author'].date.split()[0])).strftime(RpmPkgPolicy.tag_timestamp_format)
+    fields['committime'] = datetime.fromtimestamp(int(commit_info['committer'].date.split()[0])).strftime(RpmPkgPolicy.tag_timestamp_format)
+    fields['version'] = version=RpmPkgPolicy.compose_full_version(fields)
+
+    # Parse tags with incremental numbering
+    re_fields = dict(fields,
+                     nowtimenum=fields['nowtime'] + ".(?P<nownum>[0-9]+)",
+                     authortimenum=fields['authortime'] + ".(?P<authornum>[0-9]+)",
+                     committimenum=fields['committime'] + ".(?P<commitnum>[0-9]+)")
+    try:
+        tag_re = re.compile("^%s$" % (tag_format_str % re_fields))
+    except KeyError, err:
+        raise GbpError, "Unknown field '%s' in packaging-tag format string" % err
+
+    fields['nowtimenum'] = fields['nowtime'] + ".1"
+    fields['authortimenum'] = fields['authortime'] + ".1"
+    fields['committimenum'] = fields['committime'] + ".1"
+    for t in reversed(repo.get_tags()):
+        m = tag_re.match(t)
+        if m:
+            if 'nownum' in m.groupdict():
+                fields['nowtimenum'] = "%s.%s" % (fields['nowtime'], int(m.group('nownum'))+1)
+            if 'authornum' in m.groupdict():
+                fields['authortimenum'] = "%s.%s" % (fields['authortime'], int(m.group('authornum'))+1)
+            if 'commitnum' in m.groupdict():
+                fields['committimenum'] = "%s.%s" % (fields['committime'], int(m.group('commitnum'))+1)
+            break
+
+
+def packaging_tag_name(repo, spec, commit_info, options):
+    """Compose packaging tag as string"""
+    tag_str_fields = dict(spec.version, vendor=options.vendor)
+    update_tag_str_fields(tag_str_fields, options.packaging_tag, repo,
+                          commit_info)
+    return repo.version_to_tag(options.packaging_tag, tag_str_fields)
+
+
+def create_packaging_tag(repo, tag, commit, version, options):
+    """Create a packaging/release Git tag"""
+    msg = "%s release %s" % (options.vendor,
+                             RpmPkgPolicy.compose_full_version(version))
+    repo.create_tag(name=tag, msg=msg, sign=options.sign_tags,
+                    keyid=options.keyid, commit=commit)
+
+
 def parse_args(argv, prefix):
     args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == 0 ]
     builder_args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == -1 ]
@@ -470,14 +520,13 @@ def main(argv):
 
         # Tag (note: tags the exported version)
         if options.tag or options.tag_only:
-            gbp.log.info("Tagging %s" % rpm.RpmPkgPolicy.compose_full_version(spec.version))
-            tag_str_fields = dict(spec.version, vendor=options.vendor)
-            tag = repo.version_to_tag(options.packaging_tag, tag_str_fields)
+            gbp.log.info("Tagging %s" % RpmPkgPolicy.compose_full_version(spec.version))
+            commit_info = repo.get_commit_info(tree)
+            tag = packaging_tag_name(repo, spec, commit_info, options)
             if options.retag and repo.has_tag(tag):
                 repo.delete_tag(tag)
-            repo.create_tag(name=tag, msg="%s release %s" % (options.vendor,
-                                rpm.RpmPkgPolicy.compose_full_version(spec.version)),
-                            sign=options.sign_tags, keyid=options.keyid, commit=tree)
+            create_packaging_tag(repo, tag, commit=tree, version=spec.version,
+                                 options=options)
             if options.posttag:
                 sha = repo.rev_parse("%s^{}" % tag)
                 Command(options.posttag, shell=True,