Mercurial > hgrepos > DevTools > mercurial-extensions
changeset 33:dc8db9693262
kwarchive expands keyword on given files (.hgkwarchive with generic Mercurial patterns)
| author | Franz Glasner <hg@dom66.de> |
|---|---|
| date | Sat, 11 Nov 2017 23:05:37 +0100 |
| parents | cfa53f8a6607 |
| children | 7c4addd60935 |
| files | extensions/kwarchive.py |
| diffstat | 1 files changed, 99 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/extensions/kwarchive.py Sat Nov 11 17:17:00 2017 +0100 +++ b/extensions/kwarchive.py Sat Nov 11 23:05:37 2017 +0100 @@ -1,5 +1,27 @@ # -*- coding: utf-8 -*- """archive with keyword expansion into selected files + +The patterns of files to to expanded are configured in an versioned +``.hgkwarchive`` configuration file found in the root of the working +directory. + +The ``.hgkwarchive`` file uses the same syntax as all other Mercurial +configuration files. + +The ``[patterns]`` section specifies which files should have the keywords +expanded. + + +Example:: + + [patterns] + # expand keywords in every python file except those matching "x*" + **.py = + x* = NO + +A non-existing ``.hgkwarchive`` file deactivates keyword expansion as does +an empty ``[patterns]`` section. + """ from __future__ import absolute_import @@ -11,10 +33,11 @@ import os +import itertools from mercurial.i18n import _ -from mercurial import (archival, commands, cmdutil, error, pycompat, - scmutil, util) +from mercurial import (archival, commands, config, cmdutil, error, match, + pycompat, scmutil, templatefilters, util) testedwith = "4.3.2" @@ -101,7 +124,14 @@ # expands keywords # for ac in ("fileit", "tarit", "zipit",): - patch_archiver_class(ac) + patch_archiver_class( + ac, + make_keyword_filter( + ui, + repo, + ctx, + ac, + archival.tidyprefix(dest, kind, prefix))) archival.archive(repo, dest, node, kind, not opts.get('no_decode'), matchfn, prefix, subrepos=opts.get('subrepos')) @@ -109,20 +139,80 @@ # XXX FIXME: Should the original methods be restored here? -def patch_archiver_class(archivername): +def patch_archiver_class(archivername, filter): """Patch an archiver class and return the original unbound method""" archiver_class = getattr(archival, archivername) orig_addfile = getattr(archiver_class, "addfile") def new_addfile(self, name, mode, isline, data): - print "==> ARCHIVER(%s)" % archivername, name, mode, isline - return orig_addfile(self, name, mode, isline, data) + return orig_addfile(self, name, mode, isline, filter(name, data)) setattr(archiver_class, "addfile", new_addfile) return orig_addfile -def filter2(s, params, ui, **kwargs): - print "=============>", repr(params), repr(kwargs) - return s +def make_keyword_filter(ui, repo, ctx, archive_class, prefix, + hgpath="default"): + + # node specific keywords + keywords = { + "HGpath": ui.config("paths", hgpath) or repo.root, + "HGrevision": ctx.hex(), + "Revision": templatefilters.short(ctx.hex()), + "Author": templatefilters.person(ctx.user()), + "Date": templatefilters.isodatesec(ctx.date()), + } + # .hgkwarchive + try: + kwconfig = ctx[".hgkwarchive"] + except (IOError, LookupError): + def _filter(name, data): + return data + else: + cfg = config.config() + cfg.parse(".kwarchive", kwconfig.data()) + include = [] + exclude = [] + patterns = [] + if cfg.items("patterns"): + for pattern, style in cfg.items("patterns"): + style = style.upper() + if style in ("YES", "INCLUDE",): + include.append(pattern) + if style in ("NO", "EXCLUDE",): + exclude.append(pattern) + else: + patterns.append(pattern) + matcher = match.match(repo.root, '', patterns=patterns, + include=include, exclude=exclude) + else: + matcher = match.never(repo.root, '') + + def _filter(name, data): + real_name = name + if archive_class != "fileit": + if prefix: + assert name.startswith(prefix) + real_name = name[len(prefix):] + if not matcher(real_name): + return data + # file specific keywords + file_keywords = { + "HGsource": keywords["HGpath"] + '/' + real_name, + "Source": real_name, + "File": templatefilters.basename(real_name), + "Header": "%s %s %s %s" % (real_name, keywords["Revision"], keywords["Date"], keywords["Author"]), + "HGid": "%s %s %s %s" % (keywords["HGpath"] + '/' + real_name, keywords["Revision"], keywords["Date"], keywords["Author"]), + "HGheader": "%s %s %s %s" % (keywords["HGpath"] + '/' + real_name, keywords["HGrevision"], keywords["Date"], keywords["Author"]), + "Id": "%s %s %s %s" % (templatefilters.basename(real_name), keywords["Revision"], keywords["Date"], keywords["Author"]), + } + # This prevents unwanted keyword expansion here + _MARKER = '$' + for kw, value in itertools.chain(keywords.items(), file_keywords.items()): + filekw = _MARKER + kw + _MARKER + filevalue = "%s%s: %s %s" % (_MARKER, kw, value, _MARKER) + data = data.replace(filekw, filevalue) + return data + + return _filter
