From 5c6a486913f6e0038617e59fa3f94c79e68bb779 Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Fri, 15 Nov 2024 06:06:30 -0700 Subject: [PATCH 01/19] build: added link to published pypi project --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 5eaa637..731f5b6 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,11 @@ Principles: - Compatable 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 +---------------- + +https://pypi.org/project/app-skellington/ + Application Configuration ------------------------- Site configurations are supported through ConfigObj. There is a config.spec From dab6154f33b1f2cd4f84f08c324165acb1127934 Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Fri, 15 Nov 2024 19:44:11 -0700 Subject: [PATCH 02/19] feat: switched license to MIT no attribution --- LICENSE.txt | 35 +++++++++++++++-------------------- README.md | 53 +++++++++++++++++++++++++++-------------------------- 2 files changed, 42 insertions(+), 46 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index a454efe..bb2ff5b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,25 +1,20 @@ App Skellington +MIT No Attribution + Copyright (c) 2024 Mathew Guest -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +`NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 731f5b6..c39f85b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ app_skellington =============== + Application framework for Python, features include: - Pain-free multi-level command menu: Expose public class methods as commands available to user. - Simple to define services and automatic dependency injection based on name (with custom invocation as an option). \*WIP @@ -13,13 +14,12 @@ Principles: - Compatable 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 ----------------- +# PyPi Hosted Link https://pypi.org/project/app-skellington/ -Application Configuration -------------------------- +# Application Configuration + Site configurations are supported through ConfigObj. There is a config.spec in the src directory which is a validation file; it contains the accepted parameter names, types, and limits for configurable options in the @@ -37,21 +37,19 @@ parameters are added into the config file. Linux: -/home/\/.config/\/config.ini - -/home/\/.cache/\/log/\.log + * /home/\/.config/\/config.ini + * /home/\/.cache/\/log/\.log Windows: -C:\\Users\\\\\\\\Local\\\\\config.ini - -C:\\Users\\\\\\\\Local\\\\\Logs\\\.log + * C:\\Users\\\\\\\\Local\\\\\config.ini + * C:\\Users\\\\\\\\Local\\\\\Logs\\\.log Application configuration can be overridden ad-hoc through the --config argument. -Debug - Turn on Logging ------------------------ +# Debug - Turn on Logging + Set 'APPSKELLINGTON_ENABLE_LOGGING' environment variable to any value which turns on AppSkellington-level logging. For example, @@ -62,12 +60,12 @@ or export APPSKELLINGTON_DEBUG=1 -Tests ------ +# Tests + Tests are a WIP. Recommendation is to run 'pytest' in the 'tests' directory. -Development ------------ +# Development + Clone the repo: ```commandline git clone https://git-mirror.zavage.net/zavage-software/app_skellington.git @@ -88,14 +86,17 @@ pre-commit install Begin development. -License -------- -I'm releasing this software under one of the most permissive -licenses, the MIT software license. This applies to this source repository -and all files within it. Alternatively, you are permitted you -to use any of this under the GPL to the fullest legal extent allowed. +# License + +MIT no attribution required - https://opensource.org/license/mit-0 + + * Allows commercial use. + * Allows modifications and closed-source derivatives. + * Fully interoperable with nearly all other open-source licenses, including GPL (when combined properly). + +# See Also + + * Project page: https://zavage-software.com/portfolio/app_skellington + * Please report bugs, improvements, or feedback! + * Contact: mathew@zavage.net -Notes ------ -See official website: https://zavage-software.com -Please report bugs, improvements, or feedback! From edb7cd346a2c139e2648cee7c4d691b8fea1f312 Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Fri, 15 Nov 2024 20:10:05 -0700 Subject: [PATCH 03/19] doc: updating url to projectg page --- pyproject.toml | 9 ++++----- setup.py | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bd75071..56d01b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,13 +3,13 @@ name = "app_skellington" version = "0.1.0" description = "app_skellington CLI framework" authors = [ - "Mathew Guest ", + "Mathew Guest ", ] -license = "Creative Commons" +license = "MIT" 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" +repository = "https://git-repos.zavage.net/Zavage-Software/app_skellington" +documentation = "https://git-repos.zavage.net/Zavage-Software/app_skellington" keywords = [""] packages = [{ include = "app_skellington" }] @@ -22,7 +22,6 @@ include = [ [tool.poetry.dependencies] python = "^3.8" -# psycopg2-binary = "^2.9" [tool.poetry.group.dev.dependencies] black = "*" diff --git a/setup.py b/setup.py index 3e884b8..1b7b5dc 100755 --- a/setup.py +++ b/setup.py @@ -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-repos.zavage.net/Mirror/app_skellington", license="MIT", python_requires=">=3", classifiers=[ From 321f50b54202c2ce703e6d54e5da59d8ff1bcd2f Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Fri, 15 Nov 2024 20:10:05 -0700 Subject: [PATCH 04/19] doc: updating url to project page # Conflicts: # pyproject.toml # setup.py --- pyproject.toml | 78 ++++++++++++++++++++++------------------------ pyproject.toml.old | 48 ++++++++++++++++++++++++++++ setup.py | 66 --------------------------------------- 3 files changed, 85 insertions(+), 107 deletions(-) create mode 100644 pyproject.toml.old delete mode 100755 setup.py diff --git a/pyproject.toml b/pyproject.toml index 56d01b0..2667616 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,48 +1,44 @@ -[tool.poetry] +[build-system] +requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"] +build-backend = "setuptools.build_meta" + +[project] name = "app_skellington" -version = "0.1.0" -description = "app_skellington CLI framework" -authors = [ - "Mathew Guest ", -] -license = "MIT" +dynamic = ["version"] +license = {file = "LICENSE.txt"} readme = "README.md" -homepage = "https://zavage-software.com" +description = "app_skellington CLI framework" +requires-python = ">=3.8" +dependencies = [ + "appdirs", + "configobj", + "colorlog" +] +authors = [ + {name = "Mathew Guest", email = "mat@zavage.net"} +] +keywords = ["cli", "logging", "application"] +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent" +] + + +[project.urls] +homepage = "https://zavage-software.com/portfolio/app_skellington" repository = "https://git-repos.zavage.net/Zavage-Software/app_skellington" documentation = "https://git-repos.zavage.net/Zavage-Software/app_skellington" -keywords = [""] -packages = [{ include = "app_skellington" }] -include = [ - "README.md", + +[project.optional-dependencies] +dev = [ + "black", + "pre-commit", + "isort", + "flake8" ] -# [tool.poetry.scripts] - - -[tool.poetry.dependencies] -python = "^3.8" - -[tool.poetry.group.dev.dependencies] -black = "*" -pre-commit = "*" -isort = "*" -flake8 = "*" -#pytest = "^7.2" -#Sphinx = "^5.3.0" -#sphinx-rtd-theme = "^1.3.0" - -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" - -[tool.black] -line-length = 120 -target-version = ['py38'] - -[tool.isort] -multi_line_output = 3 -combine_as_imports = true -include_trailing_comma = true -force_grid_wrap = 3 -ensure_newline_before_comments = true +[tool.setuptools_scm] +version_scheme = "guess-next-dev" +local_scheme = "node-and-date" \ No newline at end of file diff --git a/pyproject.toml.old b/pyproject.toml.old new file mode 100644 index 0000000..56d01b0 --- /dev/null +++ b/pyproject.toml.old @@ -0,0 +1,48 @@ +[tool.poetry] +name = "app_skellington" +version = "0.1.0" +description = "app_skellington CLI framework" +authors = [ + "Mathew Guest ", +] +license = "MIT" +readme = "README.md" +homepage = "https://zavage-software.com" +repository = "https://git-repos.zavage.net/Zavage-Software/app_skellington" +documentation = "https://git-repos.zavage.net/Zavage-Software/app_skellington" +keywords = [""] + +packages = [{ include = "app_skellington" }] +include = [ + "README.md", +] + +# [tool.poetry.scripts] + + +[tool.poetry.dependencies] +python = "^3.8" + +[tool.poetry.group.dev.dependencies] +black = "*" +pre-commit = "*" +isort = "*" +flake8 = "*" +#pytest = "^7.2" +#Sphinx = "^5.3.0" +#sphinx-rtd-theme = "^1.3.0" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.black] +line-length = 120 +target-version = ['py38'] + +[tool.isort] +multi_line_output = 3 +combine_as_imports = true +include_trailing_comma = true +force_grid_wrap = 3 +ensure_newline_before_comments = true diff --git a/setup.py b/setup.py deleted file mode 100755 index 1b7b5dc..0000000 --- a/setup.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python -# -# Usage: -# -# First, enable the python environment you want to install to, or if installing -# system-wide then ensure you're logged in with sufficient permissions -# (admin or root to install to system directories) -# -# installation: -# -# $ ./setup.py install -# -# de-installation: -# -# $ pip uninstall app_skellington - - -import os - -from setuptools import setup - -__project__ = "app_skellington" -__version__ = "0.1.1" -__description__ = "A high-powered command line menu framework." - -long_description = __description__ -readme_filepath = os.path.join(os.path.abspath(os.path.dirname(__file__)), "README.md") -with open(readme_filepath, encoding="utf-8") as fp: - long_description = fp.read() - -setup( - name=__project__, - version=__version__, - description="A high-powered command line menu framework.", - long_description=long_description, - author="Mathew Guest", - author_email="mat@zavage.net", - url="https://git-repos.zavage.net/Mirror/app_skellington", - license="MIT", - python_requires=">=3", - classifiers=[ - "Development Status :: 3 - Alpha", - "Environment :: Console", - "Framework :: Pytest", - "Intended Audience :: Developers", - "Intended Audience :: System Administrators", - "License :: OSI Approved :: MIT License", - "Natural Language :: English", - "Operating System :: MacOS", - "Operating System :: Microsoft", - "Operating System :: Microsoft :: Windows", - "Operating System :: OS Independent", - "Operating System :: POSIX", - "Operating System :: POSIX :: Linux", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities", - ], - # Third-party dependencies; will be automatically installed - install_requires=( - "appdirs", - "configobj", - "colorlog", - ), - # Local packages to be installed (our packages) - packages=("app_skellington",), -) From 67a8e6e9455d0cb53377555b99df4a793efd9a6b Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sat, 16 Nov 2024 00:24:09 -0700 Subject: [PATCH 05/19] build: update pyproject.toml to conform to PEP 621 --- README.md | 45 ++++-- poetry.lock | 371 ------------------------------------------------- pyproject.toml | 2 +- 3 files changed, 37 insertions(+), 381 deletions(-) delete mode 100644 poetry.lock diff --git a/README.md b/README.md index c39f85b..e6c55f8 100644 --- a/README.md +++ b/README.md @@ -66,25 +66,49 @@ Tests are a WIP. Recommendation is to run 'pytest' in the 'tests' directory. # Development +I recommend pyenv to install a reliable, controlled python of preferred version locally. + +``` +curl https://pyenv.run | bash + +# Add to .bashrc or similar for different shells: +tee -a "$HOME"/.profile <<'EOF' + +export PYENV_ROOT="$HOME/.pyenv" +[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH" +eval "$(pyenv init -)" + +EOF +``` + * reference https://github.com/pyenv/pyenv + Clone the repo: ```commandline git clone https://git-mirror.zavage.net/zavage-software/app_skellington.git ``` -Verify your desired python environment. - -Poetry install to install dependencies and the program in your desired python environment -```commandline -poetry install -# verify no errors -``` - Install pre-commit hooks: ```commandline pre-commit install ``` -Begin development. +Build: +``` +python -m build +``` + +Install: + +``` +pip install . +``` + + + +# Version + +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. # License @@ -99,4 +123,7 @@ MIT no attribution required - https://opensource.org/license/mit-0 * Project page: https://zavage-software.com/portfolio/app_skellington * Please report bugs, improvements, or feedback! * Contact: mathew@zavage.net + + * Packing and distribution conforms to PEP 621 https://peps.python.org/pep-0621/ + * Reference https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/ diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index bbb5037..0000000 --- a/poetry.lock +++ /dev/null @@ -1,371 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. - -[[package]] -name = "black" -version = "24.4.2" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-24.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce"}, - {file = "black-24.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021"}, - {file = "black-24.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063"}, - {file = "black-24.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96"}, - {file = "black-24.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474"}, - {file = "black-24.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c"}, - {file = "black-24.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb"}, - {file = "black-24.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1"}, - {file = "black-24.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d"}, - {file = "black-24.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04"}, - {file = "black-24.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc"}, - {file = "black-24.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0"}, - {file = "black-24.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7"}, - {file = "black-24.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94"}, - {file = "black-24.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8"}, - {file = "black-24.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c"}, - {file = "black-24.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1"}, - {file = "black-24.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741"}, - {file = "black-24.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"}, - {file = "black-24.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7"}, - {file = "black-24.4.2-py3-none-any.whl", hash = "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c"}, - {file = "black-24.4.2.tar.gz", hash = "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - -[[package]] -name = "cfgv" -version = "3.4.0" -description = "Validate configuration and produce human readable error messages." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, - {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, -] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "distlib" -version = "0.3.8" -description = "Distribution utilities" -optional = false -python-versions = "*" -files = [ - {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, - {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, -] - -[[package]] -name = "filelock" -version = "3.15.4" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.8" -files = [ - {file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"}, - {file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] -typing = ["typing-extensions (>=4.8)"] - -[[package]] -name = "flake8" -version = "5.0.4" -description = "the modular source code checker: pep8 pyflakes and co" -optional = false -python-versions = ">=3.6.1" -files = [ - {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, - {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.9.0,<2.10.0" -pyflakes = ">=2.5.0,<2.6.0" - -[[package]] -name = "identify" -version = "2.6.0" -description = "File identification library for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"}, - {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"}, -] - -[package.extras] -license = ["ukkonen"] - -[[package]] -name = "isort" -version = "5.13.2" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, - {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, -] - -[package.extras] -colors = ["colorama (>=0.4.6)"] - -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "nodeenv" -version = "1.9.1" -description = "Node.js virtual environment builder" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, - {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "platformdirs" -version = "4.2.2" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] - -[[package]] -name = "pre-commit" -version = "3.5.0" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"}, - {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"}, -] - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -virtualenv = ">=20.10.0" - -[[package]] -name = "pycodestyle" -version = "2.9.1" -description = "Python style guide checker" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, - {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, -] - -[[package]] -name = "pyflakes" -version = "2.5.0" -description = "passive checker of Python programs" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, - {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.1" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, -] - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "virtualenv" -version = "20.26.3" -description = "Virtual Python Environment builder" -optional = false -python-versions = ">=3.7" -files = [ - {file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"}, - {file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"}, -] - -[package.dependencies] -distlib = ">=0.3.7,<1" -filelock = ">=3.12.2,<4" -platformdirs = ">=3.9.1,<5" - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] - -[metadata] -lock-version = "2.0" -python-versions = "^3.8" -content-hash = "c20dac4ba2095b38a3009c1520b6cd1e9865cc50dff8559ddd767403898406c6" diff --git a/pyproject.toml b/pyproject.toml index 2667616..0a47964 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,4 +41,4 @@ dev = [ [tool.setuptools_scm] version_scheme = "guess-next-dev" -local_scheme = "node-and-date" \ No newline at end of file +local_scheme = "node-and-date" From 82543ce157b97990a3e7d9dc582d55c024d9d67e Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sat, 16 Nov 2024 00:37:19 -0700 Subject: [PATCH 06/19] build: removed old pyproject.toml based on poetry --- pyproject.toml.old | 48 ---------------------------------------------- 1 file changed, 48 deletions(-) delete mode 100644 pyproject.toml.old diff --git a/pyproject.toml.old b/pyproject.toml.old deleted file mode 100644 index 56d01b0..0000000 --- a/pyproject.toml.old +++ /dev/null @@ -1,48 +0,0 @@ -[tool.poetry] -name = "app_skellington" -version = "0.1.0" -description = "app_skellington CLI framework" -authors = [ - "Mathew Guest ", -] -license = "MIT" -readme = "README.md" -homepage = "https://zavage-software.com" -repository = "https://git-repos.zavage.net/Zavage-Software/app_skellington" -documentation = "https://git-repos.zavage.net/Zavage-Software/app_skellington" -keywords = [""] - -packages = [{ include = "app_skellington" }] -include = [ - "README.md", -] - -# [tool.poetry.scripts] - - -[tool.poetry.dependencies] -python = "^3.8" - -[tool.poetry.group.dev.dependencies] -black = "*" -pre-commit = "*" -isort = "*" -flake8 = "*" -#pytest = "^7.2" -#Sphinx = "^5.3.0" -#sphinx-rtd-theme = "^1.3.0" - -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" - -[tool.black] -line-length = 120 -target-version = ['py38'] - -[tool.isort] -multi_line_output = 3 -combine_as_imports = true -include_trailing_comma = true -force_grid_wrap = 3 -ensure_newline_before_comments = true From 25ded9e2b351032644c60a19a091d31acec427fd Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sat, 16 Nov 2024 00:57:00 -0700 Subject: [PATCH 07/19] style: black and isort --- README.md | 12 ++++++-- app_skellington/_bootstrap.py | 4 ++- app_skellington/app_container.py | 19 ++++++------ app_skellington/cfg.py | 40 ++++++++++++++++++------ app_skellington/cli.py | 52 ++++++++++++++++++++++++-------- app_skellington/log.py | 30 ++++++++++++++---- tests/cfg/test_cfg.py | 20 +++++++++--- 7 files changed, 130 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index e6c55f8..0c84492 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,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 # PyPi Hosted Link @@ -103,6 +103,13 @@ Install: pip install . ``` +Formatting and Linters: +``` +black app_skellington +isort app_skellington +flake8 app_skellington +``` + # Version @@ -123,7 +130,6 @@ MIT no attribution required - https://opensource.org/license/mit-0 * Project page: https://zavage-software.com/portfolio/app_skellington * Please report bugs, improvements, or feedback! * Contact: mathew@zavage.net - + * Packing and distribution conforms to PEP 621 https://peps.python.org/pep-0621/ * Reference https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/ - diff --git a/app_skellington/_bootstrap.py b/app_skellington/_bootstrap.py index 9fcc6f7..2470f46 100644 --- a/app_skellington/_bootstrap.py +++ b/app_skellington/_bootstrap.py @@ -39,7 +39,9 @@ if os.environ.get("APPSKELLINGTON_DEBUG", None): handler = logging.StreamHandler() handler.setFormatter(fmt) _bootstrap_logger.addHandler(handler) - _bootstrap_logger.debug("log - APPSKELLINGTON_DEBUG set in environment: Enabling verbose logging.") + _bootstrap_logger.debug( + "log - APPSKELLINGTON_DEBUG set in environment: Enabling verbose logging." + ) # Logging is by default off, excepting CRITICAL else: diff --git a/app_skellington/app_container.py b/app_skellington/app_container.py index e20d3d8..237a7b9 100644 --- a/app_skellington/app_container.py +++ b/app_skellington/app_container.py @@ -7,12 +7,7 @@ import sys import appdirs -from . import ( - _util, - cfg, - cli, - log, -) +from . import _util, cfg, cli, log # Application scaffolding: from ._bootstrap import _bootstrap_logger @@ -47,7 +42,9 @@ class ApplicationContainer: directories. """ - def __init__(self, configspec_filepath=None, configini_filepath=None, *args, **kwargs): + def __init__( + self, configspec_filepath=None, configini_filepath=None, *args, **kwargs + ): self.appname = kwargs.get("appname") or DEFAULT_APP_NAME self.appauthor = kwargs.get("appauthor") or DEFAULT_APP_AUTHOR @@ -100,7 +97,9 @@ class ApplicationContainer: app['datalayer'] => returns the made-up "datalayer" service. """ try: - service_factory = self._dependencies[service_name] # Retrieve factory function + service_factory = self._dependencies[ + service_name + ] # Retrieve factory function return service_factory() # Call factory() to return instance of service except KeyError as ex: msg = "failed to inject service: {}".format(service_name) @@ -160,7 +159,9 @@ class ApplicationContainer: """ sig = inspect.signature(constructor.__init__) params = sig.parameters - params = [params[paramname].name for paramname in params] # Convert Param() type => str + params = [ + params[paramname].name for paramname in params + ] # Convert Param() type => str cls_dependencies = params[1:] # Skip 'self' parameter on class methods. return functools.partial(self._construct_model, constructor, *cls_dependencies) diff --git a/app_skellington/cfg.py b/app_skellington/cfg.py index ac9baf7..ea112fd 100644 --- a/app_skellington/cfg.py +++ b/app_skellington/cfg.py @@ -31,7 +31,9 @@ class Config: "allow_options_beyond_spec": True, } - def __init__(self, configspec_filepath=None, configini_filepath=None, capabilities=None): + def __init__( + self, configspec_filepath=None, configini_filepath=None, capabilities=None + ): self._config_obj = None # must be type configobj.ConfigObj() self._configini_data = None self._configini_filepath = None @@ -93,11 +95,15 @@ class Config: self._configspec_filepath = filepath self._configspec_data = data self._has_changed_internally = True - _bootstrap_logger.debug("cfg - Set configspec and read contents: %s", filepath) + _bootstrap_logger.debug( + "cfg - Set configspec and read contents: %s", filepath + ) self.load_config() return except OSError as ex: - _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") self.load_config() @@ -187,12 +193,16 @@ class Config: # raise_errors ) _bootstrap_logger.debug( - "cfg - Parsed configuration. config.spec = %s, config.ini = %s", config_spec, config_ini + "cfg - Parsed configuration. config.spec = %s, config.ini = %s", + config_spec, + config_ini, ) return True except configobj.ParseError as ex: - msg = "cfg - Failed to load config: error in config.spec configuration: {}".format(config_filepath) + msg = "cfg - Failed to load config: error in config.spec configuration: {}".format( + config_filepath + ) _bootstrap_logger.error(msg) return False except OSError as ex: @@ -217,7 +227,9 @@ class Config: self._config_obj, configobj.ConfigObj ), "expecting configobj.ConfigObj, received %s" % type(self._config_obj) # NOTE(MG) copy arg below instructs configobj to use defaults from spec file - test_results = self._config_obj.validate(val, copy=True, preserve_errors=True) + test_results = self._config_obj.validate( + val, copy=True, preserve_errors=True + ) if test_results is True: _bootstrap_logger.info( "cfg- Successfully validated configuration against spec. input = %s, validation spec = %s", @@ -227,19 +239,27 @@ class Config: return True elif test_results is False: - _bootstrap_logger.debug("cfg - Potentially discovered invalid config.spec") + _bootstrap_logger.debug( + "cfg - Potentially discovered invalid config.spec" + ) else: self._validate_parse_errors(test_results) return False except ValueError as ex: - _bootstrap_logger.error("cfg - Failed while validating config against spec. ") + _bootstrap_logger.error( + "cfg - Failed while validating config against spec. " + ) return False def _validate_parse_errors(self, test_results): _bootstrap_logger.critical("cfg - Config file failed validation.") - for section_list, key, rslt in configobj.flatten_errors(self._config_obj, test_results): - _bootstrap_logger.critical("cfg - Config error info: %s %s %s", section_list, key, rslt) + for section_list, key, rslt in configobj.flatten_errors( + self._config_obj, test_results + ): + _bootstrap_logger.critical( + "cfg - Config error info: %s %s %s", section_list, key, rslt + ) if key is not None: _bootstrap_logger.critical( "cfg - Config failed validation: [%s].%s appears invalid. msg = %s", diff --git a/app_skellington/cli.py b/app_skellington/cli.py index b6b8680..2c791ca 100644 --- a/app_skellington/cli.py +++ b/app_skellington/cli.py @@ -75,7 +75,9 @@ class CommandTree: """ Adds an argument to the root parser. """ - _bootstrap_logger.info("adding argument to root parser: %s and %s", args, kwargs) + _bootstrap_logger.info( + "adding argument to root parser: %s and %s", args, kwargs + ) self.root_parser.add_argument(*args, **kwargs) def init_submenu(self, param_name, is_required=False): @@ -89,7 +91,9 @@ class CommandTree: func_args = {"dest": param_name, "metavar": param_name, "required": is_required} if sys.version_info.major == 3 and sys.version_info.minor < 7: 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"] # END fix for Python<3.7 @@ -100,13 +104,17 @@ class CommandTree: submenu.submenu_path = "" submenu.var_name = param_name - _bootstrap_logger.info("Initialized root-level submenu: Parameter = '%s'", param_name) + _bootstrap_logger.info( + "Initialized root-level submenu: Parameter = '%s'", param_name + ) self.entries[param_name] = submenu self.submenu_param = param_name return submenu - def register_command(self, func, cmd_name=None, func_signature=None, docstring=None): + def register_command( + self, func, cmd_name=None, func_signature=None, docstring=None + ): """ When no submenu functionality is desired, this links a single command into underlying argparse options. @@ -154,7 +162,9 @@ class CommandTree: helptext = "default provided" else: helptext = "default = '{}'".format(param.default) - self.root_parser.add_argument(key, help=helptext, nargs="?", default=param.default) + self.root_parser.add_argument( + key, help=helptext, nargs="?", default=param.default + ) else: helptext = "required" self.root_parser.add_argument(key, help=helptext) @@ -230,16 +240,22 @@ class CommandTree: # the CommandTree with no SubMenu (submenu will be disabled # in this case): if self._cmd_tree_is_single_command: - assert self._cmd_tree_is_single_command is True, "corrupt data structure in CommandMenu" + assert ( + self._cmd_tree_is_single_command is True + ), "corrupt data structure in CommandMenu" assert self._entries is None, "corrupt data structure in CommandMenu" - assert isinstance(self._single_command, CommandEntry), "corrupt data structure in CommandMenu" + assert isinstance( + self._single_command, CommandEntry + ), "corrupt data structure in CommandMenu" return self._single_command # There is at least one submenu we need to go down: else: assert self._single_command is None, "corrupt data structure in CommandMenu" - assert self._cmd_tree_is_single_command == False, "corrupt data structure in CommandMenu" + assert ( + self._cmd_tree_is_single_command == False + ), "corrupt data structure in CommandMenu" # Key or variable name used by argparse to store the submenu options argparse_param = self.submenu_param # e.g.: submenu_root @@ -251,10 +267,14 @@ class CommandTree: input("") val = args.get(argparse_param) - _bootstrap_logger.debug("cli - argparse command is '{}' = {}".format(argparse_param, val)) + _bootstrap_logger.debug( + "cli - argparse command is '{}' = {}".format(argparse_param, val) + ) lookup = submenu.entries.get(val) - _bootstrap_logger.debug("cli - lookup, entries[{}] = {}".format(val, lookup)) + _bootstrap_logger.debug( + "cli - lookup, entries[{}] = {}".format(val, lookup) + ) # pop value del args[argparse_param] @@ -297,7 +317,9 @@ class SubMenu: self.entries = {} - def register_command(self, func, cmd_name=None, func_signature=None, docstring=None): + def register_command( + self, func, cmd_name=None, func_signature=None, docstring=None + ): """ Registers a command as an entry in this submenu. Provided function is converted into argparse arguments and made available to the user. @@ -371,7 +393,9 @@ class SubMenu: helptext = "default provided" else: helptext = "default = '{}'".format(param.default) - child_node.add_argument(key, help=helptext, nargs="?", default=param.default) + child_node.add_argument( + key, help=helptext, nargs="?", default=param.default + ) else: helptext = "required" child_node.add_argument(key, help=helptext) @@ -422,7 +446,9 @@ class SubMenu: func_args = {"dest": var_name, "metavar": var_name, "required": is_required} if sys.version_info.major == 3 and sys.version_info.minor < 7: 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"] # END fix for Python<3.7 diff --git a/app_skellington/log.py b/app_skellington/log.py index a134285..761ffef 100644 --- a/app_skellington/log.py +++ b/app_skellington/log.py @@ -16,7 +16,13 @@ DEFAULT_LOG_SETTINGS = { "format": "%(white)s%(name)7s%(reset)s|%(log_color)s%(message)s", } }, - "handlers": {"stderr": {"class": "logging.StreamHandler", "level": "debug", "formatter": "colored"}}, + "handlers": { + "stderr": { + "class": "logging.StreamHandler", + "level": "debug", + "formatter": "colored", + } + }, "loggers": { "root": { "handlers": [ @@ -65,7 +71,9 @@ class LoggingLayer: noise for typical operation. """ if config_dict is None: - _bootstrap_logger.debug("log - No application logging configuration provided. Using default") + _bootstrap_logger.debug( + "log - No application logging configuration provided. Using default" + ) config_dict = DEFAULT_LOG_SETTINGS self.transform_config(config_dict) @@ -108,19 +116,26 @@ class LoggingLayer: config_dict["loggers"][""] = config_dict["loggers"]["root"] del config_dict["loggers"]["root"] except Exception as ex: - _bootstrap_logger.warn("was not able to find and patch root logger configuration from arguments") + _bootstrap_logger.warn( + "was not able to find and patch root logger configuration from arguments" + ) # Evaluate the full filepath of the file handler if "file" not in config_dict["handlers"]: return - if os.path.abspath(config_dict["handlers"]["file"]["filename"]) == config_dict["handlers"]["file"]["filename"]: + if ( + os.path.abspath(config_dict["handlers"]["file"]["filename"]) + == config_dict["handlers"]["file"]["filename"] + ): # Path is already absolute pass else: dirname = appdirs.user_log_dir(self.appname, self.appauthor) _util.ensure_dir_exists(dirname) - log_filepath = os.path.join(dirname, config_dict["handlers"]["file"]["filename"]) + log_filepath = os.path.join( + dirname, config_dict["handlers"]["file"]["filename"] + ) config_dict["handlers"]["file"]["filename"] = log_filepath def _add_own_logconfig(self, config_dict): @@ -133,7 +148,10 @@ class LoggingLayer: # See _bootstrap.py if os.environ.get("APPSKELLINGTON_DEBUG", None): if _logger_name not in config_dict["loggers"]: - config_dict["loggers"][_logger_name] = {"level": "debug", "propagate": "false"} + config_dict["loggers"][_logger_name] = { + "level": "debug", + "propagate": "false", + } else: config_dict["loggers"][_logger_name]["level"] = "debug" diff --git a/tests/cfg/test_cfg.py b/tests/cfg/test_cfg.py index 459dfe8..219033f 100644 --- a/tests/cfg/test_cfg.py +++ b/tests/cfg/test_cfg.py @@ -32,12 +32,18 @@ def sample_invalid_configspec_filepath(): class TestConfig_e2e: def test_allows_reading_ini_and_no_spec(self, sample_configini_filepath): cfg = Config(configini_filepath=sample_configini_filepath) - assert cfg["root_option"] == "root_option_val", "expecting default from config.spec (didnt get)" - assert cfg["app"]["sub_option"] == "sub_option_val", "expecting default for sub option" + assert ( + cfg["root_option"] == "root_option_val" + ), "expecting default from config.spec (didnt get)" + assert ( + cfg["app"]["sub_option"] == "sub_option_val" + ), "expecting default for sub option" def test_allows_reading_spec_and_no_ini(self, sample_configspec_filepath): cfg = Config(configspec_filepath=sample_configspec_filepath) - assert cfg["root_option"] == "def_string", "expecting default from config.spec (didnt get)" + assert ( + cfg["root_option"] == "def_string" + ), "expecting default from config.spec (didnt get)" # NOTE(MG) Changed the functionality to not do it this way. # def test_constructor_fails_with_invalid_spec( @@ -65,7 +71,9 @@ class TestConfig_e2e: assert cfg["root_option"] == "newval" cfg["app"]["sub_option"] = "another_new_val" - assert cfg["app"]["sub_option"] == "another_new_val", "expecting default for sub option" + assert ( + cfg["app"]["sub_option"] == "another_new_val" + ), "expecting default for sub option" def test_can_set_option_without_config(self): cfg = Config() @@ -78,5 +86,7 @@ class TestConfig_e2e: def test_uses_spec_as_defaults(self, sample_configspec_filepath): cfg = Config(configspec_filepath=sample_configspec_filepath) - assert cfg["root_option"] == "def_string", "expecting default from config.spec (didnt get)" + assert ( + cfg["root_option"] == "def_string" + ), "expecting default from config.spec (didnt get)" assert cfg["app"]["sub_option"] == "def_sub", "expecting default for sub option" From d76932bcb9b3ea54d12d67c9c7f1ce73e97968b0 Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sat, 16 Nov 2024 01:10:34 -0700 Subject: [PATCH 08/19] build: removing poetry from pre-commit --- .pre-commit-config.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 58734b9..a6b8bb8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,9 +29,3 @@ repos: hooks: - id: black language_version: python3.8 - -# Poetry -- repo: https://github.com/python-poetry/poetry - rev: 1.8.2 - hooks: - - id: poetry-lock From ac4b765099d5ea70ee1ee0e15787fda408cebdbb Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sat, 16 Nov 2024 01:54:04 -0700 Subject: [PATCH 09/19] build: fixed flake8 warnings --- app_skellington/__init__.py | 24 ++++++++++++++++++------ app_skellington/_util.py | 8 +++----- app_skellington/app_container.py | 9 +++------ app_skellington/cfg.py | 28 +++++++++++----------------- app_skellington/cli.py | 21 +++++++++------------ app_skellington/log.py | 5 ++--- 6 files changed, 46 insertions(+), 49 deletions(-) diff --git a/app_skellington/__init__.py b/app_skellington/__init__.py index 8c1461f..1f8ce08 100644 --- a/app_skellington/__init__.py +++ b/app_skellington/__init__.py @@ -1,7 +1,19 @@ -import logging -import sys +# flake8: noqa -from .app_container import * -from .cfg import * -from .cli import * -from .log import * +from .app_container import ( + DEFAULT_APP_AUTHOR, + DEFAULT_APP_NAME, + ApplicationContainer, + ApplicationContext, + NoCommandSpecified, + ServiceNotFound, +) +from .cfg import Config, EnvironmentVariables +from .cli import ( + EXPLICIT_FAIL_ON_UNKNOWN_ARGS, + CommandEntry, + CommandTree, + HelpGenerator, + SubMenu, +) +from .log import LoggingLayer diff --git a/app_skellington/_util.py b/app_skellington/_util.py index 433b9da..84f5f8e 100644 --- a/app_skellington/_util.py +++ b/app_skellington/_util.py @@ -4,8 +4,6 @@ import inspect import os import sys -from . import _util - def eprint(*args, **kwargs): """ @@ -30,9 +28,9 @@ def does_file_exist(filepath): instant in execution. """ try: - fp = open(filepath, "r") + open(filepath, "r") return True - except FileNotFoundError as ex: + except FileNotFoundError: return False @@ -88,7 +86,7 @@ def get_asset(module, filepath): root = os.path.realpath(root) root = os.path.dirname(os.path.abspath(root)) - except Exception as ex: + except Exception: raise path = os.path.join(root, filepath) diff --git a/app_skellington/app_container.py b/app_skellington/app_container.py index 237a7b9..9911d85 100644 --- a/app_skellington/app_container.py +++ b/app_skellington/app_container.py @@ -1,9 +1,6 @@ -import collections import functools import inspect -import logging import os -import sys import appdirs @@ -86,7 +83,7 @@ class ApplicationContainer: """ try: del self._dependencies[service_name] - except KeyError as ex: + except KeyError: pass def __getitem__(self, service_name): @@ -101,7 +98,7 @@ class ApplicationContainer: service_name ] # Retrieve factory function return service_factory() # Call factory() to return instance of service - except KeyError as ex: + except KeyError: msg = "failed to inject service: {}".format(service_name) _bootstrap_logger.critical(msg) raise ServiceNotFound @@ -180,7 +177,7 @@ class ApplicationContainer: return False try: self.cli.run_command() - except NoCommandSpecified as ex: + except NoCommandSpecified: print("Failure: No command specified.") def interactive_shell(self): diff --git a/app_skellington/cfg.py b/app_skellington/cfg.py index ea112fd..13b76dd 100644 --- a/app_skellington/cfg.py +++ b/app_skellington/cfg.py @@ -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,7 +95,7 @@ class Config: ) self.load_config() return - except OSError as ex: + except OSError: _bootstrap_logger.critical( "cfg - Failed to find config.spec: file not found (%s)", filepath ) @@ -112,7 +107,7 @@ class Config: try: has_item = key in self._config_obj return has_item - except KeyError as ex: + except KeyError: pass def __delitem__(self, key): @@ -122,7 +117,7 @@ class Config: """ try: del self[key] - except KeyError as ex: + except KeyError: pass def __getitem__(self, key): @@ -136,7 +131,7 @@ class Config: else: # return self._config_obj[key].dict() return self._config_obj[key] - except KeyError as ex: + except KeyError: raise def __setitem__(self, key, value): @@ -156,7 +151,7 @@ class Config: try: v = self.__getitem__(key) return v - except KeyError as ex: + except KeyError: return default def load_config(self, configspec_filepath=None, configini_filepath=None): @@ -199,18 +194,17 @@ class Config: ) return True - except configobj.ParseError as ex: - msg = "cfg - Failed to load config: error in config.spec configuration: {}".format( - config_filepath - ) + except configobj.ParseError: + msg = f"cfg - Failed to load config: error in config.spec configuration: {self.configspec_filepath}" _bootstrap_logger.error(msg) return False - except OSError as ex: + except OSError: msg = "cfg - Failed to load config: config.spec file not found." _bootstrap_logger.error(msg) return False except Exception as ex: - print(ex) + _bootstrap_logger.error(ex) + return False def _validate_config_against_spec(self): config_spec = self.configspec_filepath @@ -246,7 +240,7 @@ class Config: else: self._validate_parse_errors(test_results) return False - except ValueError as ex: + except ValueError: _bootstrap_logger.error( "cfg - Failed while validating config against spec. " ) diff --git a/app_skellington/cli.py b/app_skellington/cli.py index 2c791ca..79cc280 100644 --- a/app_skellington/cli.py +++ b/app_skellington/cli.py @@ -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): """ @@ -144,13 +141,13 @@ class CommandTree: # help is displayed next to the command in the submenu enumeration or # list of commands: - help_text = HelpGenerator.generate_help_from_sig(docstring) + HelpGenerator.generate_help_from_sig(docstring) # description is displayed when querying help for the specific command: - description_text = HelpGenerator.generate_description_from_sig(docstring) + HelpGenerator.generate_description_from_sig(docstring) # end copy-paste from SubMenu.register_command - # begin copy-paste then editted from SubMenu.register_command - # For each paramter in the function create an argparse argument in + # begin copy-paste then edited from SubMenu.register_command + # For each parameter in the function create an argparse argument in # the child ArgumentParser created for this menu entry: for key in params: if key == "self": @@ -210,7 +207,7 @@ class CommandTree: return pargs, unk, True # Note: SystemExit is raised when '-h' argument is supplied. - except SystemExit as ex: + except SystemExit: return None, None, False def run_command(self, args=None): @@ -254,7 +251,7 @@ class CommandTree: assert self._single_command is None, "corrupt data structure in CommandMenu" assert ( - self._cmd_tree_is_single_command == False + self._cmd_tree_is_single_command is False ), "corrupt data structure in CommandMenu" # Key or variable name used by argparse to store the submenu options @@ -510,7 +507,7 @@ class HelpGenerator: The 'help' text is displayed next to the command when enumerating the submenu commands. """ - if doctext == None: + if doctext is None: return doctext regex = "(.*?)[.?!]" match = re.match(regex, doctext, re.MULTILINE | re.DOTALL) @@ -524,7 +521,7 @@ class HelpGenerator: The 'description' paragraph is provided when the user requests help on a specific command. """ - if doctext == None: + if doctext is None: return doctext regex = "(.*?)[.?!]" match = re.match(regex, doctext, re.MULTILINE | re.DOTALL) diff --git a/app_skellington/log.py b/app_skellington/log.py index 761ffef..2ec2a7a 100644 --- a/app_skellington/log.py +++ b/app_skellington/log.py @@ -3,7 +3,6 @@ import logging.config import os import appdirs -import colorlog from . import _util from ._bootstrap import _bootstrap_logger, _logger_name @@ -115,7 +114,7 @@ class LoggingLayer: if config_dict["loggers"].get("root") is not None: config_dict["loggers"][""] = config_dict["loggers"]["root"] del config_dict["loggers"]["root"] - except Exception as ex: + except Exception: _bootstrap_logger.warn( "was not able to find and patch root logger configuration from arguments" ) @@ -169,7 +168,7 @@ class LoggingLayer: """ try: s = dict_[key] - except KeyError as ex: + except KeyError: raise if s == "critical": dict_[key] = logging.CRITICAL From 881a2db9dc11c0bc8ff957084d719cdbdca303a6 Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sat, 16 Nov 2024 02:06:00 -0700 Subject: [PATCH 10/19] doc: publish instructions --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 0c84492..7484335 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,15 @@ isort app_skellington flake8 app_skellington ``` +Publish: + +``` +# Create a tag with the desired version number: +git tag -a v0.2.0 -m "0.2.0 provides modern pyproject.toml build with setuptools, versioning, and publishing" +git push origin v0.2.0 +python -m build +twine upload dist/* +``` # Version From fb0ef3d8f6a5dc086d6d79f7d601f48492242ae3 Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sat, 16 Nov 2024 03:02:32 -0700 Subject: [PATCH 11/19] doc: more documentation on publishing --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7484335..6ad4fcb 100644 --- a/README.md +++ b/README.md @@ -113,12 +113,21 @@ flake8 app_skellington Publish: ``` -# Create a tag with the desired version number: +# Push latest commit, or on commit ready to publish: +git push + +# Create a tag with the desired version number and push: git tag -a v0.2.0 -m "0.2.0 provides modern pyproject.toml build with setuptools, versioning, and publishing" git push origin v0.2.0 + +# Build the wheel: python -m build + +# Publish to pypi: +twine check dist/* twine upload dist/* ``` + * Reference https://packaging.python.org/en/latest/overview/ # Version From adbae0074cae369a4a66f20d5d13c34827457fb4 Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sat, 16 Nov 2024 03:03:35 -0700 Subject: [PATCH 12/19] build: turning on flake8 pre-commit hook --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a6b8bb8..b668dc5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,10 +17,10 @@ repos: args: ["--profile", "black", "--filter-files"] # Flake8 -#- repo: https://github.com/pycqa/flake8 -# rev: '7.0.0' -# hooks: -# - id: flake8 +- repo: https://github.com/pycqa/flake8 + rev: '7.0.0' + hooks: + - id: flake8 # Black # Using this mirror lets us use mypyc-compiled black, which is about 2x faster From f0a4bdbcedb4aef3f3ea643354801267cb60e36c Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sat, 16 Nov 2024 03:16:04 -0700 Subject: [PATCH 13/19] doc: updated git url, now using gitea over gogs --- README.md | 2 +- app_skellington/cli.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6ad4fcb..cc8f507 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ EOF Clone the repo: ```commandline -git clone https://git-mirror.zavage.net/zavage-software/app_skellington.git +git clone https://git-repos.zavage.net/zavage-software/app_skellington.git ``` Install pre-commit hooks: diff --git a/app_skellington/cli.py b/app_skellington/cli.py index 79cc280..4f8e901 100644 --- a/app_skellington/cli.py +++ b/app_skellington/cli.py @@ -176,7 +176,7 @@ class CommandTree: registered_name = cmd_name _bootstrap_logger.info("registered command: %s", registered_name) - # end copy-paste then editted from SubMenu.register_command + # end copy-paste then edited from SubMenu.register_command self._cmd_tree_is_single_command = True self._single_command = cmd From 76477134988bbcb1e5c5099b6ac632653f572419 Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sat, 16 Nov 2024 04:04:56 -0700 Subject: [PATCH 14/19] build: removing dead code --- app_skellington/app_container.py | 3 --- app_skellington/cli.py | 24 ++++++++++-------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/app_skellington/app_container.py b/app_skellington/app_container.py index 9911d85..772d59e 100644 --- a/app_skellington/app_container.py +++ b/app_skellington/app_container.py @@ -180,9 +180,6 @@ class ApplicationContainer: except NoCommandSpecified: print("Failure: No command specified.") - def interactive_shell(self): - pass - def invoke_from_cli(self): self.invoke_command() diff --git a/app_skellington/cli.py b/app_skellington/cli.py index 4f8e901..30d7b1d 100644 --- a/app_skellington/cli.py +++ b/app_skellington/cli.py @@ -3,7 +3,7 @@ import inspect import re import sys -from . import app_container +from . import NoCommandSpecified, app_container from ._bootstrap import _bootstrap_logger # If explicit fail is enabled, any command with at least one unknown @@ -41,12 +41,12 @@ class CommandTree: ./scriptname --option="value" [submenu] [command] - is different than + is different from ./scriptname [submenu] [command] --option="value" in that option is being applied to the application in the first example and - applied to the refresh_datasets command (under the nhsn command group) in + applied to the command (under the submenu command group) in the second. In the same way the -h, --help options print different docs depending on where the help option was passed. """ @@ -82,17 +82,7 @@ class CommandTree: Creates a root-level submenu with no entries. SubMenu node is returned which can have submenus and commands attached to it. """ - # NOTE(MG) Fix for Python>=3.7, - # argparse.ArgumentParser added 'required' argument. - # Must also be written into SubMenu.create_submenu. func_args = {"dest": param_name, "metavar": param_name, "required": is_required} - if sys.version_info.major == 3 and sys.version_info.minor < 7: - if is_required: - _bootstrap_logger.warn( - "Unable to enforce required submenu: Requires >= Python 3.7" - ) - del func_args["required"] - # END fix for Python<3.7 # Creates an argument as a slot in the underlying argparse. subparsers = self.root_parser.add_subparsers(**func_args) @@ -211,6 +201,12 @@ class CommandTree: return None, None, False def run_command(self, args=None): + """ + Args: + args (list[str]): Direct from STDIN + Raises: + NoCommandSpecified for invalid command. + """ args, unk, success = self.parse(args) if not success: _bootstrap_logger.info("cli - SystemExit: Perhaps user invoked --help") @@ -226,7 +222,7 @@ class CommandTree: cmd = self._lookup_command(args) if cmd is None: _bootstrap_logger.critical("cli - Failed to find command.") - return False + raise NoCommandSpecified return self._invoke_command(cmd, args) From 55a97968060154bc68bc04f6055220e4db1172bd Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sat, 16 Nov 2024 22:05:18 -0700 Subject: [PATCH 15/19] doc: updating contact email --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cc8f507..9fa5625 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ eval "$(pyenv init -)" EOF ``` * reference https://github.com/pyenv/pyenv + * Use pyenv to install desired python version, and/or create any virtual environments you desire Clone the repo: ```commandline @@ -147,7 +148,7 @@ MIT no attribution required - https://opensource.org/license/mit-0 * Project page: https://zavage-software.com/portfolio/app_skellington * Please report bugs, improvements, or feedback! - * Contact: mathew@zavage.net + * Contact: mat@zavage.net * Packing and distribution conforms to PEP 621 https://peps.python.org/pep-0621/ * Reference https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/ From 470514ba4b0edef9b2280f8bbd65d0522e6632d2 Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Sun, 17 Nov 2024 04:50:45 -0700 Subject: [PATCH 16/19] build: adding _version.py, small build config change, and doc note --- README.md | 4 ++++ app_skellington/_version.py | 17 +++++++++++++++++ pyproject.toml | 3 ++- 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 app_skellington/_version.py diff --git a/README.md b/README.md index 9fa5625..a2079bb 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,10 @@ 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 MIT no attribution required - https://opensource.org/license/mit-0 diff --git a/app_skellington/_version.py b/app_skellington/_version.py new file mode 100644 index 0000000..607cd4a --- /dev/null +++ b/app_skellington/_version.py @@ -0,0 +1,17 @@ +# file generated by setuptools_scm +# don't change, don't track in version control +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.2.2" +__version_tuple__ = version_tuple = (0, 2, 2) diff --git a/pyproject.toml b/pyproject.toml index 0a47964..b9f2dd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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" From afd2b5eb4298e54133113f4859c70a31d291fd2c Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Tue, 19 Nov 2024 23:49:03 -0700 Subject: [PATCH 17/19] doc: gitea toc --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a2079bb..88d4632 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,10 @@ -app_skellington +--- +gitea: none +include_toc: true +--- + +**app_skellington** + =============== Application framework for Python, features include: From f0fb18da710df1dff7bbd47d115d9462e0f7e8a7 Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Tue, 19 Nov 2024 23:54:18 -0700 Subject: [PATCH 18/19] doc: pypi instructions --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 88d4632..7f874dc 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,6 @@ 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. - Simple to define services and automatic dependency injection based on name (with custom invocation as an option). \*WIP @@ -22,8 +20,19 @@ Principles: # PyPi Hosted Link +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 +``` + # Application Configuration Site configurations are supported through ConfigObj. There is a config.spec From b2e082b7c6b5698b03159c452f3c2a1bce079d06 Mon Sep 17 00:00:00 2001 From: Mathew Guest Date: Tue, 19 Nov 2024 23:59:42 -0700 Subject: [PATCH 19/19] doc: more cleanup and description, linking license --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7f874dc..83db7b2 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ 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 @@ -33,6 +33,11 @@ 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 @@ -77,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 @@ -157,6 +162,8 @@ You can view the current version number with the command: # License +See [license](LICENSE.txt) + MIT no attribution required - https://opensource.org/license/mit-0 * Allows commercial use.