Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: cabal2nix integration for IFD-less evalutation #382

Merged
merged 10 commits into from
Dec 23, 2024
7 changes: 7 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@
};
};

test-cabal2nix = {
dir = "test/cabal2nix";
overrideInputs = {
inherit nixpkgs flake-parts haskell-flake;
};
};

test-with-subdir = {
dir = "test/with-subdir";
overrideInputs = {
Expand Down
21 changes: 18 additions & 3 deletions nix/build-haskell-package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,30 @@ let
name = "${name}";
inherit src;
};

in

name: root:
name: root: cabal2NixFile:
lib.pipe root
[
# Avoid rebuilding because of changes in parent directories
(mkNewStorePath "source-${name}")
(x: log.traceDebug "${name}.mkNewStorePath ${x.outPath}" x)

(root: self.callCabal2nix name root { })
(x: log.traceDebug "${name}.cabal2nixDeriver ${x.cabal2nixDeriver.outPath}" x)
(root:
let path = "${root}/${cabal2NixFile}";
in
# Check if cached cabal2nix generated nix expression is present,
# if present use it with callPackage
# to avoid IFD
if builtins.pathExists path
then
(log.traceDebug "${name}.callPackage[cabal2nix] ${path}")
(self.callPackage path { })
else
lib.pipe (self.callCabal2nix name root { })
[
(pkg: log.traceDebug "${name}.callCabal2nix root=${root} deriver=${pkg.cabal2nixDeriver.outPath}" pkg)
]
)
]
3 changes: 1 addition & 2 deletions nix/modules/project/packages/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ in
getOrMkPackage = name: cfg:
if lib.types.path.check cfg.source
then
log.traceDebug "${name}.callCabal2nix ${cfg.source}"
(build-haskell-package name cfg.source)
(build-haskell-package name cfg.source cfg.cabal2NixFile)
else
log.traceDebug "${name}.callHackage ${cfg.source}"
(self.callHackage name cfg.source { });
Expand Down
10 changes: 10 additions & 0 deletions nix/modules/project/packages/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ in
'';
};

cabal2NixFile = lib.mkOption {
type = lib.types.str;
description = ''
The Nix file which contains cached (pre-generated) `cabal2nix` expressions.

By default, it refers to `cabal.nix` file.
'';
default = "cabal.nix";
};

cabal.executables = mkOption {
type = types.nullOr (types.listOf types.str);
description = ''
Expand Down
11 changes: 11 additions & 0 deletions test/cabal2nix/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{ mkDerivation, base, lib, random }:
mkDerivation {
pname = "haskell-flake-test";
version = "0.1.0.0";
src = ./.;
isLibrary = false;
isExecutable = true;
executableHaskellDepends = [ base random ];
license = "unknown";
mainProgram = "haskell-flake-test";
}
35 changes: 35 additions & 0 deletions test/cabal2nix/flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
# Disable IFD for this test.
nixConfig = {
allow-import-from-derivation = false;
};

# Since there is no flake.lock file (to avoid incongruent haskell-flake
# pinning), we must specify revisions for *all* inputs to ensure
# reproducibility.
inputs = {
nixpkgs = { };
flake-parts = { };
haskell-flake = { };
};

outputs = inputs@{ self, nixpkgs, flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = nixpkgs.lib.systems.flakeExposed;
imports = [
inputs.haskell-flake.flakeModule
];
debug = true;
perSystem = { config, self', pkgs, lib, ... }: {
haskellProjects.default = {
# If IFD is disabled,
# we need to specify the pre-generated `cabal2nix` expressions
# file to haskell-flake for the package,
# otherwise build would fail as it would use `callCabal2nix` function
# which uses IFD.
packages.haskell-flake-test.cabal2NixFile = "default.nix";
settings = { };
};
};
};
}
20 changes: 20 additions & 0 deletions test/cabal2nix/haskell-flake-test.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
cabal-version: 3.0
name: haskell-flake-test
version: 0.1.0.0
license: NONE
author: Joe
maintainer: [email protected]
build-type: Simple

common warnings
ghc-options: -Wall

executable haskell-flake-test
import: warnings
main-is: Main.hs
build-depends:
base,
random
hs-source-dirs: src
default-language: Haskell2010

6 changes: 6 additions & 0 deletions test/cabal2nix/src/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Main where

import System.Random

main :: IO ()
main = putStrLn "Hello, Haskell!"