doc: README and CLAUDE.md for the uv workflow; fix debug env var and platform claims

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
golem
2026-10-05 00:21:58 -06:00
co-authored by Claude Opus 5.5
parent ecbdef0bbe
commit 7d80557a3e
3 changed files with 59 additions and 76 deletions
+11 -10
View File
@@ -4,24 +4,25 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## What this is
`app_skellington` is a small Python library (published to PyPI) for building CLI applications. It has nothing runnable on its own. It glues together argparse-based multi-level command menus, name-based dependency injection, ConfigObj INI config with spec validation, and colorlog logging. It targets Python >=3.8 on Linux, Windows and Mac. Runtime deps are `appdirs`, `configobj` and `colorlog`.
`app_skellington` is a small Python library (published to PyPI) for building CLI applications. It has nothing runnable on its own. It glues together argparse-based multi-level command menus, name-based dependency injection, ConfigObj INI config with spec validation, and colorlog logging. It targets Python >=3.8. Only Linux is tested; Windows and macOS are goals. Runtime deps are `appdirs`, `configobj` and `colorlog`.
## Commands
```bash
pip install -e '.[dev]' pytest # dev extras = ruff, pre-commit; pytest is NOT in the extras
pytest tests # full suite from repo root (or `pytest .` from inside tests/)
pytest tests/cfg/test_cfg.py::TestConfig_e2e::test_uses_spec_as_defaults # single test
pytest tests -k "<keyword>"
uv sync # .venv with the package (editable) + dev group: ruff, pytest, pre-commit, pyyaml
uv run pytest # full suite (testpaths = tests)
uv run pytest tests/cfg/test_cfg.py::TestConfig_e2e::test_uses_spec_as_defaults # single test
uv run pytest -k "<keyword>"
uv run --python 3.8 pytest # any supported Python; uv.lock forks per version
ruff check --fix # lint + import sorting (config in pyproject.toml)
ruff format # formatter, line length 88
uv run ruff check --fix # lint + import sorting (config in pyproject.toml)
uv run ruff format # formatter, line length 88
python -m build # sdist + wheel into dist/
python -m setuptools_scm # print the version the build will get
uv build # sdist + wheel into dist/; the version shows in the file names
uv lock # after any dependency change; commit uv.lock
```
- **Versioning is tag-driven.** setuptools_scm uses `release-branch-semver` and derives the version from the latest `vX.Y.Z` git tag. It writes `app_skellington/_version.py` at build time. That file is tracked, but don't hand-edit it. `pip install -e .` also rewrites it, so `git restore` it rather than committing the churn. A release means tagging, then `python -m build`, then `twine upload dist/*`. The README covers the full publish steps.
- **Versioning is tag-driven.** setuptools_scm uses `release-branch-semver` and derives the version from the latest `vX.Y.Z` git tag. It generates `app_skellington/_version.py`, which is git-ignored, so never commit it. The release steps (tag on `main`, `uv build`, TestPyPI, verify, PyPI) are in the README's Publish section.
- **ruff** handles formatting (88 columns) and lint (`E`, `F`, `W`, `I`). E501 is ignored on purpose, since the formatter owns line length. Keep the `ruff==` pin in `pyproject.toml` equal to the `rev:` in `.pre-commit-config.yaml`.
- Tests cover only `cfg` (ConfigObj fixtures live in `tests/cfg/`) plus a CommandTree constructor smoke test. `tests/test_log.py` is empty.
+44 -62
View File
@@ -10,12 +10,12 @@ Application framework for Python, features include:
- Simple to define services and automatic dependency injection based on name (with custom invocation as an option). \*WIP
- INI-style config and and validation (provided through ConfigObj).
- Colored logging (provided through colorlog)
- Works on Linux, Windows, and Mac.
- Linux supported. Windows and macOS are goals, but untested.
Principles:
- Lend to creating beautiful, easy to read and understand code in the application.
- Minimize coupling of applications to this framework.
- Compatible with Linux, Windows, and Mac. Try to be compatible as possible otherwise.
- Aim for Linux, Windows and macOS. Only Linux is tested today; full multi-platform CI is a long-term goal.
- Try to be compatible with alternate Python runtimes such as PyPy and older python environments. \*WIP
# Python Package Index (PyPi) - Installation Instruction
@@ -70,7 +70,7 @@ argument.
# Debug - Turn on Logging
Set 'APPSKELLINGTON_ENABLE_LOGGING' environment variable to any value which turns
Set the 'APPSKELLINGTON_DEBUG' environment variable to any value to turn
on AppSkellington-level logging. For example,
APPSKELLINGTON_DEBUG=1 <executable>
@@ -82,83 +82,65 @@ or
# Tests
Tests are a WIP and not fully built out yet. Recommendation is to run 'pytest' in the 'tests' directory.
```
uv run pytest # full suite
uv run pytest tests/cfg/test_cfg.py::TestConfig_e2e::test_uses_spec_as_defaults
uv run pytest -k "<keyword>"
uv run --python 3.8 pytest # against another supported Python
```
# Development
I recommend pyenv to install a reliable, controlled python of preferred version locally.
Install [uv](https://docs.astral.sh/uv/). It manages Python versions and the
virtual environment, so you don't need pyenv or a hand-made venv.
```
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
* Use pyenv to install desired python version, and/or create any virtual environments you desire
Clone the repo:
```commandline
git clone https://git-repos.zavage.net/zavage-software/app_skellington.git
cd app_skellington
uv sync # creates .venv with the package (editable) + dev tools
uv run pre-commit install # ruff lint + format on every commit
```
Install pre-commit hooks:
```commandline
pre-commit install
Lint and format (ruff, line length 88):
```
uv run ruff check --fix
uv run ruff format
```
Build:
Build the sdist and wheel into `dist/`:
```
python -m build
uv build
```
Install:
```
pip install .
```
Formatting and Linters:
```
black app_skellington
isort app_skellington
flake8 app_skellington
```
Publish:
```
# 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/
Dependencies are locked in `uv.lock`. After editing dependencies in
`pyproject.toml`, run `uv lock` and commit the result.
# 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.
setuptools_scm derives the version from the latest `vX.Y.Z` git tag. Between
tags you get development versions like `0.3.0.dev4+g1a2b3c4`. The generated
`app_skellington/_version.py` is git-ignored.
You can view the current version number with the command:
uv build # the version appears in the dist/ file names
python -m setuptools_scm
# Publish
Publish only from a tagged commit on `main`, after CI is green, and only after
TestPyPI has been checked.
```
git switch main && git pull --ff-only
git tag -a v0.2.3 -m "0.2.3: <summary>"
git push origin v0.2.3
rm -rf dist && uv build
ls dist # must be exactly app_skellington-0.2.3.tar.gz and app_skellington-0.2.3-py3-none-any.whl
uv publish --publish-url https://test.pypi.org/legacy/ dist/* # TestPyPI first
scripts/verify_index_release.sh 0.2.3 # every supported Python
uv publish dist/* # then PyPI
scripts/verify_index_release.sh 0.2.3 https://pypi.org/simple/
```
* Reference https://packaging.python.org/en/latest/overview/
# License
+4 -4
View File
@@ -4,14 +4,14 @@ Contained is the early stages of unit testing for app_skellington framework.
Usage
-----
Run all tests (cwd is testing directory):
Run all tests (from the repo root):
pytest .
uv run pytest
Run test by keyword:
pytest -k "<test keyword>" .
uv run pytest -k "<test keyword>"
Run test by directory:
pytest <dirname>
uv run pytest tests/<dirname>