Skip to content

Commit

Permalink
feat: read build-backend ignore lists (#66)
Browse files Browse the repository at this point in the history
* feat: read build-backend ignore lists

Signed-off-by: Henry Schreiner <[email protected]>

* feat: add some more backends

Signed-off-by: Henry Schreiner <[email protected]>

* fix: pull out logic

Signed-off-by: Henry Schreiner <[email protected]>

* fix: adding maturin test

Signed-off-by: Henry Schreiner <[email protected]>

* tests: add some extra ignored files

Signed-off-by: Henry Schreiner <[email protected]>

* tests: test for unknown backend

Signed-off-by: Henry Schreiner <[email protected]>

* chore: ignore coverage on return __all__

Signed-off-by: Henry Schreiner <[email protected]>

---------

Signed-off-by: Henry Schreiner <[email protected]>
  • Loading branch information
henryiii authored Oct 14, 2024
1 parent 08067d2 commit 2b869e1
Show file tree
Hide file tree
Showing 6 changed files with 366 additions and 0 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ git-only = []
default-ignore = true
recurse-submodules = true
mode = "git"
build-backend = "auto"
```

You can add `.gitignore` style lines here, and you can turn off the default
Expand All @@ -112,6 +113,13 @@ You can also select `mode = "all"`, which will instead check every file on your
system. Be prepared to ignore lots of things manually, like `*.pyc` files, if
you use this.

You can tell check-sdist to look for exclude lists for a specific build backend
with `build-backend`, or `"none"` to only use it's own exclude list. Build
backends supported are `"flit_core.buildapi"`, `"hatchling.build"`,
`"scikit_build_core.build"`, `"pdm.backend"`, `"maturin"`, and
`"poetry.core.masonry.api"`. The default, `"auto"`, will try to detect the build
backend if `build-system.build-backend` is set to a known value.

### See also

- [check-manifest](https://github.com/mgedmin/check-manifest): A (currently)
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ testpaths = [

[tool.coverage]
run.source = ["check_sdist"]
report.exclude_also = [
"return __all__",
]


[tool.mypy]
Expand Down
5 changes: 5 additions & 0 deletions src/check_sdist/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from . import __version__
from ._compat import tomllib
from .backends import backend_ignored_patterns
from .git import git_files
from .inject import inject_junk_files
from .resources import resources
Expand Down Expand Up @@ -54,6 +55,7 @@ def compare(

installer = select_installer(installer)

pyproject = {}
config = {}
pyproject_toml = source_dir.joinpath("pyproject.toml")
with contextlib.suppress(FileNotFoundError), pyproject_toml.open("rb") as f:
Expand All @@ -65,6 +67,7 @@ def compare(
default_ignore = config.get("default-ignore", True)
recurse_submodules = config.get("recurse-submodules", True)
mode = config.get("mode", "git")
backend = config.get("build-backend", "auto")

sdist = sdist_files(source_dir, isolated=isolated, installer=installer) - {
"PKG-INFO"
Expand All @@ -90,6 +93,8 @@ def compare(
sdist_only = frozenset(p for p in sdist - git if not sdist_spec.match_file(p))
git_only = frozenset(p for p in git - sdist if not git_spec.match_file(p))

git_only = backend_ignored_patterns(backend, pyproject, git_only)

if verbose:
print("SDist contents:")
print(*(f" {x}" for x in sorted(sdist)), sep="\n")
Expand Down
102 changes: 102 additions & 0 deletions src/check_sdist/backends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from __future__ import annotations

from pathlib import Path
from typing import Any

import pathspec

__all__ = ["backend_ignored_patterns"]


def __dir__() -> list[str]:
return __all__


def glob_filter(patterns: list[str], files: frozenset[str]) -> frozenset[str]:
"""
Filter out files based on glob patterns.
"""
new_files = set(files)
for pattern in patterns:
results = {str(p.as_posix()) for p in Path().glob(pattern)}
new_files -= results
return frozenset(new_files)


def pathspec_filter(patterns: list[str], files: frozenset[str]) -> frozenset[str]:
"""
Filter out files based on gitignore-style patterns.
"""
spec = pathspec.GitIgnoreSpec.from_lines(patterns)
return frozenset(p for p in files if not spec.match_file(p))


def backend_ignored_patterns(
backend: str, pyproject: dict[str, Any], files: frozenset[str]
) -> frozenset[str]:
"""
Return the ignored patterns for the given backend. If the generator is
"none", then no patterns are ignored. If the generator is "auto", then the
value is read from the pyproject.toml file. Any recognized backend can also
be specified directly.
"""

if backend == "none":
return files

backend_resolved = (
pyproject.get("build-system", {}).get(
"build-backend", "setuptools.build_meta.__legacy__"
)
if backend == "auto"
else backend
)

if backend_resolved == "flit_core.buildapi":
exclude = (
pyproject.get("tool", {})
.get("flit", {})
.get("sdist", {})
.get("exclude", [])
)
return glob_filter(exclude, files)
if backend_resolved == "hatchling.build":
exclude = (
pyproject.get("tool", {})
.get("hatch", {})
.get("build", {})
.get("targets", {})
.get("sdist", {})
.get("exclude", [])
)
return pathspec_filter(exclude, files)
if backend_resolved == "scikit_build_core.build":
exclude = (
pyproject.get("tool", {})
.get("scikit-build", {})
.get("sdist", {})
.get("exclude", [])
)
return pathspec_filter(exclude, files)
if backend_resolved == "pdm.backend":
exclude = (
pyproject.get("tool", {})
.get("pdm", {})
.get("build", {})
.get("excludes", [])
)
return glob_filter(exclude, files)
if backend_resolved == "poetry.core.masonry.api":
exclude = [
x if isinstance(x, str) else x["path"]
for x in pyproject.get("tool", {}).get("poetry", {}).get("exclude", [])
if isinstance(x, str) or "sdist" in x.get("format", ["sdist"])
]
return glob_filter(exclude, files)
if backend_resolved == "maturin":
exclude = pyproject.get("tool", {}).get("maturin", {}).get("exclude", [])
return glob_filter(exclude, files)
if backend != "auto":
msg = f"Unknown backend: {backend} - please add support in check_dist.backends"
raise ValueError(msg)
return files
14 changes: 14 additions & 0 deletions src/check_sdist/resources/check-sdist.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@
"description": "What to use as baseline",
"default": "git",
"enum": ["git", "all"]
},
"build-backend": {
"description": "What to expect as build-backend, in order to look for exclude lists",
"default": "auto",
"enum": [
"auto",
"none",
"flit_core.buildapi",
"hatchling.build",
"scikit_build_core.build",
"pdm.backend.api",
"poetry.core.masonry.api",
"maturin"
]
}
}
}
Loading

0 comments on commit 2b869e1

Please sign in to comment.