diff extensions/kwarchive.py @ 296:15d23729d176

Generate the real filter configuration data in an independent function. This function can be used for subrepos also. The real filter function fetches by a subrepositorie's relpath.
author Franz Glasner <hg@dom66.de>
date Tue, 29 Jan 2019 18:07:43 +0100
parents eeb8c52d8802
children aa945541d2ca
line wrap: on
line diff
--- a/extensions/kwarchive.py	Mon Jan 28 09:31:57 2019 +0100
+++ b/extensions/kwarchive.py	Tue Jan 29 18:07:43 2019 +0100
@@ -260,6 +260,7 @@
                 hgpath=opts.get("path"),
                 path_filter=get_checked_path_filter_option(opts),
                 user_filter=get_checked_user_filter_option(opts),
+                subrepos=opts.get("subrepos"),
                 kwconfig=opts.get("kwconfig")))
 
     archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
@@ -444,7 +445,69 @@
                         hgpath="default",
                         path_filter="short",
                         user_filter="user",
+                        subrepos=False,
                         kwconfig=""):
+
+    filterdata_by_subrepos = {
+        "": _make_repo_filterdata(ui, ctx, hgpath, None, kwconfig,
+                                  path_filter, user_filter),
+    }
+    subrepos = list(filterdata_by_subrepos.keys())
+    subrepos.sort(key=len, reverse=True)
+
+    def _filter(name, data):
+        real_name = name
+        if archive_class != "fileit":
+            if prefix:
+                assert name.startswith(prefix)
+                real_name = name[len(prefix):]
+        for s in subrepos:
+            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]
+                break
+            else:
+                raise ValueError("invalid repo configuration")
+        if not matcher(real_name):
+            return data
+        try:
+            nodeid = node.hex(manifest[real_name])
+        except LookupError:
+            nodeid = None
+        # file specific keywords
+        file_keywords = make_file_keywords(keywords, real_name, nodeid)
+        # This prevents unwanted keyword expansion here
+        _MARKER_RCS = '$'
+        _MARKER_RST = '|'
+        for kw, value in itertools.chain(keyword_substitutions.items(), keywords.items(), file_keywords.items()):
+            #
+            # an empty database means: all keywords allowed, no aliases,
+            # no substitutions
+            #
+            if keyword_whitelist:
+                kwds = keyword_whitelist.get(kw, [])
+            else:
+                kwds = [kw]
+            for kw in kwds:
+                if matcher_rcs(real_name):
+                    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):
+                    filekw = "%sVCS%s%s" % (_MARKER_RST, kw, _MARKER_RST)
+                    filevalue = value
+                    data = data.replace(filekw, filevalue)
+        return data
+
+    return _filter
+
+
+def _make_repo_filterdata(ui, ctx, hgpath, hglocation, kwconfig,
+                          path_filter, user_filter):
     keywords = make_node_keywords(ui, ctx,
                                   hgpath=hgpath,
                                   path_filter=path_filter,
@@ -459,8 +522,8 @@
             kwconfigdata = ctx[KWARCHIVE_CONFIG].data()
             kwconfigname = KWARCHIVE_CONFIG
     except (IOError, LookupError):
-        def _filter(name, data):
-            return data
+        # sigil for no keyword expansion configured -> filter is pass-through
+        return None
     else:
         #
         # Parse the data in ".hgkwarchive" and generate a
@@ -543,45 +606,9 @@
         #
         manifest = ctx.manifest()
 
-        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
-            try:
-                nodeid = node.hex(manifest[real_name])
-            except LookupError:
-                nodeid = None
-            # file specific keywords
-            file_keywords = make_file_keywords(keywords, real_name, nodeid)
-            # This prevents unwanted keyword expansion here
-            _MARKER_RCS = '$'
-            _MARKER_RST = '|'
-            for kw, value in itertools.chain(keyword_substitutions.items(), keywords.items(), file_keywords.items()):
-                #
-                # an empty database means: all keywords allowed, no aliases,
-                # no substitutions
-                #
-                if keyword_whitelist:
-                    kwds = keyword_whitelist.get(kw, [])
-                else:
-                    kwds = [kw]
-                for kw in kwds:
-                    if matcher_rcs(real_name):
-                        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):
-                        filekw = "%sVCS%s%s" % (_MARKER_RST, kw, _MARKER_RST)
-                        filevalue = value
-                        data = data.replace(filekw, filevalue)
-            return data
-
-    return _filter
+        return (matcher, matcher_rcs, matcher_rst,
+                manifest,
+                keyword_whitelist, keyword_substitutions, keywords,)
 
 
 def make_node_keywords(ui, ctx,