• Stars
    star
    434
  • Rank 96,613 (Top 2 %)
  • Language
    Nix
  • License
    Apache License 2.0
  • Created over 4 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Seamless integration of https://pre-commit.com git hooks with Nix.

Seamless integration of git hooks with Nix

pre-commit.png

Features

  • Trivial integration for Nix projects (wires up a few things behind the scenes)

  • Provide a low-overhead build of all the tooling available for the hooks to use (naive implementation of calling nix-shell does bring some latency when committing)

  • Common hooks for languages like Python, Haskell, Elm, etc. see all hook options

  • Run hooks as part of development and on during CI

Getting started

devenv.sh

https://devenv.sh/pre-commit-hooks/

Flakes support

Given the following flake.nix example:

{
  description = "An example project.";

  inputs.pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix";
  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = { self, nixpkgs, pre-commit-hooks, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      {
        checks = {
          pre-commit-check = pre-commit-hooks.lib.${system}.run {
            src = ./.;
            hooks = {
              nixpkgs-fmt.enable = true;
            };
          };
        };
        devShell = nixpkgs.legacyPackages.${system}.mkShell {
          inherit (self.checks.${system}.pre-commit-check) shellHook;
          buildInputs = self.checks.${system}.pre-commit-check.enabledPackages;
        };
      }
    );
}

Add /.pre-commit-config.yaml to the .gitignore.

To run the all the hooks on CI:

nix flake check

To install pre-commit hooks developers would run:

nix develop

Nix

  1. Optionally use binary caches to avoid compilation:

    nix-env -iA cachix -f https://cachix.org/api/v1/install
    cachix use pre-commit-hooks
  2. Integrate hooks to be built as part of default.nix:

     let
       nix-pre-commit-hooks = import (builtins.fetchTarball "https://github.com/cachix/pre-commit-hooks.nix/tarball/master");
     in {
       # Configured with the module options defined in `modules/pre-commit.nix`:
       pre-commit-check = nix-pre-commit-hooks.run {
         src = ./.;
         # If your hooks are intrusive, avoid running on each commit with a default_states like this:
         # default_stages = ["manual" "push"];
         hooks = {
           elm-format.enable = true;
    
           # override a package with a different version
           ormolu.enable = true;
           ormolu.package = pkgs.haskellPackages.ormolu;
           ormolu.settings.defaultExtensions = [ "lhs" "hs" ];
    
           # some hooks have more than one package, like clippy:
           clippy.enable = true;
           clippy.packageOverrides.cargo = pkgs.cargo;
           clippy.packageOverrides.clippy = tools.clippy;
           # some hooks provide settings
           clippy.settings.allFeatures = true;
         };
       };
     }

    Run $ nix-build -A pre-commit-check to perform the checks as a Nix derivation.

  3. Integrate hooks to prepare environment as part of shell.nix:

     let
       pre-commit = import ./default.nix;
     in (import <nixpkgs> {}).mkShell {
       shellHook = ''
         ${pre-commit.pre-commit-check.shellHook}
       '';
       buildInputs = pre-commit.pre-commit-check.enabledPackages;
     }

    Add /.pre-commit-config.yaml to .gitignore.

    Run $ nix-shell to execute shellHook which will:

    • build the tools and .pre-commit-config.yaml config file symlink which references the binaries, for speed and safe garbage collection
    • provide the pre-commit executable that git commit will invoke

Optional

Direnv

.envrc:

use nix

Hooks

Nix

Haskell

C/C++/C#/ObjC

You may restrict which languages should be formatted by clang-format using clang-format.types_or. For example to check only C and C++ files:

clang-format = {
  enable = true;
  types_or = lib.mkForce [ "c" "c++" ];
};

Otherwise, the default internal list is used which includes everything that clang-format supports.

Clojure

Elm

Elixir

OCaml

Purescript

JavaScript/TypeScript

  • biome
  • denofmt: Runs deno fmt
  • denolint: Runs deno lint
  • eslint
  • rome: (alias to the biome hook)

Python

PHP

Rust

Golang

Julia

Shell

LaTeX

Lua

HTML

Markdown

Terraform

  • terraform-format: built-in formatter
  • tflint

YAML

TOML

JSON

Typst

Fortran

Spell checker

Link checker

Git

Various other hooks

Custom hooks

Sometimes it is useful to add a project specific command as an extra check that is not part of the pre-defined set of hooks provided by this project.

Example configuration:

 let
   nix-pre-commit-hooks = import (builtins.fetchTarball "https://github.com/cachix/pre-commit-hooks.nix/tarball/master");
 in {
   pre-commit-check = nix-pre-commit-hooks.run {
     hooks = {
       # ...

       # Example custom hook for a C project using Make:
       unit-tests = {
         enable = true;

         # The name of the hook (appears on the report table):
         name = "Unit tests";

         # The command to execute (mandatory):
         entry = "make check";

         # The pattern of files to run on (default: "" (all))
         # see also https://pre-commit.com/#hooks-files
         files = "\\.(c|h)$";

         # List of file types to run on (default: [ "file" ] (all files))
         # see also https://pre-commit.com/#filtering-files-with-types
         # You probably only need to specify one of `files` or `types`:
         types = [ "text" "c" ];

         # Exclude files that were matched by these patterns (default: [ ] (none)):
         excludes = [ "irrelevant\\.c" ];

         # The language of the hook - tells pre-commit
         # how to install the hook (default: "system")
         # see also https://pre-commit.com/#supported-languages
         language = "system";

         # Set this to false to not pass the changed files
         # to the command (default: true):
         pass_filenames = false;

         # Which git hooks the command should run for (default: [ "pre-commit" ]):
         stages = ["pre-push"];
       };
     };
   };
 }

Custom hooks are defined with the same schema as pre-defined hooks.

Contributing hooks

Everyone is encouraged to add new hooks.

Have a look at the existing hooks and the options.

There's no guarantee the hook will be accepted, but the general guidelines are:

  • Nix closure of the tool should be small e.g. < 50MB. A problematic example:
  $ du -sh $(nix-build -A go)
  463M  /nix/store/v4ys4lrjngf62lvvrdbs7r9kbxh9nqaa-go-1.18.6
  • The tool must not be very specific (e.g. language tooling is OK, but project specific tooling is not)
  • The tool needs to live in a separate repository (even if a simple bash script, unless it's a oneliner)

More Repositories

1

devenv

Fast, Declarative, Reproducible, and Composable Developer Environments
Nix
3,227
star
2

cachix

Command line client for Nix binary cache hosting:
Haskell
733
star
3

install-nix-action

Installs Nix on GitHub Actions for the supported platforms: Linux and macOS.
Shell
418
star
4

cachix-action

Build software only once and put it in a global cache
TypeScript
209
star
5

nixpkgs-python

All Python versions, kept up-to-date on hourly basis using Nix.
Nix
106
star
6

elm2nix

Convert Elm project into Nix expressions
Haskell
105
star
7

ghcide-nix

Nix installation for ghcide
Nix
76
star
8

docs.cachix.org

Documentation for Cachix service.
Python
58
star
9

cachix-deploy-hetzner-dedicated

Bootstrap Hetzner Dedicated machines with a single command and deploy using GitHub Actions
Nix
22
star
10

stamina.hs

Retrying for humans using Haskell.
Haskell
20
star
11

haskell-release-action

Automation for releasing haskell packages
17
star
12

paddle

Haskell API for Paddle payments
Haskell
11
star
13

nixpkgs-unfree-redistributable

Nix
6
star
14

cachix-ci-agents

self-hosted github runners
Nix
6
star
15

katip-raven

Katip scribe for raven client (https://sentry.io)
Haskell
5
star
16

cachix-deploy-flake

Functions to help manage Cachix Deploy when using flakes.
Nix
5
star
17

clickhouse-haskell

Haskell
4
star
18

websockets-simple

High-level library for Client/Server websocket communication in Haskell
Haskell
3
star
19

mixpanel-client

Haskell client implementation of mixpanel HTTP api
Haskell
3
star
20

fastspring

Haskell API for https://fastspring.com/
Haskell
3
star
21

cachix-deploy-terraform

HCL
2
star
22

buildkite-example

2
star
23

travis-ci-example

Nix
2
star
24

circleci-example

Nix
2
star
25

feedback

Feedback about https://cachix.org service
2
star
26

cachix-deploy-amis

AMIs for using Cachix Deploy
HCL
1
star
27

haskell-wishlist

Things we wish Haskell had
1
star
28

cachix-deploy-aws

HCL
1
star
29

parse-range-header.js

TypeScript
1
star
30

fastcdc-rs2hs

A Haskell wrapper around fastcdc-rs.
Haskell
1
star