Skip to content
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
2 changes: 1 addition & 1 deletion .copier-answers.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Changes here will be overwritten by Copier
_commit: ebb6e1c
_commit: '4372075'
_src_path: https://github.com/python-project-templates/base.git
add_docs: true
add_extension: python
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ on:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
Expand Down
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ lint-py: ## lint python with ruff
python -m ruff format --check check_dist

lint-docs: ## lint docs with mdformat and codespell
python -m mdformat --check README.md
python -m codespell_lib README.md
python -m mdformat --check README.md $(wildcard docs/src)
python -m codespell_lib README.md $(wildcard docs/src)

fix-py: ## autoformat python code with ruff
python -m ruff check --fix check_dist
python -m ruff format check_dist

fix-docs: ## autoformat docs with mdformat and codespell
python -m mdformat README.md
python -m codespell_lib --write README.md
python -m mdformat README.md $(wildcard docs/src)
python -m codespell_lib --write README.md $(wildcard docs/src)

lint: lint-py lint-docs ## run all linters
lints: lint
Expand All @@ -52,7 +52,7 @@ check-dist: ## check python sdist and wheel with check-dist
check-types: ## check python types with ty
ty check --python $$(which python)

checks: check-dist
checks: check-dist check-types

# Alias
check: checks
Expand Down
1 change: 1 addition & 0 deletions check_dist/tests/test_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,7 @@ def test_no_project_name(self):

def test_common_patterns_present(self):
cfg = copier_defaults({"add_extension": "cpp", "project_name": "foo"})
assert cfg is not None
assert "LICENSE" in cfg["sdist"]["present"]
assert "pyproject.toml" in cfg["sdist"]["present"]
assert ".copier-answers.yaml" in cfg["sdist"]["absent"]
Expand Down
60 changes: 30 additions & 30 deletions docs/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,28 @@ python -m check_dist._cli
## How it works

1. **Build** — `check-dist` builds an sdist and a wheel using [build](https://pypi.org/project/build/).
2. **List** — It lists every file inside each archive.
3. **VCS comparison** — For the sdist, it compares the contents against files tracked by version control (currently git), taking into account any `[tool.hatch.build.targets.sdist]` configuration in `pyproject.toml`.
4. **Present / absent checks** — It verifies that files matching your `present` patterns exist and files matching your `absent` patterns do not, for both the sdist and the wheel.
5. **Platform extension checks** — It flags files that use a shared-library extension from another platform (e.g. a `.so` inside a Windows wheel).
1. **List** — It lists every file inside each archive.
1. **VCS comparison** — For the sdist, it compares the contents against files tracked by version control (currently git), taking into account any `[tool.hatch.build.targets.sdist]` configuration in `pyproject.toml`.
1. **Present / absent checks** — It verifies that files matching your `present` patterns exist and files matching your `absent` patterns do not, for both the sdist and the wheel.
1. **Platform extension checks** — It flags files that use a shared-library extension from another platform (e.g. a `.so` inside a Windows wheel).

## `pyproject.toml` configuration

All configuration lives under the `[tool.check-dist]` table, split into `sdist` and `wheel` sub-tables.

### `[tool.check-dist.sdist]`

| Key | Type | Description |
| --- | --- | --- |
| Key | Type | Description |
| --------- | --------------- | ------------------------------------------------------------ |
| `present` | list of strings | Patterns that **must** match at least one file in the sdist. |
| `absent` | list of strings | Patterns that **must not** match any file in the sdist. |
| `absent` | list of strings | Patterns that **must not** match any file in the sdist. |

### `[tool.check-dist.wheel]`

| Key | Type | Description |
| --- | --- | --- |
| Key | Type | Description |
| --------- | --------------- | ------------------------------------------------------------ |
| `present` | list of strings | Patterns that **must** match at least one file in the wheel. |
| `absent` | list of strings | Patterns that **must not** match any file in the wheel. |
| `absent` | list of strings | Patterns that **must not** match any file in the wheel. |

### Example

Expand Down Expand Up @@ -82,26 +82,26 @@ absent = [

Patterns in `present` and `absent` lists support several matching modes:

| Pattern | Matches |
| --- | --- |
| `LICENSE` | A file named exactly `LICENSE` at any depth. |
| `my_package` | Any file whose path starts with `my_package/` (directory match). |
| `*.py` | Any file ending in `.py` (glob against the basename). |
| Pattern | Matches |
| ----------------- | ----------------------------------------------------------------------- |
| `LICENSE` | A file named exactly `LICENSE` at any depth. |
| `my_package` | Any file whose path starts with `my_package/` (directory match). |
| `*.py` | Any file ending in `.py` (glob against the basename). |
| `my_package/*.py` | `.py` files directly inside `my_package/` (glob against the full path). |
| `.github` | Any file under `.github/`. |
| `.github` | Any file under `.github/`. |

Standard `fnmatch` wildcards are supported: `*`, `?`, `[seq]`, `[!seq]`.

## Platform-aware extension handling

`check-dist` automatically translates shared-library extensions across platforms so you can write a single configuration that works everywhere.

| Written in config | Linux | macOS | Windows |
| --- | --- | --- | --- |
| `*.so` | `*.so` | `*.so` | `*.pyd` |
| `*.pyd` | `*.so` | `*.so` | `*.pyd` |
| `*.dll` | `*.so` | `*.dylib` | `*.dll` |
| `*.dylib` | `*.so` | `*.dylib` | `*.dll` |
| Written in config | Linux | macOS | Windows |
| ----------------- | ------ | --------- | ------- |
| `*.so` | `*.so` | `*.so` | `*.pyd` |
| `*.pyd` | `*.so` | `*.so` | `*.pyd` |
| `*.dll` | `*.so` | `*.dylib` | `*.dll` |
| `*.dylib` | `*.so` | `*.dylib` | `*.dll` |

In addition, if a file with a **wrong** extension for the current platform appears in a distribution (e.g. a `.so` file in a Windows wheel), `check-dist` will raise an error.

Expand Down Expand Up @@ -133,7 +133,7 @@ exclude = ["target"]

This tells `check-dist` that the sdist should contain files from the listed paths, minus any excluded patterns.

> **Note:** Hatchling force-includes VCS exclusion files (e.g. `.gitignore`) in sdists regardless of exclude rules. Do not add `.gitignore` to your `absent` list for sdist checks.
> **Note:** Hatchling force-includes VCS exclusion files (e.g. `.gitignore`) in sdists regardless of exclude rules. Do not add `.gitignore` to your `absent` list for sdist checks.

## Copier template defaults

Expand Down Expand Up @@ -177,7 +177,7 @@ options:

The `--pre-built` flag is useful when you have an existing build pipeline
that produces the sdist and wheel (e.g. projects with complex native
toolchains like Rust + WASM or C++ + Emscripten). Point it at the
toolchains like Rust + WASM or C++ + Emscripten). Point it at the
directory containing the `.tar.gz` and `.whl` files:

```bash
Expand All @@ -190,11 +190,11 @@ dist was produced and warn about the failed build.

### Exit codes

| Code | Meaning |
| --- | --- |
| 0 | All checks passed. |
| 1 | One or more checks failed. |
| 2 | An unexpected error occurred (e.g. build failure, git not found). |
| Code | Meaning |
| ---- | ----------------------------------------------------------------- |
| 0 | All checks passed. |
| 1 | One or more checks failed. |
| 2 | An unexpected error occurred (e.g. build failure, git not found). |

## Python API

Expand All @@ -210,7 +210,7 @@ for msg in messages:

Key functions exposed from `check_dist`:

- `check_dist(source_dir, *, no_isolation=False, verbose=False, pre_built=None)` — run all checks, returns `(bool, list[str])`. Pass `pre_built="dist/"` to skip building.
- `check_dist(source_dir, *, no_isolation=False, verbose=False, pre_built=None)` — run all checks, returns `(bool, list[str])`. Pass `pre_built="dist/"` to skip building.
- `load_config(pyproject_path, *, source_dir=None)` — load `[tool.check-dist]` configuration, falling back to copier defaults when `source_dir` is provided.
- `load_copier_config(source_dir)` — load `.copier-answers.yaml` from a directory.
- `copier_defaults(copier_config)` — derive `present`/`absent` patterns from copier answers.
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ develop = [
"codespell",
"hatchling",
"mdformat",
"mdformat-frontmatter",
"mdformat-tables>=1",
"pytest",
"pytest-cov",
Expand Down Expand Up @@ -108,7 +109,7 @@ absent = [
[tool.coverage.run]
branch = true
omit = [
"check_dist/tests/integration/",
"check_dist/tests/integration/*",
]

[tool.coverage.report]
Expand Down