on iko/ghcjs-patch-master help sign in
Update the project modules and fix missing args param (#1144)
f279cdeHamish Mackenzie
docs/tutorials/getting-started-flakes.md+13−11
@@ -50,24 +50,26 @@ Add `flake.nix`:
50 final.haskell-nix.project' {
50 final.haskell-nix.project' {
51 src = ./.;
51 src = ./.;
52 compiler-nix-name = "ghc8104";
52 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];
53 };
62 };
54 })
63 })
55 ];
64 ];
56 pkgs = import nixpkgs { inherit system overlays; };
65 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+ };
58 in flake // {
70 in flake // {
59 # Built by `nix build .`
71 # Built by `nix build .`
60 defaultPackage = flake.packages."hello:exe:hello";
72 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− };
71 });
73 });
72}
74}
73```
75```
lib/default.nix+2−1
@@ -339,8 +339,9 @@ in {
339 # The resulting config is then passed to the project function's implementation.
339 # The resulting config is then passed to the project function's implementation.
340 evalProjectModule = projectType: m: f: f
340 evalProjectModule = projectType: m: f: f
341 (lib.evalModules {
341 (lib.evalModules {
342− modules = [m] ++ [
342+ modules = (if builtins.isList m then m else [m]) ++ [
343 # Include ../modules/cabal-project.nix or ../modules/stack-project.nix
343 # Include ../modules/cabal-project.nix or ../modules/stack-project.nix
344+ (import ../modules/project-common.nix)
344 (import projectType)
345 (import projectType)
345 # Pass the pkgs to the modules
346 # Pass the pkgs to the modules
346 ({ config, lib, ... }: {
347 ({ config, lib, ... }: {
modules/cabal-project.nix−20
@@ -11,14 +11,6 @@ in {
11 _file = "haskell.nix/modules/cabal-project.nix";
11 _file = "haskell.nix/modules/cabal-project.nix";
12 options = {
12 options = {
13 # Used by callCabalProjectToNix
13 # 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− };
22 compiler-nix-name = mkOption {
14 compiler-nix-name = mkOption {
23 type = str;
15 type = str;
24 description = "The name of the ghc compiler to use eg. \"ghc884\"";
16 description = "The name of the ghc compiler to use eg. \"ghc884\"";
@@ -137,17 +129,5 @@ in {
137 type = nullOr (listOf unspecified);
129 type = nullOr (listOf unspecified);
138 default = [];
130 default = [];
139 };
131 };
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− };
152 };
132 };
153}
133}
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;
5 _file = "haskell.nix/modules/stack-project.nix";
5 _file = "haskell.nix/modules/stack-project.nix";
6 options = {
6 options = {
7 # Used by callStackToNix
7 # 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− };
16 stackYaml = mkOption {
8 stackYaml = mkOption {
17 type = str;
9 type = str;
18 default = "stack.yaml";
10 default = "stack.yaml";
@@ -109,17 +101,5 @@ with types;
109 default = null;
101 default = null;
110 description = "Deprecated in favour of `compiler-nix-name`";
102 description = "Deprecated in favour of `compiler-nix-name`";
111 };
103 };
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− };
124 };
104 };
125}
105}
overlays/haskell.nix+22−10
@@ -531,7 +531,7 @@ final: prev: {
531 tools = final.buildPackages.haskell-nix.tools pkg-set.config.compiler.nix-name;
531 tools = final.buildPackages.haskell-nix.tools pkg-set.config.compiler.nix-name;
532 roots = final.haskell-nix.roots pkg-set.config.compiler.nix-name;
532 roots = final.haskell-nix.roots pkg-set.config.compiler.nix-name;
533 projectFunction = haskell-nix: haskell-nix.cabalProject';
533 projectFunction = haskell-nix: haskell-nix.cabalProject';
534− inherit projectModule;
534+ inherit projectModule args;
535 };
535 };
536 in project);
536 in project);
537
537
@@ -793,7 +793,7 @@ final: prev: {
793 tools = final.buildPackages.haskell-nix.tools pkg-set.config.compiler.nix-name;
793 tools = final.buildPackages.haskell-nix.tools pkg-set.config.compiler.nix-name;
794 roots = final.haskell-nix.roots pkg-set.config.compiler.nix-name;
794 roots = final.haskell-nix.roots pkg-set.config.compiler.nix-name;
795 projectFunction = haskell-nix: haskell-nix.stackProject';
795 projectFunction = haskell-nix: haskell-nix.stackProject';
796− inherit projectModule;
796+ inherit projectModule args;
797 };
797 };
798 in project);
798 in project);
799
799
@@ -809,9 +809,17 @@ final: prev: {
809 # selected file ends in a `.yaml` it is assumed to be for `stackProject`.
809 # selected file ends in a `.yaml` it is assumed to be for `stackProject`.
810 # If neither `stack.yaml` nor `cabal.project` exist `cabalProject` is
810 # If neither `stack.yaml` nor `cabal.project` exist `cabalProject` is
811 # used (as it will use a default `cabal.project`).
811 # used (as it will use a default `cabal.project`).
812− project' = { src, projectFileName ? null, ... }@args':
812+ project' = projectModule:
813 let
813 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;
815 dir = __readDir (src.origSrcSubDir or src);
823 dir = __readDir (src.origSrcSubDir or src);
816 exists = fileName: builtins.elem (dir.${fileName} or "") ["regular" "symlink"];
824 exists = fileName: builtins.elem (dir.${fileName} or "") ["regular" "symlink"];
817 stackYamlExists = exists "stack.yaml";
825 stackYamlExists = exists "stack.yaml";
@@ -829,15 +837,19 @@ final: prev: {
829 else "cabal.project"; # the cabal.project file is optional
837 else "cabal.project"; # the cabal.project file is optional
830 in
838 in
831 if final.lib.hasSuffix ".yaml" selectedFileName
839 if final.lib.hasSuffix ".yaml" selectedFileName
840+ then stackProject' ([
841+ (import ../modules/project.nix)
832− then stackProject' (args // { stackYaml = selectedFileName; })
842+ { caller = "project'"; stackYaml = selectedFileName; }
843+ ] ++ projectModule'
844+ )
845+ else cabalProject' ([
846+ (import ../modules/project.nix)
833− else cabalProject' (args // { cabalProjectFileName = selectedFileName; });
847+ { caller = "project'"; cabalProjectFileName = selectedFileName; }
848+ ] ++ projectModule');
834
849
835 # This is the same as the `cabalPackage` and `stackPackage` wrappers
850 # This is the same as the `cabalPackage` and `stackPackage` wrappers
836 # for `cabalPackage` and `stackPackage`.
851 # 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;
841 in p.hsPkgs // p;
853 in p.hsPkgs // p;
842
854
843 # Like `cabalProject'`, but for building the GHCJS compiler.
855 # Like `cabalProject'`, but for building the GHCJS compiler.