Skip to content
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

feat: read build-backend ignore lists #66

Merged
merged 7 commits into from
Oct 14, 2024
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
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
Loading