Commits

Marcin Kasperski  committed 6b5b0b8

initial preps

  • Participants
  • Parent commits 848609c

Comments (0)

Files changed (2)

File make_release.pl

 #
 # Package maintainer helper. Builds, tests, tags and releases
 # the package to cpan. Nothing interesting, just saves some typing.
+#
+# Assumptions:
+#
+# - Module::Build is used for distribution
+# - source is kept in Mercurial
+# - version_hook.py is used to automatically manage version numbers
+#   according to tags
 
 use FindBin;
 use autodie qw(:all);

File sample-version_hook.py

+# -*- coding: utf-8 -*-
+
+"""
+Updating version number in files automatically whenever "hg tag" is
+issued.
+
+To use:
+
+1. Save as version_hook.py in the package directory
+
+2. Edit UPDATED_FILES below
+
+3. Add in .hg/hgrc
+
+       [hooks]
+       pre-tag=python:version_hook.py:version_update
+
+  Note: pre-tag, not pretag! Hook should run before changeset being
+  tagged is selected.
+
+With such config, simple
+
+  hg tag 0.27
+
+sets 0.27 as version number and commits this change before the tag
+is actually set.
+
+Hook scans configured files for constructs like::
+
+   our $VERSION = 'something';
+
+and::
+
+   Version 1.2342.
+
+In case other construct is needed, check version_regexps below.
+"""
+
+# Will be updated automatically
+VERSION = "0.2001"
+
+# List of files to scan and update
+UPDATED_FILES = [
+    "lib/Passwd/Keyring/KDEWallet.pm",
+    ]
+
+def _patch_perl_files(ui, new_version_no):
+    """
+    Patches all perl files to new version number, returns modified files.
+    """
+    import os, re
+    version_regexps = [
+        re.compile(r"^(?P<pfx>our +\$VERSION *= *').*?(?P<sfx>'.*)$"),
+        re.compile(r"^(?P<pfx>Version +)\d+\.\d+(\.\d+)?(?P<sfx>\.? *)$"),
+        ]
+
+    location = os.path.dirname(__file__)
+    updated_files = []
+    for candidate in UPDATED_FILES:
+        full_name = os.path.join(location, candidate)
+        changes = 0
+        file_lines = []
+        ui.note("Checking file %s\n" % candidate)
+        with open(full_name, "r") as input:
+            for line in input.readlines():
+                m = None
+                for rgxp in version_regexps:
+                    m = rgxp.search(line)
+                    if m:
+                        ui.note("Patching line %s" % line)
+                        break
+                if m:
+                    file_lines.append(
+                        m.group('pfx') + new_version_no + m.group('sfx') + "\n")
+                    changes += 1
+                else:
+                    file_lines.append(line)
+        if changes:
+            ui.status("Version updater: Replacing old version number with {0:>s} in {1}\n".format(new_version_no, full_name))
+            with open(full_name, "w") as output:
+                output.writelines(file_lines)
+            updated_files.append(full_name)
+    return updated_files
+    
+def version_update(repo, ui, hooktype, pats, opts, **kwargs):
+    """
+    Method used in mercurial version-update hook. Don't call directly.
+    """
+    import re
+    import mercurial.commands
+
+    # Regexps for handled version number syntaxes
+    tag_regexps = [
+        # something_1-2, something-1.2 and similar
+        re.compile(r"[^-_0-9][-_](?P<major>[0-9]+)[-_\.](?P<minor>[0-9]+)$"),
+        # 1.2, 1-2, 1_2
+        re.compile(r"^(?P<major>[0-9]+)[-_\.](?P<minor>[0-9]+)$"),
+        ]
+
+    if opts.get('local'):
+        ui.note("Version updater: ignoring local tag\n")
+        return
+    if opts.get('remove'):
+        ui.note("Version updater: ignoring tag removal\n")
+        return
+    if opts.get('rev'):
+        ui.note("Version updater: ignoring tag placed by rev\n")
+        return
+
+    if len(pats) != 1:
+        ui.warn("Version updater: unexpected arguments, pats=%s\n" % pats)
+        return True # means fail
+
+    tag_name = pats[0]
+
+    version_no = None
+    for tag_regexp in tag_regexps:
+        m = tag_regexp.search(tag_name)
+        if m:
+            version_no = "{major:>s}.{minor:>s}".format(**m.groupdict())
+            break
+    if not version_no:
+        ui.warn("Version updater: Given tag does not seem to be versioned. Please make proper tags (1.2, xxxx_1-2, xaear-aera-1.2 or similar\n")
+        return True # means fail
+
+    if version_no == VERSION:
+        ui.note("Version updater: version number {0:>s} is already correct\n".format(version_no))
+        return False # means OK
+
+    # Regexp for VERSION= line
+    py_version_regexp = re.compile(r"^VERSION *= *")
+
+    my_name = __file__
+    if my_name.endswith(".pyc") or my_name.endswith(".pyo"):
+        my_name = my_name[:-1]
+
+    ui.status("Version updater: Replacing old version number {0:>s} with {1:>s} in {2}\n".format(
+        VERSION, version_no, my_name))
+
+    file_lines = []
+    changes = 0
+    with open(my_name, "r") as input:
+        for line in input.readlines():
+            if py_version_regexp.search(line):
+                file_lines.append('VERSION = "%s"\n' % version_no)
+                changes += 1
+            else:
+                file_lines.append(line)
+    if not changes:
+        ui.warn("Version updater: Line starting with VERSION= not found in {0:>s}.\nPlease correct this file and retry\n".format(my_name))
+        return True #means fail
+    with open(my_name, "w") as output:
+        output.writelines(file_lines)
+
+    updated_perl_files = _patch_perl_files(ui, version_no)
+
+    ui.note("Commiting updated version number\n")
+    mercurial.commands.commit(
+        ui, repo,
+        my_name,
+        *updated_perl_files,
+        message="Version number set to %s" % version_no)
+    return False #means ok