configuration: add delete_config()
We currently have no way to delete options once set. This is not good for users that want to delete things so they go back to their default values. Add a library API and tests for this; we'll extend the config command with options that use them next. Signed-off-by: Marti Bolivar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
4636b3def2
commit
4fe9d4a042
|
@ -118,6 +118,53 @@ def update_config(section, key, value, configfile=ConfigFile.LOCAL):
|
|||
updater[section][key] = value
|
||||
updater.write()
|
||||
|
||||
def delete_config(section, key, configfile=None):
|
||||
'''Delete the option section.key from the given file or files.
|
||||
|
||||
:param section: section whose key to delete
|
||||
:param key: key to delete
|
||||
:param configfile: If ConfigFile.ALL, delete section.key in all files
|
||||
where it is set.
|
||||
If None, delete only from the highest-precedence
|
||||
global or local file where it is set, allowing
|
||||
lower-precedence values to take effect again.
|
||||
If a list of ConfigFile enumerators, delete
|
||||
from those files.
|
||||
Otherwise, delete from the given ConfigFile.
|
||||
|
||||
Deleting the only key in a section deletes the entire section.
|
||||
|
||||
If the option is not set, KeyError is raised.'''
|
||||
stop = False
|
||||
if configfile is None:
|
||||
to_check = [_location(x) for x in
|
||||
[ConfigFile.LOCAL, ConfigFile.GLOBAL]]
|
||||
stop = True
|
||||
elif configfile == ConfigFile.ALL:
|
||||
to_check = [_location(x) for x in
|
||||
[ConfigFile.SYSTEM, ConfigFile.GLOBAL, ConfigFile.LOCAL]]
|
||||
elif isinstance(configfile, ConfigFile):
|
||||
to_check = [_location(configfile)]
|
||||
else:
|
||||
to_check = [_location(x) for x in configfile]
|
||||
|
||||
found = False
|
||||
for path in to_check:
|
||||
cobj = configobj.ConfigObj(path)
|
||||
if section not in cobj or key not in cobj[section]:
|
||||
continue
|
||||
|
||||
del cobj[section][key]
|
||||
if not cobj[section].items():
|
||||
del cobj[section]
|
||||
cobj.write()
|
||||
found = True
|
||||
if stop:
|
||||
break
|
||||
|
||||
if not found:
|
||||
raise KeyError('{}.{}'.format(section, key))
|
||||
|
||||
def _location(cfg):
|
||||
# Making this a function that gets called each time you ask for a
|
||||
# configuration file makes it respect updated environment
|
||||
|
|
|
@ -235,6 +235,113 @@ def test_local_creation():
|
|||
assert 'pytest' not in cfg(f=GLOBAL)
|
||||
assert cfg(f=LOCAL)['pytest']['key'] == 'val'
|
||||
|
||||
@patch('west.configuration._location', new=tstloc)
|
||||
def test_delete_basic():
|
||||
# Basic deletion test: write local, verify global and system deletions
|
||||
# don't work, then delete local does work.
|
||||
config.update_config('pytest', 'key', 'val', configfile=LOCAL)
|
||||
assert cfg(f=ALL)['pytest']['key'] == 'val'
|
||||
with pytest.raises(KeyError):
|
||||
config.delete_config('pytest', 'key', configfile=SYSTEM)
|
||||
with pytest.raises(KeyError):
|
||||
config.delete_config('pytest', 'key', configfile=GLOBAL)
|
||||
config.delete_config('pytest', 'key', configfile=LOCAL)
|
||||
assert 'pytest' not in cfg(f=ALL)
|
||||
|
||||
@patch('west.configuration._location', new=tstloc)
|
||||
def test_delete_all():
|
||||
# Deleting ConfigFile.ALL should delete from everywhere.
|
||||
config.update_config('pytest', 'key', 'system', configfile=SYSTEM)
|
||||
config.update_config('pytest', 'key', 'global', configfile=GLOBAL)
|
||||
config.update_config('pytest', 'key', 'local', configfile=LOCAL)
|
||||
assert cfg(f=SYSTEM)['pytest']['key'] == 'system'
|
||||
assert cfg(f=GLOBAL)['pytest']['key'] == 'global'
|
||||
assert cfg(f=LOCAL)['pytest']['key'] == 'local'
|
||||
config.delete_config('pytest', 'key', configfile=ALL)
|
||||
assert 'pytest' not in cfg(f=ALL)
|
||||
|
||||
@patch('west.configuration._location', new=tstloc)
|
||||
def test_delete_none():
|
||||
# Deleting None should delete from lowest-precedence global or
|
||||
# local file only.
|
||||
config.update_config('pytest', 'key', 'system', configfile=SYSTEM)
|
||||
config.update_config('pytest', 'key', 'global', configfile=GLOBAL)
|
||||
config.update_config('pytest', 'key', 'local', configfile=LOCAL)
|
||||
assert cfg(f=SYSTEM)['pytest']['key'] == 'system'
|
||||
assert cfg(f=GLOBAL)['pytest']['key'] == 'global'
|
||||
assert cfg(f=LOCAL)['pytest']['key'] == 'local'
|
||||
config.delete_config('pytest', 'key', configfile=None)
|
||||
assert cfg(f=ALL)['pytest']['key'] == 'global'
|
||||
config.delete_config('pytest', 'key', configfile=None)
|
||||
assert cfg(f=ALL)['pytest']['key'] == 'system'
|
||||
with pytest.raises(KeyError):
|
||||
config.delete_config('pytest', 'key', configfile=None)
|
||||
|
||||
@patch('west.configuration._location', new=tstloc)
|
||||
def test_delete_list():
|
||||
# Test delete of a list of places.
|
||||
config.update_config('pytest', 'key', 'system', configfile=SYSTEM)
|
||||
config.update_config('pytest', 'key', 'global', configfile=GLOBAL)
|
||||
config.update_config('pytest', 'key', 'local', configfile=LOCAL)
|
||||
assert cfg(f=SYSTEM)['pytest']['key'] == 'system'
|
||||
assert cfg(f=GLOBAL)['pytest']['key'] == 'global'
|
||||
assert cfg(f=LOCAL)['pytest']['key'] == 'local'
|
||||
config.delete_config('pytest', 'key', configfile=[GLOBAL, LOCAL])
|
||||
assert cfg(f=SYSTEM)['pytest']['key'] == 'system'
|
||||
assert 'pytest' not in cfg(f=GLOBAL)
|
||||
assert 'pytest' not in cfg(f=LOCAL)
|
||||
|
||||
@patch('west.configuration._location', new=tstloc)
|
||||
def test_delete_system():
|
||||
# Test SYSTEM-only delete.
|
||||
config.update_config('pytest', 'key', 'system', configfile=SYSTEM)
|
||||
config.update_config('pytest', 'key', 'global', configfile=GLOBAL)
|
||||
config.update_config('pytest', 'key', 'local', configfile=LOCAL)
|
||||
assert cfg(f=SYSTEM)['pytest']['key'] == 'system'
|
||||
assert cfg(f=GLOBAL)['pytest']['key'] == 'global'
|
||||
assert cfg(f=LOCAL)['pytest']['key'] == 'local'
|
||||
config.delete_config('pytest', 'key', configfile=SYSTEM)
|
||||
assert 'pytest' not in cfg(f=SYSTEM)
|
||||
assert cfg(f=GLOBAL)['pytest']['key'] == 'global'
|
||||
assert cfg(f=LOCAL)['pytest']['key'] == 'local'
|
||||
|
||||
@patch('west.configuration._location', new=tstloc)
|
||||
def test_delete_global():
|
||||
# Test GLOBAL-only delete.
|
||||
config.update_config('pytest', 'key', 'system', configfile=SYSTEM)
|
||||
config.update_config('pytest', 'key', 'global', configfile=GLOBAL)
|
||||
config.update_config('pytest', 'key', 'local', configfile=LOCAL)
|
||||
assert cfg(f=SYSTEM)['pytest']['key'] == 'system'
|
||||
assert cfg(f=GLOBAL)['pytest']['key'] == 'global'
|
||||
assert cfg(f=LOCAL)['pytest']['key'] == 'local'
|
||||
config.delete_config('pytest', 'key', configfile=GLOBAL)
|
||||
assert cfg(f=SYSTEM)['pytest']['key'] == 'system'
|
||||
assert 'pytest' not in cfg(f=GLOBAL)
|
||||
assert cfg(f=LOCAL)['pytest']['key'] == 'local'
|
||||
|
||||
@patch('west.configuration._location', new=tstloc)
|
||||
def test_delete_local():
|
||||
# Test LOCAL-only delete.
|
||||
config.update_config('pytest', 'key', 'system', configfile=SYSTEM)
|
||||
config.update_config('pytest', 'key', 'global', configfile=GLOBAL)
|
||||
config.update_config('pytest', 'key', 'local', configfile=LOCAL)
|
||||
assert cfg(f=SYSTEM)['pytest']['key'] == 'system'
|
||||
assert cfg(f=GLOBAL)['pytest']['key'] == 'global'
|
||||
assert cfg(f=LOCAL)['pytest']['key'] == 'local'
|
||||
config.delete_config('pytest', 'key', configfile=LOCAL)
|
||||
assert cfg(f=SYSTEM)['pytest']['key'] == 'system'
|
||||
assert cfg(f=GLOBAL)['pytest']['key'] == 'global'
|
||||
assert 'pytest' not in cfg(f=LOCAL)
|
||||
|
||||
@patch('west.configuration._location', new=tstloc)
|
||||
def test_delete_local_one():
|
||||
# Test LOCAL-only delete of one option doesn't affect the other.
|
||||
config.update_config('pytest', 'key1', 'foo', configfile=LOCAL)
|
||||
config.update_config('pytest', 'key2', 'bar', configfile=LOCAL)
|
||||
config.delete_config('pytest', 'key1', configfile=LOCAL)
|
||||
assert 'pytest' in cfg(f=LOCAL)
|
||||
assert cfg(f=LOCAL)['pytest']['key2'] == 'bar'
|
||||
|
||||
def test_default_config():
|
||||
# Writing to a value without a config destination should default
|
||||
# to --local.
|
||||
|
|
Loading…
Reference in New Issue