Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
7e02553c18 | |||
cb07dd6bb2 | |||
70c5c12fa5 |
0
CHANGELOG.md
Normal file
0
CHANGELOG.md
Normal file
@ -10,7 +10,7 @@ Application framework for Python, features include:
|
|||||||
Principles:
|
Principles:
|
||||||
- Lend to creating beautiful, easy to read and understand code in the application.
|
- Lend to creating beautiful, easy to read and understand code in the application.
|
||||||
- Minimize coupling of applications to this framework.
|
- 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
|
- Try to be compatible with alternate Python runtimes such as PyPy and older python environments. \*WIP
|
||||||
|
|
||||||
Application Configuration
|
Application Configuration
|
||||||
@ -47,8 +47,8 @@ argument.
|
|||||||
|
|
||||||
Debug - Turn on Logging
|
Debug - Turn on Logging
|
||||||
-----------------------
|
-----------------------
|
||||||
Set 'APPSKELLINGTON_ENABLE_LOGGING' environment variable to any value which turns
|
Set 'APPSKELLINGTON_DEBUG' environment variable to any value which turns
|
||||||
on AppSkellington-level logging. For example,
|
on AppSkellington logger. For example,
|
||||||
|
|
||||||
APPSKELLINGTON_DEBUG=1 <executable>
|
APPSKELLINGTON_DEBUG=1 <executable>
|
||||||
|
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
import logging
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from .app_container import *
|
from .app_container import *
|
||||||
from .cfg import *
|
from .cfg import *
|
||||||
from .cli import *
|
from .cli import *
|
||||||
|
@ -4,8 +4,6 @@ import inspect
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from . import _util
|
|
||||||
|
|
||||||
|
|
||||||
def eprint(*args, **kwargs):
|
def eprint(*args, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -30,7 +28,7 @@ def does_file_exist(filepath):
|
|||||||
instant in execution.
|
instant in execution.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
fp = open(filepath, "r")
|
open(filepath, "r")
|
||||||
return True
|
return True
|
||||||
except FileNotFoundError as ex:
|
except FileNotFoundError as ex:
|
||||||
return False
|
return False
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
import collections
|
|
||||||
import functools
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
|
|
||||||
import appdirs
|
import appdirs
|
||||||
|
|
||||||
@ -105,6 +102,7 @@ class ApplicationContainer:
|
|||||||
except KeyError as ex:
|
except KeyError as ex:
|
||||||
msg = "failed to inject service: {}".format(service_name)
|
msg = "failed to inject service: {}".format(service_name)
|
||||||
_bootstrap_logger.critical(msg)
|
_bootstrap_logger.critical(msg)
|
||||||
|
_bootstrap_logger.debug(ex)
|
||||||
raise ServiceNotFound
|
raise ServiceNotFound
|
||||||
|
|
||||||
def __setitem__(self, service_name, value):
|
def __setitem__(self, service_name, value):
|
||||||
@ -132,7 +130,7 @@ class ApplicationContainer:
|
|||||||
dependencies.append(self[dep_name])
|
dependencies.append(self[dep_name])
|
||||||
return model_constructor(*dependencies)
|
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.
|
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)
|
_bootstrap_logger.info("default config filepath calculated to be: %s", filepath)
|
||||||
return 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.
|
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)
|
return functools.partial(self._construct_model, constructor, *cls_dependencies)
|
||||||
|
|
||||||
def load_command(self):
|
def load_command(self) -> bool:
|
||||||
args, unk, success = self.cli.parse()
|
args, unk, success = self.cli.parse()
|
||||||
if not success:
|
if not success:
|
||||||
return False
|
return False
|
||||||
@ -183,13 +181,13 @@ class ApplicationContainer:
|
|||||||
print("Failure: No command specified.")
|
print("Failure: No command specified.")
|
||||||
|
|
||||||
def interactive_shell(self):
|
def interactive_shell(self):
|
||||||
pass
|
raise NotImplementedError()
|
||||||
|
|
||||||
def invoke_from_cli(self):
|
def invoke_from_cli(self):
|
||||||
self.invoke_command()
|
self.invoke_command()
|
||||||
|
|
||||||
def usage(self):
|
def usage(self):
|
||||||
pass
|
raise NotImplementedError()
|
||||||
# Applications need a default usage
|
# Applications need a default usage
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,15 +4,10 @@
|
|||||||
# ConfigObj module and it's recommended to use config.spec files to define
|
# ConfigObj module and it's recommended to use config.spec files to define
|
||||||
# your available configuration of the relevant application.
|
# your available configuration of the relevant application.
|
||||||
|
|
||||||
import argparse
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import appdirs
|
|
||||||
import configobj
|
import configobj
|
||||||
import validate
|
import validate
|
||||||
|
|
||||||
from . import _util
|
|
||||||
from ._bootstrap import _bootstrap_logger
|
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)
|
_bootstrap_logger.critical("cfg - Failed to find config.spec: file not found (%s)", filepath)
|
||||||
raise OSError("Failed to read provided config.spec file")
|
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):
|
def __contains__(self, key):
|
||||||
try:
|
try:
|
||||||
has_item = key in self._config_obj
|
has_item = key in self._config_obj
|
||||||
return has_item
|
return has_item
|
||||||
except KeyError as ex:
|
except KeyError as ex:
|
||||||
pass
|
_bootstrap_logger.error("failed to __containers__ on key (%s): %s", key, ex)
|
||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key):
|
||||||
"""
|
"""
|
||||||
@ -117,7 +113,7 @@ class Config:
|
|||||||
try:
|
try:
|
||||||
del self[key]
|
del self[key]
|
||||||
except KeyError as ex:
|
except KeyError as ex:
|
||||||
pass
|
_bootstrap_logger.error("failed to __delitem__ on key (%s): %s", key, ex)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
"""
|
"""
|
||||||
@ -131,6 +127,7 @@ class Config:
|
|||||||
# return self._config_obj[key].dict()
|
# return self._config_obj[key].dict()
|
||||||
return self._config_obj[key]
|
return self._config_obj[key]
|
||||||
except KeyError as ex:
|
except KeyError as ex:
|
||||||
|
_bootstrap_logger.error("failed to __getitem__ on key (%s): %s", key, ex)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
@ -151,9 +148,16 @@ class Config:
|
|||||||
v = self.__getitem__(key)
|
v = self.__getitem__(key)
|
||||||
return v
|
return v
|
||||||
except KeyError as ex:
|
except KeyError as ex:
|
||||||
|
_bootstrap_logger.error("failed to retrieve config key (%s): %s", key, ex)
|
||||||
return default
|
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:
|
# Set new arguments if were passed in:
|
||||||
if configspec_filepath is not None:
|
if configspec_filepath is not None:
|
||||||
self.configspec_filepath = configspec_filepath
|
self.configspec_filepath = configspec_filepath
|
||||||
@ -200,7 +204,7 @@ class Config:
|
|||||||
_bootstrap_logger.error(msg)
|
_bootstrap_logger.error(msg)
|
||||||
return False
|
return False
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print(ex)
|
_bootstrap_logger.error(ex)
|
||||||
|
|
||||||
def _validate_config_against_spec(self):
|
def _validate_config_against_spec(self):
|
||||||
config_spec = self.configspec_filepath
|
config_spec = self.configspec_filepath
|
||||||
@ -234,6 +238,7 @@ class Config:
|
|||||||
return False
|
return False
|
||||||
except ValueError as ex:
|
except ValueError as ex:
|
||||||
_bootstrap_logger.error("cfg - Failed while validating config against spec. ")
|
_bootstrap_logger.error("cfg - Failed while validating config against spec. ")
|
||||||
|
_bootstrap_logger.debug(ex)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _validate_parse_errors(self, test_results):
|
def _validate_parse_errors(self, test_results):
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import app_skellington
|
|
||||||
|
|
||||||
from . import app_container
|
from . import app_container
|
||||||
from ._bootstrap import _bootstrap_logger
|
from ._bootstrap import _bootstrap_logger
|
||||||
|
|
||||||
@ -69,7 +66,7 @@ class CommandTree:
|
|||||||
self._single_command = None
|
self._single_command = None
|
||||||
|
|
||||||
def print_tree(self):
|
def print_tree(self):
|
||||||
raise NotImplemented
|
raise NotImplementedError()
|
||||||
|
|
||||||
def add_argument(self, *args, **kwargs):
|
def add_argument(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -3,7 +3,6 @@ import logging.config
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
import appdirs
|
import appdirs
|
||||||
import colorlog
|
|
||||||
|
|
||||||
from . import _util
|
from . import _util
|
||||||
from ._bootstrap import _bootstrap_logger, _logger_name
|
from ._bootstrap import _bootstrap_logger, _logger_name
|
||||||
|
@ -7,9 +7,9 @@ authors = [
|
|||||||
]
|
]
|
||||||
license = "Creative Commons"
|
license = "Creative Commons"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
homepage = "https://zavage-software.com"
|
homepage = "https://zavage-software.com/portfolio/app_skellington"
|
||||||
repository = "https://git-mirror.zavage.net/Zavage-Software/app_skellington"
|
repository = "https://git-mirror.zavage.net/zavage-software/app_skellington"
|
||||||
documentation = "https://git-mirror.zavage.net/Zavage-Software/app_skellington"
|
documentation = "https://git-mirror.zavage.net/zavage-software/app_skellington"
|
||||||
keywords = [""]
|
keywords = [""]
|
||||||
|
|
||||||
packages = [{ include = "app_skellington" }]
|
packages = [{ include = "app_skellington" }]
|
||||||
|
4
setup.py
4
setup.py
@ -34,8 +34,8 @@ setup(
|
|||||||
description="A high-powered command line menu framework.",
|
description="A high-powered command line menu framework.",
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
author="Mathew Guest",
|
author="Mathew Guest",
|
||||||
author_email="t3h.zavage@gmail.com",
|
author_email="mat@zavage.net",
|
||||||
url="https://git-mirror.zavage.net/Mirror/app_skellington",
|
url="https://git-mirror.zavage.net/zavage-software/app_skellington",
|
||||||
license="MIT",
|
license="MIT",
|
||||||
python_requires=">=3",
|
python_requires=">=3",
|
||||||
classifiers=[
|
classifiers=[
|
||||||
|
Loading…
Reference in New Issue
Block a user