3dec151080ae — Vincent Hatakeyama 3 years ago
✨ add a way to use expanded projects’ layout as the base layout for subelements.
2 files changed, 28 insertions(+), 9 deletions(-)

M README.md
M hgext3rd/confman/utils.py
M README.md +4 -0
@@ 129,6 129,10 @@ The `expand=` or `expand.whitelist=<...>
 `expand.blacklist=<...>` notations indicate a repository that contain
 a configuration and should be used by `confman` as such.
 
+It is also possible to use `expand.nested` to use the layout of the other project as
+the place to put the expanded elements. This can be combined with white and black list,
+`.nested` just needs to be put before them.
+
 Here's a real-life configuration tree:
 
 ![conf pythonianfr](pythonianfrconf.png)

          
M hgext3rd/confman/utils.py +24 -9
@@ 201,11 201,14 @@ class oconfig(object):
         # PATCH: level and filtering
         level=0,
         section_filter=None,
+        layout_prefix=None,
     ):
         sectionre = compilere(r'\[([^\[]+)\]')
         itemre = compilere(r'([^=\s][^=]*?)\s*=\s*(.*\S|)')
         # PATCH
-        expandre = compilere(r'(expand)(\.whitelist|\.blacklist|)(\.re|)\s*=\s*(.*)$')
+        expandre = compilere(
+            r'(expand)(\.nested|)(\.whitelist|\.blacklist|)(\.re|)\s*=\s*(.*)$'
+        )
         # /PATCH
         contre = compilere(r'\s+(\S|\S.*\S)\s*$')
         emptyre = compilere(r'(;|#|\s*$)')

          
@@ 282,16 285,19 @@ class oconfig(object):
                 if include:
                     morewhite = ()
                     moreblack = ()
-                    if m.group(2) == '.whitelist':
-                        morewhite = tuple(m.group(4).split())
-                    elif m.group(2) == '.blacklist':
-                        moreblack += tuple(m.group(4).split())
+                    if m.group(3) == '.whitelist':
+                        morewhite = tuple(m.group(5).split())
+                    elif m.group(3) == '.blacklist':
+                        moreblack += tuple(m.group(5).split())
                     _section_filter = sectionfilter(
-                        regexp=bool(m.group(3)),
+                        regexp=bool(m.group(4)),
                         parent=section_filter,
                         morewhite=morewhite,
                         moreblack=moreblack,
                     )
+                    sub_layout_prefix = None
+                    if m.group(2) == ".nested":
+                        sub_layout_prefix = self.get(section, "layout")
 
                     try:
                         include(

          
@@ 300,6 306,7 @@ class oconfig(object):
                             sections=sections,
                             level=level + 1,
                             section_filter=_section_filter,
+                            layout_prefix=sub_layout_prefix,
                         )
                     except IOError as inst:
                         if inst.errno != errno.ENOENT:

          
@@ 315,7 322,10 @@ class oconfig(object):
                 cont = True
                 if sections and section not in sections:
                     continue
-                self.set(section, item, m.group(2), "%s:%d" % (src, line))
+                value = m.group(2)
+                if item == "layout" and layout_prefix:
+                    value = os.path.join(layout_prefix, value)
+                self.set(section, item, value, "%s:%d" % (src, line))
                 continue
             m = unsetre.match(l)
             if m:

          
@@ 331,7 341,9 @@ class oconfig(object):
                 l.rstrip().encode('utf-8'), ("%s:%s" % (src, line)).encode('utf-8')
             )
 
-    def parse_guestrepo(self, dirpath, level=0, section_filter=None):
+    def parse_guestrepo(
+        self, dirpath, level=0, section_filter=None, layout_prefix=None
+    ):
         "Parse guestrepo files in dirpath"
         # a guestrepo configuration is made of two files:
         # .hggrmapping and .hgguestrepo

          
@@ 355,7 367,10 @@ class oconfig(object):
         for layout in guestconf[b'']:
             section, cset = guestconf[b''][layout][0].split(None, 1)
             if section_filter(section):
-                self.set(section.decode('utf-8'), 'layout', layout.decode('utf-8'))
+                decoded_layout = layout.decode('utf-8')
+                if layout_prefix:
+                    decoded_layout = os.path.join(layout_prefix, decoded_layout)
+                self.set(section.decode('utf-8'), 'layout', decoded_layout)
                 self.set(section.decode('utf-8'), 'track', cset.decode('utf-8'))
 
     def read(self, path, fp=None, sections=None, remap=None, **kwargs):