From 2dcfa161c048bf1873c2633dd6102654bb797a37 Mon Sep 17 00:00:00 2001 From: Hamish Mackenzie Date: Wed, 18 Jun 2025 17:28:57 +1200 Subject: [PATCH 1/6] Fix `index-sha256` bit rot If an new package is deployed to `hackage.haskell.org`, to use it before it is captured by the `hackage.nix` update add the following to the project arguments: ```nix index-state="2025-06-16T00:00:00Z"; # Use current time here # This hash in not valid, the error message will give the correct hash index-sha256="sha256-NS28jJYko/tNUKVhncntu/mV8tsQmTA52T000000000="; ``` This change PR fixes some "bit rot" issues: * A warning about `--index-state` argument being out of range is now an error. * The sha256 might now be in base16 or base32. --- lib/call-cabal-project-to-nix.nix | 2 +- mk-local-hackage-repo/default.nix | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/call-cabal-project-to-nix.nix b/lib/call-cabal-project-to-nix.nix index 952ebb1e09..d11ca7e70e 100644 --- a/lib/call-cabal-project-to-nix.nix +++ b/lib/call-cabal-project-to-nix.nix @@ -678,7 +678,7 @@ let # Setting the desired `index-state` here in case it is not # in the cabal.project file. This will further restrict the # packages used by the solver (cached-index-state >= index-state-max). - pkgs.lib.optionalString (index-state != null) "--index-state=${index-state}" + pkgs.lib.optionalString (index-state != null && index-state < cached-index-state) "--index-state=${index-state}" } \ -w ${ # We are using `-w` rather than `--with-ghc` here to override diff --git a/mk-local-hackage-repo/default.nix b/mk-local-hackage-repo/default.nix index 66647dddea..e0e1d4e039 100644 --- a/mk-local-hackage-repo/default.nix +++ b/mk-local-hackage-repo/default.nix @@ -17,7 +17,7 @@ pkgs: { name, index }: -pkgs.buildPackages.runCommand "hackage-repo-${name}" { preferLocalBuild = true; } '' +pkgs.pkgsBuildBuild.runCommand "hackage-repo-${name}" { preferLocalBuild = true; } '' mkdir -p $out export expires="4000-01-01T00:00:00Z" @@ -29,7 +29,7 @@ ${ # of the index derivation (when the `extra-hackages` feature is used the index # may not have an outputHash). pkgs.lib.optionalString (index ? outputHash) '' - if [[ "${index.outputHash}" != "$index_sha256" ]]; then + if [[ "$(${pkgs.pkgsBuildBuild.nix}/bin/nix-hash --type sha256 --to-base16 ${index.outputHash})" != "$index_sha256" ]]; then echo "ERROR See https://github.com/input-output-hk/haskell.nix/issues/884" exit 1 fi From 8b786e557344b7feb85dfe6350312947b50657a8 Mon Sep 17 00:00:00 2001 From: Hamish Mackenzie Date: Wed, 18 Jun 2025 17:38:11 +1200 Subject: [PATCH 2/6] Add comment --- lib/call-cabal-project-to-nix.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/call-cabal-project-to-nix.nix b/lib/call-cabal-project-to-nix.nix index d11ca7e70e..42679dffc5 100644 --- a/lib/call-cabal-project-to-nix.nix +++ b/lib/call-cabal-project-to-nix.nix @@ -678,6 +678,8 @@ let # Setting the desired `index-state` here in case it is not # in the cabal.project file. This will further restrict the # packages used by the solver (cached-index-state >= index-state-max). + # Cabal treats `--index-state` > the last known package as an error, + # so we only include this if it is < cached-index-state. pkgs.lib.optionalString (index-state != null && index-state < cached-index-state) "--index-state=${index-state}" } \ -w ${ From b2ccf2f7d5754e9007e14d0bfac78ad6e4433919 Mon Sep 17 00:00:00 2001 From: Hamish Mackenzie Date: Wed, 18 Jun 2025 19:49:31 +1200 Subject: [PATCH 3/6] Doc change to trigger hydra CI --- docs/reference/library.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/library.md b/docs/reference/library.md index 4137cc0d45..c6014831cd 100644 --- a/docs/reference/library.md +++ b/docs/reference/library.md @@ -273,8 +273,8 @@ needed for `importAndFilterProject`. |----------------------|------|---------------------| | `name` | String | Optional name for better error messages. | | `src` | Path | Location of the cabal project files. | -| `compiler-nix-name` | String | The name of the ghc compiler to use eg. "ghc884" | -| `index-state` | Timestamp | Optional hackage index-state, eg. "2019-10-10T00:00:00Z". | +| `compiler-nix-name` | String | The name of the ghc compiler to use eg. "ghc9122" | +| `index-state` | Timestamp | Optional hackage index-state, eg. "2025-01-10T00:00:00Z". | | `index-sha256` | Sha256 | Optional hash of the truncated hackage index-state. | | `plan-sha256` | Sha256 | Optional hash of the plan-to-nix output (makes the plan-to-nix step a fixed output derivation). | | `cabalProject` | String | Optional cabal project file contents (defaults to readFile "${src}/cabal.project"). | From 75098f8e585ae3db165e0b7b6d4ed5caaebe0047 Mon Sep 17 00:00:00 2001 From: Hamish Mackenzie Date: Wed, 18 Jun 2025 23:26:22 +1200 Subject: [PATCH 4/6] Fix cross compilation shells --- overlays/haskell.nix | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/overlays/haskell.nix b/overlays/haskell.nix index 01a15ecdce..9d2c5372b2 100644 --- a/overlays/haskell.nix +++ b/overlays/haskell.nix @@ -832,18 +832,13 @@ final: prev: { shellFor' = crossPlatforms: let shellArgs = builtins.removeAttrs rawProject.args.shell [ "crossPlatforms" ]; - # These are the args we will pass to the shells for the corss compiler - argsCross = - # These things should match main shell - final.lib.filterAttrs (n: _: builtins.elem n [ - "packages" "components" "additional" "exactDeps" "packageSetupDeps" - ]) shellArgs // { - # The main shell's hoogle will probably be faster to build. - withHoogle = false; - }; # Shells for cross compilation - crossShells = builtins.map (project: project.shellFor' (_p: []) argsCross) - (crossPlatforms projectCross); + crossShells = builtins.map (project: project.shellFor { + # Prevent recursion + crossPlatforms = final.lib.mkForce (_p: []); + # The main shell's hoogle will probably be faster to build. + withHoogle = final.lib.mkForce false; + }) (crossPlatforms projectCross); in rawProject.hsPkgs.shellFor (shellArgs // { # Add inputs from the cross compilation shells inputsFrom = shellArgs.inputsFrom or [] ++ crossShells; @@ -1152,7 +1147,7 @@ final: prev: { let ghc = final.buildPackages.haskell-nix.compiler.${compiler-nix-name}.override { hadrianEvalPackages = evalPackages; }; in - final.recurseIntoAttrs ({ + final.recurseIntoAttrs ({ # Things that require no IFD to build source-pin-hackage = hackageSrc; source-pin-stackage = stackageSrc; From c94f4af310d96607fda54a87e885862fe2b3b1e4 Mon Sep 17 00:00:00 2001 From: Hamish Mackenzie Date: Thu, 19 Jun 2025 16:38:05 +1200 Subject: [PATCH 5/6] Use hackage.nix/index-state.nix --- flake.lock | 23 ++++++++++++++++++++--- flake.nix | 4 ++++ overlays/haskell.nix | 8 +++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index aa71cdeb03..ef617057a0 100644 --- a/flake.lock +++ b/flake.lock @@ -120,11 +120,11 @@ "hackage": { "flake": false, "locked": { - "lastModified": 1750206399, - "narHash": "sha256-xfdraUW6ocTsK7vpP5WK6dthi0W4x+0Rv9Q+OayUMoY=", + "lastModified": 1750307553, + "narHash": "sha256-iiafNoeLHwlSLQTyvy8nPe2t6g5AV4PPcpMeH/2/DLs=", "owner": "input-output-hk", "repo": "hackage.nix", - "rev": "de0d14da94af55d9f05691bee8251cd8b5853294", + "rev": "f7867baa8817fab296528f4a4ec39d1c7c4da4f3", "type": "github" }, "original": { @@ -150,6 +150,22 @@ "type": "github" } }, + "hackage-internal": { + "flake": false, + "locked": { + "lastModified": 1750307553, + "narHash": "sha256-iiafNoeLHwlSLQTyvy8nPe2t6g5AV4PPcpMeH/2/DLs=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "f7867baa8817fab296528f4a4ec39d1c7c4da4f3", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, "hls": { "flake": false, "locked": { @@ -527,6 +543,7 @@ "ghc-8.6.5-iohk": "ghc-8.6.5-iohk", "hackage": "hackage", "hackage-for-stackage": "hackage-for-stackage", + "hackage-internal": "hackage-internal", "hls": "hls", "hls-1.10": "hls-1.10", "hls-2.0": "hls-2.0", diff --git a/flake.nix b/flake.nix index a28bd6abbc..54723b2b81 100644 --- a/flake.nix +++ b/flake.nix @@ -31,6 +31,10 @@ url = "github:input-output-hk/hackage.nix/for-stackage"; flake = false; }; + hackage-internal = { + url = "github:input-output-hk/hackage.nix"; + flake = false; + }; stackage = { url = "github:input-output-hk/stackage.nix"; flake = false; diff --git a/overlays/haskell.nix b/overlays/haskell.nix index 9d2c5372b2..4afc754f03 100644 --- a/overlays/haskell.nix +++ b/overlays/haskell.nix @@ -437,8 +437,8 @@ final: prev: { # If you want to update this value it important to check the # materializations. Turn `checkMaterialization` on below and # check the CI results before turning it off again. - internalHackageIndexState = "2024-10-17T00:00:00Z"; # Remember to also update ../nix-tools/cabal.project and ../nix-tools/flake.lock - + internalHackageIndexState = builtins.head (builtins.attrNames ( + import (sources.hackage-internal + "/index-state.nix"))); checkMaterialization = false; # This is the default. Use an overlay to set it to true and test all the materialized files # Helps materialize the output of derivations @@ -601,7 +601,9 @@ final: prev: { # Takes a haskell src directory runs cabal new-configure and plan-to-nix. # Resulting nix files are added to nix-plan subdirectory. callCabalProjectToNix = import ../lib/call-cabal-project-to-nix.nix { - index-state-hashes = import indexStateHashesPath; + index-state-hashes = + import (sources.hackage + "/index-state.nix") + // import (sources.hackage-internal + "/index-state.nix"); inherit (final.buildPackages.haskell-nix) haskellLib; pkgs = final.buildPackages.pkgs; inherit (final.buildPackages.pkgs) cacert; From 6ebbbaea798cf64a64481a5359f712c7b3c6ad08 Mon Sep 17 00:00:00 2001 From: Hamish Mackenzie Date: Thu, 19 Jun 2025 22:17:45 +1200 Subject: [PATCH 6/6] Support for older hackage.nix versions --- overlays/haskell.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/overlays/haskell.nix b/overlays/haskell.nix index 4afc754f03..3d6ad1c6c0 100644 --- a/overlays/haskell.nix +++ b/overlays/haskell.nix @@ -602,7 +602,11 @@ final: prev: { # Resulting nix files are added to nix-plan subdirectory. callCabalProjectToNix = import ../lib/call-cabal-project-to-nix.nix { index-state-hashes = - import (sources.hackage + "/index-state.nix") + ( + if builtins.pathExists (hackageSrc + "/index-state.nix") + then import (hackageSrc + "/index-state.nix") + else import (hackageSrc + "/index-state-hashes.nix") + ) // import (sources.hackage-internal + "/index-state.nix"); inherit (final.buildPackages.haskell-nix) haskellLib; pkgs = final.buildPackages.pkgs;