config: read the right config if run from subdir
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Fri, 6 Jul 2012 06:58:06 +0000 (09:58 +0300)
committerGuido Günther <agx@sigxcpu.org>
Sun, 28 Dec 2014 12:35:36 +0000 (13:35 +0100)
A step towards being able to run GBP tools from subdirectories.

Now expands '%(top_dir)s' and '%(git_dir)s' in config file path to root
of the working directory and git metadata directory, respectively.

Also, adds a new method _read_config_file() in preparation for
supporting per-tree config files.

Fixes tests.test_Config: currently the only correct way to define the
config file(s) to be parsed is by using the GBP_CONF_FILES environment
variable.

Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
gbp/config.py
gbp/scripts/import_dscs.py
tests/test_Config.py

index 63c11cbd3c6a6e61612445fc6b17c121a3be5967..8c0bc22595b458373e7bcbdff6968cee842909e2 100644 (file)
@@ -25,6 +25,7 @@ try:
 except ImportError:
     gbp_version = "[Unknown version]"
 import gbp.tristate
+from gbp.git import GitRepositoryError, GitRepository
 
 no_upstream_branch_msg = """
 Repository does not have branch '%s' for upstream sources. If there is none see
@@ -307,28 +308,32 @@ class GbpOptionParser(OptionParser):
 
     def_config_files = [ '/etc/git-buildpackage/gbp.conf',
                          '~/.gbp.conf',
-                         '.gbp.conf',
-                         'debian/gbp.conf',
-                         '.git/gbp.conf' ]
+                         '%(top_dir)s/.gbp.conf',
+                         '%(top_dir)s/debian/gbp.conf',
+                         '%(git_dir)s/gbp.conf' ]
 
     @classmethod
-    def get_config_files(klass):
+    def get_config_files(klass, no_local=False):
         """
         Get list of config files from the I{GBP_CONF_FILES} environment
         variable.
 
+        @param no_local: don't return the per-repo configuration files
+        @type no_local: C{str}
         @return: list of config files we need to parse
         @rtype: C{list}
 
         >>> conf_backup = os.getenv('GBP_CONF_FILES')
         >>> if conf_backup is not None: del os.environ['GBP_CONF_FILES']
+        >>> homedir = os.path.expanduser("~")
         >>> files = GbpOptionParser.get_config_files()
-
-        # Remove the ~-expanded one
-        >>> del files[1]
-        >>> files
-        ['/etc/git-buildpackage/gbp.conf', '.gbp.conf', 'debian/gbp.conf', '.git/gbp.conf']
-
+        >>> files_mangled = [file.replace(homedir, 'HOME') for file in files]
+        >>> files_mangled
+        ['/etc/git-buildpackage/gbp.conf', 'HOME/.gbp.conf', '%(top_dir)s/.gbp.conf', '%(top_dir)s/debian/gbp.conf', '%(git_dir)s/gbp.conf']
+        >>> files = GbpOptionParser.get_config_files(no_local=True)
+        >>> files_mangled = [file.replace(homedir, 'HOME') for file in files]
+        >>> files_mangled
+        ['/etc/git-buildpackage/gbp.conf', 'HOME/.gbp.conf']
         >>> os.environ['GBP_CONF_FILES'] = 'test1:test2'
         >>> GbpOptionParser.get_config_files()
         ['test1', 'test2']
@@ -337,7 +342,24 @@ class GbpOptionParser(OptionParser):
         """
         envvar = os.environ.get('GBP_CONF_FILES')
         files = envvar.split(':') if envvar else klass.def_config_files
-        return [ os.path.expanduser(f) for f in files ]
+        files = [os.path.expanduser(fname) for fname in files]
+        if no_local:
+            files = [fname for fname in files if fname.startswith('/')]
+        return files
+
+    def _read_config_file(self, parser, repo, filename):
+        """Read config file"""
+        str_fields = {}
+        if repo:
+            str_fields['git_dir'] = repo.git_dir
+            if not repo.bare:
+                str_fields['top_dir'] = repo.path
+        try:
+            filename = filename % str_fields
+        except KeyError:
+            # Skip if filename wasn't expanded, i.e. we're not in git repo
+            return
+        parser.read(filename)
 
     def parse_config_files(self):
         """
@@ -349,7 +371,14 @@ class GbpOptionParser(OptionParser):
         self.config = dict(self.__class__.defaults)
         # Update with the values from the defaults section. This is needed
         # in case the config file doesn't have a [<command>] section at all
-        parser.read(self.config_files)
+        config_files = self.get_config_files()
+        try:
+            repo = GitRepository(".")
+        except GitRepositoryError:
+            repo = None
+        # Read all config files
+        for filename in config_files:
+            self._read_config_file(parser, repo, filename)
         self.config.update(dict(parser.defaults()))
 
         # Make sure we read any legacy sections prior to the real subcommands
@@ -405,7 +434,6 @@ class GbpOptionParser(OptionParser):
         self.sections = sections
         self.prefix = prefix
         self.config = {}
-        self.config_files = self.get_config_files()
         self.parse_config_files()
         self.valid_options = []
 
index 2a71560ec85fc920e41d0d59d5fd86d9569afa6e..5409ca1179c75e6dbc42c27f2ce0dfd94ba1db4b 100644 (file)
@@ -73,8 +73,7 @@ def set_gbp_conf_files():
     Filter out all gbp.conf files that are local to the git repository and set
     GBP_CONF_FILES accordingly so gbp import-dsc will only use these.
     """
-    files = GbpOptionParser.get_config_files()
-    global_config = [ f for f in files if f.startswith('/') ]
+    global_config = GbpOptionParser.get_config_files(no_local=True)
     gbp_conf_files = ':'.join(global_config)
     os.environ['GBP_CONF_FILES'] = gbp_conf_files
     gbp.log.debug("Setting GBP_CONF_FILES to '%s'" % gbp_conf_files)
index 046af27890962d4eb27e9e606bd4f624b1814257..6750d84486db298e0000c99a09519ca0d2c74b65 100644 (file)
@@ -65,21 +65,21 @@ def test_filter():
     The filter option should always parse as a list
     >>> import os
     >>> from gbp.config import GbpOptionParser
-    >>> parser = GbpOptionParser('bar')
     >>> tmpdir = str(context.new_tmpdir('bar'))
     >>> confname = os.path.join(tmpdir, 'gbp.conf')
-    >>> parser.config_files = [confname]
     >>> f = open(confname, 'w')
     >>> f.write('[bar]\\nfilter = asdf\\n')
     >>> f.close()
-    >>> parser.parse_config_files()
+    >>> os.environ['GBP_CONF_FILES'] = confname
+    >>> parser = GbpOptionParser('bar')
     >>> parser.config['filter']
     ['asdf']
     >>> f = open(confname, 'w')
     >>> f.write("[bar]\\nfilter = ['this', 'is', 'a', 'list']\\n")
     >>> f.close()
-    >>> parser.parse_config_files()
+    >>> parser = GbpOptionParser('bar')
     >>> parser.config['filter']
     ['this', 'is', 'a', 'list']
+    >>> del os.environ['GBP_CONF_FILES']
     """