ikamen
ikamen

Reputation: 3485

Pre-commit hook based on an executable (not git repo)

I'd like to run executable coming from pip that isn't available as a git repository. It seems that documentation assumes anything you'd like to run comes from git repositories: https://pre-commit.com/#plugins. How can I run arbitrary shell commands as pre-commit hooks?

Upvotes: 6

Views: 1860

Answers (3)

A Webb
A Webb

Reputation: 711

Here is an example of how you can run a bash script or a tool installed via pip (in my case ruff).

repos:
  - repo: local
    hooks:
      - id: check-k8s-scripts
        name: Check K8's Scripts
        entry: ./precommits.sh
        language: system
        stages: [pre-push]
      - id: check-code-issues
        name: Check Code Issues
        entry: ruff check .
        language: python
        stages: [pre-push]
        exclude: ^tests/
        files: .*\.py$

Upvotes: 0

guy mograbi
guy mograbi

Reputation: 28638

I want to expand on the accepted answer with an example on how to run any script in your repository.

Say you have a new hook build/hooks/my-hook.js that you implemented on top of nodejs. Lets also say this new hook wants to operate on jsonnet type files.

Here is how you can trigger it with pre-commit

-   repo: local
    hooks:
    - id: my-hook
      name: my-hook
      language: system
      entry: node
      args: [build/hooks/my-plugin.js]
      types: [jsonnet]

entry - points to the executable we want to run. In our case - node.
args - the arguments we send to nodejs. The first one will be which file to execute. The plugin will get the filenames to run on from pre-commit.

So for example process.argv will include:

  • path/to/node
  • path/to/build/hooks/my-plugin.js
  • file1.jsonnet
  • file2.jsonnet
  • ...
// build/hooks/my-plugin.js

console.log(process.argv)

to see the output, remember to use the verbose flag

pre-commit run --verbose

How to make the plugin to fail when needed?

pre-commit will automatically identify if the plugin modified a staged file and will fail the commit.

Alternatively, if your plugin does not change files, simply call exit with code 1 - pre-commit will honor that.

Upvotes: 1

ikamen
ikamen

Reputation: 3485

The pre-commit allows to use local sentinel for a repo section. The example config below runs black as installed on the system:

repos:
-   repo: local
    hooks:
    - id: black
      name: black
      language: system
      entry: black
      types: [python]

Upvotes: 8

Related Questions