diff --git a/modules/modules.nix b/modules/modules.nix index 219f6ed0..25aee605 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -23,6 +23,7 @@ let _module.args.baseModules = modules; _module.args.pkgsPath = lib.mkDefault pkgs.path; _module.args.pkgs = lib.mkDefault pkgs; + _module.args._devshelltoml = config.lib._tomlfile or null; # set by importTOML }; }; in diff --git a/nix/importTOML.nix b/nix/importTOML.nix index 8bb2bb2f..1f58bb59 100644 --- a/nix/importTOML.nix +++ b/nix/importTOML.nix @@ -24,5 +24,5 @@ in { _file = file; imports = map importModule (data.imports or [ ]); - config = builtins.removeAttrs data [ "imports" ]; + config = (builtins.removeAttrs data [ "imports" ]) // { lib._tomlfile = file; }; } diff --git a/nix/types.nix b/nix/types.nix new file mode 100644 index 00000000..31555661 --- /dev/null +++ b/nix/types.nix @@ -0,0 +1,37 @@ +{ lib }: + +with lib.types; { + + /** + Synopsis: maybeResolveRel + + If it's a string, returns an absolute path transforming relative + paths with regard to the tomlfile attribute, first. Or + transparently passes through path types, otherwise. + + Use for fields that can define relative paths in devshell TOML files. + **/ + maybeResolveRel = tomlfile: let + tomldir = builtins.dirOf tomlfile; + in obj: + # Not a toml file: return as-is + if (file == null) then + obj + # It must be a string + else if (!(builtins.isString obj)) then + # Never happens untill nix gains some sort type + # caster for importTOML: prepare for day X. + builtins.throw "${obj} defined in ${tomlfile} is not a string." + # It looks like an absolute path: type cast into a path type + else if (lib.strings.hasPrefix "/" obj) then + /. + obj + # It looks like an explicit relpath: strip "." to conform to the builtin path type caster + else if (lib.strings.hasPrefix "./" obj) || then + /. + (tomldir + (lib.strings.removePrefix "." obj)) + # It is treated as an implicit relpat: prefix with "/" to conform to ... + else + /. + (tomldir + "/" obj) + ; + + pathType = tomlfile: o: coercedTo path maybeResolveRel tomlfile o; +}