summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/git/config.py24
-rw-r--r--test/git/test_config.py25
-rw-r--r--test/git/test_repo.py9
3 files changed, 48 insertions, 10 deletions
diff --git a/lib/git/config.py b/lib/git/config.py
index 0187af1d..b555677e 100644
--- a/lib/git/config.py
+++ b/lib/git/config.py
@@ -23,8 +23,6 @@ class _MetaParserBuilder(type):
Equip all base-class methods with a _needs_values decorator, and all non-const methods
with a _set_dirty_and_flush_changes decorator in addition to that.
"""
- new_type = super(_MetaParserBuilder, metacls).__new__(metacls, name, bases, clsdict)
-
mutating_methods = clsdict['_mutating_methods_']
for base in bases:
methods = ( t for t in inspect.getmembers(base, inspect.ismethod) if not t[0].startswith("_") )
@@ -35,9 +33,11 @@ class _MetaParserBuilder(type):
if name in mutating_methods:
method_with_values = _set_dirty_and_flush_changes(method_with_values)
# END mutating methods handling
+
clsdict[name] = method_with_values
# END for each base
+ new_type = super(_MetaParserBuilder, metacls).__new__(metacls, name, bases, clsdict)
return new_type
@@ -98,7 +98,7 @@ class GitConfigParser(cp.RawConfigParser, object):
)
# list of RawConfigParser methods able to change the instance
- _mutating_methods_ = ("remove_section", "remove_option", "set")
+ _mutating_methods_ = ("add_section", "remove_section", "remove_option", "set")
def __init__(self, file_or_files, read_only=True):
"""
@@ -141,8 +141,10 @@ class GitConfigParser(cp.RawConfigParser, object):
"""
Write pending changes if required and release locks
"""
- if self.read_only:
- return
+ # checking for the lock here makes sure we do not raise during write()
+ # in case an invalid parser was created who could not get a lock
+ if self.read_only or not self._has_lock():
+ return
try:
try:
@@ -242,7 +244,7 @@ class GitConfigParser(cp.RawConfigParser, object):
close_fp = False
# assume a path if it is not a file-object
if not hasattr(file_object, "seek"):
- fp = open(file_object, "w")
+ fp = open(file_object)
close_fp = True
# END fp handling
@@ -271,6 +273,7 @@ class GitConfigParser(cp.RawConfigParser, object):
map(lambda t: write_section(t[0],t[1]), self._sections.items())
+ @_needs_values
def write(self):
"""
Write changes to our file, if there are changes at all
@@ -307,6 +310,15 @@ class GitConfigParser(cp.RawConfigParser, object):
if self.read_only:
raise IOError("Cannot execute non-constant method %s.%s" % (self, method_name))
+ @_needs_values
+ @_set_dirty_and_flush_changes
+ def add_section(self, section):
+ """
+ Assures added options will stay in order
+ """
+ super(GitConfigParser, self).add_section(section)
+ self._sections[section] = OrderedDict()
+
@property
def read_only(self):
"""
diff --git a/test/git/test_config.py b/test/git/test_config.py
index c3080fb0..c5a8dc2c 100644
--- a/test/git/test_config.py
+++ b/test/git/test_config.py
@@ -36,6 +36,29 @@ class TestBase(TestCase):
assert w_config._sections
w_config.write() # enforce writing
assert file_obj.getvalue() == file_obj_orig.getvalue()
+
+ # creating an additional config writer must fail due to exclusive access
+ self.failUnlessRaises(IOError, GitConfigParser, file_obj, read_only = False)
+
+ # should still have a lock and be able to make changes
+ assert w_config._has_lock()
+
+ # changes should be written right away
+ sname = "my_section"
+ oname = "mykey"
+ val = "myvalue"
+ w_config.add_section(sname)
+ assert w_config.has_section(sname)
+ w_config.set(sname, oname, val)
+ assert w_config.has_option(sname,oname)
+ assert w_config.get(sname, oname) == val
+
+ file_obj.seek(0)
+ r_config = GitConfigParser(file_obj, read_only=True)
+ assert r_config.has_section(sname)
+ assert r_config.has_option(sname, oname)
+ assert r_config.get(sname, oname) == val
+
# END for each filename
def test_base(self):
@@ -64,5 +87,3 @@ class TestBase(TestCase):
assert num_sections and num_options
assert r_config._is_initialized == True
-
- self.fail("TODO: Base config writer testing")
diff --git a/test/git/test_repo.py b/test/git/test_repo.py
index 843a4b4e..0d8a473d 100644
--- a/test/git/test_repo.py
+++ b/test/git/test_repo.py
@@ -228,6 +228,11 @@ class TestRepo(TestCase):
def test_config_writer(self):
for config_level in self.repo.config_level:
- writer = self.repo.config_writer(config_level)
- assert not writer.read_only
+ try:
+ writer = self.repo.config_writer(config_level)
+ assert not writer.read_only
+ except IOError:
+ # its okay not to get a writer for some configuration files if we
+ # have no permissions
+ pass
# END for each config level