mirror of
https://github.com/planetmint/planetmint.git
synced 2025-06-06 22:26:42 +00:00
162 lines
5.1 KiB
Python
162 lines
5.1 KiB
Python
# Copyright © 2020 Interplanetary Database Association e.V.,
|
|
# Planetmint and IPDB software contributors.
|
|
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
|
|
# Code is Apache-2.0 and docs are CC-BY-4.0
|
|
|
|
"""Utility functions and basic common arguments
|
|
for ``argparse.ArgumentParser``.
|
|
"""
|
|
|
|
import argparse
|
|
import builtins
|
|
import functools
|
|
import multiprocessing as mp
|
|
import sys
|
|
|
|
import bigchaindb
|
|
import bigchaindb.config_utils
|
|
from bigchaindb.version import __version__
|
|
|
|
|
|
def configure_bigchaindb(command):
|
|
"""Decorator to be used by command line functions, such that the
|
|
configuration of bigchaindb is performed before the execution of
|
|
the command.
|
|
|
|
Args:
|
|
command: The command to decorate.
|
|
|
|
Returns:
|
|
The command wrapper function.
|
|
|
|
"""
|
|
@functools.wraps(command)
|
|
def configure(args):
|
|
config_from_cmdline = None
|
|
try:
|
|
if args.log_level is not None:
|
|
config_from_cmdline = {
|
|
'log': {
|
|
'level_console': args.log_level,
|
|
'level_logfile': args.log_level,
|
|
},
|
|
'server': {'loglevel': args.log_level},
|
|
}
|
|
except AttributeError:
|
|
pass
|
|
bigchaindb.config_utils.autoconfigure(
|
|
filename=args.config, config=config_from_cmdline, force=True)
|
|
command(args)
|
|
|
|
return configure
|
|
|
|
|
|
def _convert(value, default=None, convert=None):
|
|
def convert_bool(value):
|
|
if value.lower() in ('true', 't', 'yes', 'y'):
|
|
return True
|
|
if value.lower() in ('false', 'f', 'no', 'n'):
|
|
return False
|
|
raise ValueError('{} cannot be converted to bool'.format(value))
|
|
|
|
if value == '':
|
|
value = None
|
|
|
|
if convert is None:
|
|
if default is not None:
|
|
convert = type(default)
|
|
else:
|
|
convert = str
|
|
|
|
if convert == bool:
|
|
convert = convert_bool
|
|
|
|
if value is None:
|
|
return default
|
|
else:
|
|
return convert(value)
|
|
|
|
|
|
# We need this because `input` always prints on stdout, while it should print
|
|
# to stderr. It's a very old bug, check it out here:
|
|
# - https://bugs.python.org/issue1927
|
|
def input_on_stderr(prompt='', default=None, convert=None):
|
|
"""Output a string to stderr and wait for input.
|
|
|
|
Args:
|
|
prompt (str): the message to display.
|
|
default: the default value to return if the user
|
|
leaves the field empty
|
|
convert (callable): a callable to be used to convert
|
|
the value the user inserted. If None, the type of
|
|
``default`` will be used.
|
|
"""
|
|
|
|
print(prompt, end='', file=sys.stderr)
|
|
value = builtins.input()
|
|
return _convert(value, default, convert)
|
|
|
|
|
|
def start(parser, argv, scope):
|
|
"""Utility function to execute a subcommand.
|
|
|
|
The function will look up in the ``scope``
|
|
if there is a function called ``run_<parser.args.command>``
|
|
and will run it using ``parser.args`` as first positional argument.
|
|
|
|
Args:
|
|
parser: an ArgumentParser instance.
|
|
argv: the list of command line arguments without the script name.
|
|
scope (dict): map containing (eventually) the functions to be called.
|
|
|
|
Raises:
|
|
NotImplementedError: if ``scope`` doesn't contain a function called
|
|
``run_<parser.args.command>``.
|
|
"""
|
|
args = parser.parse_args(argv)
|
|
|
|
if not args.command:
|
|
parser.print_help()
|
|
raise SystemExit()
|
|
|
|
# look up in the current scope for a function called 'run_<command>'
|
|
# replacing all the dashes '-' with the lowercase character '_'
|
|
func = scope.get('run_' + args.command.replace('-', '_'))
|
|
|
|
# if no command has been found, raise a `NotImplementedError`
|
|
if not func:
|
|
raise NotImplementedError('Command `{}` not yet implemented'.
|
|
format(args.command))
|
|
|
|
args.multiprocess = getattr(args, 'multiprocess', False)
|
|
|
|
if args.multiprocess is False:
|
|
args.multiprocess = 1
|
|
elif args.multiprocess is None:
|
|
args.multiprocess = mp.cpu_count()
|
|
|
|
return func(args)
|
|
|
|
|
|
base_parser = argparse.ArgumentParser(add_help=False, prog='bigchaindb')
|
|
|
|
base_parser.add_argument('-c', '--config',
|
|
help='Specify the location of the configuration file '
|
|
'(use "-" for stdout)')
|
|
|
|
# NOTE: this flag should not have any default value because that will override
|
|
# the environment variables provided to configure the logger.
|
|
base_parser.add_argument('-l', '--log-level',
|
|
type=str.upper, # convert to uppercase for comparison to choices
|
|
choices=['DEBUG', 'BENCHMARK', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
|
|
help='Log level')
|
|
|
|
base_parser.add_argument('-y', '--yes', '--yes-please',
|
|
action='store_true',
|
|
help='Assume "yes" as answer to all prompts and run '
|
|
'non-interactively')
|
|
|
|
base_parser.add_argument('-v', '--version',
|
|
action='version',
|
|
version='%(prog)s {}'.format(__version__))
|