{ nixpkgs ? import ./Bild/Nixpkgs.nix }: with nixpkgs; let ghcCompiler = "ghc884"; ghcjsCompiler = "ghcjs86"; # provided by .envrc root = builtins.getEnv "BIZ_ROOT"; # general functions to put in a lib lines = s: lib.pipe s [ (builtins.split "\n") (builtins.filter (x: builtins.typeOf x == "string")) ]; removeNull = ls: builtins.filter (x: x != null) ls; selectAttrs = deps: packageSet: lib.attrsets.attrVals deps packageSet; # returns true if a is a subset of b, where a and b are attrsets subset = a: b: builtins.all (x: builtins.elem x b) a; haskellDeps = hpkgs: import ./Bild/Deps/Haskell.nix hpkgs; mkGhcPackageSet = pkgs.haskell.packages.${ghcCompiler}.ghcWithHoogle; #mkGhcjsPackageSet = pkgs.haskell.packages.${ghcjsCompiler}.ghcWithPackages; in rec { # gather data needed for compiling by analyzing the main module analyze = main: rec { # path to the module relative to the git root relpath = builtins.replaceStrings ["${root}/"] [""] (builtins.toString main); # Haskell-appropriate name of the module module = builtins.replaceStrings ["/" ".hs"] ["." ""] relpath; # file contents content = builtins.readFile main; # search for the ': out' declaration out = lib.pipe content [ lines (map (builtins.match "^-- : out ([[:alnum:]._-]*)$")) removeNull lib.lists.flatten builtins.head ]; # collect all of the ': dep' declarations deps = lib.pipe content [ lines (map (builtins.match "^-- : dep ([[:alnum:]._-]*)$")) removeNull lib.lists.flatten ]; # collect ': sys' declarations sysdeps = lib.pipe content [ lines (map (builtins.match "^-- : sys ([[:alnum:]._-]*)$")) removeNull lib.lists.flatten ]; }; ghcPackageSetFull = mkGhcPackageSet haskellDeps; ghc = main: let data = analyze main; ghc = mkGhcPackageSet (hp: selectAttrs data.deps hp); in stdenv.mkDerivation { name = data.module; src = ../.; nativeBuildInputs = [ ghc ] ++ selectAttrs data.sysdeps nixpkgs; strictDeps = true; buildPhase = '' mkdir -p $out/bin # compile with ghc ${ghc}/bin/ghc \ -Werror \ -i. \ --make ${main} \ -main-is ${data.module} \ -o $out/bin/${data.out} ''; # the install process was handled above installPhase = "exit 0"; } // { env = ghc; }; #ghcjs = main: # let # data = analyze main; # ghcjs = mkGhcjsPackageSet (hp: selectAttrs data.deps hp); # in stdenv.mkDerivation { # name = data.module; # src = ../.; # nativeBuildInputs = [ ghcjs ]; # strictDeps = true; # buildPhase = '' # mkdir -p $out/static # # compile with ghcjs # ${ghcjs}/bin/ghcjs \ # -Werror \ # -i. \ # --make ${main} \ # -main-is ${data.module} \ # -o ${data.out} # # optimize js output # ${pkgs.closurecompiler}/bin/closure-compiler \ # ${data.out}/all.js > $out/static/${data.out} # ''; # installPhase = "exit 0"; # } // { env = ghcjs; }; env = mkShell { name = "bizdev"; buildInputs = [ # haskell deps (mkGhcPackageSet haskellDeps) # ghcjs doesn't need everything, and many things fail to build #(mkGhcjsPackageSet (hp: with hp; [ # aeson # clay # containers # miso # protolude # servant # split # text # ghcjs-base #])) # python deps (nixpkgs.python38.withPackages (p: [ p.black p.pylint ])) # tools nixpkgs.haskell.packages.${ghcCompiler}.apply-refact nixpkgs.cmark nixpkgs.figlet nixpkgs.haskell.packages.${ghcCompiler}.fast-tags nixpkgs.hlint nixpkgs.lolcat nixpkgs.niv.niv nixpkgs.nixops nixpkgs.ormolu nixpkgs.python37Packages.black nixpkgs.python37Packages.pylint nixpkgs.shellcheck nixpkgs.wemux nixpkgs.gmnisrv nixpkgs.gmni (pkgs.writeScriptBin "ftags" (builtins.readFile ./Ide/ftags.sh)) ] ++ lib.optional nixpkgs.stdenv.isLinux [ # scheme deps (i think these are broken on macOS) nixpkgs.guile nixpkgs.inspekt3d nixpkgs.libfive nixpkgs.ccze ]; shellHook = ". ${./Bild/ShellHook.sh}"; }; os = cfg: (nixos (args: cfg)).toplevel; sources = nixpkgs.sources; }