summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain <syt@logilab.fr>2006-10-20 10:54:52 +0200
committerSylvain <syt@logilab.fr>2006-10-20 10:54:52 +0200
commit73e209316de58904d219dd99d4ce50cb65b27f25 (patch)
tree4b151413bdebd3278542e8d6033c39c515bf6fe3
parent6dd8e6d68bc95ee67d36def536cdd5b0d81f66a6 (diff)
downloadlogilab-common-73e209316de58904d219dd99d4ce50cb65b27f25.tar.gz
basic deprecated config handling support
-rw-r--r--ChangeLog1
-rw-r--r--configuration.py64
-rw-r--r--test/data/test.ini20
-rw-r--r--test/unittest_configuration.py27
4 files changed, 105 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 829355b..dda49e9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,7 @@ ChangeLog for logilab.common
* db:
- fixed date handling
- new method on advanced helper to generate backup command
+ * configuration: basic deprecated config handling support
* new implementation of pytest
2006-10-03 -- 0.19.3
diff --git a/configuration.py b/configuration.py
index 3b4047d..fb95ccf 100644
--- a/configuration.py
+++ b/configuration.py
@@ -313,11 +313,7 @@ class OptionsManagerMixIn(object):
def __init__(self, usage, config_file=None, version=None, quiet=0):
self.config_file = config_file
- # configuration file parser
- self._config_parser = ConfigParser()
- # command line parser
- self._optik_parser = OptionParser(usage=usage, version=version)
- self._optik_parser.options_manager = self
+ self.reset_parsers(usage, version=None)
# list of registered options providers
self.options_providers = []
# dictionary assocating option name to checker
@@ -326,6 +322,13 @@ class OptionsManagerMixIn(object):
self._nocallback_options = {}
# verbosity
self.quiet = quiet
+
+ def reset_parsers(self, usage='', version=None):
+ # configuration file parser
+ self._config_parser = ConfigParser()
+ # command line parser
+ self._optik_parser = OptionParser(usage=usage, version=version)
+ self._optik_parser.options_manager = self
def register_options_provider(self, provider, own_group=True):
"""register an options provider"""
@@ -730,7 +733,7 @@ class ConfigurationMixIn(OptionsManagerMixIn, OptionsProviderMixIn):
"""add some options to the configuration"""
options_by_group = {}
for optname, optdict in options:
- options_by_group.setdefault(optdict['group'], []).append((optname, optdict))
+ options_by_group.setdefault(optdict.get('group', self.name.upper()), []).append((optname, optdict))
for group, options in options_by_group.items():
self.add_option_group(group, None, options, self)
self.options += tuple(options)
@@ -799,3 +802,52 @@ class OptionsManager2ConfigurationAdapter:
except AttributeError:
return default
+def read_old_config(newconfig, changes, configfile):
+ """possible changes:
+ * ('renamed', oldname, newname)
+ * ('moved', option, oldgroup, newgroup)
+ """
+ # build an index of changes
+ changesindex = {}
+ for action in changes:
+ if action[0] not in ('moved', 'renamed'):
+ raise Exception('unknown change %s' % action[0])
+ if action[0] == 'moved':
+ option, oldgroup, newgroup = action[1:]
+ changesindex.setdefault(option, []).append((action[0], oldgroup, newgroup))
+ continue
+ if action[0] == 'renamed':
+ oldname, newname = action[1:]
+ changesindex.setdefault(newname, []).append((action[0], oldname))
+ continue
+ raise Exception('unknown change %s' % action[0])
+ # build a config object able to read the old config
+ options = []
+ for optname, optdef in newconfig.options:
+ for action in changesindex.pop(optname, ()):
+ if action[0] == 'moved':
+ oldgroup, newgroup = action[1:]
+ optdef = optdef.copy()
+ optdef['group'] = oldgroup
+ elif action[0] == 'renamed':
+ optname = action[1]
+ options.append((optname, optdef))
+ if changesindex:
+ raise Exception('unapplied changes: %s' % changesindex)
+ oldconfig = newconfig.__class__(options=options, name=newconfig.name)
+ # read the old config
+ oldconfig.load_file_configuration(configfile)
+ # apply values reverting changes
+ changes.reverse()
+ done = set()
+ for action in changes:
+ if action[0] == 'renamed':
+ oldname, newname = action[1:]
+ newconfig[newname] = oldconfig[oldname]
+ done.add(newname)
+ continue
+ for optname, optdef in newconfig.options:
+ if optname in done:
+ continue
+ newconfig.set_option(optname, oldconfig[optname], opt_dict=optdef)
+
diff --git a/test/data/test.ini b/test/data/test.ini
new file mode 100644
index 0000000..3785702
--- /dev/null
+++ b/test/data/test.ini
@@ -0,0 +1,20 @@
+# test configuration
+[TEST]
+
+dothis=yes
+
+value=' '
+
+# you can also document the option
+multiple=yop
+
+number=2
+
+#choice
+renamed=yo
+
+multiple-choice=yo,ye
+
+
+[OLD]
+named=key:val
diff --git a/test/unittest_configuration.py b/test/unittest_configuration.py
index b65d4c2..dc00aec 100644
--- a/test/unittest_configuration.py
+++ b/test/unittest_configuration.py
@@ -5,7 +5,7 @@ from sys import version_info
from logilab.common.testlib import TestCase, unittest_main
from logilab.common.configuration import Configuration, OptionValueError, \
- OptionsManagerMixIn, OptionsProviderMixIn, Method
+ OptionsManagerMixIn, OptionsProviderMixIn, Method, read_old_config
options = [('dothis', {'type':'yn', 'default': True, 'metavar': '<y or n>'}),
('value', {'type': 'string', 'metavar': '<string>', 'short': 'v'}),
@@ -214,7 +214,32 @@ options:
from logilab.common import __pkginfo__
self.cfg.generate_manpage(__pkginfo__, stream=StringIO())
+ def test_rewrite_config(self):
+ changes = [('renamed', 'renamed', 'choice'),
+ ('moved', 'named', 'old', 'test'),
+ ]
+ read_old_config(self.cfg, changes, 'data/test.ini')
+ stream = StringIO()
+ self.cfg.generate_config(stream)
+ self.assertLinesEquals(stream.getvalue().strip(), """# test configuration
+[TEST]
+
+dothis=yes
+
+value=' '
+
+# you can also document the option
+multiple=yop
+
+number=2
+
+choice=yo
+multiple-choice=yo,ye
+
+named=key:val
+""")
+
class Linter(OptionsManagerMixIn, OptionsProviderMixIn):
options = (
('profile', {'type' : 'yn', 'metavar' : '<y_or_n>',