Skip to content

Added basic git pre-commit hook setup for auto-formatting #1405

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ $ pip freeze | grep pyperclip

If your versions are lower than the prerequisite versions, you should update.

If you do not already have Python installed on your machine, we recommend using [uv](https://github.com/astral-sh/uv)
If you do not already have Python installed on your machine, we recommend using [uv](https://github.com/astral-sh/uv)
for all of your Python needs because it is extremely fast, meets all Python installation and packaging needs, and works
on all platforms (Windows, Mac, and Linux). You can install `uv` using instructions at the link above.

Expand Down Expand Up @@ -221,7 +221,13 @@ To create a virtual environment and install everything needed for `cmd2` develop
from a GitHub checkout:

```sh
uv venv
make install
```

To install the recommended Git pre-commit hooks for auto-formatting locally, do the following:

```sh
uv run pre-commit run -a
```

To create a new virtualenv, using a specific version of Python you have installed, use the
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ uv.lock
# Node/npm used for installing Prettier locally to override the outdated version that is bundled with the VSCode extension
node_modules/
package-lock.json
package.json
package.json
22 changes: 22 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: "v5.0.0"
hooks:
- id: check-case-conflict
- id: check-merge-conflict
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.9.2"
hooks:
- id: ruff-format
args: [--config=pyproject.toml]

- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v3.1.0"
hooks:
- id: prettier
additional_dependencies:
- prettier@3.4.2
- prettier-plugin-toml@2.0.1
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Markdown documentation files with non-standards syntax for mkdocstrings that Prettier should not auto-format
docs/features/initialization.md
docs/features/initialization.md
32 changes: 14 additions & 18 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,23 @@
# Required
version: 2

# Set the OS, Python version and other tools you might need
build:
os: ubuntu-24.04
tools:
python: "3"

# Build documentation in the "docs/" directory with MkDocs
mkdocs:
configuration: mkdocs.yml

# Optionally build your docs in additional formats such as PDF and ePub
# formats:
# - pdf
# - epub
formats: all

# Optional but recommended, declare the Python requirements required to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- method: pip
path: .
extra_requirements:
- docs
# Build documentation in the "docs/" directory with MkDocs
mkdocs:
configuration: mkdocs.yml

# Set the OS, Python version and other tools you might need
build:
os: ubuntu-24.04
tools:
python: "3.13"
jobs:
install:
- pip install .
- pip install dependency-groups
- pip-install-dependency-groups docs
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## 2.5.9 (TBD)
## 2.5.9 (January 17, 2025)

- Bug Fixes
- Fixed 'index out of range' error when passing no arguments to an argparse-based command function.
Expand Down
67 changes: 67 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Simple Makefile for use with a uv-based development environment
.PHONY: install
install: ## Install the virtual environment
@echo "🚀 Creating virtual environment"
@uv sync

.PHONY: check
check: ## Run code quality tools.
@echo "🚀 Checking lock file consistency with 'pyproject.toml'"
@uv lock --locked
@echo "🚀 Linting code: Running pre-commit"
@uv run pre-commit run -a
@echo "🚀 Static type checking: Running mypy"
@uv run mypy

.PHONY: test
test: ## Test the code with pytest.
@echo "🚀 Testing code: Running pytest"
@uv run python -m pytest --cov --cov-config=pyproject.toml --cov-report=xml tests
@uv run python -m pytest --cov --cov-config=pyproject.toml --cov-report=xml tests_isolated

.PHONY: docs-test
docs-test: ## Test if documentation can be built without warnings or errors
@uv run mkdocs build -s

.PHONY: docs
docs: ## Build and serve the documentation
@uv run mkdocs serve

.PHONY: build
build: clean-build ## Build wheel file
@echo "🚀 Creating wheel file"
@uvx --from build pyproject-build --installer uv

.PHONY: clean-build
clean-build: ## Clean build artifacts
@echo "🚀 Removing build artifacts"
@uv run python -c "import shutil; import os; shutil.rmtree('dist') if os.path.exists('dist') else None"

.PHONY: tag
tag: ## Add a Git tag and push it to origin with syntax: make tag TAG=tag_name
@echo "🚀 Creating git tag: ${TAG}"
@git tag -a ${TAG}
@echo "🚀 Pushing tag to origin: ${TAG}"
@git push origin ${TAG}

.PHONY: validate-tag
validate-tag: ## Check to make sure that a tag exists for the current HEAD and it looks like a valid version number
@echo "🚀 Validating version tag"
@uv run inv validatetag

.PHONY: publish-test
publish-test: validatetag build ## Test publishing a release to PyPI.
@echo "🚀 Publishing: Dry run."
@uvx twine upload --repository testpypi dist/*

.PHONY: publish
publish: validatetag build ## Publish a release to PyPI.
@echo "🚀 Publishing."
@uvx twine upload --repository-url https://upload.pypi.org/legacy/ dist/*

.PHONY: help
help:
@uv run python -c "import re; \
[[print(f'\033[36m{m[0]:<20}\033[0m {m[1]}') for m in re.findall(r'^([a-zA-Z_-]+):.*?## (.*)$$', open(makefile).read(), re.M)] for makefile in ('$(MAKEFILE_LIST)').strip().split()]"

.DEFAULT_GOAL := help
1 change: 0 additions & 1 deletion examples/scripts/nested.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
!echo "Doing a relative run script"
_relative_run_script script.txt

2 changes: 1 addition & 1 deletion examples/tmux_launch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ if [ $# -eq 1 ]
fi

tmux new-session -s "tmux window demo" -n "$FIRST_COMMAND" "$FIRST_COMMAND ;read" \; \
new-window -n "$SECOND_COMMAND" "$SECOND_COMMAND ; read" \; previous-window
new-window -n "$SECOND_COMMAND" "$SECOND_COMMAND ; read" \; previous-window
2 changes: 1 addition & 1 deletion examples/tmux_split.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ fi

tmux new-session -s "tmux split pane demo" "$FIRST_COMMAND ; read" \; \
split-window "$SECOND_COMMAND ; read" \; \
select-layout even-vertical
select-layout even-vertical
95 changes: 45 additions & 50 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ["build", "setuptools>=64", "setuptools-scm>=8"]
requires = ["build>=1.2.1", "setuptools>=64", "setuptools-scm>=8"]
build-backend = "setuptools.build_meta"

[project]
Expand Down Expand Up @@ -28,58 +28,71 @@ classifiers = [
"Topic :: Software Development :: Libraries :: Python Modules",
]
dependencies = [
"gnureadline; platform_system == 'Darwin'",
"pyperclip",
"pyreadline3; platform_system == 'Windows'",
"wcwidth",
"gnureadline>=8; platform_system == 'Darwin'",
"pyperclip>=1.8",
"pyreadline3>=3.4; platform_system == 'Windows'",
"wcwidth>=0.2.10",
]

[project.optional-dependencies]
build = ["build", "setuptools", "setuptools-scm"]
[dependency-groups]
build = ["build>=1.2.1", "setuptools>=64", "setuptools-scm>=8"]
dev = [
"black",
"codecov",
"griffe-typingdoc",
"invoke",
"mkdocs-include-markdown-plugin",
"mkdocs-macros-plugin",
"mkdocs-material",
"mkdocstrings[python]",
"mypy",
"pytest",
"pytest-cov",
"pytest-mock",
"ruff",
"twine",
"black>=24",
"codecov>=2",
"griffe-typingdoc>=0.2",
"invoke>=2",
"mkdocs-include-markdown-plugin>=6",
"mkdocs-macros-plugin>=1",
"mkdocs-material>=8",
"mkdocstrings[python]>=0.26",
"mypy>=1.12",
"pre-commit>=2.20.0",
"pytest>=7",
"pytest-cov>=4",
"pytest-mock>=3.14",
"ruff>=0.9",
"twine>=6",
]
docs = [
"black",
"griffe-typingdoc",
"mkdocs-include-markdown-plugin",
"mkdocs-macros-plugin",
"mkdocs-material",
"mkdocstrings[python]",
"setuptools",
"setuptools_scm",
"black>=24",
"griffe-typingdoc>=0.2",
"mkdocs-include-markdown-plugin>=6",
"mkdocs-macros-plugin>=1",
"mkdocs-material>=8",
"mkdocstrings[python]>=0.26",
"setuptools>=64",
"setuptools_scm>=8",
]
test = ["codecov", "coverage", "pytest", "pytest-cov", "pytest-mock"]
validate = ["mypy", "ruff", "types-setuptools"]
plugins = ["cmd2-ext-test"]
test = [
"codecov>=2",
"coverage>=7",
"pytest>=7",
"pytest-cov>=4",
"pytest-mock>=3.14",
]
validate = ["mypy>=1.12", "ruff>=0.9", "types-setuptools>=69"]

[tool.mypy]
disallow_incomplete_defs = true
disallow_untyped_calls = true
disallow_untyped_defs = true
exclude = [
"^.git/",
"^.venv/",
"^build/", # .build directory
"^docs/", # docs directory
"^dist/",
"^examples/", # examples directory
"^plugins/*", # plugins directory
"^noxfile\\.py$", # nox config file
"setup\\.py$", # any files named setup.py
"^site/",
"^tasks\\.py$", # tasks.py invoke config file
"^tests/", # tests directory
"^tests_isolated/", # tests_isolated directory
]
files = ['.']
show_column_numbers = true
show_error_codes = true
show_error_context = true
Expand Down Expand Up @@ -276,25 +289,7 @@ packages = ["cmd2"]
[tool.setuptools_scm]

[tool.uv]
dev-dependencies = [
"black",
"build",
"cmd2-ext-test",
"codecov",
"griffe-typingdoc",
"invoke",
"mkdocs-include-markdown-plugin",
"mkdocs-macros-plugin",
"mkdocs-material",
"mkdocstrings[python]",
"mypy",
"pytest",
"pytest-cov",
"pytest-mock",
"ruff",
"ruff",
"twine",
]
default-groups = ["dev", "plugins"]

[tool.uv.sources]
cmd2-ext-test = { path = "plugins/ext_test", editable = true }
2 changes: 1 addition & 1 deletion readme_files/shout_out.csv
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ Application Name, Description

Oldies but goodie,,
[JSShell](https://github.com/Den1al/JSShell),An interactive multi-user web JavaScript shell.
[FLASHMINGO](https://github.com/fireeye/flashmingo),Automatic analysis of SWF files based on some heuristics. Extensible via plugins.
[FLASHMINGO](https://github.com/fireeye/flashmingo),Automatic analysis of SWF files based on some heuristics. Extensible via plugins.
Loading