From 4fe876cd5a57b06879ca27c836f4185b63870cc3 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Sun, 20 Jun 2021 19:04:33 -0500 Subject: [PATCH 1/2] imp: pathType resolves strings that look like relpaths to `file` E.g. useful for toml strings that should represent a relative file to the toml file. fixes: #95 --- nix/types.nix | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 nix/types.nix 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; +} From a86a5f945aa98db356c7599bff5458cdce4cf4c5 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Sun, 20 Jun 2021 19:06:20 -0500 Subject: [PATCH 2/2] imp: add `_devshelltoml` module arg (only set for toml files) This argument is null otherwise, hence it is only be used in the concrete context of a devshell toml file Usage: ```nix {config, lib, pkgs, _devshelltoml, ...}: let pathType = (import ../../nix/types.nix { inherit lib; }).pathType; in { type = pathType _devshellToml; # will handle non-toml files gracefully } ``` --- modules/modules.nix | 1 + nix/importTOML.nix | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) 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; }; }