Rev 5363: Implements 'bzr lock --config <file>'. in file:///home/vila/src/bzr/bugs/525571-lock-bazaar-conf-files/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Mon Aug 23 17:34:38 BST 2010
At file:///home/vila/src/bzr/bugs/525571-lock-bazaar-conf-files/
------------------------------------------------------------
revno: 5363
revision-id: v.ladeuil+lp at free.fr-20100823163438-lpl5kj8g0ze6772b
parent: v.ladeuil+lp at free.fr-20100823140433-03cyut95alojc8be
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: lockable-config-files
timestamp: Mon 2010-08-23 18:34:38 +0200
message:
Implements 'bzr lock --config <file>'.
* bzrlib/tests/blackbox/test_break_lock.py:
(TestConfigBreakLock): Corresponding tests.
* bzrlib/config.py:
(LockableConfig.break_lock): Added.
* bzrlib/builtins.py:
(cmd_break_lock): Add a --config option.
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2010-08-23 09:31:24 +0000
+++ b/NEWS 2010-08-23 16:34:38 +0000
@@ -36,6 +36,15 @@
New Features
************
+* ``bzr break-lock --config [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
+ change a configuration variable value must be decorated with
+ @needs_write_lock (set_option() for example).
+ (Vincent Ladeuil, #525571)
+
* The ``lp:`` prefix will now use your known username (from
``bzr launchpad-login``) to expand ``~`` to your username. For example:
``bzr launchpad-login user && bzr push lp:~/project/branch`` will now
@@ -64,6 +73,9 @@
* CommitBuilder now uses the committer instead of _config.username to generate
the revision-id. (Aaron Bentley, #614404)
+* Configuration files in ``${BZR_HOME}`` are now protected against
+ concurrent writers by using a lock. (Vincent Ladeuil, #525571)
+
* Cope with Microsoft FTP Server and VSFTPd that return reply '250
Directory created' when mkdir succeeds. (Martin Pool, #224373)
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2010-08-20 09:39:20 +0000
+++ b/bzrlib/builtins.py 2010-08-23 16:34:38 +0000
@@ -32,7 +32,7 @@
bzrdir,
directory_service,
delta,
- config,
+ config as _mod_config,
errors,
globbing,
hooks,
@@ -3322,7 +3322,7 @@
try:
c = Branch.open_containing(u'.')[0].get_config()
except errors.NotBranchError:
- c = config.GlobalConfig()
+ c = _mod_config.GlobalConfig()
else:
c = Branch.open(directory).get_config()
if email:
@@ -3333,7 +3333,7 @@
# display a warning if an email address isn't included in the given name.
try:
- config.extract_email_address(name)
+ _mod_config.extract_email_address(name)
except errors.NoEmailInUsername, e:
warning('"%s" does not seem to contain an email address. '
'This is allowed, but not recommended.', name)
@@ -3345,7 +3345,7 @@
else:
c = Branch.open(directory).get_config()
else:
- c = config.GlobalConfig()
+ c = _mod_config.GlobalConfig()
c.set_user_option('email', name)
@@ -3418,13 +3418,13 @@
'bzr alias --remove expects an alias to remove.')
# If alias is not found, print something like:
# unalias: foo: not found
- c = config.GlobalConfig()
+ c = _mod_config.GlobalConfig()
c.unset_alias(alias_name)
@display_command
def print_aliases(self):
"""Print out the defined aliases in a similar format to bash."""
- aliases = config.GlobalConfig().get_aliases()
+ aliases = _mod_config.GlobalConfig().get_aliases()
for key, value in sorted(aliases.iteritems()):
self.outf.write('bzr alias %s="%s"\n' % (key, value))
@@ -3440,7 +3440,7 @@
def set_alias(self, alias_name, alias_command):
"""Save the alias in the global config."""
- c = config.GlobalConfig()
+ c = _mod_config.GlobalConfig()
c.set_alias(alias_name, alias_command)
@@ -4807,7 +4807,10 @@
class cmd_break_lock(Command):
- __doc__ = """Break a dead lock on a repository, branch or working directory.
+ __doc__ = """Break a dead lock.
+
+ This command breaks a lock on a repository, branch, working directory or
+ config file.
CAUTION: Locks should only be broken when you are sure that the process
holding the lock has been stopped.
@@ -4818,17 +4821,27 @@
:Examples:
bzr break-lock
bzr break-lock bzr+ssh://example.com/bzr/foo
+ bzr break-lock --conf ~/.bazaar
"""
+
takes_args = ['location?']
+ takes_options = [
+ Option('config',
+ help='LOCATION is the directory where the config lock is.'),
+ ]
- def run(self, location=None, show=False):
+ def run(self, location=None, config=False):
if location is None:
location = u'.'
- control, relpath = bzrdir.BzrDir.open_containing(location)
- try:
- control.break_lock()
- except NotImplementedError:
- pass
+ if config:
+ conf = _mod_config.LockableConfig(file_name=location)
+ conf.break_lock()
+ else:
+ control, relpath = bzrdir.BzrDir.open_containing(location)
+ try:
+ control.break_lock()
+ except NotImplementedError:
+ pass
class cmd_wait_until_signalled(Command):
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py 2010-08-23 14:04:33 +0000
+++ b/bzrlib/config.py 2010-08-23 16:34:38 +0000
@@ -575,6 +575,9 @@
def unlock(self):
self._lock.unlock()
+ def break_lock(self):
+ self._lock.break_lock()
+
def _write_config_file(self):
if self._lock is None or not self._lock.is_held:
# NB: if the following exception is raised it probably means a
=== modified file 'bzrlib/tests/blackbox/test_break_lock.py'
--- a/bzrlib/tests/blackbox/test_break_lock.py 2010-07-22 08:00:02 +0000
+++ b/bzrlib/tests/blackbox/test_break_lock.py 2010-08-23 16:34:38 +0000
@@ -22,8 +22,10 @@
from bzrlib import (
branch,
bzrdir,
+ config,
errors,
lockdir,
+ osutils,
tests,
)
@@ -101,3 +103,24 @@
out, err = self.run_bzr('break-lock foo')
self.assertEqual('', out)
self.assertEqual('', err)
+
+class TestConfigBreakLock(tests.TestCaseWithTransport):
+
+ def setUp(self):
+ super(TestConfigBreakLock, self).setUp()
+ self.config_file_name = './my.conf'
+ self.build_tree_contents([(self.config_file_name,
+ '[DEFAULT]\none=1\n')])
+ self.config = config.LockableConfig(file_name=self.config_file_name)
+ self.config.lock_write()
+
+ def test_create_pending_lock(self):
+ self.addCleanup(self.config.unlock)
+ self.assertTrue(self.config._lock.is_held)
+
+ def test_break_lock(self):
+ self.run_bzr('break-lock --config %s'
+ % osutils.dirname(self.config_file_name),
+ stdin="y\n")
+ self.assertRaises(errors.LockBroken, self.config.unlock)
+
More information about the bazaar-commits
mailing list