Merge branch 'release/v0.19.x' into develop
Conflicts: mopidy/config/__init__.py
This commit is contained in:
commit
ae3a932ed3
@ -26,6 +26,10 @@ Bug fix release.
|
||||
- Logging: Fix that some loggers would be disabled if
|
||||
:confval:`logging/config_file` was set. (Fixes: :issue:`740`)
|
||||
|
||||
- Core: Return exit status 1 when exiting because of initialization error.
|
||||
|
||||
- Configuration: :option:`mopidy --config` now supports directories.
|
||||
|
||||
|
||||
v0.19.3 (2014-08-03)
|
||||
====================
|
||||
|
||||
@ -50,11 +50,12 @@ Options
|
||||
Save debug log to the file specified in the :confval:`logging/debug_file`
|
||||
config value, typically ``./mopidy.log``.
|
||||
|
||||
.. cmdoption:: --config <file>
|
||||
.. cmdoption:: --config <file|directory>
|
||||
|
||||
Specify config file to use. To use multiple config files, separate them
|
||||
with a colon. The later files override the earlier ones if there's a
|
||||
conflict.
|
||||
Specify config files and directories to use. To use multiple config files
|
||||
or directories, separate them with a colon. The later files override the
|
||||
earlier ones if there's a conflict. When specifying a directory, all files
|
||||
ending in .conf in the directory are used.
|
||||
|
||||
.. cmdoption:: --option <option>, -o <option>
|
||||
|
||||
|
||||
@ -276,8 +276,10 @@ class RootCommand(Command):
|
||||
exceptions.FrontendError,
|
||||
exceptions.MixerError):
|
||||
logger.info('Initialization error. Exiting...')
|
||||
exit_status_code = 1
|
||||
except KeyboardInterrupt:
|
||||
logger.info('Interrupted. Exiting...')
|
||||
exit_status_code = 0
|
||||
finally:
|
||||
loop.quit()
|
||||
self.stop_frontends(frontend_classes)
|
||||
@ -286,6 +288,7 @@ class RootCommand(Command):
|
||||
self.stop_audio()
|
||||
self.stop_mixer(mixer_class)
|
||||
process.stop_remaining_actors()
|
||||
return exit_status_code
|
||||
|
||||
def get_mixer_class(self, config, mixer_classes):
|
||||
logger.debug(
|
||||
|
||||
@ -114,27 +114,14 @@ def _load(files, defaults, overrides):
|
||||
|
||||
# Load config from a series of config files
|
||||
files = [path.expand_path(f) for f in files]
|
||||
for filename in files:
|
||||
if not os.path.exists(filename):
|
||||
logger.debug(
|
||||
'Loading config from %s failed; it does not exist', filename)
|
||||
continue
|
||||
|
||||
try:
|
||||
logger.info('Loading config from %s', filename)
|
||||
with io.open(filename, 'rb') as filehandle:
|
||||
parser.readfp(filehandle)
|
||||
except configparser.MissingSectionHeaderError as e:
|
||||
logger.warning('%s does not have a config section, not loaded.',
|
||||
filename)
|
||||
except configparser.ParsingError as e:
|
||||
linenos = ', '.join(str(lineno) for lineno, line in e.errors)
|
||||
logger.warning(
|
||||
'%s has errors, line %s has been ignored.', filename, linenos)
|
||||
except IOError:
|
||||
# TODO: if this is the initial load of logging config we might not
|
||||
# have a logger at this point, we might want to handle this better.
|
||||
logger.debug('Config file %s not found; skipping', filename)
|
||||
for name in files:
|
||||
if os.path.isdir(name):
|
||||
for filename in os.listdir(name):
|
||||
filename = os.path.join(name, filename)
|
||||
if os.path.isfile(filename) and filename.endswith('.conf'):
|
||||
_load_file(parser, filename)
|
||||
else:
|
||||
_load_file(parser, name)
|
||||
|
||||
# If there have been parse errors there is a python bug that causes the
|
||||
# values to be lists, this little trick coerces these into strings.
|
||||
@ -151,6 +138,29 @@ def _load(files, defaults, overrides):
|
||||
return raw_config
|
||||
|
||||
|
||||
def _load_file(parser, filename):
|
||||
if not os.path.exists(filename):
|
||||
logger.debug(
|
||||
'Loading config from %s failed; it does not exist', filename)
|
||||
return
|
||||
|
||||
try:
|
||||
logger.info('Loading config from %s', filename)
|
||||
with io.open(filename, 'rb') as filehandle:
|
||||
parser.readfp(filehandle)
|
||||
except configparser.MissingSectionHeaderError as e:
|
||||
logger.warning('%s does not have a config section, not loaded.',
|
||||
filename)
|
||||
except configparser.ParsingError as e:
|
||||
linenos = ', '.join(str(lineno) for lineno, line in e.errors)
|
||||
logger.warning(
|
||||
'%s has errors, line %s has been ignored.', filename, linenos)
|
||||
except IOError:
|
||||
# TODO: if this is the initial load of logging config we might not
|
||||
# have a logger at this point, we might want to handle this better.
|
||||
logger.debug('Config file %s not found; skipping', filename)
|
||||
|
||||
|
||||
def _validate(raw_config, schemas):
|
||||
# Get validated config
|
||||
config = {}
|
||||
|
||||
@ -60,6 +60,18 @@ class LoadConfigTest(unittest.TestCase):
|
||||
result = config._load([file1, file2], [], [])
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_load_directory(self):
|
||||
directory = path_to_data_dir('conf1.d')
|
||||
expected = {'foo': {'bar': 'baz'}, 'foo2': {'bar': 'baz'}}
|
||||
result = config._load([directory], [], [])
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_load_directory_only_conf_files(self):
|
||||
directory = path_to_data_dir('conf2.d')
|
||||
expected = {'foo': {'bar': 'baz'}}
|
||||
result = config._load([directory], [], [])
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_load_file_with_utf8(self):
|
||||
expected = {'foo': {'bar': 'æøå'.encode('utf-8')}}
|
||||
result = config._load([path_to_data_dir('file3.conf')], [], [])
|
||||
|
||||
2
tests/data/conf1.d/file1.conf
Normal file
2
tests/data/conf1.d/file1.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[foo]
|
||||
bar = baz
|
||||
2
tests/data/conf1.d/file2.conf
Normal file
2
tests/data/conf1.d/file2.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[foo2]
|
||||
bar = baz
|
||||
2
tests/data/conf2.d/file1.conf
Normal file
2
tests/data/conf2.d/file1.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[foo]
|
||||
bar = baz
|
||||
2
tests/data/conf2.d/file2.conf.disabled
Normal file
2
tests/data/conf2.d/file2.conf.disabled
Normal file
@ -0,0 +1,2 @@
|
||||
[foo2]
|
||||
bar = baz
|
||||
Loading…
Reference in New Issue
Block a user