diff options
Diffstat (limited to 'Biz/Bild/Rules.nix')
-rw-r--r-- | Biz/Bild/Rules.nix | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/Biz/Bild/Rules.nix b/Biz/Bild/Rules.nix new file mode 100644 index 0000000..6afe9a0 --- /dev/null +++ b/Biz/Bild/Rules.nix @@ -0,0 +1,149 @@ +{ nixpkgs }: + +with nixpkgs; + +let + # provided by .envrc + root = builtins.getEnv "BIZ_ROOT"; + + # general functions to put in a lib + lines = s: lib.strings.splitString "\n" s; + removeNull = ls: builtins.filter (x: x != null) ls; + + depsToPackageSet = packageSet: deps: + 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; + + allDeps = import ./Deps.nix; + + # 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 ': exe' declaration + exe = builtins.head (lib.lists.flatten (removeNull + (map (builtins.match "^-- : exe ([[:alnum:]._-]*)$") + (lines content)))); + # collect all of the ': dep' declarations + deps = lib.lists.flatten (removeNull + (map (builtins.match "^-- : dep ([[:alnum:]._-]*)$") + (lines content))); + }; + + mkGhc = compiler: (deps: compiler (hp: + if (subset deps allDeps) + then depsToPackageSet hp deps + else throw '' + missing from nix/haskell-deps.nix: + ${toString (lib.lists.subtractLists allDeps deps)} + '')); + + ghc_ = mkGhc pkgs.haskell.packages.ghc865.ghcWithHoogle; + ghcjs_ = mkGhc pkgs.haskell.packages.ghcjs.ghcWithPackages; +in { + ghc = main: + let + data = analyze main; + ghc = ghc_ data.deps; + in stdenv.mkDerivation { + name = data.module; + src = ../.; + nativeBuildInputs = [ ghc ]; + strictDeps = true; + buildPhase = '' + mkdir -p $out/bin + # compile with ghc + ${ghc}/bin/ghc -Werror -Weverything -i. \ + --make ${main} \ + -main-is ${data.module} \ + -o $out/bin/${data.exe} + ''; + # the install process was handled above + installPhase = "exit 0"; + } // { env = ghc; }; + + ghcjs = main: + let + data = analyze main; + ghcjs = ghcjs_ data.deps; + in stdenv.mkDerivation { + name = data.module; + src = ../.; + nativeBuildInputs = [ ghcjs ]; + strictDeps = true; + buildPhase = '' + mkdir -p $out/static + # compile with ghcjs + ${ghcjs}/bin/ghcjs -Werror -Weverything -i. \ + --make ${main} \ + -main-is ${data.module} \ + -o ${data.exe} + # optimize js output + ${pkgs.closurecompiler}/bin/closure-compiler \ + ${data.exe}/all.js > $out/static/${data.exe} + ''; + installPhase = "exit 0"; + } // { env = ghcjs; }; + + env = mkShell { + name = "bizdev"; + buildInputs = [ + (ghc_ allDeps) + # ghcjs doesn't need everything, and many things fail to build + (ghcjs_ [ + "aeson" + "clay" + "containers" + "miso" + "protolude" + "servant" + "split" + "string-quote" + "text" + "ghcjs-base" + ]) + + nixpkgs.figlet + nixpkgs.hlint + nixpkgs.lolcat + nixpkgs.niv.niv + nixpkgs.ormolu + nixpkgs.python37Packages.black + nixpkgs.python37Packages.pylint + nixpkgs.wemux + ]; + shellHook = ". ${./ShellHook.sh}"; + }; + + os = cfg: (nixos (args: lib.attrsets.recursiveUpdate cfg { + boot.cleanTmpDir = true; + networking.firewall.allowPing = true; + nix.binaryCaches = [ "https://cache.nixos.org" ]; + nix.gc.automatic = true; + nix.gc.dates = "Sunday 02:15"; + nix.optimise.automatic = true; + nix.optimise.dates = [ "Sunday 02:30" ]; + nixpkgs.overlays = overlays; + programs.mosh.enable = true; + programs.mosh.withUtempter = true; + security.acme.email = "ben@bsima.me"; + security.acme.acceptTerms = true; + security.sudo.wheelNeedsPassword = false; + services.clamav.daemon.enable = true; # security + services.clamav.updater.enable = true; # security + services.fail2ban.enable = true; # security + services.openssh.enable = true; + services.openssh.openFirewall = true; + services.openssh.forwardX11 = true; + services.openssh.passwordAuthentication = false; + system.autoUpgrade.enable = false; # 'true' breaks our nixpkgs pin + })).toplevel; +} |