on iko/ghcjs-patch-master help sign in
Update the project modules and fix missing args param (#1144)

There are now 4 project modules used to check the arguments passed to the various project functions: * `project-common.nix` - Arguments used by all the project functions * `stack-project.nix` - Used by the `stackProject` and `stackProject'` functions * `cabal-project.nix` - Used by the `cabalProject` and `cabalProject'` functions * `project.nix` - Just the `projectFileName` argument that is used by `project` and `project'` functions to determine whether to call `stackProject` or `cabalProject` function. This also includes the `rawProject.args` that was mistakenly left out of #1141 causing #1142 and improvements for the docs for the use of the `shell` argument in `flake.nix` files.

commitf279cdef5f74f4262045e83713fb5f80df2ef576 authorHamish Mackenzie <Hamish.Mackenzie@iohk.io> dateSun 20 Jun 2021, 18:00 (5 years ago) parentf53f98a
7 files changed+74−62
docs/tutorials/getting-started-flakes.md+13−11 lib/default.nix+2−1 modules/cabal-project.nix−20 modules/project-common.nix+28 modules/project.nix+9 modules/stack-project.nix−20 overlays/haskell.nix+22−10
docs/tutorials/getting-started-flakes.md+13−11
@@ -50,24 +50,26 @@ Add `flake.nix`:
5050 final.haskell-nix.project' {
5151 src = ./.;
5252 compiler-nix-name = "ghc8104";
53+ # This is used by `nix develop .` to open a shell for use with
54+ # `cabal`, `hlint` and `haskell-language-server`
55+ shell.tools = {
56+ cabal = {};
57+ hlint = {};
58+ haskell-language-server = {};
59+ };
60+ # This adds `js-unknown-ghcjs-cabal` to the shell.
61+ shell.crossPlatform = p: [p.ghcjs];
5362 };
5463 })
5564 ];
5665 pkgs = import nixpkgs { inherit system overlays; };
57− flake = pkgs.helloProject.flake {};
66+ flake = pkgs.helloProject.flake {
67+ # This adds support for `nix build .#js-unknown-ghcjs-cabal:hello:exe:hello`
68+ crossPlatforms = p: [p.ghcjs];
69+ };
5870 in flake // {
5971 # Built by `nix build .`
6072 defaultPackage = flake.packages."hello:exe:hello";
61−
62− # This is used by `nix develop .` to open a shell for use with
63− # `cabal`, `hlint` and `haskell-language-server`
64− devShell = pkgs.helloProject.shellFor {
65− tools = {
66− cabal = "latest";
67− hlint = "latest";
68− haskell-language-server = "latest";
69− };
70− };
7173 });
7274}
7375```
lib/default.nix+2−1
@@ -339,8 +339,9 @@ in {
339339 # The resulting config is then passed to the project function's implementation.
340340 evalProjectModule = projectType: m: f: f
341341 (lib.evalModules {
342− modules = [m] ++ [
342+ modules = (if builtins.isList m then m else [m]) ++ [
343343 # Include ../modules/cabal-project.nix or ../modules/stack-project.nix
344+ (import ../modules/project-common.nix)
344345 (import projectType)
345346 # Pass the pkgs to the modules
346347 ({ config, lib, ... }: {
modules/cabal-project.nix−20
@@ -11,14 +11,6 @@ in {
1111 _file = "haskell.nix/modules/cabal-project.nix";
1212 options = {
1313 # Used by callCabalProjectToNix
14− name = mkOption {
15− type = nullOr str;
16− default = config.src.name or null;
17− description = "Optional name for better error messages";
18− };
19− src = mkOption {
20− type = either path package;
21− };
2214 compiler-nix-name = mkOption {
2315 type = str;
2416 description = "The name of the ghc compiler to use eg. \"ghc884\"";
@@ -137,17 +129,5 @@ in {
137129 type = nullOr (listOf unspecified);
138130 default = [];
139131 };
140−
141− # Default shell arguments
142− shell = mkOption {
143− # TODO make this a submodule
144− type = unspecified;
145− default = {};
146− description = ''
147− Arguments to use for the default shell `p.shell` (these are passed to p.shellFor).
148− For instance to include `cabal` and `ghcjs` support use
149− shell = { tools.cabal = {}; crossPlatforms = p: [ p.ghcjs ]; }
150− '';
151− };
152132 };
153133}
modules/project-common.nixnew file+28
@@ -0,0 +1,28 @@
1+{ lib, ... }:
2+with lib;
3+with lib.types;
4+{
5+ _file = "haskell.nix/modules/project-common.nix";
6+ options = {
7+ # Used by callCabalProjectToNix and callStackToNix
8+ name = mkOption {
9+ type = nullOr str;
10+ default = "haskell-project"; # TODO figure out why `config.src.name or null` breaks hix;
11+ description = "Optional name for better error messages";
12+ };
13+ src = mkOption {
14+ type = either path package;
15+ };
16+ # Default shell arguments
17+ shell = mkOption {
18+ # TODO make this a submodule
19+ type = unspecified;
20+ default = {};
21+ description = ''
22+ Arguments to use for the default shell `p.shell` (these are passed to p.shellFor).
23+ For instance to include `cabal` and `ghcjs` support use
24+ shell = { tools.cabal = {}; crossPlatforms = p: [ p.ghcjs ]; }
25+ '';
26+ };
27+ };
28+}
modules/project.nixnew file+9
@@ -0,0 +1,9 @@
1+{ lib, ... }: {
2+ _file = "haskell.nix/modules/project.nix";
3+ options = {
4+ projectFileName = lib.mkOption {
5+ type = lib.types.nullOr lib.types.str;
6+ default = null;
7+ };
8+ };
9+}
modules/stack-project.nix−20
@@ -5,14 +5,6 @@ with types;
55 _file = "haskell.nix/modules/stack-project.nix";
66 options = {
77 # Used by callStackToNix
8− name = mkOption {
9− type = nullOr str;
10− default = config.src.name or null;
11− description = "Optional name for better error messages";
12− };
13− src = mkOption {
14− type = either path package;
15− };
168 stackYaml = mkOption {
179 type = str;
1810 default = "stack.yaml";
@@ -109,17 +101,5 @@ with types;
109101 default = null;
110102 description = "Deprecated in favour of `compiler-nix-name`";
111103 };
112−
113− # Default shell arguments
114− shell = mkOption {
115− # TODO make this a submodule
116− type = unspecified;
117− default = {};
118− description = ''
119− Arguments to use for the default shell `p.shell` (these are passed to p.shellFor).
120− For instance to include `cabal` and `ghcjs` support use
121− shell = { tools.cabal = {}; crossPlatforms = p: [ p.ghcjs ]; }
122− '';
123− };
124104 };
125105}
overlays/haskell.nix+22−10
@@ -531,7 +531,7 @@ final: prev: {
531531 tools = final.buildPackages.haskell-nix.tools pkg-set.config.compiler.nix-name;
532532 roots = final.haskell-nix.roots pkg-set.config.compiler.nix-name;
533533 projectFunction = haskell-nix: haskell-nix.cabalProject';
534− inherit projectModule;
534+ inherit projectModule args;
535535 };
536536 in project);
537537
@@ -793,7 +793,7 @@ final: prev: {
793793 tools = final.buildPackages.haskell-nix.tools pkg-set.config.compiler.nix-name;
794794 roots = final.haskell-nix.roots pkg-set.config.compiler.nix-name;
795795 projectFunction = haskell-nix: haskell-nix.stackProject';
796− inherit projectModule;
796+ inherit projectModule args;
797797 };
798798 in project);
799799
@@ -809,9 +809,17 @@ final: prev: {
809809 # selected file ends in a `.yaml` it is assumed to be for `stackProject`.
810810 # If neither `stack.yaml` nor `cabal.project` exist `cabalProject` is
811811 # used (as it will use a default `cabal.project`).
812− project' = { src, projectFileName ? null, ... }@args':
812+ project' = projectModule:
813813 let
814− args = { caller = "project'"; } // final.lib.filterAttrs (n: _: n != "projectFileName") args';
814+ projectModule' = if builtins.isList projectModule then projectModule else [projectModule];
815+ inherit ((final.lib.evalModules {
816+ modules = [
817+ (import ../modules/project-common.nix)
818+ (import ../modules/stack-project.nix)
819+ (import ../modules/cabal-project.nix)
820+ (import ../modules/project.nix)
821+ ] ++ projectModule';
822+ }).config) src projectFileName;
815823 dir = __readDir (src.origSrcSubDir or src);
816824 exists = fileName: builtins.elem (dir.${fileName} or "") ["regular" "symlink"];
817825 stackYamlExists = exists "stack.yaml";
@@ -829,15 +837,19 @@ final: prev: {
829837 else "cabal.project"; # the cabal.project file is optional
830838 in
831839 if final.lib.hasSuffix ".yaml" selectedFileName
832− then stackProject' (args // { stackYaml = selectedFileName; })
833− else cabalProject' (args // { cabalProjectFileName = selectedFileName; });
840+ then stackProject' ([
841+ (import ../modules/project.nix)
842+ { caller = "project'"; stackYaml = selectedFileName; }
843+ ] ++ projectModule'
844+ )
845+ else cabalProject' ([
846+ (import ../modules/project.nix)
847+ { caller = "project'"; cabalProjectFileName = selectedFileName; }
848+ ] ++ projectModule');
834849
835850 # This is the same as the `cabalPackage` and `stackPackage` wrappers
836851 # for `cabalPackage` and `stackPackage`.
837− project = args':
838− let
839− args = { caller = "project"; } // args';
840− p = project' args;
852+ project = args: let p = project' args;
841853 in p.hsPkgs // p;
842854
843855 # Like `cabalProject'`, but for building the GHCJS compiler.