Rev 5333: Final cleanup. in file:///home/vila/src/bzr/bugs/525571-lock-bazaar-conf-files/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Wed Jun 30 15:53:07 BST 2010
At file:///home/vila/src/bzr/bugs/525571-lock-bazaar-conf-files/
------------------------------------------------------------
revno: 5333
revision-id: v.ladeuil+lp at free.fr-20100630145307-kivkluj078vsl07d
parent: v.ladeuil+lp at free.fr-20100630141957-su7t86t2fo1c1n1u
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 525571-lock-bazaar-conf-files
timestamp: Wed 2010-06-30 16:53:07 +0200
message:
Final cleanup.
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2010-06-30 10:29:33 +0000
+++ b/NEWS 2010-06-30 14:53:07 +0000
@@ -36,8 +36,8 @@
New Features
************
-* ``bzr break-lock`` now defines a --config parameter that is required
- to break locks on config files. (Vincent Ladeuil, #525571)
+* ``bzr break-lock --conf [location]`` can now break config files
+ locks. (Vincent Ladeuil, #525571)
* ``bzrlib.config.LockableConfig`` is a base class for config files that
needs to be protected against multiple writers. All methods that
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2010-06-30 14:19:57 +0000
+++ b/bzrlib/builtins.py 2010-06-30 14:53:07 +0000
@@ -4850,7 +4850,7 @@
takes_args = ['location?']
takes_options = [
Option('conf',
- help='LOCATION is a directory containing configuration files.'),
+ help='LOCATION is the directory where the config lock is.'),
]
def run(self, location=None, conf=False):
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py 2010-06-30 14:19:57 +0000
+++ b/bzrlib/config.py 2010-06-30 14:53:07 +0000
@@ -386,6 +386,11 @@
self._parser = p
return p
+ def reload(self):
+ """Reload the config file from disk."""
+ if self._parser is not None:
+ self._parser.reload()
+
def _get_matching_sections(self):
"""Return an ordered list of (section_name, extra_path) pairs.
@@ -511,6 +516,22 @@
If several processes try to write the config file, the accesses need to be
serialized.
+
+ Daughter classes should decorate all methods that update a config with the
+ ``@needs_write_lock`` decorator (they call, directly or indirectly, the
+ ``_write_config_file()`` method. These methods (typically ``set_option()``
+ and variants must reload the config file from disk before calling
+ ``_write_config_file()``, this can be achieved by calling the
+ ``self.reload()`` method.
+
+ This should be enough to implement the following logic:
+ - lock for exclusive write access,
+ - reload the config file from disk,
+ - set the new value
+ - unlock
+
+ This logic guarantees that a writer can update a value without erasing an
+ update made by another writer.
"""
lock_name = 'lock'
@@ -522,6 +543,10 @@
self._lock = None
def lock_write(self, token=None):
+ """Takes a write lock in the directory containing the config file.
+
+ If the directory doesn't exist it is created.
+ """
if self._lock is None:
ensure_config_dir_exists(self.dir)
self._lock = lockdir.LockDir(self.transport, self.lock_name)
@@ -567,8 +592,9 @@
def get_aliases(self):
"""Return the aliases section."""
- if 'ALIASES' in self._get_parser():
- return self._get_parser()['ALIASES']
+ p = self._get_parser()
+ if 'ALIASES' in p:
+ return p['ALIASES']
else:
return {}
@@ -580,6 +606,7 @@
@needs_write_lock
def unset_alias(self, alias_name):
"""Unset an existing alias."""
+ self.reload()
aliases = self._get_parser().get('ALIASES')
if not aliases or alias_name not in aliases:
raise errors.NoSuchAlias(alias_name)
@@ -587,8 +614,7 @@
self._write_config_file()
def _set_option(self, option, value, section):
- if self._parser is not None:
- self._parser.reload()
+ self.reload()
self._get_parser().setdefault(section, {})[option] = value
self._write_config_file()
@@ -717,17 +743,16 @@
STORE_LOCATION_APPENDPATH]:
raise ValueError('bad storage policy %r for %r' %
(store, option))
- if self._parser is not None:
- self._parser.reload()
+ self.reload()
+ p = self._get_parser()
location = self.location
if location.endswith('/'):
location = location[:-1]
- if (not location in self._get_parser() and
- not location + '/' in self._get_parser()):
- self._get_parser()[location]={}
- elif location + '/' in self._get_parser():
+ if not location in p and not location + '/' in p:
+ p[location] = {}
+ elif location + '/' in p:
location = location + '/'
- self._get_parser()[location][option]=value
+ p[location][option] = value
# the allowed values of store match the config policies
self._set_option_policy(location, option, store)
self._write_config_file()
More information about the bazaar-commits
mailing list