mirror of
https://git.zavage.net/Zavage-Software/app_skellington.git
synced 2024-12-21 22:29:20 -07:00
Merge branch 'master' of git.zavage.net:Zavage/app_skellington
This commit is contained in:
commit
1f8013bd49
@ -12,6 +12,8 @@ from . import _util
|
|||||||
from . import cli
|
from . import cli
|
||||||
from . import cfg
|
from . import cfg
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
# These two variables affect the directory paths for
|
# These two variables affect the directory paths for
|
||||||
# config files and logging.
|
# config files and logging.
|
||||||
DEFAULT_APP_NAME = ''
|
DEFAULT_APP_NAME = ''
|
||||||
@ -54,8 +56,14 @@ class ApplicationContainer:
|
|||||||
config = cfg.Config(configspec_filepath, configini_filepath)
|
config = cfg.Config(configspec_filepath, configini_filepath)
|
||||||
|
|
||||||
logger = log.LoggingLayer(self.appname, self.appauthor)
|
logger = log.LoggingLayer(self.appname, self.appauthor)
|
||||||
|
# Try and load logging configuration if provided
|
||||||
|
log_config = config.get('logging')
|
||||||
|
if log_config is not None:
|
||||||
|
logger.configure_logging(log_config)
|
||||||
|
else:
|
||||||
logger.configure_logging()
|
logger.configure_logging()
|
||||||
|
|
||||||
|
|
||||||
self.ctx = ApplicationContext(config, logger)
|
self.ctx = ApplicationContext(config, logger)
|
||||||
|
|
||||||
# Reference to root_app avail. in context
|
# Reference to root_app avail. in context
|
||||||
|
@ -18,6 +18,11 @@ class Config:
|
|||||||
"""
|
"""
|
||||||
Structure to store application runtime configuration. Also contains
|
Structure to store application runtime configuration. Also contains
|
||||||
functionality to load configuration from local site file.
|
functionality to load configuration from local site file.
|
||||||
|
|
||||||
|
Provide config.spec - specification file which defines allowed parameters and types.
|
||||||
|
|
||||||
|
Provide config.ini - configuration instance which contains values for any
|
||||||
|
configuration arguments.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DEFAULT_CAPABILITIES = {
|
DEFAULT_CAPABILITIES = {
|
||||||
@ -146,6 +151,19 @@ class Config:
|
|||||||
"""
|
"""
|
||||||
self._config_obj[key] = value
|
self._config_obj[key] = value
|
||||||
|
|
||||||
|
def get(self, key, default=None):
|
||||||
|
"""
|
||||||
|
Attempt to retrieve configuration item, otherwise return default
|
||||||
|
provided value.
|
||||||
|
|
||||||
|
Similar to Dictionary.get()
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
v = self.__getitem__(key)
|
||||||
|
return v
|
||||||
|
except KeyError as ex:
|
||||||
|
return default
|
||||||
|
|
||||||
def load_config(
|
def load_config(
|
||||||
self, configspec_filepath=None, configini_filepath=None
|
self, configspec_filepath=None, configini_filepath=None
|
||||||
):
|
):
|
||||||
|
@ -80,9 +80,8 @@ class CommandTree:
|
|||||||
Creates a root-level submenu with no entries. SubMenu node is
|
Creates a root-level submenu with no entries. SubMenu node is
|
||||||
returned which can have submenus and commands attached to it.
|
returned which can have submenus and commands attached to it.
|
||||||
"""
|
"""
|
||||||
# NOTE(MG) Fix below strategizes whether to pass in 'required'
|
# NOTE(MG) Fix for Python>=3.7,
|
||||||
# paremter to ArgumentParser.add_subparsers()
|
# argparse.ArgumentParser added 'required' argument.
|
||||||
# which was added in in Python3.7.
|
|
||||||
# Must also be written into SubMenu.create_submenu.
|
# Must also be written into SubMenu.create_submenu.
|
||||||
func_args = {
|
func_args = {
|
||||||
'dest': param_name,
|
'dest': param_name,
|
||||||
@ -91,11 +90,12 @@ class CommandTree:
|
|||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
sys.version_info.major == 3
|
sys.version_info.major == 3
|
||||||
and sys.version_info.minor <= 6
|
and sys.version_info.minor < 7
|
||||||
):
|
):
|
||||||
if is_required:
|
if is_required:
|
||||||
_bootstrap_logger.warn('Unable to enforce required submenu: Requires >= Python 3.7')
|
_bootstrap_logger.warn('Unable to enforce required submenu: Requires >= Python 3.7')
|
||||||
del func_args['required']
|
del func_args['required']
|
||||||
|
# END fix for Python<3.7
|
||||||
|
|
||||||
# Creates an argument as a slot in the underlying argparse.
|
# Creates an argument as a slot in the underlying argparse.
|
||||||
subparsers = self.root_parser.add_subparsers(
|
subparsers = self.root_parser.add_subparsers(
|
||||||
@ -447,9 +447,8 @@ class SubMenu:
|
|||||||
help='sub-submenu help',
|
help='sub-submenu help',
|
||||||
description='sub-sub description')
|
description='sub-sub description')
|
||||||
|
|
||||||
# NOTE(MG) Fix below strategizes whether to pass in 'required'
|
# NOTE(MG) Fix for Python>=3.7,
|
||||||
# paremter to ArgumentParser.add_subparsers()
|
# argparse.ArgumentParser added 'required' argument.
|
||||||
# which was added in in Python3.7.
|
|
||||||
# Must also be written into CommandTree.init_submenu
|
# Must also be written into CommandTree.init_submenu
|
||||||
func_args = {
|
func_args = {
|
||||||
'dest': var_name,
|
'dest': var_name,
|
||||||
@ -458,11 +457,14 @@ class SubMenu:
|
|||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
sys.version_info.major == 3
|
sys.version_info.major == 3
|
||||||
and sys.version_info.minor <= 6
|
and sys.version_info.minor < 7
|
||||||
):
|
):
|
||||||
if is_required:
|
if is_required:
|
||||||
_bootstrap_logger.warn('Unable to enforce required submenu: Requires >= Python 3.7')
|
_bootstrap_logger.warn('Unable to enforce required submenu: Requires >= Python 3.7')
|
||||||
del func_args['required']
|
del func_args['required']
|
||||||
|
# END fix for Python<3.7
|
||||||
|
|
||||||
|
|
||||||
# Turn entry into a submenu of it's own:
|
# Turn entry into a submenu of it's own:
|
||||||
# type = _SubParsersAction
|
# type = _SubParsersAction
|
||||||
subp_node = entry_node.add_subparsers(
|
subp_node = entry_node.add_subparsers(
|
||||||
|
@ -77,7 +77,6 @@ class LoggingLayer:
|
|||||||
self.transform_config(config_dict)
|
self.transform_config(config_dict)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# TODO(MG) Pretty print
|
|
||||||
_bootstrap_logger.debug('log - Log configuration: %s', config_dict)
|
_bootstrap_logger.debug('log - Log configuration: %s', config_dict)
|
||||||
logging.config.dictConfig(config_dict)
|
logging.config.dictConfig(config_dict)
|
||||||
_bootstrap_logger.debug('log - Configured all logging')
|
_bootstrap_logger.debug('log - Configured all logging')
|
||||||
@ -107,13 +106,16 @@ class LoggingLayer:
|
|||||||
d = config_dict['loggers'][logger]
|
d = config_dict['loggers'][logger]
|
||||||
self._convert_str_to_loglevel(d, 'level')
|
self._convert_str_to_loglevel(d, 'level')
|
||||||
|
|
||||||
# Replace 'root' logger with '', logging module convention for root handler
|
|
||||||
# Note: '' is disallowed in ConfigObj (hence the reason for this replacement)
|
# Implementation note:
|
||||||
|
# app_skellington expects root logger configuration to be under 'root'
|
||||||
|
# instead of '' (python spec) because '' is not a valid name in ConfigObj.
|
||||||
try:
|
try:
|
||||||
|
if config_dict['loggers'].get('root') is not None:
|
||||||
config_dict['loggers'][''] = config_dict['loggers']['root']
|
config_dict['loggers'][''] = config_dict['loggers']['root']
|
||||||
del config_dict['loggers']['root']
|
del config_dict['loggers']['root']
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
_bootstrap.logger.warn('internal failure patching root logger')
|
_bootstrap_logger.warn('was not able to find and patch root logger configuration from arguments')
|
||||||
|
|
||||||
|
|
||||||
# Evaluate the full filepath of the file handler
|
# Evaluate the full filepath of the file handler
|
||||||
|
Loading…
Reference in New Issue
Block a user