Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jaesivsm committed Oct 23, 2017
1 parent 3c45ea3 commit 9d72b79
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 2 deletions.
46 changes: 46 additions & 0 deletions the_conf/interractive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
def _print_line_informations(choices=None, default=None):
if choices is not None:
print('[%s]' % '/'.join([str(chc).upper()
if chc == default else str(chc)
for chc in choices]), end=' ')
if default not in {'', None}:
if choices and default not in choices:
for new_default, value in choices.items():
if value == default:
default = new_default
break
print('(default: %r)' % default, end=' ')
return default


def ask(text, choices=None, default=None, required=False, cast=str):
choices = [] if choices is None else [cast(chc) for chc in choices]
while True:
print(text, end=' ')
default = _print_line_informations(choices, default)
print(':', end=' ')

result = input()

if cast is not None:
try:
result = cast(result)
except ValueError:
print("Couldn't cast %r to %r" % (result, cast))
continue

if not result and required:
print('you must provide an answer')
elif result and choices and result not in choices:
print('%r is not in %r' % (result, choices))
else:
return result


def ask_bool(text, default=True, required=False):
default = 'yes' if default else 'no'
result = ask(text, choices=['y', 'yes', 'n', 'no'],
default=default, required=required, cast=str)
if result.lower() in {'y', 'yes'}:
return True
return False
30 changes: 28 additions & 2 deletions the_conf/the_conf.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging

from the_conf import files, command_line, node
from the_conf import files, command_line, node, interractive

logger = logging.getLogger(__name__)
DEFAULT_ORDER = 'cmd', 'files', 'env'
Expand All @@ -14,11 +14,12 @@ def __new__(cls, *args, **kwargs):
cls.__instance = object.__new__(cls)
return cls.__instance

def __init__(self, *metaconfs, cmd_line_opts=None):
def __init__(self, *metaconfs, prompt_values=False, cmd_line_opts=None):
self._source_order = DEFAULT_ORDER
self._config_files = None
self._main_conf_file = None
self._cmd_line_opts = cmd_line_opts
self._prompt_values = prompt_values

super().__init__()
for mc in metaconfs:
Expand Down Expand Up @@ -66,6 +67,9 @@ def load(self):
else:
raise Exception('unknown order %r')

if self._prompt_values:
self.prompt_values(False, False, False, False)

for path, value, param in self._get_path_val_param():
if value is node.NoValue and param.get('required'):
raise ValueError('loading finished and %r is not set'
Expand All @@ -91,3 +95,25 @@ def write(self, config_file=None):

files.write(self.extract_config(),
config_file or self._config_files[0])

def prompt_values(self, only_empty=True, only_no_default=True,
only_required=True, only_w_help=True):
for path, value, param in self._get_path_val_param():
if only_w_help and not param.get('help_txt'):
continue
if only_required and not param.get('required'):
continue
if only_no_default and not param.get('default'):
continue
if only_empty and value is not node.NoValue:
continue
if param.get('type') is bool:
self._set_to_path(path, interractive.ask_bool(
param.get('help_txt', '.'.join(path)),
default=param.get('default'),
required=param.get('required')))
else:
self._set_to_path(path, interractive.ask(
param.get('help_txt', '.'.join(path)),
choices=param.get('among'), default=param.get('default'),
required=param.get('required'), cast=param.get('type')))

0 comments on commit 9d72b79

Please sign in to comment.