Skip to content

feat: implement `pre_commit` macro

Matthew Clarkson requested to merge implementation into main

This is a huge patch that implements the functionality to use Bazel run targets as pre-commit hooks.

The patch provides the following rules:

  • pre_commit: a macro that bundles the below rules
  • pre_commit_hook: a macro to select a specific Bazel command rule such as pre_commit_hook_run
  • pre_commit_hook_run: creates a pre-commit hook description that executes bazel run for the provided target
  • pre_commit_hooks: bundles multiple pre_commit_hook rules together for easy usage
  • pre_commit_config: accepts pre_commit_hook{,s} and generates a .pre-commit-config.yaml file
  • pre_commit_install: installs a provided .pre-commit-config.yaml file into .git/hooks
  • pre_commit_run: performs pre-commit run against the provided .pre-commit-config.yaml file
  • pre_commit_stage: describes a pre-commit hook stage to be used with pre_commit_hook
  • pre_commit_tag: describes a pre-commit hook file type tag to be used with pre_commit_hook

It has the following providers:

  • PreCommitConfigInfo: a generated configuration file
  • PreCommitHookJSONInfo: a provider that can be serialized to JSON for ingestion into pre_commit_config
  • PreCommitHookInfo: a generated JSON file that pre_commit_config can parse and generate a configuration from
  • PreCommitHooksInfo: contains a depset of PreCommitHookInfo providers
  • PreCommitTagInfo: contains a identify file kind tag
  • PreCommitStageInfo: contains a pre-commit hook stage

The patch has the following public labels:

  • @pre-commit: a monkey patched pre-commit to ensure it works with Bazel effectively and provides a hermetic git and bazel implementation for running the hooks
  • @pre-commit//pre-commit:pkg: a py_library that provdes the pre_commit Python module. Uses universal lockfiles and Python version select to provide the correct module to downstream users.
  • @pre-commit//pre-commit/git: a label_flag for changing the hermetic git implementation used
  • @pre-commit//pre-commit/bazel: a label_flag for changing the hermetic bazel implementation used
  • @pre-commit//pre-commit/stage:*: stages to be used with pre_commit_hook#stages
  • @pre-commit//pre-commit/tag:*: tags to be used with pre_commit_hook#types{,_or}

The README.md is a good place to start to understand the module.

Areas that require more-indepth review:

  • Do the various rules have a sensible API?
  • Does the MR work for yourself?
    • Try cloning the MR and run bazelisk run -- hooks:install/bazelisk run -- hooks
  • Is the monkey patching in pre-commit/__main.py understandable?
  • Is it clear how to use the module for creating hooks downstream?
    • Ideally, we would create a @pre-commit-hooks module that provides our commonly used hooks
Edited by Matthew Clarkson

Merge request reports

Loading