Compare commits

...

3 Commits

10 changed files with 31 additions and 37 deletions

0
CHANGELOG.md Normal file

@ -10,7 +10,7 @@ Application framework for Python, features include:
Principles:
- Lend to creating beautiful, easy to read and understand code in the application.
- Minimize coupling of applications to this framework.
- Compatable with Linux, Windows, and Mac. Try to be compatible as possible otherwise.
- Compatible with Linux, Windows, and Mac. Try to be compatible as possible otherwise.
- Try to be compatible with alternate Python runtimes such as PyPy and older python environments. \*WIP
Application Configuration
@ -47,8 +47,8 @@ argument.
Debug - Turn on Logging
-----------------------
Set 'APPSKELLINGTON_ENABLE_LOGGING' environment variable to any value which turns
on AppSkellington-level logging. For example,
Set 'APPSKELLINGTON_DEBUG' environment variable to any value which turns
on AppSkellington logger. For example,
APPSKELLINGTON_DEBUG=1 <executable>

@ -1,6 +1,3 @@
import logging
import sys
from .app_container import *
from .cfg import *
from .cli import *

@ -4,8 +4,6 @@ import inspect
import os
import sys
from . import _util
def eprint(*args, **kwargs):
"""
@ -30,7 +28,7 @@ def does_file_exist(filepath):
instant in execution.
"""
try:
fp = open(filepath, "r")
open(filepath, "r")
return True
except FileNotFoundError as ex:
return False

@ -1,9 +1,6 @@
import collections
import functools
import inspect
import logging
import os
import sys
import appdirs
@ -105,6 +102,7 @@ class ApplicationContainer:
except KeyError as ex:
msg = "failed to inject service: {}".format(service_name)
_bootstrap_logger.critical(msg)
_bootstrap_logger.debug(ex)
raise ServiceNotFound
def __setitem__(self, service_name, value):
@ -132,7 +130,7 @@ class ApplicationContainer:
dependencies.append(self[dep_name])
return model_constructor(*dependencies)
def _get_config_filepath(self, app_name, app_author, config_filename="config.ini"):
def _get_config_filepath(self, app_name, app_author, config_filename="config.ini") -> str:
"""
Attempt to find config.ini in the user's config directory.
@ -144,7 +142,7 @@ class ApplicationContainer:
_bootstrap_logger.info("default config filepath calculated to be: %s", filepath)
return filepath
def _get_configspec_filepath(self, configspec_filename="config.spec"):
def _get_configspec_filepath(self, configspec_filename: str = "config.spec") -> str:
"""
Attempt to find config.spec inside the installed package directory.
"""
@ -165,7 +163,7 @@ class ApplicationContainer:
return functools.partial(self._construct_model, constructor, *cls_dependencies)
def load_command(self):
def load_command(self) -> bool:
args, unk, success = self.cli.parse()
if not success:
return False
@ -183,13 +181,13 @@ class ApplicationContainer:
print("Failure: No command specified.")
def interactive_shell(self):
pass
raise NotImplementedError()
def invoke_from_cli(self):
self.invoke_command()
def usage(self):
pass
raise NotImplementedError()
# Applications need a default usage

@ -4,15 +4,10 @@
# ConfigObj module and it's recommended to use config.spec files to define
# your available configuration of the relevant application.
import argparse
import os
import sys
import appdirs
import configobj
import validate
from . import _util
from ._bootstrap import _bootstrap_logger
@ -100,14 +95,15 @@ class Config:
_bootstrap_logger.critical("cfg - Failed to find config.spec: file not found (%s)", filepath)
raise OSError("Failed to read provided config.spec file")
self.load_config()
# TODO(MG) initial code was present but unreachable. is an error in coding.
# self.load_config()
def __contains__(self, key):
try:
has_item = key in self._config_obj
return has_item
except KeyError as ex:
pass
_bootstrap_logger.error("failed to __containers__ on key (%s): %s", key, ex)
def __delitem__(self, key):
"""
@ -117,7 +113,7 @@ class Config:
try:
del self[key]
except KeyError as ex:
pass
_bootstrap_logger.error("failed to __delitem__ on key (%s): %s", key, ex)
def __getitem__(self, key):
"""
@ -131,6 +127,7 @@ class Config:
# return self._config_obj[key].dict()
return self._config_obj[key]
except KeyError as ex:
_bootstrap_logger.error("failed to __getitem__ on key (%s): %s", key, ex)
raise
def __setitem__(self, key, value):
@ -151,9 +148,16 @@ class Config:
v = self.__getitem__(key)
return v
except KeyError as ex:
_bootstrap_logger.error("failed to retrieve config key (%s): %s", key, ex)
return default
def load_config(self, configspec_filepath=None, configini_filepath=None):
def load_config(self, configspec_filepath=None, configini_filepath=None) -> bool:
"""
Loads config from file, validating against configspec.
Returns:
bool: success status of command and validation.
"""
# Set new arguments if were passed in:
if configspec_filepath is not None:
self.configspec_filepath = configspec_filepath
@ -200,7 +204,7 @@ class Config:
_bootstrap_logger.error(msg)
return False
except Exception as ex:
print(ex)
_bootstrap_logger.error(ex)
def _validate_config_against_spec(self):
config_spec = self.configspec_filepath
@ -234,6 +238,7 @@ class Config:
return False
except ValueError as ex:
_bootstrap_logger.error("cfg - Failed while validating config against spec. ")
_bootstrap_logger.debug(ex)
return False
def _validate_parse_errors(self, test_results):

@ -1,11 +1,8 @@
import argparse
import inspect
import logging
import re
import sys
import app_skellington
from . import app_container
from ._bootstrap import _bootstrap_logger
@ -69,7 +66,7 @@ class CommandTree:
self._single_command = None
def print_tree(self):
raise NotImplemented
raise NotImplementedError()
def add_argument(self, *args, **kwargs):
"""

@ -3,7 +3,6 @@ import logging.config
import os
import appdirs
import colorlog
from . import _util
from ._bootstrap import _bootstrap_logger, _logger_name

@ -7,9 +7,9 @@ authors = [
]
license = "Creative Commons"
readme = "README.md"
homepage = "https://zavage-software.com"
repository = "https://git-mirror.zavage.net/Zavage-Software/app_skellington"
documentation = "https://git-mirror.zavage.net/Zavage-Software/app_skellington"
homepage = "https://zavage-software.com/portfolio/app_skellington"
repository = "https://git-mirror.zavage.net/zavage-software/app_skellington"
documentation = "https://git-mirror.zavage.net/zavage-software/app_skellington"
keywords = [""]
packages = [{ include = "app_skellington" }]

@ -34,8 +34,8 @@ setup(
description="A high-powered command line menu framework.",
long_description=long_description,
author="Mathew Guest",
author_email="t3h.zavage@gmail.com",
url="https://git-mirror.zavage.net/Mirror/app_skellington",
author_email="mat@zavage.net",
url="https://git-mirror.zavage.net/zavage-software/app_skellington",
license="MIT",
python_requires=">=3",
classifiers=[