@@ -122,14 +122,39 @@ let
122 else builtins.trace ("Using latest index state" + (if name == null then "" else " for " + name) + "!")
122 else builtins.trace ("Using latest index state" + (if name == null then "" else " for " + name) + "!")
123 (pkgs.lib.last (builtins.attrNames index-state-hashes));
123 (pkgs.lib.last (builtins.attrNames index-state-hashes));
126+ assert (if index-state-found == null
127+ then throw "No index state passed and none found in ${cabalProjectFileName}" else true);
129+ assert (if index-sha256 == null && !(pkgs.lib.hasSuffix "Z" index-state-found)
130+ then throw "Index state found was ${index-state-found} and no `index-sha256` was provided. "
131+ "The index hash lookup code requires zulu time zone (ends in a Z)" else true);
134+ # If a hash was not specified find a suitable cached index state to
135+ # use that will contain all the packages we need. By using the
136+ # first one after the desired index-state we can avoid recalculating
137+ # when new index-state-hashes are added.
138+ # See https://github.com/input-output-hk/haskell.nix/issues/672
139+ cached-index-state = if index-sha256 != null
140+ then index-state-found
143+ suitable-index-states =
145+ (s: s >= index-state-found) # This compare is why we need zulu time
146+ (builtins.attrNames index-state-hashes);
148+ if builtins.length suitable-index-states == 0
149+ then index-state-found
150+ else pkgs.lib.head suitable-index-states;
125 # Lookup hash for the index state we found
152 # Lookup hash for the index state we found
126 index-sha256-found = if index-sha256 != null
153 index-sha256-found = if index-sha256 != null
127 then index-sha256
154 then index-sha256
128− else index-state-hashes.${index-state-found} or null;
155+ else index-state-hashes.${cached-index-state} or null;
131− assert (if index-state-found == null
132− then throw "No index state passed and none found in ${cabalProjectFileName}" else true);
133 assert (if index-sha256-found == null
158 assert (if index-sha256-found == null
134 then throw "Unknown index-state ${index-state-found}, the latest index-state I know about is ${pkgs.lib.last (builtins.attrNames index-state-hashes)}. You may need to update to a newer hackage.nix." else true);
159 then throw "Unknown index-state ${index-state-found}, the latest index-state I know about is ${pkgs.lib.last (builtins.attrNames index-state-hashes)}. You may need to update to a newer hackage.nix." else true);
@@ -389,12 +414,23 @@ let
390 export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
415 export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
391 export GIT_SSL_CAINFO=${cacert}/etc/ssl/certs/ca-bundle.crt
416 export GIT_SSL_CAINFO=${cacert}/etc/ssl/certs/ca-bundle.crt
418+ # This creates `.cabal` directory that is as it would have
419+ # been at the time `cached-index-state`. We may include
420+ # some packages that will be excluded by `index-state-found`
421+ # which is used by cabal (cached-index-state >= index-state-found).
392− HOME=${dotCabal {
422+ dotCabal {
393− inherit cabal-install nix-tools extra-hackage-tarballs;
423+ inherit cabal-install nix-tools extra-hackage-tarballs;
394− index-state =
424+ index-state = cached-index-state;
425+ sha256 = index-sha256-found;
427+ } cabal v2-configure \
429+ # Setting the desired `index-state` here in case it was not
430+ # from the cabal.project file. This will further restrict the
431+ # packages used by the solver (cached-index-state >= index-state-found).
395− builtins.trace ("Using index-state: ${index-state-found}" + (if name == null then "" else " for " + name))
432+ builtins.trace ("Using index-state: ${index-state-found}" + (if name == null then "" else " for " + name))
396− index-state-found;
433+ index-state-found} \
397− sha256 = index-sha256-found; }} cabal v2-configure \
398 --with-ghc=${ghc.targetPrefix}ghc \
434 --with-ghc=${ghc.targetPrefix}ghc \
399 --with-ghc-pkg=${ghc.targetPrefix}ghc-pkg \
435 --with-ghc-pkg=${ghc.targetPrefix}ghc-pkg \
400 --enable-tests \
436 --enable-tests \
@@ -437,4 +473,9 @@ let
437 # move pkgs.nix to default.nix ensure we can just nix `import` the result.
473 # move pkgs.nix to default.nix ensure we can just nix `import` the result.
438 mv $out${subDir'}/pkgs.nix $out${subDir'}/default.nix
474 mv $out${subDir'}/pkgs.nix $out${subDir'}/default.nix
477+ projectNix = plan-nix;
478+ index-state = index-state-found;
440−in { projectNix = plan-nix; inherit src; inherit (fixedProject) sourceRepos; }
480+ inherit (fixedProject) sourceRepos;