about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Klink <flokli@flokli.de>2023-11-06T09·43+0200
committerflokli <flokli@flokli.de>2023-11-07T11·27+0000
commit9f5b1213f91ea8c725f24ad3fbe59f7dd5eb86ec (patch)
tree7f8781728e0aa980cc9fb5aa703804c093df0be3
parent14849829fd4a2906d5cd2f723226b02801897983 (diff)
feat(tvix/nix-compat): add drvfmt r/6971
This small tool formats A-Term in a more readable format. It's a lossy
conversion for non-valid UTF-8 environment values.

Change-Id: I65a51054d7faf528321bc2d9fc4425180a7813f5
Reviewed-on: https://cl.tvl.fyi/c/depot/+/9970
Tested-by: BuildkiteCI
Autosubmit: flokli <flokli@flokli.de>
Reviewed-by: tazjin <tazjin@tvl.su>
-rw-r--r--tvix/Cargo.nix7
-rw-r--r--tvix/nix-compat/src/bin/drvfmt.rs41
2 files changed, 48 insertions, 0 deletions
diff --git a/tvix/Cargo.nix b/tvix/Cargo.nix
index 0707ad58bb..1e41b08584 100644
--- a/tvix/Cargo.nix
+++ b/tvix/Cargo.nix
@@ -4195,6 +4195,13 @@ rec {
         crateName = "nix-compat";
         version = "0.1.0";
         edition = "2021";
+        crateBin = [
+          {
+            name = "drvfmt";
+            path = "src/bin/drvfmt.rs";
+            requiredFeatures = [ ];
+          }
+        ];
         # We can't filter paths with references in Nix 2.4
         # See https://github.com/NixOS/nix/issues/5410
         src =
diff --git a/tvix/nix-compat/src/bin/drvfmt.rs b/tvix/nix-compat/src/bin/drvfmt.rs
new file mode 100644
index 0000000000..b82e8d5158
--- /dev/null
+++ b/tvix/nix-compat/src/bin/drvfmt.rs
@@ -0,0 +1,41 @@
+use std::{collections::BTreeMap, io::Read};
+
+use nix_compat::derivation::Derivation;
+use serde_json::json;
+
+/// construct a serde_json::Value from a Derivation.
+/// Some environment values can be non-valid UTF-8 strings.
+/// `serde_json` prints them out really unreadable.
+/// This is a tool to print A-Terms in a more readable fashion, so we brutally
+/// use [BString::to_string] to get a UTF-8 string (replacing invalid characters
+/// with the Unicode replacement codepoint).
+fn build_serde_json_value(drv: Derivation) -> serde_json::Value {
+    json!({
+        "args": drv.arguments,
+        "builder": drv.builder,
+        "env":   drv.environment.into_iter().map(|(k,v)| (k, v.to_string())).collect::<BTreeMap<String, String>>(),
+        "inputDrvs": drv.input_derivations,
+        "inputSrcs": drv.input_sources,
+        "outputs": drv.outputs,
+        "system": drv.system,
+    })
+}
+
+fn main() {
+    // read A-Term from stdin
+    let mut buf = Vec::new();
+    std::io::stdin()
+        .read_to_end(&mut buf)
+        .expect("failed to read from stdin");
+
+    match Derivation::from_aterm_bytes(&buf) {
+        Ok(drv) => {
+            println!(
+                "{}",
+                serde_json::to_string_pretty(&build_serde_json_value(drv))
+                    .expect("unable to serialize")
+            );
+        }
+        Err(e) => eprintln!("unable to parse derivation: {:#?}", e),
+    }
+}