diff --git a/docs/src/extending-dream2nix.md b/docs/src/extending-dream2nix.md index 1a9619cb..7f6ff866 100644 --- a/docs/src/extending-dream2nix.md +++ b/docs/src/extending-dream2nix.md @@ -3,6 +3,11 @@ `dream2nix` can be extended while you are `init`ializing it. This can be done in a few ways. For extending, you need to utilize the `config.extra` option of the dream2nix config. +## Module System Transition +The dream2nix architecture is currently in the process of being refactored into nixos modules. The actual APIs can deviate from what is described in this document. +For up-to-date examples see `/examples/_d2n-extended` and `/examples/_d2n-extended-new-subsystem` +Once the transition is completed we will update this document and remove this notice. + ## Declare `extra`s from a nix file ```nix diff --git a/examples/_d2n-extended-new-subsystem/extra.nix b/examples/_d2n-extended-new-subsystem/extra.nix index d59fd4d0..124a84bb 100644 --- a/examples/_d2n-extended-new-subsystem/extra.nix +++ b/examples/_d2n-extended-new-subsystem/extra.nix @@ -11,28 +11,6 @@ }) ]; }; - translators.dummy = {...}: { - type = "pure"; - translate = {hello, ...}: {...}: { - result = { - _generic = { - subsystem = "hello"; - defaultPackage = "hello"; - location = ""; - sourcesAggregatedHash = null; - packages = {${hello.pname} = hello.version;}; - }; - _subsystem = {}; - cyclicDependencies = {}; - dependencies.${hello.pname}.${hello.version} = []; - sources.${hello.pname}.${hello.version} = { - type = "http"; - url = hello.src.url; - hash = hello.src.outputHash; - }; - }; - }; - }; builders.dummy = {...}: { type = "pure"; build = {hello, ...}: {...}: { diff --git a/examples/_d2n-extended-new-subsystem/flake.nix b/examples/_d2n-extended-new-subsystem/flake.nix index c4d2149f..6c1c77d8 100644 --- a/examples/_d2n-extended-new-subsystem/flake.nix +++ b/examples/_d2n-extended-new-subsystem/flake.nix @@ -11,6 +11,9 @@ systems = ["x86_64-linux"]; config.projectRoot = ./.; config.extra = ./extra.nix; + config.modules = [ + ./translators.nix + ]; source = ./.; settings = [ { diff --git a/examples/_d2n-extended-new-subsystem/translators.nix b/examples/_d2n-extended-new-subsystem/translators.nix new file mode 100644 index 00000000..d5dcf30f --- /dev/null +++ b/examples/_d2n-extended-new-subsystem/translators.nix @@ -0,0 +1,26 @@ +{ + translators.dummy = {...}: { + type = "pure"; + name = "dummy"; + subsystem = "hello"; + translate = {hello, ...}: {...}: { + result = { + _generic = { + subsystem = "hello"; + defaultPackage = "hello"; + location = ""; + sourcesAggregatedHash = null; + packages = {${hello.pname} = hello.version;}; + }; + _subsystem = {}; + cyclicDependencies = {}; + dependencies.${hello.pname}.${hello.version} = []; + sources.${hello.pname}.${hello.version} = { + type = "http"; + url = hello.src.url; + hash = hello.src.outputHash; + }; + }; + }; + }; +} diff --git a/examples/_d2n-extended/flake.nix b/examples/_d2n-extended/flake.nix index b85a2854..69125bd4 100644 --- a/examples/_d2n-extended/flake.nix +++ b/examples/_d2n-extended/flake.nix @@ -13,10 +13,20 @@ (dream2nix.lib.makeFlakeOutputs { systems = ["x86_64-linux"]; config.projectRoot = ./.; + config.modules = [ + (builtins.toFile "cargo-toml-new.nix" '' + { + translators.cargo-toml-new = { + imports = ["${inp.dream2nix}/src/subsystems/rust/translators/cargo-toml"]; + name = "cargo-toml-new"; + subsystem = "rust"; + }; + } + '') + ]; config.extra = { subsystems.rust = { builders.brp-new = "${inp.dream2nix}/src/subsystems/rust/builders/build-rust-package"; - translators.cargo-toml-new = "${inp.dream2nix}/src/subsystems/rust/translators/cargo-toml"; discoverers.default = "${inp.dream2nix}/src/subsystems/rust/discoverers/default"; }; fetchers.crates-io = "${inp.dream2nix}/src/fetchers/crates-io"; diff --git a/src/default.nix b/src/default.nix index 33dc5faa..bd5586a8 100644 --- a/src/default.nix +++ b/src/default.nix @@ -49,17 +49,22 @@ in let configFile = pkgs.writeText "dream2nix-config.json" (b.toJSON config); + # pass spacialArgs itself in specialArgs in order to forward it to submodules. + specialModuleArgs = l.fix (self: { + specialArgs = self; + inherit + callPackageDream + dlib + ; + }); + evaledModules = lib.evalModules { - modules = [ - ./modules/top-level.nix - ]; + modules = + [./modules/top-level.nix] + ++ (config.modules or []); + # TODO: remove specialArgs once all functionality is moved to /src/modules - specialArgs = { - inherit - callPackageDream - dlib - ; - }; + specialArgs = specialModuleArgs; }; framework = evaledModules.config; @@ -709,6 +714,7 @@ in { callPackageDream dream2nixWithExternals fetchers + framework indexers fetchSources realizeProjects diff --git a/src/modules/functions.subsystem-loading/implementation.nix b/src/modules/functions.subsystem-loading/implementation.nix index a4534bbd..e2a2ed0a 100644 --- a/src/modules/functions.subsystem-loading/implementation.nix +++ b/src/modules/functions.subsystem-loading/implementation.nix @@ -17,10 +17,6 @@ modules: subsystemsDir = lib.toString ../../subsystems; subsystems = dlib.dirNames subsystemsDir; - /* - Discover modules in: - /src/subsystems/{subsystem}/{module-type}/{module-name} - */ collect = moduleDirName: lib.concatMap (subsystem: let @@ -43,10 +39,6 @@ modules: names) subsystems; - /* - Imports discovered module files. - Adds name and subsystem attributes to each module derived from the path. - */ import_ = collectedModules: lib.mapAttrs (name: description: @@ -54,12 +46,6 @@ modules: // {inherit (description) name subsystem;}) (lib.listToAttrs collectedModules); - /* - To keep module implementations simpler, additional generic logic is added - by a loader. - - The loader is subsytem specific and needs to be passed as an argument. - */ instantiate = importedModules: loader: lib.mapAttrs (name: module: @@ -67,10 +53,6 @@ modules: // {inherit (module) name subsystem;}) importedModules; - /* - re-structures the instantiated instances into a deeper attrset like: - {subsytem}.{module-name} = ... - */ structureBySubsystem = instances: lib.foldl lib.recursiveUpdate diff --git a/src/modules/functions.subsystem-loading/interface.nix b/src/modules/functions.subsystem-loading/interface.nix index 96ebf8fe..c4887d70 100644 --- a/src/modules/functions.subsystem-loading/interface.nix +++ b/src/modules/functions.subsystem-loading/interface.nix @@ -3,9 +3,33 @@ t = lib.types; in { options.functions.subsystem-loading = { - collect = lib.mkOption {type = t.functionTo t.anything;}; - import_ = lib.mkOption {type = t.functionTo t.anything;}; - instantiate = lib.mkOption {type = t.functionTo t.anything;}; - structureBySubsystem = lib.mkOption {type = t.functionTo t.anything;}; + collect = lib.mkOption { + type = t.functionTo t.anything; + description = '' + Discover modules in /src/subsystems/{subsystem}/{module-type}/{module-name} + ''; + }; + import_ = lib.mkOption { + type = t.functionTo t.anything; + description = '' + Imports discovered module files. + Adds name and subsystem attributes to each module derived from the path. + ''; + }; + instantiate = lib.mkOption { + type = t.functionTo t.anything; + description = '' + To keep module implementations simpler, additional generic logic is added + by a loader. + The loader is subsytem specific and needs to be passed as an argument. + ''; + }; + structureBySubsystem = lib.mkOption { + type = t.functionTo t.anything; + description = '' + re-structures the instantiated instances into a deeper attrset like: + {subsytem}.{module-name} = ... + ''; + }; }; } diff --git a/src/modules/translators/interface-translator.nix b/src/modules/translators/interface-translator.nix index 08875b7c..ef9c6aa2 100644 --- a/src/modules/translators/interface-translator.nix +++ b/src/modules/translators/interface-translator.nix @@ -44,6 +44,7 @@ in { default = null; }; extraArgs = lib.mkOption { + default = {}; type = t.attrsOf (t.submodule { options = { description = lib.mkOption { diff --git a/src/modules/translators/interface.nix b/src/modules/translators/interface.nix index 726b721a..d1358fbf 100644 --- a/src/modules/translators/interface.nix +++ b/src/modules/translators/interface.nix @@ -1,13 +1,17 @@ { config, lib, + specialArgs, ... }: let t = lib.types; in { options = { translators = lib.mkOption { - type = t.attrsOf (t.submodule ./interface-translator.nix); + type = t.attrsOf (t.submoduleWith { + modules = [./interface-translator.nix]; + inherit specialArgs; + }); description = '' Translator module definitions ''; diff --git a/tests/examples/default.nix b/tests/examples/default.nix index 5b90a701..b7eac6f8 100644 --- a/tests/examples/default.nix +++ b/tests/examples/default.nix @@ -29,7 +29,7 @@ cp -r ${examples}/$dir/* . chmod -R +w . nix flake lock --override-input dream2nix ${../../.} - nix run .#resolveImpure + nix run .#resolveImpure --show-trace # disable --read-only check for these because they do IFD so they will # write to store at eval time evalBlockList=("haskell_cabal-plan" "haskell_stack-lock")