Hello all,
I’m trying to understand how the bash script of a runCommand invocation may work. Specifically, I don’t understand how the test at this line may work: https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/kubernetes/certs.nix#L45
I’ll copy here the relevant lines:
writeCFSSL = content:
pkgs.runCommand content.name {
buildInputs = [ pkgs.cfssl pkgs.jq ];
} ''
mkdir -p $out
cd $out
json=${pkgs.lib.escapeShellArg (builtins.toJSON content)}
# for a given $field in the $json, treat the associated value as a
# file path and substitute the contents thereof into the $json
# object.
expandFileField() {
local field=$1
if jq -e --arg field "$field" 'has($field)'; then
local path="$(echo "$json" | jq -r ".$field")"
json="$(echo "$json" | jq --arg val "$(cat "$path")" ".$field = \$val")"
fi
}
expandFileField key
expandFileField ca
expandFileField cert
echo "$json" | cfssljson -bare ${content.name}
'';
My understanding problem is with the test at the line if jq -e --arg field "$field" 'has($field)'
.
From what i see from the documentation of the jq
utility it expects the JSON formatted data either as a filename on the command line or as stdin (you can find jq
docs here: jq Manual (development version) ).
So, if jq
needs a JSON doc on stdin, how can that test work?
I’ve also investigated how runCommand
is defined, and it seems just a thin layer over mkDerivation
and there seems not to be any stdin external handling.
anyone has a clue?