Skip to content

Allow .pre-commit-hooks.yaml hooks to extend repo: builtin hooks #2504

Closed

Description

@pygarap

Summary

Allow .pre-commit-hooks.yaml hooks to extend repo: builtin hooks through a prek-only extends field, for hook authors who publish a repository consumed by end users.

For each extended manifest hook, prek should load the referenced repo: builtin hook as the base implementation, apply the supported hook fields declared in .pre-commit-hooks.yaml, and execute that builtin hook with the resulting configuration.

The referenced hook must be a Rust-native hook available through the Explicit Builtin Repository. The manifest hook can customize its public identity, metadata, filters, arguments, and other supported hook options without requiring a wrapper executable, an external interpreter, or a separate hook environment.

Proposed syntax [.pre-commit-hooks.yaml]

- id: pytest-filename-conventions
  name: Enforce pytest filename conventions
  description: Ensures files under tests/ follow pytest naming conventions (test_*.py, __init__.py, or conftest.py).
  extends:
    repo: builtin
    id: require-filename-pattern
  files: '(^|/)tests/.+\.py$'
  args:
    - '^test_.*\.py$'
    - '^__init__\.py$'
    - '^conftest\.py$'

- id: text-unicode-replacement-char
  name: No Unicode replacement characters
  description: Forbids text files containing the Unicode replacement character U+FFFD.
  extends:
    repo: builtin
    id: deny-pattern
  args:
    - "\uFFFD"
  types: [text]

For pytest-filename-conventions, prek should execute the builtin require-filename-pattern implementation while applying the manifest hook's name, description, files, and args.

For text-unicode-replacement-char, prek should execute the builtin deny-pattern implementation while applying the manifest hook's name, description, args, and types.

Consumers could then use the published hooks as normal remote hooks:

.pre-commit-config.yaml

repos:
  - repo: https://github.com/example/prek-hooks
    rev: v1.0.0
    hooks:
      - id: pytest-filename-conventions
      - id: text-unicode-replacement-char

Equivalent builtin configuration[.pre-commit-config.yaml]

The manifest hooks above should behave exactly like this direct repo: builtin configuration:

repos:
  - repo: builtin
    hooks:
      - id: require-filename-pattern
        name: Enforce pytest filename conventions
        description: Ensures files under tests/ follow pytest naming conventions (test_*.py, __init__.py, or conftest.py).
        files: '(^|/)tests/.+\.py$'
        args:
          - '^test_.*\.py$'
          - '^__init__\.py$'
          - '^conftest\.py$'
      - id: deny-pattern
        name: No Unicode replacement characters
        description: Forbids text files containing the Unicode replacement character U+FFFD.
        args:
          - "\uFFFD"
        types: [text]

Required behavior

  • Allow only repo: builtin for extends.repo.
  • Require extends.id to identify an existing hook available through the Explicit Builtin Repository.
  • Load the referenced builtin hook as the base implementation.
  • Apply the supported hook fields from the .pre-commit-hooks.yaml hook to that base hook.
  • Apply normal consumer configuration overrides after the manifest hook fields.
  • Execute the referenced builtin Rust implementation using the final effective configuration.
  • Use the manifest hook's top-level id for selection and output; use extends.id only to select the builtin implementation.
  • Require id, name, and extends for an extended manifest hook.
  • Do not require entry or language; reject entry, and allow language only when set to system.
  • Execute the bundled Rust implementation without installing dependencies, creating a hook environment, or invoking an external interpreter.
  • Apply the same argument support and compatibility checks as the equivalent direct repo: builtin configuration.
  • Report clear validation errors for unknown builtin hook IDs and incompatible fields.
  • Support extended hooks in prek validate-manifest and prek try-repo.
  • Keep existing manifest hooks unchanged and document that extends is specific to prek.

References

Activity

  1. Repository owner locked and limited conversation to collaborators on Aug 9, 2026
  2. converted this issue into a discussion #2515 on Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions