From 6859d6dbdc7685dd7f8387c8ee60227eb56f6f04 Mon Sep 17 00:00:00 2001 From: JGStew Date: Wed, 15 Jul 2026 00:40:08 -0400 Subject: [PATCH 1/4] renaming it --- .github/workflows/tag_and_release.yaml | 2 +- .github/workflows/test_build.yaml | 14 ++-- .pre-commit-config.yaml | 24 +++---- README.md | 14 ++-- .../__init__.py | 0 .../add_main_docstring.py | 0 .../autopkg_processor_check_conventions.py | 0 .../autopkg_recipe_check_conventions.py | 0 .../bigfix_bes_check_conventions.py | 0 .../fix_files_to_ascii.py | 0 .../git_clean.py | 0 .../github_action_set_output_fix.py | 2 +- .../minimum_changes.py | 0 .../regex_search_filter_replace.py | 0 .../revert_missing_change.py | 0 .../shared_utils.py | 0 .../validate_bes.py | 0 .../validate_plist.py | 0 .../verify_files_are_ascii.py | 0 .../verify_files_contain_entry.py | 0 .../verify_files_contain_pattern.py | 0 pyproject.toml | 2 +- setup.cfg | 36 +++++----- tests/conftest.py | 2 +- tests/test_add_main_docstring.py | 4 +- ...est_autopkg_processor_check_conventions.py | 4 +- .../test_autopkg_recipe_check_conventions.py | 4 +- tests/test_bigfix_bes_check_conventions.py | 4 +- tests/test_fix_files_to_ascii.py | 4 +- tests/test_git_clean.py | 4 +- tests/test_github_action_set_output_fix.py | 4 +- tests/test_minimum_changes.py | 4 +- tests/test_package_rename.py | 72 +++++++++++++++++++ tests/test_regex_search_filter_replace.py | 4 +- tests/test_revert_missing_change.py | 4 +- tests/test_shared_utils.py | 4 +- tests/test_validate_bes.py | 4 +- tests/test_validate_plist.py | 4 +- tests/test_verify_files_are_ascii.py | 4 +- tests/test_verify_files_contain_entry.py | 4 +- tests/test_verify_files_contain_pattern.py | 4 +- 41 files changed, 152 insertions(+), 80 deletions(-) rename {pre_commit_hooks => pre_commit_jgstew}/__init__.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/add_main_docstring.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/autopkg_processor_check_conventions.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/autopkg_recipe_check_conventions.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/bigfix_bes_check_conventions.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/fix_files_to_ascii.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/git_clean.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/github_action_set_output_fix.py (97%) rename {pre_commit_hooks => pre_commit_jgstew}/minimum_changes.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/regex_search_filter_replace.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/revert_missing_change.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/shared_utils.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/validate_bes.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/validate_plist.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/verify_files_are_ascii.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/verify_files_contain_entry.py (100%) rename {pre_commit_hooks => pre_commit_jgstew}/verify_files_contain_pattern.py (100%) create mode 100644 tests/test_package_rename.py diff --git a/.github/workflows/tag_and_release.yaml b/.github/workflows/tag_and_release.yaml index 673e273..9cbbf53 100644 --- a/.github/workflows/tag_and_release.yaml +++ b/.github/workflows/tag_and_release.yaml @@ -6,7 +6,7 @@ on: branches: - main paths: - - "pre_commit_hooks/__init__.py" + - "pre_commit_jgstew/__init__.py" - ".github/workflows/tag_and_release.yaml" # creates git tags and GitHub releases (and uploads the wheel), so the job diff --git a/.github/workflows/test_build.yaml b/.github/workflows/test_build.yaml index 5bac0aa..9089f42 100644 --- a/.github/workflows/test_build.yaml +++ b/.github/workflows/test_build.yaml @@ -44,7 +44,7 @@ jobs: run: if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Test python import from src shell: bash - run: python -c "import pre_commit_hooks; print(pre_commit_hooks.__version__)" + run: python -c "import pre_commit_jgstew; print(pre_commit_jgstew.__version__)" - name: Run pytest shell: bash run: | @@ -65,22 +65,22 @@ jobs: run: pip install $(find "dist" -type f -name "*.whl") - name: Test python import shell: bash - run: python -c "import pre_commit_hooks; print(pre_commit_hooks.__version__)" + run: python -c "import pre_commit_jgstew; print(pre_commit_jgstew.__version__)" - name: Test pre-commit hook invoke shell: bash - run: python -c "import pre_commit_hooks.git_clean; pre_commit_hooks.git_clean.main()" + run: python -c "import pre_commit_jgstew.git_clean; pre_commit_jgstew.git_clean.main()" - name: Test pre-commit hook invoke shell: bash - run: python -c "import pre_commit_hooks.minimum_changes; pre_commit_hooks.minimum_changes.main()" + run: python -c "import pre_commit_jgstew.minimum_changes; pre_commit_jgstew.minimum_changes.main()" - name: Test pre-commit hook invoke shell: bash - run: python -c "import pre_commit_hooks.regex_search_filter_replace; pre_commit_hooks.regex_search_filter_replace.main()" + run: python -c "import pre_commit_jgstew.regex_search_filter_replace; pre_commit_jgstew.regex_search_filter_replace.main()" - name: Test pre-commit hook invoke shell: bash - run: python -c "import pre_commit_hooks.revert_missing_change; pre_commit_hooks.revert_missing_change.main()" + run: python -c "import pre_commit_jgstew.revert_missing_change; pre_commit_jgstew.revert_missing_change.main()" - name: Test pre-commit hook invoke shell: bash - run: python -c "import pre_commit_hooks.validate_plist; pre_commit_hooks.validate_plist.main()" + run: python -c "import pre_commit_jgstew.validate_plist; pre_commit_jgstew.validate_plist.main()" - name: pip install of pre-commit shell: bash run: pip install pre-commit diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3845d7d..b871052 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -105,7 +105,7 @@ repos: stages: [manual] - id: python-use-type-annotations stages: [manual] - exclude: ^pre_commit_hooks/autopkg_recipe_check_conventions.py$ + exclude: ^pre_commit_jgstew/autopkg_recipe_check_conventions.py$ - id: python-no-eval stages: [manual] - id: python-check-blanket-type-ignore @@ -127,7 +127,7 @@ repos: (?x)^( README.md| pyproject.toml| - pre_commit_hooks/__init__.py| + pre_commit_jgstew/__init__.py| setup.cfg| setup.py )$ @@ -201,7 +201,7 @@ repos: # - anyascii # Local Hooks: - # https://towardsdatascience.com/getting-started-with-python-pre-commit-hooks-28be2b2d09d5 + # https://towardsdatascience.com/getting-started-with-python-pre-commit-jgstew-28be2b2d09d5 # language: python -> pre-commit provisions an isolated venv, so bare `python` # always resolves (no dependence on a system `python` shim). Third-party # imports must be declared via additional_dependencies. @@ -209,7 +209,7 @@ repos: hooks: - id: validate-bes-local name: validate-bes-local - entry: python pre_commit_hooks/validate_bes.py + entry: python pre_commit_jgstew/validate_bes.py language: python # isolated venv: declare the third-party import used by validate_bes.py additional_dependencies: [validate_bes_xml] @@ -219,7 +219,7 @@ repos: hooks: - id: verify-files-contain-entry-local name: verify-files-contain-entry-local - entry: python pre_commit_hooks/verify_files_contain_entry.py + entry: python pre_commit_jgstew/verify_files_contain_entry.py language: python pass_filenames: True files: \.bes$ @@ -232,7 +232,7 @@ repos: hooks: - id: verify-files-contain-pattern-local name: verify-files-contain-pattern-local - entry: python pre_commit_hooks/verify_files_contain_pattern.py + entry: python pre_commit_jgstew/verify_files_contain_pattern.py language: python pass_filenames: True files: \.test_file$ @@ -241,7 +241,7 @@ repos: hooks: - id: minimum-changes-local name: minimum-changes-local - entry: python pre_commit_hooks/minimum_changes.py + entry: python pre_commit_jgstew/minimum_changes.py language: python pass_filenames: True args: [--min-changes=2] @@ -250,14 +250,14 @@ repos: hooks: - id: git-clean name: git-clean-local - entry: python pre_commit_hooks/git_clean.py + entry: python pre_commit_jgstew/git_clean.py language: python files: .test_file # - repo: local # hooks: # - id: revert-missing-change # name: revert-missing-change-local - # entry: python pre_commit_hooks/revert_missing_change.py + # entry: python pre_commit_jgstew/revert_missing_change.py # language: python # pass_filenames: True # args: ['--change_regex=v[0-9]+(\.[0-9]+)*\s*'] @@ -266,7 +266,7 @@ repos: hooks: - id: github-action-set-output-fix name: github-action-set-output-fix-local - entry: python pre_commit_hooks/github_action_set_output_fix.py + entry: python pre_commit_jgstew/github_action_set_output_fix.py language: python pass_filenames: True args: ['--overwrite'] @@ -284,7 +284,7 @@ repos: hooks: - id: add-missing-docstrings name: add-missing-docstrings - entry: python pre_commit_hooks/add_main_docstring.py + entry: python pre_commit_jgstew/add_main_docstring.py language: python pass_filenames: True - repo: local @@ -294,7 +294,7 @@ repos: # `check-processor-conventions` hook; see README / jgstew-recipes. - id: check-processor-conventions name: check-processor-conventions-local - entry: python pre_commit_hooks/autopkg_processor_check_conventions.py + entry: python pre_commit_jgstew/autopkg_processor_check_conventions.py language: python pass_filenames: True args: ["--auto-fix=no"] diff --git a/README.md b/README.md index 4afdf19..70b7a49 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# pre-commit-hooks +# pre-commit-jgstew custom pre-commit hooks by JGStew. @@ -48,9 +48,9 @@ The AutoPkg convention hooks (`check-processor-conventions`, `check-recipe-conve ## Test commands: -- test python import and version: `python -c "import pre_commit_hooks; print(pre_commit_hooks.__version__)"` +- test python import and version: `python -c "import pre_commit_jgstew; print(pre_commit_jgstew.__version__)"` - test version defined through [setup.py](setup.py): `python setup.py --version` - - version defined in [setup.cfg](setup.cfg): `version = attr: pre_commit_hooks.__version__` + - version defined in [setup.cfg](setup.cfg): `version = attr: pre_commit_jgstew.__version__` - test builds: - `python ./setup.py build` - `python -m build` @@ -58,19 +58,19 @@ The AutoPkg convention hooks (`check-processor-conventions`, `check-recipe-conve ## creating a new hook to add to this repo: -create python file in folder [pre_commit_hooks](pre_commit_hooks) with name of hook with underscores.py +create python file in folder [pre_commit_jgstew](pre_commit_jgstew) with name of hook with underscores.py add entrypoint to the [setup.cfg](setup.cfg) file -add hook definition to the [.pre-commit-hooks.yaml](.pre-commit-hooks.yaml) file +add hook definition to the [.pre-commit-jgstew.yaml](.pre-commit-jgstew.yaml) file add example hook to actually use in the [.pre-commit-config.yaml](.pre-commit-config.yaml) file ## Related: - https://github.com/homebysix/pre-commit-macadmin -- https://github.com/jumanjihouse/pre-commit-hooks -- https://github.com/Lucas-C/pre-commit-hooks +- https://github.com/jumanjihouse/pre-commit-jgstew +- https://github.com/Lucas-C/pre-commit-jgstew - https://github.com/jumanjihouse/pre-commit-hook-yamlfmt - https://pre-commit.com/hooks.html - https://pre-commit.com/#new-hooks diff --git a/pre_commit_hooks/__init__.py b/pre_commit_jgstew/__init__.py similarity index 100% rename from pre_commit_hooks/__init__.py rename to pre_commit_jgstew/__init__.py diff --git a/pre_commit_hooks/add_main_docstring.py b/pre_commit_jgstew/add_main_docstring.py similarity index 100% rename from pre_commit_hooks/add_main_docstring.py rename to pre_commit_jgstew/add_main_docstring.py diff --git a/pre_commit_hooks/autopkg_processor_check_conventions.py b/pre_commit_jgstew/autopkg_processor_check_conventions.py similarity index 100% rename from pre_commit_hooks/autopkg_processor_check_conventions.py rename to pre_commit_jgstew/autopkg_processor_check_conventions.py diff --git a/pre_commit_hooks/autopkg_recipe_check_conventions.py b/pre_commit_jgstew/autopkg_recipe_check_conventions.py similarity index 100% rename from pre_commit_hooks/autopkg_recipe_check_conventions.py rename to pre_commit_jgstew/autopkg_recipe_check_conventions.py diff --git a/pre_commit_hooks/bigfix_bes_check_conventions.py b/pre_commit_jgstew/bigfix_bes_check_conventions.py similarity index 100% rename from pre_commit_hooks/bigfix_bes_check_conventions.py rename to pre_commit_jgstew/bigfix_bes_check_conventions.py diff --git a/pre_commit_hooks/fix_files_to_ascii.py b/pre_commit_jgstew/fix_files_to_ascii.py similarity index 100% rename from pre_commit_hooks/fix_files_to_ascii.py rename to pre_commit_jgstew/fix_files_to_ascii.py diff --git a/pre_commit_hooks/git_clean.py b/pre_commit_jgstew/git_clean.py similarity index 100% rename from pre_commit_hooks/git_clean.py rename to pre_commit_jgstew/git_clean.py diff --git a/pre_commit_hooks/github_action_set_output_fix.py b/pre_commit_jgstew/github_action_set_output_fix.py similarity index 97% rename from pre_commit_hooks/github_action_set_output_fix.py rename to pre_commit_jgstew/github_action_set_output_fix.py index 81b92de..cdd1c86 100644 --- a/pre_commit_hooks/github_action_set_output_fix.py +++ b/pre_commit_jgstew/github_action_set_output_fix.py @@ -21,7 +21,7 @@ echo +(["']::set-output +name=(\S+?)::(.+?)["'])(?:$| \|) Invoke this standalone: -python3 pre_commit_hooks/github_action_set_output_fix.py .github/workflows/tag_and_release.yaml +python3 pre_commit_jgstew/github_action_set_output_fix.py .github/workflows/tag_and_release.yaml """ import argparse diff --git a/pre_commit_hooks/minimum_changes.py b/pre_commit_jgstew/minimum_changes.py similarity index 100% rename from pre_commit_hooks/minimum_changes.py rename to pre_commit_jgstew/minimum_changes.py diff --git a/pre_commit_hooks/regex_search_filter_replace.py b/pre_commit_jgstew/regex_search_filter_replace.py similarity index 100% rename from pre_commit_hooks/regex_search_filter_replace.py rename to pre_commit_jgstew/regex_search_filter_replace.py diff --git a/pre_commit_hooks/revert_missing_change.py b/pre_commit_jgstew/revert_missing_change.py similarity index 100% rename from pre_commit_hooks/revert_missing_change.py rename to pre_commit_jgstew/revert_missing_change.py diff --git a/pre_commit_hooks/shared_utils.py b/pre_commit_jgstew/shared_utils.py similarity index 100% rename from pre_commit_hooks/shared_utils.py rename to pre_commit_jgstew/shared_utils.py diff --git a/pre_commit_hooks/validate_bes.py b/pre_commit_jgstew/validate_bes.py similarity index 100% rename from pre_commit_hooks/validate_bes.py rename to pre_commit_jgstew/validate_bes.py diff --git a/pre_commit_hooks/validate_plist.py b/pre_commit_jgstew/validate_plist.py similarity index 100% rename from pre_commit_hooks/validate_plist.py rename to pre_commit_jgstew/validate_plist.py diff --git a/pre_commit_hooks/verify_files_are_ascii.py b/pre_commit_jgstew/verify_files_are_ascii.py similarity index 100% rename from pre_commit_hooks/verify_files_are_ascii.py rename to pre_commit_jgstew/verify_files_are_ascii.py diff --git a/pre_commit_hooks/verify_files_contain_entry.py b/pre_commit_jgstew/verify_files_contain_entry.py similarity index 100% rename from pre_commit_hooks/verify_files_contain_entry.py rename to pre_commit_jgstew/verify_files_contain_entry.py diff --git a/pre_commit_hooks/verify_files_contain_pattern.py b/pre_commit_jgstew/verify_files_contain_pattern.py similarity index 100% rename from pre_commit_hooks/verify_files_contain_pattern.py rename to pre_commit_jgstew/verify_files_contain_pattern.py diff --git a/pyproject.toml b/pyproject.toml index de22102..69e3bfd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ build-backend = "setuptools.build_meta" ignore-words-list = "caf" [tool.pytest.ini_options] -# Put the repo root on sys.path so `from pre_commit_hooks import ...` resolves +# Put the repo root on sys.path so `from pre_commit_jgstew import ...` resolves # from source without the package being installed. Without this, running the # bare `pytest` console script (as the pre-commit pytest hook does, in an # isolated env where the package is not installed) fails to import the package. diff --git a/setup.cfg b/setup.cfg index dd1f7af..870338b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] -name = pre-commit-hooks -version = attr: pre_commit_hooks.__version__ +name = pre-commit-jgstew +version = attr: pre_commit_jgstew.__version__ author = JGStew author_email = noreply@jgstew.com description = custom Python based pre-commit hooks @@ -22,7 +22,7 @@ classifiers = [options] package_dir = = . -packages = pre_commit_hooks +packages = pre_commit_jgstew python_requires = >=3.5 install_requires = validate_bes_xml @@ -38,18 +38,18 @@ test = [options.entry_points] console_scripts = - minimum-changes = pre_commit_hooks.minimum_changes:main - validate-bes = pre_commit_hooks.validate_bes:main - verify-files-contain-entry = pre_commit_hooks.verify_files_contain_entry:main - verify-files-contain-pattern = pre_commit_hooks.verify_files_contain_pattern:main - verify-files-are-ascii = pre_commit_hooks.verify_files_are_ascii:main - fix-files-to-ascii = pre_commit_hooks.fix_files_to_ascii:main - git-clean = pre_commit_hooks.git_clean:main - regex-search-filter-replace = pre_commit_hooks.regex_search_filter_replace:main - revert-missing-change = pre_commit_hooks.revert_missing_change:main - validate-plist = pre_commit_hooks.validate_plist:main - github-action-set-output-fix = pre_commit_hooks.github_action_set_output_fix:main - add-missing-docstrings = pre_commit_hooks.add_main_docstring:main - check-processor-conventions = pre_commit_hooks.autopkg_processor_check_conventions:main - check-recipe-conventions = pre_commit_hooks.autopkg_recipe_check_conventions:main - check-bes-conventions = pre_commit_hooks.bigfix_bes_check_conventions:main + minimum-changes = pre_commit_jgstew.minimum_changes:main + validate-bes = pre_commit_jgstew.validate_bes:main + verify-files-contain-entry = pre_commit_jgstew.verify_files_contain_entry:main + verify-files-contain-pattern = pre_commit_jgstew.verify_files_contain_pattern:main + verify-files-are-ascii = pre_commit_jgstew.verify_files_are_ascii:main + fix-files-to-ascii = pre_commit_jgstew.fix_files_to_ascii:main + git-clean = pre_commit_jgstew.git_clean:main + regex-search-filter-replace = pre_commit_jgstew.regex_search_filter_replace:main + revert-missing-change = pre_commit_jgstew.revert_missing_change:main + validate-plist = pre_commit_jgstew.validate_plist:main + github-action-set-output-fix = pre_commit_jgstew.github_action_set_output_fix:main + add-missing-docstrings = pre_commit_jgstew.add_main_docstring:main + check-processor-conventions = pre_commit_jgstew.autopkg_processor_check_conventions:main + check-recipe-conventions = pre_commit_jgstew.autopkg_recipe_check_conventions:main + check-bes-conventions = pre_commit_jgstew.bigfix_bes_check_conventions:main diff --git a/tests/conftest.py b/tests/conftest.py index 6aedd86..f488c1b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,4 @@ -"""Shared pytest fixtures for the pre_commit_hooks test suite.""" +"""Shared pytest fixtures for the pre_commit_jgstew test suite.""" import subprocess from pathlib import Path diff --git a/tests/test_add_main_docstring.py b/tests/test_add_main_docstring.py index 6671084..908c7c8 100644 --- a/tests/test_add_main_docstring.py +++ b/tests/test_add_main_docstring.py @@ -1,8 +1,8 @@ -"""Tests for pre_commit_hooks/add_main_docstring.py.""" +"""Tests for pre_commit_jgstew/add_main_docstring.py.""" import sys -from pre_commit_hooks import add_main_docstring as hook +from pre_commit_jgstew import add_main_docstring as hook MISSING = """\ def main(): diff --git a/tests/test_autopkg_processor_check_conventions.py b/tests/test_autopkg_processor_check_conventions.py index a64cadd..1936347 100644 --- a/tests/test_autopkg_processor_check_conventions.py +++ b/tests/test_autopkg_processor_check_conventions.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Tests for pre_commit_hooks/autopkg_processor_check_conventions.py. +"""Tests for pre_commit_jgstew/autopkg_processor_check_conventions.py. These exercise the public helpers (processor detection, the stub heuristic, discovery) and the check/auto-fix pipeline via check_file/check_files, plus the @@ -16,7 +16,7 @@ import pytest -from pre_commit_hooks import autopkg_processor_check_conventions as checker +from pre_commit_jgstew import autopkg_processor_check_conventions as checker # A fully convention-conforming processor (no E-codes expected). The class name # must match the filename stem, so write this as `ExampleClean.py`. diff --git a/tests/test_autopkg_recipe_check_conventions.py b/tests/test_autopkg_recipe_check_conventions.py index 7566976..f19e637 100644 --- a/tests/test_autopkg_recipe_check_conventions.py +++ b/tests/test_autopkg_recipe_check_conventions.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Tests for pre_commit_hooks/autopkg_recipe_check_conventions.py. +"""Tests for pre_commit_jgstew/autopkg_recipe_check_conventions.py. These exercise the recipe convention checks (W100-W123), their auto-fixers, the file-level opt-out markers, and main()'s exit codes. Cross-file checks (duplicate @@ -11,7 +11,7 @@ import pytest -from pre_commit_hooks import autopkg_recipe_check_conventions as checker +from pre_commit_jgstew import autopkg_recipe_check_conventions as checker PLIST = """ diff --git a/tests/test_bigfix_bes_check_conventions.py b/tests/test_bigfix_bes_check_conventions.py index 4bdd4ca..8167a2c 100644 --- a/tests/test_bigfix_bes_check_conventions.py +++ b/tests/test_bigfix_bes_check_conventions.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Tests for pre_commit_hooks/bigfix_bes_check_conventions.py. +"""Tests for pre_commit_jgstew/bigfix_bes_check_conventions.py. These exercise the BES content checks (E200-E214, W200-W211), the auto-fixers (DownloadSize, missing dates, blank-line collapse, CDATA wrap, Title trim, @@ -11,7 +11,7 @@ import pytest -from pre_commit_hooks import bigfix_bes_check_conventions as checker +from pre_commit_jgstew import bigfix_bes_check_conventions as checker FIXED_NOW = datetime(2026, 7, 14, 18, 32, 35, tzinfo=timezone.utc) diff --git a/tests/test_fix_files_to_ascii.py b/tests/test_fix_files_to_ascii.py index 7f31dd9..567ca47 100644 --- a/tests/test_fix_files_to_ascii.py +++ b/tests/test_fix_files_to_ascii.py @@ -1,4 +1,4 @@ -"""Tests for pre_commit_hooks/fix_files_to_ascii.py. +"""Tests for pre_commit_jgstew/fix_files_to_ascii.py. Requires the `anyascii` package (installed via install_requires); skipped where it is not available. @@ -8,7 +8,7 @@ pytest.importorskip("anyascii") -from pre_commit_hooks import fix_files_to_ascii as hook # noqa: E402 +from pre_commit_jgstew import fix_files_to_ascii as hook # noqa: E402 def write(tmp_path, name, text): diff --git a/tests/test_git_clean.py b/tests/test_git_clean.py index 8fc4bac..38825db 100644 --- a/tests/test_git_clean.py +++ b/tests/test_git_clean.py @@ -1,6 +1,6 @@ -"""Tests for pre_commit_hooks/git_clean.py.""" +"""Tests for pre_commit_jgstew/git_clean.py.""" -from pre_commit_hooks import git_clean as hook +from pre_commit_jgstew import git_clean as hook def test_clean_repo_reports_zero(git_repo, monkeypatch): diff --git a/tests/test_github_action_set_output_fix.py b/tests/test_github_action_set_output_fix.py index 0e5cc63..0871251 100644 --- a/tests/test_github_action_set_output_fix.py +++ b/tests/test_github_action_set_output_fix.py @@ -1,6 +1,6 @@ -"""Tests for pre_commit_hooks/github_action_set_output_fix.py.""" +"""Tests for pre_commit_jgstew/github_action_set_output_fix.py.""" -from pre_commit_hooks import github_action_set_output_fix as hook +from pre_commit_jgstew import github_action_set_output_fix as hook SET_OUTPUT_LINE = ' run: echo "::set-output name=version::1.2.3"\n' SAVE_STATE_LINE = ' run: echo "::save-state name=foo::bar"\n' diff --git a/tests/test_minimum_changes.py b/tests/test_minimum_changes.py index d213b51..3b0c774 100644 --- a/tests/test_minimum_changes.py +++ b/tests/test_minimum_changes.py @@ -1,6 +1,6 @@ -"""Tests for pre_commit_hooks/minimum_changes.py.""" +"""Tests for pre_commit_jgstew/minimum_changes.py.""" -from pre_commit_hooks import minimum_changes as hook +from pre_commit_jgstew import minimum_changes as hook def test_small_staged_change_fails(git_repo, monkeypatch): diff --git a/tests/test_package_rename.py b/tests/test_package_rename.py new file mode 100644 index 0000000..252eaea --- /dev/null +++ b/tests/test_package_rename.py @@ -0,0 +1,72 @@ +"""Tests guarding the pre_commit_hooks -> pre_commit_jgstew package rename. + +These verify the package directory, the distribution name in setup.cfg, and +that the old name is no longer referenced anywhere in the packaging metadata. +""" + +import configparser +import importlib +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parent.parent +PACKAGE = "pre_commit_jgstew" +DIST_NAME = "pre-commit-jgstew" + + +def test_new_package_is_importable(): + """The renamed package imports and exposes a version.""" + module = importlib.import_module(PACKAGE) + assert hasattr(module, "__version__") + assert module.__version__ + + +def test_old_package_directory_is_gone(): + """The old package directory no longer exists.""" + assert not (REPO_ROOT / "pre_commit_hooks").exists() + + +def test_new_package_directory_exists(): + """The renamed package directory exists with an __init__.py.""" + pkg_dir = REPO_ROOT / PACKAGE + assert pkg_dir.is_dir() + assert (pkg_dir / "__init__.py").is_file() + + +def _read_setup_cfg(): + parser = configparser.ConfigParser() + parser.read(REPO_ROOT / "setup.cfg", encoding="utf-8") + return parser + + +def test_setup_cfg_distribution_name(): + """The setup.cfg declares the new distribution name.""" + parser = _read_setup_cfg() + assert parser["metadata"]["name"] == DIST_NAME + + +def test_setup_cfg_packages_reference_new_name(): + """The setup.cfg packages/version attr point at the new package.""" + parser = _read_setup_cfg() + assert parser["options"]["packages"].strip() == PACKAGE + assert PACKAGE in parser["metadata"]["version"] + + +def test_setup_cfg_entry_points_reference_new_package(): + """Every console_scripts entry point targets the new package.""" + parser = _read_setup_cfg() + entry_points = parser["options.entry_points"]["console_scripts"] + assert entry_points.strip() + assert "pre_commit_hooks." not in entry_points + for line in entry_points.strip().splitlines(): + line = line.strip() + if not line: + continue + # each mapping looks like "name = pre_commit_jgstew.module:main" + assert line.split("=", 1)[1].strip().startswith(PACKAGE + ".") + + +def test_setup_cfg_has_no_old_name(): + """No stale references to the old dashed or underscored name remain.""" + text = (REPO_ROOT / "setup.cfg").read_text(encoding="utf-8") + assert "pre-commit-hooks" not in text + assert "pre_commit_hooks" not in text diff --git a/tests/test_regex_search_filter_replace.py b/tests/test_regex_search_filter_replace.py index 631ea55..3c9511e 100644 --- a/tests/test_regex_search_filter_replace.py +++ b/tests/test_regex_search_filter_replace.py @@ -1,8 +1,8 @@ -"""Tests for pre_commit_hooks/regex_search_filter_replace.py.""" +"""Tests for pre_commit_jgstew/regex_search_filter_replace.py.""" import pytest -from pre_commit_hooks import regex_search_filter_replace as hook +from pre_commit_jgstew import regex_search_filter_replace as hook def write(tmp_path, name, content): diff --git a/tests/test_revert_missing_change.py b/tests/test_revert_missing_change.py index 64c596e..7bf56cf 100644 --- a/tests/test_revert_missing_change.py +++ b/tests/test_revert_missing_change.py @@ -1,10 +1,10 @@ -"""Tests for pre_commit_hooks/revert_missing_change.py.""" +"""Tests for pre_commit_jgstew/revert_missing_change.py.""" import subprocess import pytest -from pre_commit_hooks import revert_missing_change as hook +from pre_commit_jgstew import revert_missing_change as hook def test_no_files_returns_zero(): diff --git a/tests/test_shared_utils.py b/tests/test_shared_utils.py index 1b25a83..8c09fc7 100644 --- a/tests/test_shared_utils.py +++ b/tests/test_shared_utils.py @@ -1,10 +1,10 @@ -"""Tests for pre_commit_hooks/shared_utils.py.""" +"""Tests for pre_commit_jgstew/shared_utils.py.""" import subprocess import pytest -from pre_commit_hooks import shared_utils +from pre_commit_jgstew import shared_utils def test_validate_filepath_ok(tmp_path): diff --git a/tests/test_validate_bes.py b/tests/test_validate_bes.py index 0d2348c..38178c0 100644 --- a/tests/test_validate_bes.py +++ b/tests/test_validate_bes.py @@ -1,4 +1,4 @@ -"""Tests for pre_commit_hooks/validate_bes.py. +"""Tests for pre_commit_jgstew/validate_bes.py. Requires the `validate_bes_xml` package (installed via requirements.txt in CI); skipped where it is not available. @@ -12,7 +12,7 @@ pytest.importorskip("validate_bes_xml") -from pre_commit_hooks import validate_bes as hook # noqa: E402 +from pre_commit_jgstew import validate_bes as hook # noqa: E402 def test_valid_bes_passes(): diff --git a/tests/test_validate_plist.py b/tests/test_validate_plist.py index 920c3eb..630934f 100644 --- a/tests/test_validate_plist.py +++ b/tests/test_validate_plist.py @@ -1,4 +1,4 @@ -"""Tests for pre_commit_hooks/validate_plist.py. +"""Tests for pre_commit_jgstew/validate_plist.py. Requires the `validate_plist_xml` package (installed via requirements.txt in CI); skipped where it is not available. @@ -12,7 +12,7 @@ pytest.importorskip("validate_plist_xml") -from pre_commit_hooks import validate_plist as hook # noqa: E402 +from pre_commit_jgstew import validate_plist as hook # noqa: E402 def test_valid_plist_passes(): diff --git a/tests/test_verify_files_are_ascii.py b/tests/test_verify_files_are_ascii.py index 7f149ed..92f512e 100644 --- a/tests/test_verify_files_are_ascii.py +++ b/tests/test_verify_files_are_ascii.py @@ -1,6 +1,6 @@ -"""Tests for pre_commit_hooks/verify_files_are_ascii.py.""" +"""Tests for pre_commit_jgstew/verify_files_are_ascii.py.""" -from pre_commit_hooks import verify_files_are_ascii as hook +from pre_commit_jgstew import verify_files_are_ascii as hook def write(tmp_path, name, content): diff --git a/tests/test_verify_files_contain_entry.py b/tests/test_verify_files_contain_entry.py index 2e6ec65..af1a225 100644 --- a/tests/test_verify_files_contain_entry.py +++ b/tests/test_verify_files_contain_entry.py @@ -1,8 +1,8 @@ -"""Tests for pre_commit_hooks/verify_files_contain_entry.py.""" +"""Tests for pre_commit_jgstew/verify_files_contain_entry.py.""" from pathlib import Path -from pre_commit_hooks import verify_files_contain_entry as hook +from pre_commit_jgstew import verify_files_contain_entry as hook EXAMPLES = Path(__file__).parent / "examples" REF = str(EXAMPLES / "example.test_file") diff --git a/tests/test_verify_files_contain_pattern.py b/tests/test_verify_files_contain_pattern.py index fcabce0..d5118d5 100644 --- a/tests/test_verify_files_contain_pattern.py +++ b/tests/test_verify_files_contain_pattern.py @@ -1,6 +1,6 @@ -"""Tests for pre_commit_hooks/verify_files_contain_pattern.py.""" +"""Tests for pre_commit_jgstew/verify_files_contain_pattern.py.""" -from pre_commit_hooks import verify_files_contain_pattern as hook +from pre_commit_jgstew import verify_files_contain_pattern as hook def write(tmp_path, name, content): From ff428391a33b951c2f91428de35aeb10a3ae712c Mon Sep 17 00:00:00 2001 From: JGStew Date: Wed, 15 Jul 2026 00:45:07 -0400 Subject: [PATCH 2/4] new test --- tests/test_setup_version.py | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/test_setup_version.py diff --git a/tests/test_setup_version.py b/tests/test_setup_version.py new file mode 100644 index 0000000..3ffcdc4 --- /dev/null +++ b/tests/test_setup_version.py @@ -0,0 +1,39 @@ +"""Test that `setup.py --version` emits a well-formed version string. + +Mirrors running `python ./setup.py --version` at the command line. It only +checks the shape (int.int.int), not the exact value, so it does not need +updating on every release. +""" + +import importlib.util +import re +import subprocess +import sys +from pathlib import Path + +import pytest + +REPO_ROOT = Path(__file__).resolve().parent.parent + +# `setup.py` needs setuptools in the interpreter running it. Some minimal test +# environments (e.g. an isolated pytest install) lack it; skip rather than fail +# spuriously there. CI installs the build deps, so the check still runs. +_HAS_SETUPTOOLS = importlib.util.find_spec("setuptools") is not None + +# Leading anchor only: setuptools may append pre/post/dev segments (e.g. +# "1.6.3.dev0"), but the core release must be MAJOR.MINOR.PATCH. +VERSION_RE = re.compile(r"^\d+\.\d+\.\d+") + + +@pytest.mark.skipif(not _HAS_SETUPTOOLS, reason="setuptools not available") +def test_setup_py_emits_semver(): + """`setup.py --version` prints an int.int.int version on stdout.""" + result = subprocess.run( + [sys.executable, "setup.py", "--version"], + cwd=REPO_ROOT, + check=True, + capture_output=True, + text=True, + ) + version = result.stdout.strip() + assert VERSION_RE.match(version), f"unexpected version output: {version!r}" From cbc55053840033ce085c38d9d64da2535274325d Mon Sep 17 00:00:00 2001 From: JGStew Date: Wed, 15 Jul 2026 00:50:02 -0400 Subject: [PATCH 3/4] more tests --- tests/test_packaging_metadata.py | 146 +++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 tests/test_packaging_metadata.py diff --git a/tests/test_packaging_metadata.py b/tests/test_packaging_metadata.py new file mode 100644 index 0000000..40b9453 --- /dev/null +++ b/tests/test_packaging_metadata.py @@ -0,0 +1,146 @@ +"""Validate packaging metadata stays internally consistent. + +Three files describe this project's hooks and can silently drift apart: + +* ``setup.cfg`` -- ``console_scripts`` (name = module:function) +* ``.pre-commit-hooks.yaml`` -- pre-commit hook definitions (id, entry, ...) +* the ``pre_commit_jgstew`` package -- the modules/functions behind them + +These tests catch the common regressions: a renamed/deleted module, a typo in +an entry-point target, or a hook whose ``entry`` no longer maps to a real +console script. +""" + +import configparser +import importlib +import importlib.util +from pathlib import Path + +import pytest + +REPO_ROOT = Path(__file__).resolve().parent.parent +PACKAGE = "pre_commit_jgstew" + +_HAS_YAML = importlib.util.find_spec("yaml") is not None +_HAS_TOMLLIB = importlib.util.find_spec("tomllib") is not None + + +def _setup_cfg(): + parser = configparser.ConfigParser() + parser.read(REPO_ROOT / "setup.cfg", encoding="utf-8") + return parser + + +def _console_scripts(): + """Return {script-name: "module:function"} from setup.cfg.""" + raw = _setup_cfg()["options.entry_points"]["console_scripts"] + mapping = {} + for line in raw.strip().splitlines(): + line = line.strip() + if not line: + continue + name, target = line.split("=", 1) + mapping[name.strip()] = target.strip() + return mapping + + +CONSOLE_SCRIPTS = _console_scripts() + + +def _hooks(): + import yaml + + return yaml.safe_load( + (REPO_ROOT / ".pre-commit-hooks.yaml").read_text(encoding="utf-8") + ) + + +# --------------------------------------------------------------------------- # +# setup.cfg console_scripts <-> package modules +# --------------------------------------------------------------------------- # +def test_console_scripts_present(): + """Setup.cfg actually declares console scripts (guards a broken parse).""" + assert CONSOLE_SCRIPTS + + +@pytest.mark.parametrize("name, target", sorted(CONSOLE_SCRIPTS.items())) +def test_entry_point_target_is_importable(name, target): + """Each console_scripts target resolves to a callable in the package.""" + assert ":" in target, f"{name}: entry point {target!r} lacks ':function'" + module_path, func_name = target.split(":", 1) + assert module_path.startswith( + PACKAGE + "." + ), f"{name}: {module_path} is not in the {PACKAGE} package" + try: + module = importlib.import_module(module_path) + except ModuleNotFoundError as exc: + # A missing *third-party* dependency is an environment gap, not a + # metadata bug -- skip like the per-hook tests do. A missing module + # inside our own package IS a bug, so let that fail. + missing = exc.name or "" + if missing.split(".")[0] == PACKAGE: + raise + pytest.skip(f"{name}: optional dependency {missing!r} not installed") + func = getattr(module, func_name, None) + assert callable(func), f"{name}: {target} is not callable" + + +@pytest.mark.parametrize("name, target", sorted(CONSOLE_SCRIPTS.items())) +def test_entry_point_module_file_exists(name, target): + """The module file backing each console script exists on disk.""" + module_path = target.split(":", 1)[0] + relative = Path(*module_path.split(".")).with_suffix(".py") + assert (REPO_ROOT / relative).is_file(), f"{name}: missing {relative}" + + +def test_console_script_names_are_unique(): + """No duplicate console script names (configparser would hide dupes).""" + raw = _setup_cfg()["options.entry_points"]["console_scripts"] + names = [ + line.split("=", 1)[0].strip() + for line in raw.strip().splitlines() + if line.strip() + ] + assert len(names) == len(set(names)), "duplicate console_scripts names" + + +# --------------------------------------------------------------------------- # +# .pre-commit-hooks.yaml +# --------------------------------------------------------------------------- # +@pytest.mark.skipif(not _HAS_YAML, reason="PyYAML not available") +def test_hook_ids_are_unique(): + """Every hook id in .pre-commit-hooks.yaml is unique.""" + ids = [hook["id"] for hook in _hooks()] + assert len(ids) == len(set(ids)), "duplicate hook ids" + + +@pytest.mark.skipif(not _HAS_YAML, reason="PyYAML not available") +def test_hooks_have_required_fields(): + """Each hook declares the fields pre-commit needs to run it.""" + for hook in _hooks(): + for field in ("id", "name", "description", "entry", "language"): + assert hook.get(field), f"hook {hook.get('id')!r} missing {field}" + + +@pytest.mark.skipif(not _HAS_YAML, reason="PyYAML not available") +def test_hook_entries_map_to_console_scripts(): + """Every hook entry is backed by a real console script in setup.cfg.""" + for hook in _hooks(): + entry = hook["entry"].split()[0] # entry may carry trailing args + assert ( + entry in CONSOLE_SCRIPTS + ), f"hook {hook['id']!r} entry {entry!r} has no console_scripts target" + + +# --------------------------------------------------------------------------- # +# pyproject.toml +# --------------------------------------------------------------------------- # +@pytest.mark.skipif(not _HAS_TOMLLIB, reason="tomllib not available (<3.11)") +def test_pyproject_is_valid_and_declares_build_backend(): + """Pyproject.toml parses and names a build backend.""" + import tomllib + + with open(REPO_ROOT / "pyproject.toml", "rb") as handle: + data = tomllib.load(handle) + assert data["build-system"]["build-backend"] + assert data["build-system"]["requires"] From 139e2e97f84ef8b573632a538d022a10f768e220 Mon Sep 17 00:00:00 2001 From: JGStew Date: Wed, 15 Jul 2026 08:23:46 -0400 Subject: [PATCH 4/4] fix readme --- .pre-commit-config.yaml | 1 + README.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b871052..45445ed 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,6 +47,7 @@ repos: hooks: - id: minimum-changes args: [--min-changes=0] + stages: [manual] - id: verify-files-are-ascii - repo: https://github.com/python-jsonschema/check-jsonschema diff --git a/README.md b/README.md index 70b7a49..dde89ff 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,8 @@ add example hook to actually use in the [.pre-commit-config.yaml](.pre-commit-co ## Related: - https://github.com/homebysix/pre-commit-macadmin -- https://github.com/jumanjihouse/pre-commit-jgstew -- https://github.com/Lucas-C/pre-commit-jgstew +- https://github.com/jumanjihouse/pre-commit-hooks +- https://github.com/Lucas-C/pre-commit-hooks - https://github.com/jumanjihouse/pre-commit-hook-yamlfmt - https://pre-commit.com/hooks.html - https://pre-commit.com/#new-hooks