From 1e8a89e5f81bca67c5f649318179fc11727262d0 Mon Sep 17 00:00:00 2001 From: "Yang, Bo" Date: Tue, 9 May 2023 09:41:01 -0700 Subject: [PATCH 1/4] Add moduleLocation to mkFlake argument tmp --- extras/flakeModules.nix | 6 +++--- lib.nix | 11 +++++++---- modules/nixosModules.nix | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/extras/flakeModules.nix b/extras/flakeModules.nix index 6468dcbb..d4e0e639 100644 --- a/extras/flakeModules.nix +++ b/extras/flakeModules.nix @@ -1,4 +1,4 @@ -{ config, self, lib, flake-parts-lib, ... }: +{ config, self, lib, flake-parts-lib, moduleLocation, ... }: let inherit (lib) filterAttrs @@ -15,8 +15,8 @@ let type = types.lazyAttrsOf types.deferredModule; default = { }; apply = mapAttrs (k: v: { - _file = "${toString self.outPath}/flake.nix#flakeModules.${k}"; - key = "${toString self.outPath}/flake.nix#flakeModules.${k}"; + _file = "${toString moduleLocation}#flakeModules.${k}"; + key = "${toString moduleLocation}#flakeModules.${k}"; imports = [ v ]; }); description = '' diff --git a/lib.nix b/lib.nix index ae588c8f..102dabba 100644 --- a/lib.nix +++ b/lib.nix @@ -98,6 +98,7 @@ let ${errorExample} '') + , moduleLocation ? "${self.outPath}/flake.nix" }: throwIf (!args?self && !args?inputs) '' @@ -117,7 +118,7 @@ let (module: lib.evalModules { specialArgs = { - inherit self flake-parts-lib; + inherit self flake-parts-lib moduleLocation; inputs = args.inputs or /* legacy, warned above */ self.inputs; } // specialArgs; modules = [ ./all-modules.nix module ]; @@ -138,9 +139,11 @@ let mkFlake = args: module: let loc = - if args?inputs.self.outPath - then args.inputs.self.outPath + "/flake.nix" - else ""; + args.moduleLocation or ( + if args?inputs.self.outPath + then args.inputs.self.outPath + "/flake.nix" + else "" + ); mod = lib.setDefaultModuleLocation loc module; eval = flake-parts-lib.evalFlakeModule args mod; in diff --git a/modules/nixosModules.nix b/modules/nixosModules.nix index 1d21f9e7..be375bb2 100644 --- a/modules/nixosModules.nix +++ b/modules/nixosModules.nix @@ -1,4 +1,4 @@ -{ config, self, lib, flake-parts-lib, ... }: +{ config, self, lib, flake-parts-lib, moduleLocation, ... }: let inherit (lib) filterAttrs @@ -17,7 +17,7 @@ in nixosModules = mkOption { type = types.lazyAttrsOf types.unspecified; default = { }; - apply = mapAttrs (k: v: { _file = "${toString self.outPath}/flake.nix#nixosModules.${k}"; imports = [ v ]; }); + apply = mapAttrs (k: v: { _file = "${toString moduleLocation}#nixosModules.${k}"; imports = [ v ]; }); description = '' NixOS modules. From fc74939824cc92da3a39a6eb37ae2b7df89f55c3 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 13 Oct 2023 23:02:24 +0200 Subject: [PATCH 2/4] mkFlake: Prefer unsafeGetAttrPos over self.outPath for error message This would not be advisable for anything other than error messages, because Nix does not commit to any semantics for that function. --- lib.nix | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib.nix b/lib.nix index 33f20e4f..f3383673 100644 --- a/lib.nix +++ b/lib.nix @@ -121,14 +121,17 @@ let mkFlake = args: module: let - loc = + inputsPos = builtins.unsafeGetAttrPos "inputs" args; + moduleLocation = args.moduleLocation or ( - if args?inputs.self.outPath + if inputsPos != null + then inputsPos.file + else if args?inputs.self.outPath then args.inputs.self.outPath + "/flake.nix" else "" ); - mod = lib.setDefaultModuleLocation loc module; - eval = flake-parts-lib.evalFlakeModule args mod; + mod = lib.setDefaultModuleLocation moduleLocation module; + eval = flake-parts-lib.evalFlakeModule (args // { inherit moduleLocation; }) mod; in eval.config.flake; From f427ecf1a05493c788a94ee3b70bccd7285a64b5 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 13 Oct 2023 23:49:17 +0200 Subject: [PATCH 3/4] Repurpose moduleLocation impl for new errorLocation The difference is that moduleLocation is "guaranteed" reliable data, whereas errorLocation is the best choice for error messages in the core. moduleLocation is suitable for the module key attribute. errorLocation is best for the *ROOT* module _file attribute. Initially I applied errorLocation in too many places. It is only needed when the flake output attribute names are strict in it. To avoid confusion, I'm not exposing errorLocation to the modules, until we have a concrete use case for it. --- dev/tests/eval-tests.nix | 22 ++++++++++++++++++++++ lib.nix | 28 +++++++++++++++++----------- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/dev/tests/eval-tests.nix b/dev/tests/eval-tests.nix index 437ee1a7..c3c03b62 100644 --- a/dev/tests/eval-tests.nix +++ b/dev/tests/eval-tests.nix @@ -26,6 +26,22 @@ rec { systems = [ ]; }; + emptyExposeArgs = mkFlake + { inputs.self = { outPath = "the self outpath"; }; } + ({ config, moduleLocation, errorLocation, ... }: { + flake = { + inherit moduleLocation errorLocation; + }; + }); + + emptyExposeArgsNoSelf = mkFlake + { inputs.self = throw "self won't be available in case of some errors"; } + ({ config, moduleLocation, errorLocation, ... }: { + flake = { + inherit moduleLocation errorLocation; + }; + }); + example1 = mkFlake { inputs.self = { }; } { @@ -162,6 +178,12 @@ rec { assert packagesNonStrictInDevShells.packages.a.default == pkg "a" "hello"; + assert emptyExposeArgs.moduleLocation == "the self outpath/flake.nix"; + + assert emptyExposeArgs.errorLocation == __curPos.file; + + assert emptyExposeArgsNoSelf.errorLocation == __curPos.file; + ok; result = runTests "ok"; diff --git a/lib.nix b/lib.nix index f3383673..eaa56799 100644 --- a/lib.nix +++ b/lib.nix @@ -83,6 +83,22 @@ let '') , moduleLocation ? "${self.outPath}/flake.nix" }: + let + module = lib.setDefaultModuleLocation errorLocation module; + inputsPos = builtins.unsafeGetAttrPos "inputs" args; + errorLocation = + # Best case: user makes it explicit + args.moduleLocation or ( + # Slightly worse: Nix does not technically commit to unsafeGetAttrPos semantics + if inputsPos != null + then inputsPos.file + # Slightly worse: self may not be valid when an error occurs + else if args?inputs.self.outPath + then args.inputs.self.outPath + "/flake.nix" + # Fallback + else "" + ); + in throwIf (!args?self && !args?inputs) '' When invoking flake-parts, you must pass in the flake output arguments. @@ -121,17 +137,7 @@ let mkFlake = args: module: let - inputsPos = builtins.unsafeGetAttrPos "inputs" args; - moduleLocation = - args.moduleLocation or ( - if inputsPos != null - then inputsPos.file - else if args?inputs.self.outPath - then args.inputs.self.outPath + "/flake.nix" - else "" - ); - mod = lib.setDefaultModuleLocation moduleLocation module; - eval = flake-parts-lib.evalFlakeModule (args // { inherit moduleLocation; }) mod; + eval = flake-parts-lib.evalFlakeModule args module; in eval.config.flake; From c8c8e5661e2b93f2459b0ed6da1cbe31c7dba347 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Sat, 14 Oct 2023 00:06:42 +0200 Subject: [PATCH 4/4] Remove errorLocation from the tests As mentioned in the previous commit, we don't have a use case for this in flake-parts yet, as far as I'm aware. It can be exposed when we do have a concrete use case where it is needed. --- dev/tests/eval-tests.nix | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/dev/tests/eval-tests.nix b/dev/tests/eval-tests.nix index c3c03b62..2da3d990 100644 --- a/dev/tests/eval-tests.nix +++ b/dev/tests/eval-tests.nix @@ -28,17 +28,17 @@ rec { emptyExposeArgs = mkFlake { inputs.self = { outPath = "the self outpath"; }; } - ({ config, moduleLocation, errorLocation, ... }: { + ({ config, moduleLocation, ... }: { flake = { - inherit moduleLocation errorLocation; + inherit moduleLocation; }; }); emptyExposeArgsNoSelf = mkFlake { inputs.self = throw "self won't be available in case of some errors"; } - ({ config, moduleLocation, errorLocation, ... }: { + ({ config, moduleLocation, ... }: { flake = { - inherit moduleLocation errorLocation; + inherit moduleLocation; }; }); @@ -180,10 +180,6 @@ rec { assert emptyExposeArgs.moduleLocation == "the self outpath/flake.nix"; - assert emptyExposeArgs.errorLocation == __curPos.file; - - assert emptyExposeArgsNoSelf.errorLocation == __curPos.file; - ok; result = runTests "ok";