diff --git a/pkgs/pkgs-lib/formats.nix b/pkgs/pkgs-lib/formats.nix index 879b233bb670..2f3e5ad9d191 100644 --- a/pkgs/pkgs-lib/formats.nix +++ b/pkgs/pkgs-lib/formats.nix @@ -472,14 +472,12 @@ optionalAttrs allowAliases aliases runCommand name { nativeBuildInputs = [ json2x ]; - value = builtins.toJSON value; + inherit value; preferLocalBuild = true; __structuredAttrs = true; } '' - valuePath="$TMPDIR/value" - printf "%s" "$value" > "$valuePath" - json2x toml "$valuePath" "$out" + json2x toml --unwrap value "$NIX_ATTRS_JSON_FILE" "$out" '' ) { }; diff --git a/pkgs/pkgs-lib/formats/json2x/src/main.rs b/pkgs/pkgs-lib/formats/json2x/src/main.rs index b9025c67f42a..1464fb8972b9 100644 --- a/pkgs/pkgs-lib/formats/json2x/src/main.rs +++ b/pkgs/pkgs-lib/formats/json2x/src/main.rs @@ -10,6 +10,9 @@ use argh::{FromArgValue, FromArgs}; /// Convert a JSON file to another format #[derive(FromArgs)] struct Args { + /// convert only value of this attribute + #[argh(option)] + unwrap: Option, /// format of the output file, possible values: toml #[argh(positional)] format: Format, @@ -29,16 +32,31 @@ enum Format { fn main() -> anyhow::Result<()> { let args: Args = argh::from_env(); - let input = read_to_string(&args.input) + let json_text = read_to_string(&args.input) .with_context(|| format!("failed to read {}", args.input.display()))?; - let input: serde_json::Value = serde_json::from_str(&input) + let parsed_json: serde_json::Value = serde_json::from_str(&json_text) .with_context(|| format!("failed to parse {}", args.input.display()))?; + let output_value = if let Some(unwrap_key) = args.unwrap { + parsed_json + .as_object() + .ok_or_else(|| anyhow::anyhow!("{} does not contain an object", args.input.display()))? + .get(&unwrap_key) + .ok_or_else(|| { + anyhow::anyhow!( + "{} does not containt attribute '{unwrap_key}'", + args.input.display() + ) + })? + } else { + &parsed_json + }; let mut output = File::create(&args.output) .with_context(|| format!("failed to create {}", args.output.display()))?; match args.format { Format::Toml => { - let content = toml::to_string(&input).context("failed to serialize value to toml")?; + let content = + toml::to_string(output_value).context("failed to serialize value to toml")?; output .write_all(content.as_bytes()) .with_context(|| format!("failed to write to {}", args.output.display()))?;