From d6e8eb693ddb963edf764052dfdd6ec837a24995 Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Fri, 24 Oct 2025 12:55:22 +0200 Subject: [PATCH 1/2] nix: Bump GHC to 9.8.4, HLS to 2.11, Hlint 3.10 Co-authored-by: Hamish Mackenzie --- flake.nix | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/flake.nix b/flake.nix index 3e5fff4525..c867a36040 100644 --- a/flake.nix +++ b/flake.nix @@ -30,7 +30,7 @@ ]; # see flake `variants` below for alternative compilers - defaultCompiler = "ghc982"; + defaultCompiler = "ghc984"; # Used for cross compilation, and so referenced in .github/workflows/release-upload.yml. Adapt the # latter if you change this value. crossCompilerVersion = "ghc967"; @@ -125,9 +125,8 @@ ghcid = "0.8.9"; cabal-gild = "1.3.1.2"; fourmolu = "0.18.0.0"; - haskell-language-server.src = nixpkgs.haskell-nix.sources."hls-2.9"; - # This index-state makes it work for GHC 9.8.2 (it will need to tbe removed for 9.8.4) - hlint = { version = "3.8"; index-state = "2024-12-01T00:00:00Z"; }; + haskell-language-server.src = nixpkgs.haskell-nix.sources."hls-2.11"; + hlint = { version = "3.10"; }; }; # and from nixpkgs or other inputs shell.nativeBuildInputs = with nixpkgs; [gh jq yq-go actionlint shellcheck] ++ (lib.optional isDarwin macOS-security); From 8e1f6633a830ad5737b11ffc90f0b57956de0bbf Mon Sep 17 00:00:00 2001 From: Mateusz Galazyn Date: Fri, 24 Oct 2025 15:09:50 +0200 Subject: [PATCH 2/2] nix: Add alejandra, prettify and cabal-gild git hook --- .gitignore | 2 + flake.lock | 76 +++++++++++++- flake.nix | 285 ++++++++++++++++++++++++++++++++--------------------- 3 files changed, 248 insertions(+), 115 deletions(-) diff --git a/.gitignore b/.gitignore index 52c85c4f0c..1df0246b51 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,8 @@ tags ./*.vkey ./*.cert +.pre-commit-config.yaml + # For now require that users generate their own hie.yaml hie.yaml diff --git a/flake.lock b/flake.lock index beb5add91b..c44893026d 100644 --- a/flake.lock +++ b/flake.lock @@ -134,6 +134,22 @@ "type": "github" } }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1747046372, + "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -153,6 +169,27 @@ "type": "github" } }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, "hackage-for-stackage": { "flake": false, "locked": { @@ -676,6 +713,22 @@ "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1759070547, + "narHash": "sha256-JVZl8NaVRYb0+381nl7LvPE+A774/dRpif01FKLrYFQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "647e5c14cbd5067f44ac86b74f014962df460840", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "old-ghc-nix": { "flake": false, "locked": { @@ -693,6 +746,26 @@ "type": "github" } }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat_2", + "gitignore": "gitignore", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1760663237, + "narHash": "sha256-BflA6U4AM1bzuRMR8QqzPXqh8sWVCNDzOdsxXEguJIc=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "ca5b894d3e3e151ffc1db040b6ce4dcc75d31c37", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, "root": { "inputs": { "CHaP": "CHaP", @@ -704,7 +777,8 @@ "nixpkgs": [ "haskellNix", "nixpkgs-unstable" - ] + ], + "pre-commit-hooks": "pre-commit-hooks" } }, "secp256k1": { diff --git a/flake.nix b/flake.nix index c867a36040..857771e27e 100644 --- a/flake.nix +++ b/flake.nix @@ -14,6 +14,7 @@ iohkNix.url = "github:input-output-hk/iohk-nix"; incl.url = "github:divnix/incl"; flake-utils.url = "github:hamishmack/flake-utils/hkm/nested-hydraJobs"; + pre-commit-hooks.url = "github:cachix/git-hooks.nix"; CHaP = { url = "github:intersectmbo/cardano-haskell-packages?ref=repo"; @@ -50,29 +51,39 @@ inputs.iohkNix.overlays.haskell-nix-crypto # Provide static variants of selected libs on Darwin so we can link # statically against them and avoid the dylib bundling step. - (final: prev: let isDarwin = prev.stdenv.hostPlatform.isDarwin; in if isDarwin then { - static-gmp = (prev.gmp.override { withStatic = true; }).overrideDerivation (old: { - configureFlags = (old.configureFlags or []) ++ ["--enable-static" "--disable-shared"]; }); - static-libsodium-vrf = prev.libsodium-vrf.overrideDerivation (old: { - configureFlags = (old.configureFlags or []) ++ ["--disable-shared"]; }); - static-secp256k1 = prev.secp256k1.overrideDerivation (old: { - configureFlags = (old.configureFlags or []) ++ ["--enable-static" "--disable-shared"]; }); - static-openssl = prev.openssl.override { static = true; }; - static-libblst = (prev.libblst.override { enableShared = false; }); + (final: prev: let + isDarwin = prev.stdenv.hostPlatform.isDarwin; + in + if isDarwin + then { + static-gmp = (prev.gmp.override {withStatic = true;}).overrideDerivation (old: { + configureFlags = (old.configureFlags or []) ++ ["--enable-static" "--disable-shared"]; + }); + static-libsodium-vrf = prev.libsodium-vrf.overrideDerivation (old: { + configureFlags = (old.configureFlags or []) ++ ["--disable-shared"]; + }); + static-secp256k1 = prev.secp256k1.overrideDerivation (old: { + configureFlags = (old.configureFlags or []) ++ ["--enable-static" "--disable-shared"]; + }); + static-openssl = prev.openssl.override {static = true;}; + static-libblst = prev.libblst.override {enableShared = false;}; - # :exploding_head: I do not understand why in nixpkgs, all of these have to have different - # ways of making them static. - static-zlib = final.zlib.override { shared = false; }; - # ncurses: build only static wide-character library - static-ncurses = prev.ncurses.override { enableStatic = true; }; - # lmdb: drop shared object so linker must use static archive - static-lmdb = prev.lmdb.overrideDerivation (old: { - postInstall = (old.postInstall or "") + '' - # Remove shared object to force static link - rm -f $out/lib/liblmdb.so* - ''; - }); - } else {}) + # :exploding_head: I do not understand why in nixpkgs, all of these have to have different + # ways of making them static. + static-zlib = final.zlib.override {shared = false;}; + # ncurses: build only static wide-character library + static-ncurses = prev.ncurses.override {enableStatic = true;}; + # lmdb: drop shared object so linker must use static archive + static-lmdb = prev.lmdb.overrideDerivation (old: { + postInstall = + (old.postInstall or "") + + '' + # Remove shared object to force static link + rm -f $out/lib/liblmdb.so* + ''; + }); + } + else {}) ]; inherit system; inherit (inputs.haskellNix) config; @@ -90,6 +101,30 @@ then [("--ghc-option=-D__GIT_REV__=\\\"" + inputs.self.rev + "\\\"")] else []; + pre-commit-check = inputs.pre-commit-hooks.lib.${nixpkgs.system}.run { + src = ./.; + hooks = { + alejandra.enable = true; + cabal-gild = { + enable = true; + entry = let + script = nixpkgs.writeShellScript "precommit-cabal-gild" '' + for file in "$@"; do + cabal-gild --io="$file" + done + ''; + in + builtins.toString script; + files = "\\.cabal$"; + }; + prettify = { + enable = true; + entry = "scripts/githooks/haskell-style-lint"; + types = ["haskell"]; + }; + }; + }; + # We use cabalProject' to ensure we don't build the plan for # all systems. cabalProject = nixpkgs.haskell-nix.cabalProject' ({config, ...}: { @@ -101,9 +136,9 @@ crossPlatforms = p: lib.optionals (system == "x86_64-linux" && config.compiler-nix-name == crossCompilerVersion) [ - p.ucrt64 # x86_64-windows - p.aarch64-multiplatform-musl # aarch64-linux (static) - p.musl64 # x86_64-linux (static) + p.ucrt64 # x86_64-windows + p.aarch64-multiplatform-musl # aarch64-linux (static) + p.musl64 # x86_64-linux (static) ]; # CHaP input map, so we can find CHaP packages (needs to be more @@ -114,36 +149,40 @@ inputMap = { "https://chap.intersectmbo.org/" = inputs.CHaP; }; - shell.packages = p: [p.cardano-cli p.cardano-ledger-core p.cardano-api p.ouroboros-consensus-cardano]; - # tools we want in our shell, from hackage - shell.tools = - { - cabal = "3.14.1.1"; - } - // lib.optionalAttrs (config.compiler-nix-name == defaultCompiler) { - # tools that work only with default compiler - ghcid = "0.8.9"; - cabal-gild = "1.3.1.2"; - fourmolu = "0.18.0.0"; - haskell-language-server.src = nixpkgs.haskell-nix.sources."hls-2.11"; - hlint = { version = "3.10"; }; - }; - # and from nixpkgs or other inputs - shell.nativeBuildInputs = with nixpkgs; [gh jq yq-go actionlint shellcheck] ++ (lib.optional isDarwin macOS-security); - # disable Hoogle until someone request it - shell.withHoogle = false; - # Skip cross compilers for the shell - shell.crossPlatforms = _: []; - shell.shellHook = '' - export PATH="$(git rev-parse --show-toplevel)/scripts/devshell:$PATH" - ''; + shell = { + packages = p: [p.cardano-cli p.cardano-ledger-core p.cardano-api p.ouroboros-consensus-cardano]; + # tools we want in our shell, from hackage + tools = + { + cabal = "3.14.1.1"; + } + // lib.optionalAttrs (config.compiler-nix-name == defaultCompiler) { + # tools that work only with default compiler + ghcid = "0.8.9"; + cabal-gild = "1.3.1.2"; + fourmolu = "0.18.0.0"; + haskell-language-server.src = nixpkgs.haskell-nix.sources."hls-2.11"; + hlint = {version = "3.10";}; + }; + # and from nixpkgs or other inputs + nativeBuildInputs = with nixpkgs; [gh jq yq-go actionlint shellcheck] ++ (lib.optional isDarwin macOS-security); + # disable Hoogle until someone request it + withHoogle = false; + # Skip cross compilers for the shell + crossPlatforms = _: []; + shellHook = '' + export PATH="${nixpkgs.nix}/bin:$PATH" + ${pre-commit-check.shellHook} + export PATH="$(git rev-parse --show-toplevel)/scripts/devshell:$PATH" + ''; + }; # package customizations as needed. Where cabal.project is not # specific enough, or doesn't allow setting these. modules = [ ({pkgs, ...}: { packages.cardano-cli.configureFlags = ["--ghc-option=-Werror"] ++ gitRevFlag; - packages.basement.configureFlags = [ "--hsc2hs-option=--cflag=-Wno-int-conversion" ]; + packages.basement.configureFlags = ["--hsc2hs-option=--cflag=-Wno-int-conversion"]; }) ({ pkgs, @@ -167,25 +206,33 @@ "cabal.project" "scripts/plutus/scripts/v1/custom-guess-42-datum-42.plutus" ]; - in '' - ${exportCliPath} - cp -r ${filteredProjectBase}/* .. - '' + (if isDarwin - then '' - export PATH=${macOS-security}/bin:$PATH - '' - else ''''); + in + '' + ${exportCliPath} + cp -r ${filteredProjectBase}/* .. + '' + + ( + if isDarwin + then '' + export PATH=${macOS-security}/bin:$PATH + '' + else '''' + ); packages.cardano-cli.components.tests.cardano-cli-test.preCheck = let # This define files included in the directory that will be passed to `H.getProjectBase` for this test: filteredProjectBase = inputs.incl ./. mainnetConfigFiles; - in '' - ${exportCliPath} - cp -r ${filteredProjectBase}/* .. - '' + (if isDarwin - then '' - export PATH=${macOS-security}/bin:$PATH - '' - else ''''); + in + '' + ${exportCliPath} + cp -r ${filteredProjectBase}/* .. + '' + + ( + if isDarwin + then '' + export PATH=${macOS-security}/bin:$PATH + '' + else '''' + ); }) { packages.crypton-x509-system.postPatch = '' @@ -193,51 +240,61 @@ ''; } # On Darwin link statically against selected 3rd party crypto libs (as in haskell-nix-example cardano-tools) - ({ pkgs, lib, ... }: lib.mkIf pkgs.stdenv.hostPlatform.isDarwin { - packages.cardano-cli.ghcOptions = with pkgs; [ - "-L${lib.getLib static-gmp}/lib" - "-L${lib.getLib static-libsodium-vrf}/lib" - "-L${lib.getLib static-secp256k1}/lib" - "-L${lib.getLib static-openssl}/lib" - "-L${lib.getLib static-libblst}/lib" - # Prefer static libs for remaining non-system deps; use absolute archives to force static - "-L${lib.getLib static-zlib}/lib" - "-L${lib.getLib static-ncurses}/lib" - "-L${lib.getLib static-lmdb}/lib" - ]; - }) + ({ + pkgs, + lib, + ... + }: + lib.mkIf pkgs.stdenv.hostPlatform.isDarwin { + packages.cardano-cli.ghcOptions = with pkgs; [ + "-L${lib.getLib static-gmp}/lib" + "-L${lib.getLib static-libsodium-vrf}/lib" + "-L${lib.getLib static-secp256k1}/lib" + "-L${lib.getLib static-openssl}/lib" + "-L${lib.getLib static-libblst}/lib" + # Prefer static libs for remaining non-system deps; use absolute archives to force static + "-L${lib.getLib static-zlib}/lib" + "-L${lib.getLib static-ncurses}/lib" + "-L${lib.getLib static-lmdb}/lib" + ]; + }) # On Darwin, apply fixup-nix-deps style rewriting of store dylib references to system libraries - ({ pkgs, lib, ... }: lib.mkIf pkgs.stdenv.hostPlatform.isDarwin { - packages.cardano-cli.components.exes.cardano-cli.postInstall = lib.mkAfter (let - fixup-nix-deps = pkgs.writeShellApplication { - name = "fixup-nix-deps"; - text = '' - set +e - bin="$1" - [ -x "$bin" ] || exit 0 - echo "[fixup-nix-deps] scanning $bin" >&2 - for nixlib in $(otool -L "$bin" | awk '/nix\/store/{ print $1 }'); do - case "$nixlib" in - *libiconv.dylib) install_name_tool -change "$nixlib" /usr/lib/libiconv.dylib "$bin" || true ;; - *libiconv.2.dylib) install_name_tool -change "$nixlib" /usr/lib/libiconv.2.dylib "$bin" || true ;; - *libffi.*.dylib) install_name_tool -change "$nixlib" /usr/lib/libffi.dylib "$bin" || true ;; - *libc++.*.dylib) install_name_tool -change "$nixlib" /usr/lib/libc++.dylib "$bin" || true ;; - *libz.dylib) install_name_tool -change "$nixlib" /usr/lib/libz.dylib "$bin" || true ;; - *libresolv.*.dylib) install_name_tool -change "$nixlib" /usr/lib/libresolv.dylib "$bin" || true ;; - *) ;; - esac - done - echo "[fixup-nix-deps] after rewrite:" >&2 - otool -L "$bin" - set -e - ''; - }; - in '' - if [ -x "$out/bin/cardano-cli" ]; then - ${fixup-nix-deps}/bin/fixup-nix-deps "$out/bin/cardano-cli" - fi - ''); - }) + ({ + pkgs, + lib, + ... + }: + lib.mkIf pkgs.stdenv.hostPlatform.isDarwin { + packages.cardano-cli.components.exes.cardano-cli.postInstall = lib.mkAfter (let + fixup-nix-deps = pkgs.writeShellApplication { + name = "fixup-nix-deps"; + text = '' + set +e + bin="$1" + [ -x "$bin" ] || exit 0 + echo "[fixup-nix-deps] scanning $bin" >&2 + for nixlib in $(otool -L "$bin" | awk '/nix\/store/{ print $1 }'); do + case "$nixlib" in + *libiconv.dylib) install_name_tool -change "$nixlib" /usr/lib/libiconv.dylib "$bin" || true ;; + *libiconv.2.dylib) install_name_tool -change "$nixlib" /usr/lib/libiconv.2.dylib "$bin" || true ;; + *libffi.*.dylib) install_name_tool -change "$nixlib" /usr/lib/libffi.dylib "$bin" || true ;; + *libc++.*.dylib) install_name_tool -change "$nixlib" /usr/lib/libc++.dylib "$bin" || true ;; + *libz.dylib) install_name_tool -change "$nixlib" /usr/lib/libz.dylib "$bin" || true ;; + *libresolv.*.dylib) install_name_tool -change "$nixlib" /usr/lib/libresolv.dylib "$bin" || true ;; + *) ;; + esac + done + echo "[fixup-nix-deps] after rewrite:" >&2 + otool -L "$bin" + set -e + ''; + }; + in '' + if [ -x "$out/bin/cardano-cli" ]; then + ${fixup-nix-deps}/bin/fixup-nix-deps "$out/bin/cardano-cli" + fi + ''); + }) ]; }); # ... and construct a flake from the cabal project @@ -279,11 +336,11 @@ # formatter used by nix fmt formatter = nixpkgs.alejandra; - }) - # Disable aarch64-linux hydraJobs as we don't have any native builders for this architecture - # as of 2024-07-15 so this would choke the CI. aarch64-linux binary building is enabled through - # cross-compilation. - // lib.optionalAttrs (system == "aarch64-linux") { hydraJobs = { }; } + }) + # Disable aarch64-linux hydraJobs as we don't have any native builders for this architecture + # as of 2024-07-15 so this would choke the CI. aarch64-linux binary building is enabled through + # cross-compilation. + // lib.optionalAttrs (system == "aarch64-linux") {hydraJobs = {};} ); nixConfig = {