# This file exists within 'dob':
#
# https://github.com/hotoffthehamster/dob
#
# Copyright © 2019-2020 Landon Bouma. All rights reserved.
#
# This program is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software Foundation,
# either version 3 of the License, or (at your option) any later version (GPLv3+).
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# If you lost the GNU General Public License that ships with this software
# repository (read the 'LICENSE' file), see <http://www.gnu.org/licenses/>.
from gettext import gettext as _
from click_hotoffthehamster.exceptions import MissingParameter
from config_decorator.key_chained_val import KeyChainedValue
# Load all the upstream config packages to ensure `dob config dump`, etc.,
# show all config values.
from nark import config as nark_config # noqa: F401 '<>' imported but unused
from dob_bright import config as dob_bright_config # noqa: F401
from dob_viewer import config as dob_viewer_config # noqa: F401
from dob_bright.crud.interrogate import run_editor_safe
from dob_bright.termio import click_echo, dob_in_user_exit
from dob_bright.termio.config_table import echo_config_decorator_table
__all__ = (
'echo_config_table',
'echo_config_value',
'edit_config_file',
'write_config_value',
# PRIVATE:
# 'echo_config_value_setting',
# 'echo_config_value_section',
# 'exit_error_no_setting',
# 'fetch_config_object',
# 'fetch_config_objects',
# 'error_exit_not_one',
# 'config_parts_pop_value',
# 'must_parts',
# 'must_be_config_setting',
)
# *** [DUMP] TABLE
[docs]def echo_config_table(
controller,
section,
keyname,
output_format,
table_type,
):
""""""
parts = list(filter(None, (section, keyname)))
conf_objs = fetch_config_objects(controller, parts)
include_hidden = section and keyname
echo_config_decorator_table(
controller,
conf_objs,
output_format=output_format,
table_type=table_type,
include_hidden=include_hidden,
)
# *** [EDIT] CONFIG
[docs]def edit_config_file(controller):
run_editor_safe(filename=controller.configurable.config_path)
# *** [GET] ECHO
[docs]def echo_config_value(ctx, controller, parts):
must_parts(ctx, parts, _('“KEYNAME”'))
section_or_setting = fetch_config_object(controller, parts)
if isinstance(section_or_setting, KeyChainedValue):
echo_config_value_setting(section_or_setting)
else:
echo_config_value_section(section_or_setting)
def echo_config_value_setting(setting):
click_echo(setting.value)
def echo_config_value_section(section):
counts = []
if section._sections:
counts.append('{} {}'.format(len(section._sections), _('sections')))
if section._key_vals or not section._sections:
counts.append('{} {}'.format(len(section._key_vals), _('settings')))
dob_in_user_exit(
_('Configuration section “{}” contains {}.').format(
section._name,
_('and').join(counts),
)
)
# *** [SET] CONFIG
[docs]def write_config_value(ctx, controller, parts):
parts, value = config_parts_pop_value(ctx, parts)
section_or_setting = fetch_config_object(controller, parts)
setting = must_be_config_setting(section_or_setting)
try:
setting.value = value
except ValueError as err:
dob_in_user_exit(str(err))
controller.write_config(skip_unset=True)
# *** [GET/SET] FETCH
def fetch_config_object(controller, parts):
conf_objs = fetch_config_objects(controller, parts)
if len(conf_objs) == 1:
return conf_objs[0]
error_exit_not_one(parts, conf_objs)
def fetch_config_objects(controller, parts):
try:
conf_objs = controller.configurable.find_all(parts)
except AttributeError:
exit_error_no_setting(parts)
except KeyError:
# Raised by configurable on unknown part(s).
exit_error_no_setting(parts)
return conf_objs
def error_exit_not_one(parts, conf_objs):
dotted = '.'.join(parts)
if len(conf_objs) > 1:
dob_in_user_exit(
_('ERROR: Too many config objects named: “{}”').format(dotted)
)
else:
# FIXME/2019-11-17 02:18: Should errors be paged if --pager?
# - See also/Consolidate: barf_and_exit, echo_exit, dob_in_user_exit.
dob_in_user_exit(
_('ERROR: Not a config object: “{}”.').format(dotted)
)
# *** [SECTION] [KEYNAME] [VALUE] VALIDATING
def config_parts_pop_value(ctx, parts):
parts = list(parts)
must_parts(ctx, parts, _('“KEYNAME” “VALUE”'), param_type='arguments')
value = parts.pop()
must_parts(ctx, parts, _('“VALUE”'))
return parts, value
def must_parts(ctx, parts, param_hint, param_type='argument'):
parts = list(parts)
if not parts:
raise MissingParameter(
ctx=ctx, param_hint=param_hint, param_type=param_type,
)
return parts
def must_be_config_setting(section_or_setting):
if not isinstance(section_or_setting, KeyChainedValue):
dob_in_user_exit(_(
'ERROR: Not a configuration setting: “{}”.'.format(section_or_setting._name)
))
return section_or_setting
def exit_error_no_setting(parts):
dob_in_user_exit(_(
'ERROR: Not a configuration setting: “{}”.'.format('.'.join(parts))
))