diff --git a/examples/no-flake/derivation/default.nix b/examples/no-flake/derivation/default.nix index 91dadb1..121a295 100644 --- a/examples/no-flake/derivation/default.nix +++ b/examples/no-flake/derivation/default.nix @@ -14,4 +14,4 @@ system = builtins.currentSystem; }; in - drv-parts.lib.derivationFromModules hello + drv-parts.lib.derivationFromModules {} hello diff --git a/examples/no-flake/hello-from-nixpkgs/default.nix b/examples/no-flake/hello-from-nixpkgs/default.nix index f054151..2e57694 100644 --- a/examples/no-flake/hello-from-nixpkgs/default.nix +++ b/examples/no-flake/hello-from-nixpkgs/default.nix @@ -25,7 +25,7 @@ stdenv = pkgs.stdenv; }; - hello = drv-parts.lib.derivationFromModules [ + hello = drv-parts.lib.derivationFromModules {} [ helloDefaultNix helloDeps ]; diff --git a/examples/no-flake/mkDerivation/default.nix b/examples/no-flake/mkDerivation/default.nix index 332f6ac..0312e7f 100644 --- a/examples/no-flake/mkDerivation/default.nix +++ b/examples/no-flake/mkDerivation/default.nix @@ -22,4 +22,4 @@ }; }; in - drv-parts.lib.derivationFromModules hello + drv-parts.lib.derivationFromModules {} hello diff --git a/lib.nix b/lib.nix index 1dc32ba..9dc2fba 100644 --- a/lib.nix +++ b/lib.nix @@ -4,9 +4,10 @@ let l = lib // builtins; - derivationFromModules = modules: let + derivationFromModules = dependencySets: modules: let drv = lib.evalModules { modules = if l.isList modules then modules else [modules]; + specialArgs = {inherit dependencySets;}; }; in drv.config.final.derivation; diff --git a/lib/makeModule.nix b/lib/makeModule.nix index f37ec17..30199e5 100644 --- a/lib/makeModule.nix +++ b/lib/makeModule.nix @@ -32,45 +32,27 @@ defaultNix: let # generated nixos options for all flags flagOptions = makeFlagOptions flagArgs; - # throws error listing missing deps.xxx entries - throwMissingDepsError = missingDepNames: throw '' - You are trying to generate a module from a legacy default.nix file - located under ${defaultNix}, - but the `deps` option is not populated with all required dependencies. - The following dependencies are missing: - - ${l.concatStringsSep "\n - " missingDepNames} - ''; - - # Ensure that all required default.nix dependencies are passed via `deps`. - # This is a bit hacky. It would be nicer if we could define `deps.{foo}` - # as an individual option, but `deps` is already defined as `coercedTo` - # which does not support nested options. - ensureDepsPopulated = deps: let - missingDeps = l.filterAttrs (depName: _: ! deps ? ${depName}) depArgs; - missingDepNames = l.attrNames missingDeps; - in - if missingDeps == {} - then deps - else throwMissingDepsError missingDepNames; - # override func that exposes mkDerivation arguments passthruMkDrvArgs = oldArgs: {passthru.__mkDrvArgs = oldArgs;}; getMkDrvArgs = drv: (drv.overrideAttrs passthruMkDrvArgs).__mkDrvArgs; + mkDepOpt = depName: _: l.mkOption { + description = "Specify a package for the dependency ${depName}."; + type = t.raw; + }; + in {config, options, ...}: { imports = [../modules/mkDerivation/interface.nix]; options.flags = flagOptions; + options.deps = l.mapAttrs mkDepOpt depArgs; config = let - # raises errors if a dependency is missing from `config.deps` - ensuredDeps = ensureDepsPopulated config.deps; - pickFlag = flagName: _: config.flags.${flagName}; - pickDep = depName: _: ensuredDeps.${depName}; + pickDep = depName: _: config.deps.${depName}; flagArgs' = l.mapAttrs pickFlag flagArgs; depArgs' = l.mapAttrs pickDep depArgs; @@ -123,12 +105,24 @@ in {config, options, ...}: { config.stdenv = config.stdenv; }; - finalDerivation = drvPartsLib.derivationFromModules [finalDrvModule]; + finalDerivation = drvPartsLib.derivationFromModules {} [finalDrvModule]; + + /* + Populate deps with some defaults. + `lib` should be taken from the current module. + `stdenv` should be taken from `config.stdenv`. + */ + deps' = { + inherit lib; + inherit (config) stdenv; + }; + deps'' = l.intersectAttrs depArgs deps'; + deps = l.mapAttrs (_: dep: l.mkDefault dep) deps''; in { - deps.lib = lib; + deps = deps; final.derivation = finalDerivation; }; } diff --git a/modules/derivation-common/interface.nix b/modules/derivation-common/interface.nix index b717990..7de1e74 100644 --- a/modules/derivation-common/interface.nix +++ b/modules/derivation-common/interface.nix @@ -1,7 +1,6 @@ {config, lib, dependencySets, ...}: let l = lib // builtins; t = l.types; - callDeps = func: func dependencySets; optNullOrBool = l.mkOption { type = t.nullOr t.bool; default = null; @@ -116,12 +115,12 @@ So deps should be specific, but not overly specific. For instance, the caller shouldn't have to know the version of a dependency in order to override it. The name should suffice. (e.g. `nix = nixVersions.nix_2_12` instead of `inherit (nixVersions) nix_2_12`. ''; - type = - t.coercedTo - (t.functionTo (t.lazyAttrsOf t.raw)) - callDeps - (t.lazyAttrsOf t.raw); - default = {}; + type = t.submoduleWith { + # TODO: This could be made stricter by removing the freeformType + # Maybe add option `strictDeps = true/false` ? ;P + modules = [{freeformType = t.lazyAttrsOf t.raw;}]; + specialArgs = dependencySets; + }; example = lib.literalExpression '' {pkgs, inputs', ...}: { inherit (pkgs) stdenv; diff --git a/modules/drv-parts.nix b/modules/drv-parts.nix index 5bd3669..bcb23df 100644 --- a/modules/drv-parts.nix +++ b/modules/drv-parts.nix @@ -13,7 +13,7 @@ in { modules = [./derivation-common]; specialArgs = { inherit (inputs.drv-parts) drv-backends; - inherit (config) dependencySets; + inherit (config.drv-parts) dependencySets; }; } ); @@ -66,7 +66,7 @@ in { ''; }; - dependencySets = l.mkOption { + drv-parts.dependencySets = l.mkOption { type = t.lazyAttrsOf t.raw; default = { inherit pkgs inputs';