summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2015-05-05 15:16:54 +0000
committerBaserock Gerrit <gerrit@baserock.org>2015-05-22 15:07:43 +0000
commit05b2b062afa2ab4cbd504735fd16cf53d969a2a5 (patch)
tree67ef311dde7af51353b18823736dbcbf19882162
parent538780673002b49aa1193e3617c81024ba64e434 (diff)
downloadmorph-05b2b062afa2ab4cbd504735fd16cf53d969a2a5.tar.gz
Move 'git config' wrapper into its own class
We use 'git config' format config files outside Git repos, so it's useful to have a helper class independent of the GitDirectory class. This allows us to use it in the sysbranchdir.open() function to remove a hack. Change-Id: Ifa5e87f404d10666c98b9469079b7925d16becf6
-rw-r--r--morphlib/gitdir.py66
-rw-r--r--morphlib/gitdir_tests.py7
-rw-r--r--morphlib/sysbranchdir.py20
3 files changed, 75 insertions, 18 deletions
diff --git a/morphlib/gitdir.py b/morphlib/gitdir.py
index 688e4b34..9cb62e3b 100644
--- a/morphlib/gitdir.py
+++ b/morphlib/gitdir.py
@@ -134,6 +134,60 @@ class PushFailureError(PushError):
'stderr: %(stderr)s' % locals())
+class Config(object):
+ '''Class representing Git repo configuration.
+
+ The 'git config' format is reusable outside of Git repos, and this class
+ can be used for these files too.
+
+ This class doesn't take any notice of updates by other processes to the
+ config file, at present. Updates are cached in memory, so changes made from
+ outside the process may be ignored.
+
+ '''
+ def __init__(self, config_file, runcmd=None):
+ '''Creates a Config instance.
+
+ The 'filepath' parameter can be None if 'runcmd' is passed. Calls to
+ 'git config' will be passed through 'runcmd', which can set the 'cwd'
+ parameter to a git repo.
+
+ '''
+ assert runcmd or config_file
+
+ if runcmd:
+ self.runcmd = runcmd
+ self.extra_args = []
+ else:
+ self.runcmd = cliapp.runcmd
+ self.extra_args = ['-f', config_file]
+
+ self.cache = dict()
+
+ def __setitem__(self, key, value):
+ '''Set a git repository configuration variable.
+
+ The key must have at least one period in it: foo.bar for example,
+ not just foo. The part before the first period is interpreted
+ by git as a section name.
+
+ '''
+ self.cache[key] = value
+ self.runcmd(['git', 'config'] + self.extra_args + [key, value])
+
+ def __getitem__(self, key):
+ '''Return value for a git repository configuration variable.
+
+ If the variable is unset, this will raise cliapp.AppException.
+
+ '''
+ if key not in self.cache:
+ value = self.runcmd(
+ ['git', 'config'] + self.extra_args + ['-z', key])
+ self.cache[key] = value.rstrip('\0')
+ return self.cache[key]
+
+
class RefSpec(object):
'''Class representing how to push or pull a ref.
@@ -384,7 +438,7 @@ class GitDirectory(object):
dirname = morphlib.util.find_root(dirname, '.git')
self.dirname = dirname
- self._config = {}
+ self.config = Config(config_file=None, runcmd=self._runcmd)
self._ensure_is_git_repo()
@@ -486,9 +540,7 @@ class GitDirectory(object):
by git as a section name.
'''
-
- morphlib.git.gitcmd(self._runcmd, 'config', key, value)
- self._config[key] = value
+ self.config[key] = value
def get_config(self, key):
'''Return value for a git repository configuration variable.
@@ -496,11 +548,7 @@ class GitDirectory(object):
If the variable is unset, this will raise cliapp.AppException.
'''
-
- if key not in self._config:
- value = morphlib.git.gitcmd(self._runcmd, 'config', '-z', key)
- self._config[key] = value.rstrip('\0')
- return self._config[key]
+ return self.config[key]
def get_remote(self, *args, **kwargs):
'''Get a remote for this Repository.
diff --git a/morphlib/gitdir_tests.py b/morphlib/gitdir_tests.py
index f606dfe7..0eafc0e8 100644
--- a/morphlib/gitdir_tests.py
+++ b/morphlib/gitdir_tests.py
@@ -90,6 +90,13 @@ class GitDirectoryTests(unittest.TestCase):
gitdir.set_config('foo.bar', 'yoyo')
self.assertEqual(gitdir.get_config('foo.bar'), 'yoyo')
+ def test_sets_and_gets_configuration_from_file(self):
+ gitdir = self.empty_git_directory()
+ config = morphlib.gitdir.Config(
+ config_file=os.path.join(gitdir.dirname, '.git', 'config'))
+ config['foo.bar'] = 'yoyo'
+ self.assertEqual(config['foo.bar'], 'yoyo')
+
def test_gets_index(self):
gitdir = self.empty_git_directory()
self.assertIsInstance(gitdir.get_index(), morphlib.gitindex.GitIndex)
diff --git a/morphlib/sysbranchdir.py b/morphlib/sysbranchdir.py
index 69119f5b..3ca5a8cb 100644
--- a/morphlib/sysbranchdir.py
+++ b/morphlib/sysbranchdir.py
@@ -50,6 +50,8 @@ class SystemBranchDirectory(object):
self.root_repository_url = root_repository_url
self.system_branch_name = system_branch_name
+ self.config = morphlib.gitdir.Config(config_file=self._config_path)
+
@property
def _magic_path(self):
return os.path.join(self.root_directory, '.morph-system-branch')
@@ -60,14 +62,11 @@ class SystemBranchDirectory(object):
def set_config(self, key, value):
'''Set a configuration key/value pair.'''
- morphlib.git.gitcmd(cliapp.runcmd, 'config', '-f',
- self._config_path, key, value)
+ self.config[key] = value
def get_config(self, key):
'''Get a configuration value for a given key.'''
- value = morphlib.git.gitcmd(cliapp.runcmd, 'config', '-f',
- self._config_path, key)
- return value.strip()
+ return self.config[key]
def _find_git_directory(self, repo_url):
for gd in self.list_git_directories():
@@ -210,6 +209,7 @@ class SystemBranchDirectory(object):
yield m
+
def create(root_directory, root_repository_url, system_branch_name):
'''Create a new system branch directory on disk.
@@ -242,10 +242,12 @@ def create(root_directory, root_repository_url, system_branch_name):
def open(root_directory):
'''Open an existing system branch directory.'''
- # Ugly hack follows.
- sb = SystemBranchDirectory(root_directory, None, None)
- root_repository_url = sb.get_config('branch.root')
- system_branch_name = sb.get_config('branch.name')
+ config_file_path = os.path.join(
+ root_directory, '.morph-system-branch', 'config')
+ config = morphlib.gitdir.Config(config_file=config_file_path)
+
+ root_repository_url = config['branch.root']
+ system_branch_name = config['branch.name']
return SystemBranchDirectory(
root_directory, root_repository_url, system_branch_name)