Compare commits

..

8 Commits
v0.2.2 ... main

9 changed files with 100 additions and 25 deletions

@ -1 +1,2 @@
3.8.19
3.8.20
3.8.8

22
CHANGELOG.md Normal file

@ -0,0 +1,22 @@
# Changelog
## [0.2.2] (2020-07-19)
Second release is focused on cleanup, documentation.
* flake8, black, isort - all warnings and errors fixed.
* Documentation improved.
* Build and deploy process documented for developers.
* Poetry removed, replaced with modern pyproject.toml and setuptools.build_meta
for automatic version management.
## [0.1.0] (2020-07-19)
First release to PyPi.
* Basic functionality. Probably not the best code.
* Sub-menus supported, multi-level through CLI.
* Config through ConfigObj ini. Define spec file and input config.ini
* Colored Logging
* Services can be defined and provided to classes

@ -1,5 +1,9 @@
app_skellington
===============
---
gitea: none
include_toc: true
---
**app_skellington**
Application framework for Python, features include:
- Pain-free multi-level command menu: Expose public class methods as commands available to user.
@ -14,10 +18,26 @@ Principles:
- 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
# PyPi Hosted Link
# Python Package Index (PyPi) - Installation Instruction
This is the project page for PyPi: The Python Package Index for community third-party libraries
https://pypi.org/project/app-skellington/
```
pip install app_skellington # install
pip uninstall app_skellington # uninstall
pip download app_skellington # download .whl wheel files for redistributable install
pip install -U app_skellington # upgrade
pip list # list install packages in environment
pip index version app_skellington # enumerate available distributions in pypi for package
```
# Description
This is a library. There is nothing to run by itself. It would be helpful to have a sample application that uses
it or something, but I don't have that ready at the moment.
# Application Configuration
Site configurations are supported through ConfigObj. There is a config.spec
@ -62,7 +82,7 @@ or
# Tests
Tests are a WIP. Recommendation is to run 'pytest' in the 'tests' directory.
Tests are a WIP and not fully built out yet. Recommendation is to run 'pytest' in the 'tests' directory.
# Development
@ -136,8 +156,14 @@ twine upload dist/*
setuptools_scm will infer the version based on the latest tag in your Git history.
Ensure you are tagging your commits with meaningful version numbers like v1.0.0, v1.1.0, etc.
You can view the current version number with the command:
python -m setuptools_scm
# License
See [license](LICENSE.txt)
MIT no attribution required - https://opensource.org/license/mit-0
* Allows commercial use.

@ -1,14 +1,14 @@
# flake8: noqa
from .cfg import Config, EnvironmentVariables
from .app_container import (
DEFAULT_APP_AUTHOR,
DEFAULT_APP_NAME,
ApplicationContainer,
ApplicationContext,
NoCommandSpecified,
ServiceNotFound,
)
from .cfg import Config, EnvironmentVariables
from ._util import ServiceNotFound, NoCommandSpecified
from .cli import (
EXPLICIT_FAIL_ON_UNKNOWN_ARGS,
CommandEntry,

@ -124,3 +124,15 @@ def create_func(constructor, cls_method):
return cls_method(cmd_class_instance, *args, **kwargs)
return func
class ServiceNotFound(Exception):
"""
Application framework error: unable to find and inject dependency.
"""
pass
class NoCommandSpecified(Exception):
pass

@ -0,0 +1,20 @@
# file generated by setuptools-scm
# don't change, don't track in version control
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
TYPE_CHECKING = False
if TYPE_CHECKING:
from typing import Tuple, Union
VERSION_TUPLE = Tuple[Union[int, str], ...]
else:
VERSION_TUPLE = object
version: str
__version__: str
__version_tuple__: VERSION_TUPLE
version_tuple: VERSION_TUPLE
__version__ = version = "0.3.0.dev7+gd155176.d20250223"
__version_tuple__ = version_tuple = (0, 3, 0, "dev7", "gd155176.d20250223")

@ -4,7 +4,10 @@ import os
import appdirs
from . import _util, cfg, cli, log
from ._util import ServiceNotFound, NoCommandSpecified, get_root_asset
from . import log
from .cfg import Config
from .cli import CommandTree
# Application scaffolding:
from ._bootstrap import _bootstrap_logger
@ -49,7 +52,7 @@ class ApplicationContainer:
# global state, configuration, loggers, and runtime args.
self._dependencies = {}
config = cfg.Config(configspec_filepath, configini_filepath)
config = Config(configspec_filepath, configini_filepath)
logger = log.LoggingLayer(self.appname, self.appauthor)
# Try and load logging configuration if provided
@ -67,7 +70,7 @@ class ApplicationContainer:
# Reference to context service avail. in root_app
self["ctx"] = lambda: self.ctx
self.cli = cli.CommandTree() # Command-line interface
self.cli = CommandTree() # Command-line interface
# Run methods if subclass implemented them:
if callable(getattr(self, "_cli_options", None)):
@ -144,7 +147,7 @@ class ApplicationContainer:
"""
Attempt to find config.spec inside the installed package directory.
"""
return _util.get_root_asset(configspec_filename)
return get_root_asset(configspec_filename)
def _inject_service_dependencies(self, constructor):
"""
@ -188,13 +191,3 @@ class ApplicationContainer:
# Applications need a default usage
class ServiceNotFound(Exception):
"""
Application framework error: unable to find and inject dependency.
"""
pass
class NoCommandSpecified(Exception):
pass

@ -3,7 +3,7 @@ import inspect
import re
import sys
from . import NoCommandSpecified, app_container
from ._util import NoCommandSpecified
from ._bootstrap import _bootstrap_logger
# If explicit fail is enabled, any command with at least one unknown
@ -280,7 +280,7 @@ class CommandTree:
# return self._invoke_command(lookup, args)
else:
raise app_container.NoCommandSpecified("No command specified.")
raise NoCommandSpecified("No command specified.")
def _invoke_command(self, cmd, args):
command_to_be_invoked = cmd.callback

@ -40,5 +40,6 @@ dev = [
]
[tool.setuptools_scm]
version_scheme = "guess-next-dev"
version_file = "app_skellington/_version.py"
version_scheme = "release-branch-semver"
local_scheme = "node-and-date"