@@ -257,85 +257,107 @@ in rec {
257257 };
258258 };
259259
260−
261260 # An Obelisk project is a reflex-platform project with a predefined layout and role for each component
262− project = base: projectDefinition:
263− let projectOut = sys: (getReflexPlatform sys).project (args@{ nixpkgs, ... }:
264− let mkProject = { android ? null #TODO: Better error when missing
265− , ios ? null #TODO: Better error when missing
266− , packages ? {}
267− , overrides ? _: _: {}
268− , staticFiles ? base + /static
269− , tools ? _: []
270− , shellToolOverrides ? _: _: {}
271− , withHoogle ? false # Setting this to `true` makes shell reloading far slower
272− , __closureCompilerOptimizationLevel ? "ADVANCED" # Set this to `null` to skip the closure-compiler step
273− }:
274− let frontendName = "frontend";
275− backendName = "backend";
276− commonName = "common";
277− staticName = "obelisk-generated-static";
278− staticFilesImpure = if lib.isDerivation staticFiles then staticFiles else toString staticFiles;
279− processedStatic = processAssets { src = staticFiles; };
280− # The packages whose names and roles are defined by this package
281− predefinedPackages = lib.filterAttrs (_: x: x != null) {
282− ${frontendName} = nullIfAbsent (base + "/frontend");
283− ${commonName} = nullIfAbsent (base + "/common");
284− ${backendName} = nullIfAbsent (base + "/backend");
285− };
286− combinedPackages = predefinedPackages // packages;
287− projectOverrides = self: super: {
288− ${staticName} = haskellLib.dontHaddock (self.callCabal2nix staticName processedStatic.haskellManifest {});
289− ${backendName} = haskellLib.addBuildDepend super.${backendName} self.obelisk-run;
290− };
291− totalOverrides = lib.composeExtensions projectOverrides overrides;
292− inherit (lib.strings) hasPrefix;
293− privateConfigDirs = ["config/backend"];
294− injectableConfig = builtins.filterSource (path: _:
295− !(lib.lists.any (x: hasPrefix (toString base + "/" + toString x) (toString path)) privateConfigDirs)
296− );
297− __androidWithConfig = configPath: {
298− ${if android == null then null else frontendName} = {
299− executableName = "frontend";
300− ${if builtins.pathExists staticFiles then "assets" else null} =
301− nixpkgs.obeliskExecutableConfig.platforms.android.inject
302− (injectableConfig configPath)
303− processedStatic.symlinked;
304− } // android;
261+ project = base': projectDefinition:
262+ let
263+ projectOut = sys: (getReflexPlatform sys).project (args@{ nixpkgs, ... }:
264+ let
265+ projectArgs = projectDefinition args;
266+ mkProject =
267+ { android ? null #TODO: Better error when missing
268+ , ios ? null #TODO: Better error when missing
269+ , packages ? {}
270+ , overrides ? _: _: {}
271+ , staticFiles ? null
272+ , tools ? _: []
273+ , shellToolOverrides ? _: _: {}
274+ , withHoogle ? false # Setting this to `true` makes shell reloading far slower
275+ , __closureCompilerOptimizationLevel ? "ADVANCED" # Set this to `null` to skip the closure-compiler step
276+ }:
277+ let
278+ inherit (lib.strings) hasPrefix;
279+ configTree = nixpkgs.lib.makeExtensible (self: {
280+ base = base';
281+ userSettings = {
282+ inherit android ios packages overrides tools shellToolOverrides withHoogle __closureCompilerOptimizationLevel;
283+ staticFiles = if staticFiles == null then self.base + /static else staticFiles;
284+ };
285+ frontendName = "frontend";
286+ backendName = "backend";
287+ commonName = "common";
288+ staticName = "obelisk-generated-static";
289+ staticFilesImpure = let fs = self.userSettings.staticFiles; in if lib.isDerivation fs then fs else toString fs;
290+ processedStatic = processAssets { src = self.userSettings.staticFiles; };
291+ # The packages whose names and roles are defined by this package
292+ predefinedPackages = lib.filterAttrs (_: x: x != null) {
293+ ${self.frontendName} = nullIfAbsent (self.base + "/frontend");
294+ ${self.commonName} = nullIfAbsent (self.base + "/common");
295+ ${self.backendName} = nullIfAbsent (self.base + "/backend");
296+ };
297+ combinedPackages = self.predefinedPackages // self.userSettings.packages;
298+ projectOverrides = self': super': {
299+ ${self.staticName} = haskellLib.dontHaddock (self'.callCabal2nix self.staticName self.processedStatic.haskellManifest {});
300+ ${self.backendName} = haskellLib.addBuildDepend super'.${self.backendName} self'.obelisk-run;
301+ };
302+ totalOverrides = lib.composeExtensions self.projectOverrides self.userSettings.overrides;
303+ privateConfigDirs = ["config/backend"];
304+ injectableConfig = builtins.filterSource (path: _:
305+ !(lib.lists.any (x: hasPrefix (toString self.base + "/" + toString x) (toString path)) self.privateConfigDirs)
306+ );
307+ __androidWithConfig = configPath: {
308+ ${if self.userSettings.android == null then null else self.frontendName} = {
309+ executableName = "frontend";
310+ ${if builtins.pathExists staticFiles then "assets" else null} =
311+ nixpkgs.obeliskExecutableConfig.platforms.android.inject
312+ (self.injectableConfig configPath)
313+ self.processedStatic.symlinked;
314+ } // self.userSettings.android;
315+ };
316+ __iosWithConfig = configPath: {
317+ ${if self.userSettings.ios == null then null else self.frontendName} = {
318+ executableName = "frontend";
319+ ${if builtins.pathExists staticFiles then "staticSrc" else null} =
320+ nixpkgs.obeliskExecutableConfig.platforms.ios.inject
321+ (self.injectableConfig configPath)
322+ self.processedStatic.symlinked;
323+ } // self.userSettings.ios;
324+ };
325+ projectConfig = {
326+ inherit (self.userSettings) shellToolOverrides tools withHoogle;
327+ overrides = self.totalOverrides;
328+ packages = self.combinedPackages;
329+ shells = {
330+ ${if self.userSettings.android == null && self.userSettings.ios == null then null else "ghcSavedSplices"} = (lib.filter (x: lib.hasAttr x self.combinedPackages) [
331+ self.commonName
332+ self.frontendName
333+ ]);
334+ ghc = (lib.filter (x: lib.hasAttr x self.combinedPackages) [
335+ self.backendName
336+ self.commonName
337+ self.frontendName
338+ ]) ++ lib.attrNames packages;
339+ ghcjs = (lib.filter (x: lib.hasAttr x self.combinedPackages) [
340+ self.frontendName
341+ self.commonName
342+ ]) ++ lib.attrNames packages;
305343 };
306− __iosWithConfig = configPath: {
307− ${if ios == null then null else frontendName} = {
308− executableName = "frontend";
309− ${if builtins.pathExists staticFiles then "staticSrc" else null} =
310− nixpkgs.obeliskExecutableConfig.platforms.ios.inject
311− (injectableConfig configPath)
312− processedStatic.symlinked;
313− } // ios;
344+ android = self.__androidWithConfig (self.base + "/config");
345+ ios = self.__iosWithConfig (self.base + "/config");
346+
347+ passthru = {
348+ inherit (self)
349+ staticFilesImpure processedStatic
350+ __iosWithConfig __androidWithConfig
351+ ;
352+ inherit (self.userSettings)
353+ android ios overrides packages shellToolOverrides staticFiles tools withHoogle
354+ __closureCompilerOptimizationLevel
355+ ;
314356 };
315− in {
316− inherit shellToolOverrides tools withHoogle;
317− overrides = totalOverrides;
318− packages = combinedPackages;
319− shells = {
320− ${if android == null && ios == null then null else "ghcSavedSplices"} = (lib.filter (x: lib.hasAttr x combinedPackages) [
321− commonName
322− frontendName
323− ]);
324− ghc = (lib.filter (x: lib.hasAttr x combinedPackages) [
325− backendName
326− commonName
327− frontendName
328− ]) ++ lib.attrNames packages;
329− ghcjs = (lib.filter (x: lib.hasAttr x combinedPackages) [
330− frontendName
331− commonName
332− ]) ++ lib.attrNames packages;
333357 };
334− android = __androidWithConfig (base + "/config");
335− ios = __iosWithConfig (base + "/config");
336− passthru = { inherit android ios packages overrides tools shellToolOverrides withHoogle staticFiles staticFilesImpure __closureCompilerOptimizationLevel processedStatic __iosWithConfig __androidWithConfig; };
337− };
338− in mkProject (projectDefinition args));
358+ });
359+ in configTree.projectConfig;
360+ in mkProject projectArgs);
339361 mainProjectOut = projectOut system;
340362 serverOn = projectInst: version: serverExe
341363 projectInst.ghc.backend
@@ -351,7 +373,7 @@ in rec {
351373 exe = serverOn mainProjectOut dummyVersion;
352374 server = args@{ hostName, adminEmail, routeHost, enableHttps, version }:
353375 server (args // { exe = linuxExe version; });
354− obelisk = import (base + "/.obelisk/impl") {};
376+ obelisk = import (base' + "/.obelisk/impl") {};
355377 };
356378 haskellPackageSets = {
357379 inherit (reflex-platform) ghc ghcjs;