Giter VIP home page Giter VIP logo

pre-commit-hooks.nix's Introduction

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";

  outputs = { self, nixpkgs, ... }@inputs:
    let
      supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];

      forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
    in
    {
      checks = forAllSystems (system: {
        pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
          src = ./.;
          hooks = {
            nixpkgs-fmt.enable = true;
          };
        };
      });

      devShells = forAllSystems (system: {
        default = 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)

pre-commit-hooks.nix's People

Contributors

9999years avatar atavistock avatar bors[bot] avatar dependabot[bot] avatar domenkozar avatar gilligan avatar k900 avatar lafrenierejm avatar loicreynier avatar lovesegfault avatar lunik1 avatar macalinao avatar mangoiv avatar maydayv7 avatar mmlb avatar mrcjkb avatar mweinelt avatar niols avatar oxcabe avatar phip1611 avatar pierrer avatar roberth avatar sandydoo avatar sd234678 avatar sestrella avatar shikanime avatar srid avatar tljuniper avatar totoroot avatar u-quark avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.