Skip to content

Commit

Permalink
Switch from pre-commit to Hatch scripts (#89)
Browse files Browse the repository at this point in the history
pre-commit runs Git hooks. It can run on different Git events like
`pre-push` and can also easily run on CI (continuous integration)
platforms like GitHub Actions. These pre-commit hooks are often related
to code quality and help ensure code quality checks are continuously
enforced.

While it is helpful for continuously running code quality checks,
pre-commit has some downsides.

- pre-commit requires separate dependency versions and configuration in
  its own file `.pre-commit-config.yaml`, even when those dependencies
  are already configured in a Python requirements file like
  `pyproject.toml` (84b25bc).
- pre-commit requires separate file paths because it identifies files
  with Python regular expressions ("regexes") instead of globs like many
  other tools, and disregards file paths present in other configuration
  files. Translation between globs and regexes can be complicated and
  files can be unexpectedly excluded as a result.
- pre-commit commands sometimes have different behavior than the
  commands would have normally.
- pre-commit issues are often not explained or fixed.

Hatch scripts can replace pre-commit.

https://hatch.pypa.io/latest/config/environment/overview/#scripts

Changes

- Add Hatch scripts to replace pre-commit commands
  - check:
    - Black
    - Flake8
    - isort
    - Mypy
    - Prettier
    - CSpell
  - format:
    - Black
    - isort
    - Prettier
- Replace other pre-commit hooks where possible
  - Replace `mixed-line-ending` by adding `* text=auto eol=lf` to a
    `.gitattributes` file
- Update GitHub Actions workflows to run Hatch scripts
- Update docs for Hatch scripts
- Remove pre-commit from `pyproject.toml`
- Remove `.pre-commit-config.yaml`
  • Loading branch information
br3ndonland authored Nov 13, 2023
1 parent 03ac3f7 commit 1a5450b
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 116 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
18 changes: 2 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,6 @@ jobs:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
restore-keys: ${{ runner.os }}-pip-
- name: Set up pre-commit cache
if: runner.os == 'Linux'
uses: actions/cache@v3
with:
path: ~/.cache/pre-commit
key: ${{ runner.os }}-pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
restore-keys: ${{ runner.os }}-pre-commit-
- name: Install pipx for Python ${{ matrix.python-version }}
run: python -m pip install "pipx==$PIPX_VERSION"
- name: Install Hatch
Expand Down Expand Up @@ -75,15 +68,8 @@ jobs:
else
echo "Versions do not match." && exit 1
fi
- name: Run spell check
uses: streetsidesoftware/cspell-action@v2
with:
check_dot_files: true
files: "**/*.md"
incremental_files_only: false
strict: true
- name: Run pre-commit hooks
run: hatch run ${{ env.HATCH_ENV }}:pre-commit run --all-files
- name: Run Hatch script for code quality checks
run: hatch run ${{ env.HATCH_ENV }}:check
- name: Run tests
run: hatch run ${{ env.HATCH_ENV }}:coverage run
- name: Enforce test coverage
Expand Down
41 changes: 0 additions & 41 deletions .pre-commit-config.yaml

This file was deleted.

3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
*cache*
*venv*
htmlcov
public
site
65 changes: 8 additions & 57 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ Change the port numbers to run multiple containers simultaneously (`-p 81:80`).

## Code quality

### Running code quality checks

Code quality checks can be run using the Hatch scripts in _pyproject.toml_.

- Check: `hatch run check`
- Format: `hatch run format`

### Code style

- **Python code is formatted with [Black](https://black.readthedocs.io/en/stable/)**. Configuration for Black is stored in _[pyproject.toml](https://github.com/br3ndonland/inboard/blob/HEAD/pyproject.toml)_.
Expand All @@ -216,65 +223,9 @@ Change the port numbers to run multiple containers simultaneously (`-p 81:80`).
- [Mypy](https://mypy.readthedocs.io/en/stable/) is used for type-checking. [Mypy configuration](https://mypy.readthedocs.io/en/stable/config_file.html) is included in _pyproject.toml_.
- Mypy strict mode is enabled. Strict includes `--no-explicit-reexport` (`implicit_reexport = false`), which means that objects imported into a module will not be re-exported for import into other modules. Imports can be made into explicit exports with the syntax `from module import x as x` (i.e., changing from `import logging` to `import logging as logging`), or by including imports in `__all__`. This explicit import syntax can be confusing. Another option is to apply mypy overrides to any modules that need to leverage implicit exports.

### Pre-commit

[Pre-commit](https://pre-commit.com/) runs [Git hooks](https://www.git-scm.com/book/en/v2/Customizing-Git-Git-Hooks). Configuration is stored in _[.pre-commit-config.yaml](https://github.com/br3ndonland/inboard/blob/HEAD/.pre-commit-config.yaml)_. It can run locally before each commit (hence "pre-commit"), or on different Git events like `pre-push`. Pre-commit is installed in the Python virtual environment. To use:

```sh
~
cd path/to/inboard

path/to/inboard
❯ hatch env create

path/to/inboard
❯ hatch shell

# install hooks that run before each commit
path/to/inboard
.venv ❯ pre-commit install

# and/or install hooks that run before each push
path/to/inboard
.venv ❯ pre-commit install --hook-type pre-push
```

### Spell check

Spell check is performed with [CSpell](https://cspell.org/).

In GitHub Actions, CSpell runs using [cspell-action](https://github.com/streetsidesoftware/cspell-action).

To run spell check locally, consider installing [their VSCode extension](https://github.com/streetsidesoftware/vscode-spell-checker) or running from the command line.

CSpell can be run with `pnpm` if `pnpm` is installed:

```sh
pnpm -s dlx cspell --dot --gitignore "**/*.md"
```

or with `npx` if `npm` is installed:

```sh
npx -s -y cspell --dot --gitignore "**/*.md"
```

CSpell also offers a pre-commit hook through their [cspell-cli](https://github.com/streetsidesoftware/cspell-cli) repo. A `.pre-commit-config.yaml` configuration could look like this:

```yml
repos:
- repo: https://github.com/streetsidesoftware/cspell-cli
rev: v6.16.0
hooks:
- id: cspell
files: "^.*.md$"
args: ["--dot", "--gitignore", "**/*.md"]
```
CSpell is not currently used with pre-commit in this project because behavior of the pre-commit hook is inconsistent.
- [CSpell matches files with globs](https://cspell.org/docs/globs/), but [pre-commit uses Python regexes](https://pre-commit.com/#regular-expressions). Two separate file patterns have to be specified (a regex for pre-commit and a glob for CSpell), which is awkward and error-prone.
- When running with pre-commit, CSpell seems to output each error multiple times.
Spell check is performed with [CSpell](https://cspell.org/). The CSpell command is included in the Hatch script for code quality checks (`hatch run check`).

## GitHub Actions workflows

Expand Down
1 change: 0 additions & 1 deletion docs/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ The _pyproject.toml_ could look like this:
"flake8",
"isort",
"mypy",
"pre-commit",
]
docs = [
"mkdocs-material",
Expand Down
16 changes: 15 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ checks = [
"flake8>=6,<7",
"isort>=5,<6",
"mypy==1.7.0",
"pre-commit>=2,<3",
]
docs = [
"mkdocs-material>=9,<10",
Expand Down Expand Up @@ -109,6 +108,21 @@ features = [
]
path = ".venv"

[tool.hatch.envs.default.scripts]
check = [
"black --check --diff .",
"isort --check --diff .",
"flake8 --extend-exclude=.venv,bin,build,cache,dist,lib --max-line-length=88",
"mypy",
"npx -s -y prettier@'^2' . --check",
"npx -s -y cspell --dot --gitignore *.md **/*.md",
]
format = [
"black .",
"isort .",
"npx -s -y prettier@'^2' . --write",
]

[tool.hatch.envs.docs]
dev-mode = false
features = [
Expand Down

0 comments on commit 1a5450b

Please sign in to comment.