diff extensions/kwarchive.py @ 298:aa945541d2ca

kwarchive: fully implements recursing into Mercurial subrepos and do keyword expansion there also
author Franz Glasner <hg@dom66.de>
date Wed, 30 Jan 2019 00:14:15 +0100
parents 15d23729d176
children bbbb23202d6e
line wrap: on
line diff
--- a/extensions/kwarchive.py	Tue Jan 29 19:17:29 2019 +0100
+++ b/extensions/kwarchive.py	Wed Jan 30 00:14:15 2019 +0100
@@ -149,7 +149,7 @@
         ('r', 'rev', '', _('revision to distribute'), _('REV')),
         ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
         ('', 'path', 'default', _('the canonical repository to use'), _('PATH')),
-        ('', "kwconfig", '', _('an alternate pattern configuration configuration file'), _('PATTERNCONFIG')),
+        ('', "kwconfig", '', _('an alternate pattern configuration configuration file (possibly used for subrepos also)'), _('PATTERNCONFIG')),
         ('', "no-shorten-path", None, _("don't shorten the path urls")),
         ('', "path-filter", "short", _("determine how the path will be printed")),
         ('', "user-filter", "user", _("the part of the user to be printed"), _("USERFILTER"))
@@ -452,33 +452,44 @@
         "": _make_repo_filterdata(ui, ctx, hgpath, None, kwconfig,
                                   path_filter, user_filter),
     }
-    subrepos = list(filterdata_by_subrepos.keys())
-    subrepos.sort(key=len, reverse=True)
+    if subrepos:
+        _amend_filterdata_by_subrepos(filterdata_by_subrepos,
+                                      ui, ctx,
+                                      kwconfig,
+                                      path_filter,
+                                      user_filter)
+    subrepo_paths = list(filterdata_by_subrepos.keys())
+    subrepo_paths.sort(key=len, reverse=True)
 
     def _filter(name, data):
-        real_name = name
+        real_name = rel_name_in_subrepo = name
         if archive_class != "fileit":
             if prefix:
                 assert name.startswith(prefix)
-                real_name = name[len(prefix):]
-        for s in subrepos:
+                real_name = rel_name_in_subrepo = name[len(prefix):]
+        # find the filterdata configuration corresponding to current subrepo
+        for s in subrepo_paths:
             if real_name.startswith(s):
-                if filterdata_by_subrepos[s] is None:
-                    return data
-                matcher, matcher_rcs, matcher_rst, manifest, \
-                        keyword_whitelist, keyword_substitutions, keywords  = \
-                    filterdata_by_subrepos[s]
+                filterdata = filterdata_by_subrepos[s]
+                rel_name_in_subrepo = real_name[len(s):]
                 break
-            else:
-                raise ValueError("invalid repo configuration")
-        if not matcher(real_name):
+        else:
+            raise ValueError("invalid subrepo filter data")
+        if filterdata is None:
+            return data
+        matcher, matcher_rcs, matcher_rst, manifest, \
+            keyword_whitelist, keyword_substitutions, keywords  = filterdata
+
+        if not matcher(rel_name_in_subrepo):
+            #ui.write("NOT MATCHER for " + real_name + " (name: " + name + ") \n")
             return data
         try:
-            nodeid = node.hex(manifest[real_name])
+            nodeid = node.hex(manifest[rel_name_in_subrepo])
         except LookupError:
             nodeid = None
         # file specific keywords
-        file_keywords = make_file_keywords(keywords, real_name, nodeid)
+        file_keywords = make_file_keywords(
+            keywords, rel_name_in_subrepo, nodeid)
         # This prevents unwanted keyword expansion here
         _MARKER_RCS = '$'
         _MARKER_RST = '|'
@@ -492,12 +503,12 @@
             else:
                 kwds = [kw]
             for kw in kwds:
-                if matcher_rcs(real_name):
+                if matcher_rcs(rel_name_in_subrepo):
                     filekw = "%s%s%s" % (_MARKER_RCS, kw, _MARKER_RCS)
                     filevalue = "%s%s: %s %s" \
                                 % (_MARKER_RCS, kw, value, _MARKER_RCS)
                     data = data.replace(filekw, filevalue)
-                if matcher_rst(real_name):
+                if matcher_rst(rel_name_in_subrepo):
                     filekw = "%sVCS%s%s" % (_MARKER_RST, kw, _MARKER_RST)
                     filevalue = value
                     data = data.replace(filekw, filevalue)
@@ -511,7 +522,8 @@
     keywords = make_node_keywords(ui, ctx,
                                   hgpath=hgpath,
                                   path_filter=path_filter,
-                                  user_filter=user_filter)
+                                  user_filter=user_filter,
+                                  hglocation=hglocation)
     kwconfigdata = kwconfigname = None
     if kwconfig:
         kwconfigdata = util.posixfile(kwconfig, "rb").read()
@@ -611,6 +623,32 @@
                 keyword_whitelist, keyword_substitutions, keywords,)
 
 
+def _amend_filterdata_by_subrepos(filterdata_by_subrepos,
+                                  ui,
+                                  ctx,
+                                  kwconfig,
+                                  path_filter, user_filter):
+
+    for subpath in sorted(ctx.substate):
+        substate = ctx.substate[subpath]
+        # skip on non-Mercurial subrepos
+        if substate[2] != "hg":
+            continue
+        subrep = ctx.workingsub(subpath)
+        subctx = subrep._getctx()
+
+        # Really amend
+        filterdata_by_subrepos[subrepo.subrelpath(subrep) + '/'] = \
+            _make_repo_filterdata(ui, subctx, None, substate[0], kwconfig,
+                                  path_filter, user_filter)
+
+        # Recursively check for other subrepos
+        _amend_filterdata_by_subrepos(filterdata_by_subrepos,
+                                      ui, subctx,
+                                      kwconfig,
+                                      path_filter, user_filter)
+
+
 def make_node_keywords(ui, ctx,
                        hgpath="default",
                        path_filter="short",
@@ -701,15 +739,15 @@
     return keywords
 
 
-def make_file_keywords(keywords, real_name, nodeid):
+def make_file_keywords(keywords, rel_name, nodeid):
     return {
-        "HGsource": keywords["HGpath"] + '/' + real_name,
-        "Source": real_name,
-        "File": templatefilters.basename(real_name),
-        "Header": "%s %s %s %s %s" % (real_name, keywords["Revision"], keywords["Date"], keywords["Author"], keywords["State"]),
-        "HGid": "%s %s %s %s %s" % (keywords["HGpath"] + '/' + real_name, keywords["Revision"], keywords["Date"], keywords["Author"], keywords["State"]),
-        "HGheader": "%s %s %s %s %s" % (keywords["HGpath"] + '/' + real_name, keywords["HGrevision"], keywords["Date"], keywords["Author"], keywords["State"]),
-        "Id": "%s %s %s %s %s" % (templatefilters.basename(real_name), keywords["Revision"], keywords["Date"], keywords["Author"], keywords["State"]),
+        "HGsource": keywords["HGpath"] + '/' + rel_name,
+        "Source": rel_name,
+        "File": templatefilters.basename(rel_name),
+        "Header": "%s %s %s %s %s" % (rel_name, keywords["Revision"], keywords["Date"], keywords["Author"], keywords["State"]),
+        "HGid": "%s %s %s %s %s" % (keywords["HGpath"] + '/' + rel_name, keywords["Revision"], keywords["Date"], keywords["Author"], keywords["State"]),
+        "HGheader": "%s %s %s %s %s" % (keywords["HGpath"] + '/' + rel_name, keywords["HGrevision"], keywords["Date"], keywords["Author"], keywords["State"]),
+        "Id": "%s %s %s %s %s" % (templatefilters.basename(rel_name), keywords["Revision"], keywords["Date"], keywords["Author"], keywords["State"]),
         "HGnodeid": nodeid or "",
     }