From c78588f7ad020a45f63c0208145873eb605cf305 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 10:18:26 -0400 Subject: [PATCH 1/8] chore(deps): Bump pypa/gh-action-pypi-publish from 1.8.3 to 1.8.4 (#3) Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.3 to 1.8.4. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.3...v1.8.4) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75d84a6..3bb53c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,7 +90,7 @@ jobs: - name: Check products run: pipx run twine check dist/* - - uses: pypa/gh-action-pypi-publish@v1.8.3 + - uses: pypa/gh-action-pypi-publish@v1.8.4 if: github.event_name == 'release' && github.event.action == 'published' with: password: ${{ secrets.pypi_password }} From 819f375ec78b358eb3caa0f35c7886afe82e3344 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 3 Apr 2023 10:31:42 -0400 Subject: [PATCH 2/8] chore: check sdist with itself Signed-off-by: Henry Schreiner --- .pre-commit-config.yaml | 8 ++++++++ .pre-commit-hooks.yaml | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6040603..915809f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -52,6 +52,14 @@ repos: args: [] additional_dependencies: ["tomli", "pathspec", "importlib-resources"] + - repo: https://github.com/henryiii/check-sdist + rev: "v0.1.0" + hooks: + - id: check-sdist + args: [--inject-junk] + additional_dependencies: + - hatchling + - repo: https://github.com/codespell-project/codespell rev: v2.2.4 hooks: diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 2f2b501..0f6ff6c 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,5 +1,5 @@ - id: check-sdist - name: check-sdist + name: check sdist description: Check the contents of the SDist entry: check-sdist --no-isolation language: python @@ -8,7 +8,7 @@ always_run: true args: [--inject-junk] - id: check-sdist-isolated - name: check-sdist + name: check sdist (isolated) description: Check the contents of the SDist (isolated build) entry: check-sdist language: python From 1d3f852b07cefeef9a0a7e487da2057b00be14f5 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 3 Apr 2023 10:42:24 -0400 Subject: [PATCH 3/8] docs: minor readme update Signed-off-by: Henry Schreiner --- README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 6260e92..cda51fa 100644 --- a/README.md +++ b/README.md @@ -20,17 +20,17 @@ $ pipx run check-sdist ``` You can add `--no-isolation` to disable build isolation (faster, but must -preinstall build deps), `--source-dir` to select a different source dir to -check, and `--inject-junk` to temporarily inject some common junk files while -running. +preinstall build dependencies), `--source-dir` to select a different source +directory to check, and `--inject-junk` to temporarily inject some common junk +files while running. -To use the development version: +If you need the latest development version: ```console $ pipx run --spec git+https://github.com/henryiii/check-sdist check-sdist ``` -To use the pre-commit integration, use this in your `.pre-commit-config.yaml`: +To use the pre-commit integration, put this in your `.pre-commit-config.yaml`: ```yaml - repo: https://github.com/henryiii/check-sdist @@ -41,7 +41,9 @@ To use the pre-commit integration, use this in your `.pre-commit-config.yaml`: additional_dependencies: [] # list your build deps here ``` -Or, slower, but doesn't require build dependency listing: +This requires your build dependencies, but in doing so, it can cache the +environment, making it quite fast. If you don't mind slower runs and don't want +to require build dependency listing: ```yaml - repo: https://github.com/henryiii/check-sdist @@ -51,7 +53,7 @@ Or, slower, but doesn't require build dependency listing: args: [--inject-junk] ``` -To configure, these options are provided for your pyproject.toml file: +To configure, these options are supported in your `pyproject.toml` file: ```toml [tool.check-sdist] @@ -60,5 +62,5 @@ git-only = [] default-ignore = true ``` -You can add .gitignore style lines here, and you can turn off the default ignore -list, which adds some default `git-only` files. +You can add `.gitignore` style lines here, and you can turn off the default +ignore list, which adds some default git-only files. From 43e3725fdafa104dfaff121bd85f058742060794 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 3 Apr 2023 11:28:13 -0400 Subject: [PATCH 4/8] docs: readme introduction Signed-off-by: Henry Schreiner --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cda51fa..e4a1125 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,19 @@ +Have you ever shipped broken SDists with missing files or possibly dirty SDists +with files that shouldn't have been there? Have you noticed that standards +compliant tools aren't making the same SDist that `flit build` is? Is hatchling +adding `.DSStore` files when you ship from your macOS? No matter what +build-backend you use, check-sdist can help! + +Check-sdist builds an SDist and compares the contents with your Git repository +contents. It can even temporarily inject common junk files (like pycache files +or OS specific files) and help verify that those aren't getting bundled into +your SDist. If you are getting files you didn't expect or missing files you did +expect, consult your build backend's docs to see how to include or exclude +files. + To run: ```console @@ -30,7 +43,10 @@ If you need the latest development version: $ pipx run --spec git+https://github.com/henryiii/check-sdist check-sdist ``` -To use the pre-commit integration, put this in your `.pre-commit-config.yaml`: +### pre-commit integration + +To use the [pre-commit](https://pre-commit.com) integration, put this in your +`.pre-commit-config.yaml`: ```yaml - repo: https://github.com/henryiii/check-sdist @@ -53,6 +69,8 @@ to require build dependency listing: args: [--inject-junk] ``` +### Configuration + To configure, these options are supported in your `pyproject.toml` file: ```toml @@ -64,3 +82,11 @@ default-ignore = true You can add `.gitignore` style lines here, and you can turn off the default ignore list, which adds some default git-only files. + +### See Also + +- [check-manifest](https://github.com/mgedmin/check-manifest): A (currently) + setuptools specific checker that can suggest possible ways to include/exclude + files. +- [scikit-hep developer pages](https://scikit-hep.org/developer): Guidelines on + which this package was designed. From 96c4bfd15447df94d6be275bf909656eb2a83cc3 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 3 Apr 2023 11:33:06 -0400 Subject: [PATCH 5/8] docs: minor polish Signed-off-by: Henry Schreiner --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e4a1125..06919d5 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ your SDist. If you are getting files you didn't expect or missing files you did expect, consult your build backend's docs to see how to include or exclude files. +### Quick start + To run: ```console @@ -43,7 +45,7 @@ If you need the latest development version: $ pipx run --spec git+https://github.com/henryiii/check-sdist check-sdist ``` -### pre-commit integration +### Pre-commit integration To use the [pre-commit](https://pre-commit.com) integration, put this in your `.pre-commit-config.yaml`: @@ -83,7 +85,7 @@ default-ignore = true You can add `.gitignore` style lines here, and you can turn off the default ignore list, which adds some default git-only files. -### See Also +### See also - [check-manifest](https://github.com/mgedmin/check-manifest): A (currently) setuptools specific checker that can suggest possible ways to include/exclude From 40953c74df86bb8a89470058bcbf10f05a05e522 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Apr 2023 10:33:06 -0400 Subject: [PATCH 6/8] chore(deps): Bump pypa/gh-action-pypi-publish from 1.8.4 to 1.8.5 (#4) Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.4 to 1.8.5. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.4...v1.8.5) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3bb53c6..d8a7a06 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,7 +90,7 @@ jobs: - name: Check products run: pipx run twine check dist/* - - uses: pypa/gh-action-pypi-publish@v1.8.4 + - uses: pypa/gh-action-pypi-publish@v1.8.5 if: github.event_name == 'release' && github.event.action == 'published' with: password: ${{ secrets.pypi_password }} From 78a8a6ff6258682f3afa3c2a716145edf5988813 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 12 Apr 2023 08:21:32 -0700 Subject: [PATCH 7/8] fix: setuptools support (#6) Signed-off-by: Henry Schreiner --- .pre-commit-config.yaml | 5 ++-- pyproject.toml | 9 ++++++- src/check_sdist/__main__.py | 7 ++++-- src/check_sdist/resources/default-ignore.txt | 1 + src/check_sdist/sdist.py | 4 ++- tests/downstream.toml | 23 +++++++++++++++++ tests/test_downstream.py | 26 ++++++++++++++++++++ tests/test_package.py | 4 +-- 8 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 tests/downstream.toml create mode 100644 tests/test_downstream.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 915809f..81ef71a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,9 +48,10 @@ repos: rev: "v1.1.1" hooks: - id: mypy - files: src + files: src|tests args: [] - additional_dependencies: ["tomli", "pathspec", "importlib-resources"] + additional_dependencies: + ["tomli", "pathspec", "importlib-resources", "pytest"] - repo: https://github.com/henryiii/check-sdist rev: "v0.1.0" diff --git a/pyproject.toml b/pyproject.toml index e462a07..e5c7dbf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,13 +71,20 @@ testpaths = [ [tool.mypy] -files = "src" +files = ["src", "tests"] python_version = "3.8" warn_unused_configs = true strict = true show_error_codes = true enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] warn_unreachable = true +disallow_untyped_defs = false +disallow_incomplete_defs = false + +[[tool.mypy.overrides]] +module = "check_sdist.*" +disallow_untyped_defs = true +disallow_incomplete_defs = true [tool.ruff] diff --git a/src/check_sdist/__main__.py b/src/check_sdist/__main__.py index 4a13f83..4eeb47c 100644 --- a/src/check_sdist/__main__.py +++ b/src/check_sdist/__main__.py @@ -13,7 +13,7 @@ from .sdist import sdist_files -def compare(source_dir: Path, isolated: bool, verbose: bool = False) -> int: +def compare(source_dir: Path, *, isolated: bool, verbose: bool = False) -> int: """ Compare the files in the SDist with the files tracked by git. @@ -41,6 +41,7 @@ def compare(source_dir: Path, isolated: bool, verbose: bool = False) -> int: if default_ignore: with resources.joinpath("default-ignore.txt").open("r", encoding="utf-8") as f: git_only_patterns.extend(f.read().splitlines()) + sdist_only_patterns.extend("*.dist-info") sdist_spec = pathspec.GitIgnoreSpec.from_lines(sdist_only_patterns) git_spec = pathspec.GitIgnoreSpec.from_lines(git_only_patterns) @@ -99,7 +100,9 @@ def main() -> None: if args.inject_junk: stack.enter_context(inject_junk_files(args.source_dir)) - raise SystemExit(compare(args.source_dir, not args.no_isolation, args.verbose)) + raise SystemExit( + compare(args.source_dir, isolated=not args.no_isolation, verbose=args.verbose) + ) if __name__ == "__main__": diff --git a/src/check_sdist/resources/default-ignore.txt b/src/check_sdist/resources/default-ignore.txt index 39159ec..ae73849 100644 --- a/src/check_sdist/resources/default-ignore.txt +++ b/src/check_sdist/resources/default-ignore.txt @@ -4,3 +4,4 @@ noxfile.py .coverage codecov.yml +*.dist-info diff --git a/src/check_sdist/sdist.py b/src/check_sdist/sdist.py index 2a8b05f..82e9b33 100644 --- a/src/check_sdist/sdist.py +++ b/src/check_sdist/sdist.py @@ -23,7 +23,9 @@ def sdist_files(source_dir: Path, isolated: bool) -> frozenset[str]: if len(prefixes) != 1: msg = f"malformted SDist, contains multiple packages {prefixes}" raise AssertionError(msg) - return frozenset(n.split("/", maxsplit=1)[1] for n in tar.getnames()) + return frozenset( + t.name.split("/", maxsplit=1)[1] for t in tar.getmembers() if t.isfile() + ) if __name__ == "__main__": diff --git a/tests/downstream.toml b/tests/downstream.toml new file mode 100644 index 0000000..08fc51f --- /dev/null +++ b/tests/downstream.toml @@ -0,0 +1,23 @@ +[[packages]] +repo = "pypa/build" +ref = "0.10.0" +fail = 2 + +[[packages]] +repo = "FriedrichFroebel/pelican-youtube-thumbnails" +ref = "0.3.2" +fail = 2 + +[[packages]] +repo = "pypa/setuptools" +ref = "v67.6.1" +fail = 2 + +[[packages]] +repo = "scikit-build/scikit-build-core" +ref = "v0.2.1" + +[[packages]] +repo = "pybind/pybind11" +ref = "v2.10.3" +fail = 2 diff --git a/tests/test_downstream.py b/tests/test_downstream.py new file mode 100644 index 0000000..c7a5d9a --- /dev/null +++ b/tests/test_downstream.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +import subprocess +from pathlib import Path + +import pytest + +from check_sdist.__main__ import compare +from check_sdist._compat import tomllib + +DIR = Path(__file__).parent.resolve() + +with DIR.joinpath("downstream.toml").open("rb") as f: + packages = tomllib.load(f)["packages"] + + +@pytest.mark.parametrize( + ("repo", "ref", "fail"), [(x["repo"], x["ref"], x.get("fail", 0)) for x in packages] +) +def test_packages(repo, ref, fail, tmp_path, monkeypatch): + monkeypatch.chdir(tmp_path) + subprocess.run( + ["git", "clone", f"https://github.com/{repo}", "--branch", ref], check=True + ) + package_path = tmp_path / repo.split("/")[1] + assert compare(package_path, isolated=True) == fail diff --git a/tests/test_package.py b/tests/test_package.py index 942ea78..5570204 100644 --- a/tests/test_package.py +++ b/tests/test_package.py @@ -16,7 +16,7 @@ def get_all_files(path: Path) -> frozenset[str]: def test_self_dir(): start = get_all_files(DIR.parent) - assert compare(DIR.parent, True) == 0 + assert compare(DIR.parent, isolated=True) == 0 end = get_all_files(DIR.parent) assert start == end @@ -24,6 +24,6 @@ def test_self_dir(): def test_self_dir_injected(): start = get_all_files(DIR.parent) with inject_junk_files(DIR.parent): - assert compare(DIR.parent, True) == 0 + assert compare(DIR.parent, isolated=True) == 0 end = get_all_files(DIR.parent) assert start == end From d9470e918b6f96af3ab8d0baddf530eb701a52a2 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 12 Apr 2023 11:22:10 -0400 Subject: [PATCH 8/8] chore: bump version --- src/check_sdist/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/check_sdist/__init__.py b/src/check_sdist/__init__.py index 36a00c1..1b718b0 100644 --- a/src/check_sdist/__init__.py +++ b/src/check_sdist/__init__.py @@ -7,6 +7,6 @@ from __future__ import annotations -__version__ = "0.1.0" +__version__ = "0.1.1" __all__ = ["__version__"]