@@ -3,13 +3,36 @@
33, iosSdkVersion ? "10.2"
44}:
55let
6+ cleanSource = builtins.filterSource (name: _: let baseName = builtins.baseNameOf name; in !(
7+ builtins.match "^\\.ghc\\.environment.*" baseName != null ||
8+ baseName == "cabal.project.local"
9+ ));
10+
11+ commandRuntimeDeps = pkgs: with pkgs; [
12+ coreutils
13+ git
14+ gitAndTools.hub
15+ nix-prefetch-git
16+ openssh
17+ ];
18+
619 getReflexPlatform = sys: import ./dep/reflex-platform {
720 inherit iosSdkVersion;
821 system = sys;
922 enableLibraryProfiling = profiling;
23+
24+ nixpkgsOverlays = [
25+ (self: super: {
26+ obeliskExecutableConfig = import ./lib/executable-config { nixpkgs = pkgs; filterGitSource = cleanSource; };
27+ })
28+ ];
29+
1030 haskellOverlays = [
31+
1132 # Fix misc upstream packages
12− (self: super: {
33+ (self: super: let
34+ pkgs = self.callPackage ({ pkgs }: pkgs) {};
35+ in {
1336 # Need deriveSomeUniverse
1437 # PR: https://github.com/dmwit/universe/pull/32
1538 universe-template = self.callCabal2nix "universe-template" (pkgs.fetchFromGitHub {
@@ -19,8 +42,11 @@ let
1942 sha256 = "0ll2z0fh18z6x8jl8kbp7ldagwccz3wjmvrw1gw752z058n82yfa";
2043 } + /template) {};
2144 })
45+
2246 # Add obelisk packages
23− (self: super: {
47+ (self: super: let
48+ pkgs = self.callPackage ({ pkgs }: pkgs) {};
49+ in {
2450 obelisk-asset-manifest = self.callCabal2nix "obelisk-asset-manifest" (hackGet ./lib/asset + "/manifest") {};
2551 obelisk-asset-serve-snap = self.callCabal2nix "obelisk-asset-serve-snap" (hackGet ./lib/asset + "/serve-snap") {};
2652 obelisk-backend = self.callCabal2nix "obelisk-backend" (cleanSource ./lib/backend) {};
@@ -34,8 +60,8 @@ let
3460 wrapProgram "$out"/bin/ob --prefix PATH : ${pkgs.lib.makeBinPath (commandRuntimeDeps pkgs)}
3561 '';
3662 });
37− obelisk-executable-config = executableConfig.haskellPackage self;
38− obelisk-executable-config-inject = executableConfig.platforms.web.inject self;
63+ obelisk-executable-config = pkgs.obeliskExecutableConfig.haskellPackage self;
64+ obelisk-executable-config-inject = pkgs.obeliskExecutableConfig.platforms.web.inject self;
3965 obelisk-frontend = self.callCabal2nix "obelisk-frontend" (cleanSource ./lib/frontend) {};
4066 obelisk-run = self.callCabal2nix "obelisk-run" (cleanSource ./lib/run) {};
4167 obelisk-route = self.callCabal2nix "obelisk-route" (cleanSource ./lib/route) {};
@@ -43,73 +69,54 @@ let
4369 obelisk-snap = self.callCabal2nix "obelisk-snap" (cleanSource ./lib/snap) {};
4470 obelisk-snap-extras = self.callCabal2nix "obelisk-snap-extras" (cleanSource ./lib/snap-extras) {};
4571 })
46− # Dynamic linking with split objects dramatically increases startup time (about 0.5 seconds on a decent machine with SSD)
47− (self: super: {
48− obelisk-command = addOptparseApplicativeCompletionScripts "ob" (justStaticExecutables super.obelisk-command);
49− })
50− ];
51− };
52− reflex-platform = getReflexPlatform system;
53− inherit (reflex-platform) hackGet nixpkgs;
54− pkgs = nixpkgs;
55−in with pkgs.haskell.lib; with pkgs.lib;
56−let
57− # TODO: Remove this after updating nixpkgs: https://github.com/NixOS/nixpkgs/issues/37750
58− justStaticExecutables' = drv: let
59− drv' = justStaticExecutables drv;
60− in if pkgs.stdenv.isDarwin
61− then removeConfigureFlag drv' "--ghc-option=-optl=-dead_strip"
62− else drv';
63−
64− commandRuntimeDeps = pkgs: with pkgs; [
65− coreutils
66− git
67− gitAndTools.hub
68− nix-prefetch-git
69− openssh
70− ];
7172
72− #TODO: Upstream
73− # Modify a Haskell package to add completion scripts for the given
74− # executable produced by it. These completion scripts will be picked up
75− # automatically if the resulting derivation is installed, e.g. by
76− # `nix-env -i`.
77− addOptparseApplicativeCompletionScripts = exeName: pkg: overrideCabal pkg (drv: {
78− postInstall = (drv.postInstall or "") + ''
79− BASH_COMP_DIR="$out/share/bash-completion/completions"
80− mkdir -p "$BASH_COMP_DIR"
81− "$out/bin/${exeName}" --bash-completion-script "$out/bin/${exeName}" >"$BASH_COMP_DIR/ob"
73+ # Dynamic linking with split objects dramatically increases startup time (about 0.5 seconds on a decent machine with SSD)
74+ (self: super: let
75+ pkgs = self.callPackage ({ pkgs }: pkgs) {};
76+ haskellLib = pkgs.haskell.lib;
77+ #TODO: Upstream
78+ # Modify a Haskell package to add completion scripts for the given
79+ # executable produced by it. These completion scripts will be picked up
80+ # automatically if the resulting derivation is installed, e.g. by
81+ # `nix-env -i`.
82+ addOptparseApplicativeCompletionScripts = exeName: pkg: haskellLib.overrideCabal pkg (drv: {
83+ postInstall = (drv.postInstall or "") + ''
84+ BASH_COMP_DIR="$out/share/bash-completion/completions"
85+ mkdir -p "$BASH_COMP_DIR"
86+ "$out/bin/${exeName}" --bash-completion-script "$out/bin/${exeName}" >"$BASH_COMP_DIR/ob"
8287
83− ZSH_COMP_DIR="$out/share/zsh/vendor-completions"
84− mkdir -p "$ZSH_COMP_DIR"
85− "$out/bin/${exeName}" --zsh-completion-script "$out/bin/${exeName}" >"$ZSH_COMP_DIR/_ob"
88+ ZSH_COMP_DIR="$out/share/zsh/vendor-completions"
89+ mkdir -p "$ZSH_COMP_DIR"
90+ "$out/bin/${exeName}" --zsh-completion-script "$out/bin/${exeName}" >"$ZSH_COMP_DIR/_ob"
8691
87− FISH_COMP_DIR="$out/share/fish/vendor_completions.d"
88− mkdir -p "$FISH_COMP_DIR"
89− "$out/bin/${exeName}" --fish-completion-script "$out/bin/${exeName}" >"$FISH_COMP_DIR/ob.fish"
90− '';
91− });
92+ FISH_COMP_DIR="$out/share/fish/vendor_completions.d"
93+ mkdir -p "$FISH_COMP_DIR"
94+ "$out/bin/${exeName}" --fish-completion-script "$out/bin/${exeName}" >"$FISH_COMP_DIR/ob.fish"
95+ '';
96+ });
97+ in {
98+ obelisk-command = addOptparseApplicativeCompletionScripts "ob" (haskellLib.justStaticExecutables super.obelisk-command);
99+ obelisk-selftest = haskellLib.justStaticExecutables super.obelisk-selftest;
100+ })
92101
93− # The haskell environment used to build Obelisk itself, e.g. the 'ob' command
94− ghcObelisk = reflex-platform.ghc.override {
95− overrides = composeExtensions defaultHaskellOverrides ;
102+ ];
96103 };
97104
98− cleanSource = builtins.filterSource (name: _: let baseName = builtins.baseNameOf name; in !(
99− builtins.match "^\\.ghc\\.environment.*" baseName != null ||
100− baseName == "cabal.project.local"
101− ));
105+ reflex-platform = getReflexPlatform system;
106+ inherit (reflex-platform) hackGet nixpkgs;
107+ pkgs = nixpkgs;
102108
103− executableConfig = import ./lib/executable-config { nixpkgs = pkgs; filterGitSource = cleanSource; };
109+ # The haskell environment used to build Obelisk itself, e.g. the 'ob' command
110+ ghcObelisk = reflex-platform.ghc;
104111
105112 inherit (import ./lib/asset/assets.nix { inherit nixpkgs; }) mkAssets;
106113
107− defaultHaskellOverrides = composeExtensions fixUpstreamPkgs addLibs;
108−in
109−with pkgs.lib;
110−rec {
114+ haskellLib = pkgs.haskell.lib;
115+
116+in rec {
111117 inherit reflex-platform;
112118 inherit (reflex-platform) nixpkgs pinBuildInputs;
119+ inherit (nixpkgs) lib;
113120 pathGit = ./.; # Used in CI by the migration graph hash algorithm to correctly ignore files.
114121 path = reflex-platform.filterGit ./.;
115122 obelisk = ghcObelisk;
@@ -122,7 +129,7 @@ rec {
122129
123130 PATH="${command}/bin:$PATH"
124131 export OBELISK_IMPL="${hackGet ./.}"
125− "${justStaticExecutables' ghcObelisk.obelisk-selftest}/bin/obelisk-selftest" "$@"
132+ "${ghcObelisk}/bin/obelisk-selftest" "$@"
126133 '';
127134 #TODO: Why can't I build ./skeleton directly as a derivation? `nix-build -E ./.` doesn't work
128135 skeleton = pkgs.runCommand "skeleton" {
@@ -130,8 +137,7 @@ rec {
130137 } ''
131138 ln -s "$dir" "$out"
132139 '';
133− nullIfAbsent = p: if pathExists p then p else null;
134− haskellOverrides = addLibs;
140+ nullIfAbsent = p: if lib.pathExists p then p else null;
135141 #TODO: Avoid copying files within the nix store. Right now, obelisk-asset-manifest-generate copies files into a big blob so that the android/ios static assets can be imported from there; instead, we should get everything lined up right before turning it into an APK, so that copies, if necessary, only exist temporarily.
136142 processAssets = { src, packageName ? "obelisk-generated-static", moduleName ? "Obelisk.Generated.Static" }: pkgs.runCommand "asset-manifest" {
137143 inherit src;
@@ -148,7 +154,7 @@ rec {
148154 compressedJs = frontend: pkgs.runCommand "compressedJs" { buildInputs = [ pkgs.closurecompiler ]; } ''
149155 mkdir $out
150156 cd $out
151− ln -s "${justStaticExecutables frontend}/bin/frontend.jsexe/all.js" all.unminified.js
157+ ln -s "${haskellLib.justStaticExecutables frontend}/bin/frontend.jsexe/all.js" all.unminified.js
152158 closure-compiler --externs "${reflex-platform.ghcjsExternsJs}" -O ADVANCED --jscomp_warning=checkVars --create_source_map="all.js.map" --source_map_format=V3 --js_output_file="all.js" all.unminified.js
153159 echo "//# sourceMappingURL=all.js.map" >> all.js
154160 '';
@@ -224,7 +230,7 @@ rec {
224230 pkgs.runCommand "serverExe" {} ''
225231 mkdir $out
226232 set -eux
227− ln -s "${justStaticExecutables backend}"/bin/* $out/
233+ ln -s "${haskellLib.justStaticExecutables backend}"/bin/* $out/
228234 ln -s "${mkAssets assets}" $out/static.assets
229235 cp -r ${config} $out/config
230236 ln -s ${mkAssets (compressedJs frontend)} $out/frontend.jsexe.assets
@@ -264,18 +270,17 @@ rec {
264270 staticName = "obelisk-generated-static";
265271 staticPath = base + "/static";
266272 # The packages whose names and roles are defined by this package
267− predefinedPackages = filterAttrs (_: x: x != null) {
273+ predefinedPackages = lib.filterAttrs (_: x: x != null) {
268274 ${frontendName} = nullIfAbsent (base + "/frontend");
269275 ${commonName} = nullIfAbsent (base + "/common");
270276 ${backendName} = nullIfAbsent (base + "/backend");
271277 };
272278 combinedPackages = predefinedPackages // packages;
273279 projectOverrides = self: super: {
274− ${staticName} = dontHaddock (self.callCabal2nix "static" processedStatic.haskellManifest {});
275− ${backendName} = addBuildDepend super.${backendName} self.obelisk-run;
280+ ${staticName} = haskellLib.dontHaddock (self.callCabal2nix "static" processedStatic.haskellManifest {});
281+ ${backendName} = haskellLib.addBuildDepend super.${backendName} self.obelisk-run;
276282 };
277− totalOverrides = composeExtensions (composeExtensions defaultHaskellOverrides projectOverrides) overrides;
278− inherit (nixpkgs) lib;
283+ totalOverrides = lib.composeExtensions projectOverrides overrides;
279284 inherit (lib.strings) hasPrefix;
280285 privateConfigDirs = ["config/backend"];
281286 injectableConfig = builtins.filterSource (path: _:
@@ -286,16 +291,16 @@ rec {
286291 overrides = totalOverrides;
287292 packages = combinedPackages;
288293 shells = {
289− ghcSavedSplices = (filter (x: hasAttr x combinedPackages) [
294+ ghcSavedSplices = (lib.filter (x: lib.hasAttr x combinedPackages) [
290295 commonName
291296 frontendName
292297 ]);
293− ghc = (filter (x: hasAttr x combinedPackages) [
298+ ghc = (lib.filter (x: lib.hasAttr x combinedPackages) [
294299 backendName
295300 commonName
296301 frontendName
297302 ]);
298− ghcjs = filter (x: hasAttr x combinedPackages) [
303+ ghcjs = lib.filter (x: lib.hasAttr x combinedPackages) [
299304 frontendName
300305 commonName
301306 ];
@@ -304,14 +309,14 @@ rec {
304309 ${if android == null then null else frontendName} = {
305310 executableName = "frontend";
306311 ${if builtins.pathExists staticPath then "assets" else null} =
307− executableConfig.platforms.android.inject injectableConfig processedStatic.symlinked;
312+ nixpkgs.obeliskExecutableConfig.platforms.android.inject injectableConfig processedStatic.symlinked;
308313 } // android;
309314 };
310315 ios = {
311316 ${if ios == null then null else frontendName} = {
312317 executableName = "frontend";
313318 ${if builtins.pathExists staticPath then "staticSrc" else null} =
314− executableConfig.platforms.ios.inject injectableConfig processedStatic.symlinked;
319+ nixpkgs.obeliskExecutableConfig.platforms.ios.inject injectableConfig processedStatic.symlinked;
315320 } // ios;
316321 };
317322 };
@@ -323,13 +328,11 @@ rec {
323328 linuxExe = linuxExe (base + "/config");
324329 exe = serverOn system (base + "/config") ;
325330 server = args@{ hostName, adminEmail, routeHost, enableHttps, config }: let
326− injectableConfig = builtins.filterSource (path: _: !(hasPrefix (toString config + "/backend") (toString path))) config;
331+ injectableConfig = builtins.filterSource (path: _: !(lib.hasPrefix (toString config + "/backend") (toString path))) config;
327332 in server (args // { exe = linuxExe injectableConfig; });
328333 obelisk = import (base + "/.obelisk/impl") {};
329334 };
330335 haskellPackageSets = {
331− ghc = reflex-platform.ghc.override {
332− overrides = defaultHaskellOverrides;
333− };
336+ inherit (reflex-platform) ghc;
334337 };
335338}