From 8e67af7c5accb630169b1e4d8298fb13fb953807 Mon Sep 17 00:00:00 2001 From: sudosubin Date: Mon, 23 Jan 2023 00:40:34 +0900 Subject: [PATCH] feat(nix): Update lefthook nix hook configurations --- .gitignore | 2 + flake.lock | 43 +++++++++++++++ flake.nix | 35 +++++++++++++ lib/config/default.nix | 116 +++++++++++++++++++++++++++++++++++++++++ lib/default.nix | 5 ++ lib/run.nix | 15 ++++++ 6 files changed, 216 insertions(+) create mode 100644 .gitignore create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 lib/config/default.nix create mode 100644 lib/default.nix create mode 100644 lib/run.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8ef02a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# auto generated lefthook configuration file +/lefthook.yml diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..5e799e4 --- /dev/null +++ b/flake.lock @@ -0,0 +1,43 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1674236650, + "narHash": "sha256-B4GKL1YdJnII6DQNNJ4wDW1ySJVx2suB1h/v4Ql8J0Q=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "cfb43ad7b941d9c3606fb35d91228da7ebddbfc5", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 + } diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..8afede5 --- /dev/null +++ b/flake.nix @@ -0,0 +1,35 @@ +{ + description = "Easily manage git hooks with Nix, internally using lefthook."; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils, ... }: + flake-utils.lib.eachDefaultSystem (system: + let + lib = import ./lib { inherit pkgs; }; + pkgs = import nixpkgs { inherit system; }; + + in + { + inherit lib; + + checks = { + lefthook-check = lib.run { + src = ./.; + config = { + pre-commit.commands = { + nixpkgs-fmt.run = "${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt {staged_files}"; + }; + }; + }; + }; + + devShell = nixpkgs.legacyPackages.${system}.mkShell { + inherit (self.checks.${system}.lefthook-check) shellHook; + }; + } + ); +} diff --git a/lib/config/default.nix b/lib/config/default.nix new file mode 100644 index 0000000..13aa2f1 --- /dev/null +++ b/lib/config/default.nix @@ -0,0 +1,116 @@ +{ config, lib, pkgs, ... }: + +let + inherit (lib) mkOption types; + cfg = config; + + configFile = pkgs.runCommand "lefthook.yml" + { + buildInputs = [ pkgs.jq ]; + passAsFile = [ "rawJSON" ]; + rawJSON = builtins.toJSON cfg.config; + } '' + { + echo "# This file is generated by lefthook.nix in your project." + echo "# Manual changes might be lost." + jq . <"$rawJSONPath" + } >$out + ''; + +in +{ + options = { + package = mkOption { + type = types.package; + description = lib.mdDoc '' + `lefthook` package to use. + ''; + default = pkgs.lefthook; + }; + + config = mkOption { + type = types.attrs; + description = lib.mdDoc '' + lefthook configuration to use. + ''; + }; + + rootSrc = mkOption { + type = types.path; + description = lib.mdDoc '' + The root path for lefthook. + ''; + }; + + run = mkOption { + type = types.package; + readOnly = true; + }; + + installationScript = mkOption { + type = types.str; + readOnly = true; + }; + }; + + config = { + run = pkgs.runCommand "lefthook-run" { buildInputs = with pkgs; [ git ]; } '' + set +e + export HOME="$PWD" + + cp -R ${cfg.rootSrc} ./src + rm -rf ./src/.git + chmod -R +w ./src + ln -fs ${configFile} ./src/lefthook.yml + + cd ./src + git init + git add . + ${cfg.package}/bin/lefthook run pre-commit + + exitcode=$? + touch $out # TODO + [ $? -eq 0 ] && exit $exitcode + ''; + + installationScript = '' + export PATH=${cfg.package}/bin:$PATH + function _log() { echo 1>&2 "$*"; } + + if ! command -v git >/dev/null; then + _log "WARNING: lefthook.nix: git command not found, skipping installation." + elif [ ! -d .git ]; then + _log "WARNING: lefthook.nix: .git directory does not exist, skipping installation." + else + # These update procedures compare before they write, to avoid + # filesystem churn. This improves performance with watch tools like lorri + # and prevents installation loops by via lorri. + + if readlink lefthook.yml >/dev/null \ + && [[ $(readlink lefthook.yml) == ${configFile} ]]; then + _log "lefthook.nix: lefthook configuration up to date" + else + _log "lefthook.nix: updating $PWD lefthook configuration" + + if [ -L lefthook.yml ]; then + unlink lefthook.yml + fi + + if [ -f lefthook.yml ]; then + _log "WARNING: lefthook.nix: lefthook.yml already exists. Please remove lefthook.yml and add lefthook.yml to .gitignore." + else + ln -s ${configFile} lefthook.yml + + # Remove previously installed git hooks + lefthook uninstall + + # Add lefthook git hooks + lefthook install + fi + fi + fi + + unset -f _log + ''; + }; +} diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 0000000..3168e2c --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,5 @@ +{ pkgs }: + +{ + run = pkgs.callPackage ./run.nix { inherit pkgs; }; +} diff --git a/lib/run.nix b/lib/run.nix new file mode 100644 index 0000000..f7c9919 --- /dev/null +++ b/lib/run.nix @@ -0,0 +1,15 @@ +{ pkgs, lib }: +{ config ? { }, src }: + +let + eval = lib.evalModules { + modules = [ + (import ./config) + { config = { inherit config; rootSrc = src; _module.args.pkgs = pkgs; }; } + ]; + }; + +in +eval.config.run // { + shellHook = eval.config.installationScript; +}