Skip to content

Commit dec23d0

Browse files
committed
Added basic git pre-commit hook setup for auto-formatting.
Also: - Added a simple Makefile for easily installing and using a uv-based local dev setup - Refactored pyproject.toml to use the recommended dependency-groups and minimum versions for all dependencies
1 parent c5ccd25 commit dec23d0

File tree

10 files changed

+132
-58
lines changed

10 files changed

+132
-58
lines changed

.github/CONTRIBUTING.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ $ pip freeze | grep pyperclip
8888

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

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

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

223223
```sh
224-
uv venv
224+
make install
225+
```
226+
227+
To install the recommended Git pre-commit hooks for auto-formatting locally, do the following:
228+
229+
```sh
230+
uv run pre-commit run -a
225231
```
226232

227233
To create a new virtualenv, using a specific version of Python you have installed, use the

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,4 @@ uv.lock
5454
# Node/npm used for installing Prettier locally to override the outdated version that is bundled with the VSCode extension
5555
node_modules/
5656
package-lock.json
57-
package.json
57+
package.json

.pre-commit-config.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: "v5.0.0"
4+
hooks:
5+
- id: check-case-conflict
6+
- id: check-merge-conflict
7+
- id: end-of-file-fixer
8+
- id: trailing-whitespace
9+
10+
- repo: https://github.com/astral-sh/ruff-pre-commit
11+
rev: "v0.9.2"
12+
hooks:
13+
- id: ruff-format
14+
args: [--config=pyproject.toml]
15+
16+
- repo: https://github.com/pre-commit/mirrors-prettier
17+
rev: "v3.1.0"
18+
hooks:
19+
- id: prettier
20+
additional_dependencies:
21+

.prettierignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# Markdown documentation files with non-standards syntax for mkdocstrings that Prettier should not auto-format
2-
docs/features/initialization.md
2+
docs/features/initialization.md

Makefile

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Simple Makefile for use with a uv-based development environment
2+
.PHONY: install
3+
install: ## Install the virtual environment
4+
@echo "🚀 Creating virtual environment"
5+
@uv sync
6+
7+
.PHONY: check
8+
check: ## Run code quality tools.
9+
@echo "🚀 Checking lock file consistency with 'pyproject.toml'"
10+
@uv lock --locked
11+
@echo "🚀 Linting code: Running pre-commit"
12+
@uv run pre-commit run -a
13+
@echo "🚀 Static type checking: Running mypy"
14+
@uv run mypy
15+
16+
.PHONY: test
17+
test: ## Test the code with pytest.
18+
@echo "🚀 Testing code: Running pytest"
19+
@uv run python -m pytest --cov --cov-config=pyproject.toml --cov-report=xml tests
20+
21+
.PHONY: build
22+
build: clean-build ## Build wheel file
23+
@echo "🚀 Creating wheel file"
24+
@uvx --from build pyproject-build --installer uv
25+
26+
.PHONY: clean-build
27+
clean-build: ## Clean build artifacts
28+
@echo "🚀 Removing build artifacts"
29+
@uv run python -c "import shutil; import os; shutil.rmtree('dist') if os.path.exists('dist') else None"
30+
31+
.PHONY: publish
32+
publish: ## Publish a release to PyPI.
33+
@echo "🚀 Publishing: Dry run."
34+
@uvx --from build pyproject-build --installer uv
35+
@echo "🚀 Publishing."
36+
@uvx twine upload --repository-url https://upload.pypi.org/legacy/ dist/*
37+
38+
.PHONY: build-and-publish
39+
build-and-publish: build publish ## Build and publish.
40+
41+
.PHONY: docs-test
42+
docs-test: ## Test if documentation can be built without warnings or errors
43+
@uv run mkdocs build -s
44+
45+
.PHONY: docs
46+
docs: ## Build and serve the documentation
47+
@uv run mkdocs serve
48+
49+
.PHONY: help
50+
help:
51+
@uv run python -c "import re; \
52+
[[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()]"
53+
54+
.DEFAULT_GOAL := help

examples/scripts/nested.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
!echo "Doing a relative run script"
22
_relative_run_script script.txt
3-

examples/tmux_launch.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ if [ $# -eq 1 ]
3333
fi
3434

3535
tmux new-session -s "tmux window demo" -n "$FIRST_COMMAND" "$FIRST_COMMAND ;read" \; \
36-
new-window -n "$SECOND_COMMAND" "$SECOND_COMMAND ; read" \; previous-window
36+
new-window -n "$SECOND_COMMAND" "$SECOND_COMMAND ; read" \; previous-window

examples/tmux_split.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ fi
3131

3232
tmux new-session -s "tmux split pane demo" "$FIRST_COMMAND ; read" \; \
3333
split-window "$SECOND_COMMAND ; read" \; \
34-
select-layout even-vertical
34+
select-layout even-vertical

pyproject.toml

Lines changed: 44 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[build-system]
2-
requires = ["build", "setuptools>=64", "setuptools-scm>=8"]
2+
requires = ["build>=1.2.1", "setuptools>=64", "setuptools-scm>=8"]
33
build-backend = "setuptools.build_meta"
44

55
[project]
@@ -28,58 +28,70 @@ classifiers = [
2828
"Topic :: Software Development :: Libraries :: Python Modules",
2929
]
3030
dependencies = [
31-
"gnureadline; platform_system == 'Darwin'",
32-
"pyperclip",
33-
"pyreadline3; platform_system == 'Windows'",
34-
"wcwidth",
31+
"gnureadline>=8; platform_system == 'Darwin'",
32+
"pyperclip>=1.8",
33+
"pyreadline3>=3.4; platform_system == 'Windows'",
34+
"wcwidth>=0.2.10",
3535
]
3636

37-
[project.optional-dependencies]
38-
build = ["build", "setuptools", "setuptools-scm"]
37+
[dependency-groups]
38+
build = ["build>=1.2.1", "setuptools>=64", "setuptools-scm>=8"]
3939
dev = [
40-
"black",
41-
"codecov",
42-
"griffe-typingdoc",
43-
"invoke",
44-
"mkdocs-include-markdown-plugin",
45-
"mkdocs-macros-plugin",
46-
"mkdocs-material",
47-
"mkdocstrings[python]",
48-
"mypy",
49-
"pytest",
50-
"pytest-cov",
51-
"pytest-mock",
52-
"ruff",
53-
"twine",
40+
"black>=24",
41+
"codecov>=2",
42+
"griffe-typingdoc>=0.2",
43+
"invoke>=2",
44+
"mkdocs-include-markdown-plugin>=6",
45+
"mkdocs-macros-plugin>=1",
46+
"mkdocs-material>=8",
47+
"mkdocstrings[python]>=0.26",
48+
"mypy>=1.12",
49+
"pre-commit>=2.20.0",
50+
"pytest>=7",
51+
"pytest-cov>=4",
52+
"pytest-mock>=3.14",
53+
"ruff>=0.9",
54+
"twine>=6",
5455
]
5556
docs = [
56-
"black",
57-
"griffe-typingdoc",
58-
"mkdocs-include-markdown-plugin",
59-
"mkdocs-macros-plugin",
60-
"mkdocs-material",
61-
"mkdocstrings[python]",
62-
"setuptools",
63-
"setuptools_scm",
57+
"black>=24",
58+
"griffe-typingdoc>=0.2",
59+
"mkdocs-include-markdown-plugin>=6",
60+
"mkdocs-macros-plugin>=1",
61+
"mkdocs-material>=8",
62+
"mkdocstrings[python]>=0.26",
63+
"setuptools>=64",
64+
"setuptools_scm>=8",
6465
]
65-
test = ["codecov", "coverage", "pytest", "pytest-cov", "pytest-mock"]
66-
validate = ["mypy", "ruff", "types-setuptools"]
66+
test = [
67+
"codecov>=2",
68+
"coverage>=7",
69+
"pytest>=7",
70+
"pytest-cov>=4",
71+
"pytest-mock>=3.14",
72+
]
73+
validate = ["mypy>=1.12", "ruff>=0.9", "types-setuptools>=69"]
6774

6875
[tool.mypy]
6976
disallow_incomplete_defs = true
7077
disallow_untyped_calls = true
7178
disallow_untyped_defs = true
7279
exclude = [
80+
"^.git/",
81+
"^.venv/",
7382
"^build/", # .build directory
7483
"^docs/", # docs directory
84+
"^dist/",
7585
"^examples/", # examples directory
7686
"^plugins/*", # plugins directory
7787
"^noxfile\\.py$", # nox config file
7888
"setup\\.py$", # any files named setup.py
89+
"^site/",
7990
"^tasks\\.py$", # tasks.py invoke config file
8091
"^tests/", # tests directory
8192
"^tests_isolated/", # tests_isolated directory
8293
]
94+
files = ['.']
8395
show_column_numbers = true
8496
show_error_codes = true
8597
show_error_context = true
@@ -276,25 +288,7 @@ packages = ["cmd2"]
276288
[tool.setuptools_scm]
277289

278290
[tool.uv]
279-
dev-dependencies = [
280-
"black",
281-
"build",
282-
"cmd2-ext-test",
283-
"codecov",
284-
"griffe-typingdoc",
285-
"invoke",
286-
"mkdocs-include-markdown-plugin",
287-
"mkdocs-macros-plugin",
288-
"mkdocs-material",
289-
"mkdocstrings[python]",
290-
"mypy",
291-
"pytest",
292-
"pytest-cov",
293-
"pytest-mock",
294-
"ruff",
295-
"ruff",
296-
"twine",
297-
]
291+
default-groups = ["dev"]
298292

299293
[tool.uv.sources]
300294
cmd2-ext-test = { path = "plugins/ext_test", editable = true }

readme_files/shout_out.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ Application Name, Description
1111

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

0 commit comments

Comments
 (0)