devShellTools.stringValue: init

This commit is contained in:
Robert Hensing 2024-06-29 17:07:17 +02:00
parent 091d8370a2
commit 469039098b
4 changed files with 78 additions and 17 deletions

View File

@ -11,4 +11,19 @@ However, `nix-shell` is not the only way to create such environments, and even `
This library provides a set of functions that help create such environments. This library provides a set of functions that help create such environments.
<!-- ## `devShellTools.<function>` {#sec-devShellTools-<function>} --> ## `devShellTools.stringValue` {#sec-devShellTools-stringValue}
Converts Nix values to strings in the way the [`derivation` built-in function](https://nix.dev/manual/nix/2.23/language/derivations) does.
:::{.example}
## `stringValue` usage examples
```nix
devShellTools.stringValue (builtins.toFile "foo" "bar")
=> "/nix/store/...-foo"
```
```nix
devShellTools.stringValue false
=> ""
```

View File

@ -1,4 +1,16 @@
{ }: { lib }:
let
{ inherit (builtins) typeOf;
in
rec {
# This function closely mirrors what this Nix code does:
# https://github.com/NixOS/nix/blob/2.8.0/src/libexpr/primops.cc#L1102
# https://github.com/NixOS/nix/blob/2.8.0/src/libexpr/eval.cc#L1981-L2036
stringValue = value:
# We can't just use `toString` on all derivation attributes because that
# would not put path literals in the closure. So we explicitly copy
# those into the store here
if typeOf value == "path" then "${value}"
else if typeOf value == "list" then toString (map stringValue value)
else toString value;
} }

View File

@ -1,5 +1,45 @@
{ ... }:
{ {
devShellTools,
emptyFile,
lib,
stdenv,
hello,
}:
let
inherit (lib) escapeShellArg;
in
{
# nix-build -A tests.devShellTools.stringValue
stringValue =
let inherit (devShellTools) stringValue; in
stdenv.mkDerivation {
name = "devShellTools-stringValue-built-tests";
# Test inputs
inherit emptyFile hello;
one = 1;
boolTrue = true;
boolFalse = false;
foo = "foo";
list = [ 1 2 3 ];
pathDefaultNix = ./default.nix;
packages = [ hello emptyFile ];
# TODO: nested lists
buildCommand = ''
touch $out
( set -x
[[ "$one" = ${escapeShellArg (stringValue 1)} ]]
[[ "$boolTrue" = ${escapeShellArg (stringValue true)} ]]
[[ "$boolFalse" = ${escapeShellArg (stringValue false)} ]]
[[ "$foo" = ${escapeShellArg (stringValue "foo")} ]]
[[ "$hello" = ${escapeShellArg (stringValue hello)} ]]
[[ "$list" = ${escapeShellArg (stringValue [ 1 2 3 ])} ]]
[[ "$packages" = ${escapeShellArg (stringValue [ hello emptyFile ])} ]]
[[ "$pathDefaultNix" = ${escapeShellArg (stringValue ./default.nix)} ]]
[[ "$emptyFile" = ${escapeShellArg (stringValue emptyFile)} ]]
) >log 2>&1 || { cat log; exit 1; }
'';
};
} }

View File

@ -4,6 +4,7 @@
, callPackage , callPackage
, closureInfo , closureInfo
, coreutils , coreutils
, devShellTools
, e2fsprogs , e2fsprogs
, proot , proot
, fakeNss , fakeNss
@ -49,6 +50,10 @@ let
toList toList
; ;
inherit (devShellTools)
stringValue
;
mkDbExtraCommand = contents: mkDbExtraCommand = contents:
let let
contentsList = if builtins.isList contents then contents else [ contents ]; contentsList = if builtins.isList contents then contents else [ contents ];
@ -1173,17 +1178,6 @@ rec {
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/globals.hh#L464-L465 # https://github.com/NixOS/nix/blob/2.8.0/src/libstore/globals.hh#L464-L465
sandboxBuildDir = "/build"; sandboxBuildDir = "/build";
# This function closely mirrors what this Nix code does:
# https://github.com/NixOS/nix/blob/2.8.0/src/libexpr/primops.cc#L1102
# https://github.com/NixOS/nix/blob/2.8.0/src/libexpr/eval.cc#L1981-L2036
stringValue = value:
# We can't just use `toString` on all derivation attributes because that
# would not put path literals in the closure. So we explicitly copy
# those into the store here
if builtins.typeOf value == "path" then "${value}"
else if builtins.typeOf value == "list" then toString (map stringValue value)
else toString value;
# https://github.com/NixOS/nix/blob/2.8.0/src/libstore/build/local-derivation-goal.cc#L992-L1004 # https://github.com/NixOS/nix/blob/2.8.0/src/libstore/build/local-derivation-goal.cc#L992-L1004
drvEnv = lib.mapAttrs' (name: value: drvEnv = lib.mapAttrs' (name: value:
let str = stringValue value; let str = stringValue value;