diff --git a/tvix/Cargo.lock b/tvix/Cargo.lock index c1303be31..a3b91e534 100644 --- a/tvix/Cargo.lock +++ b/tvix/Cargo.lock @@ -476,6 +476,16 @@ dependencies = [ "syn 1.0.103", ] +[[package]] +name = "derivation" +version = "0.1.0" +dependencies = [ + "glob", + "serde", + "serde_json", + "test-generator", +] + [[package]] name = "diff" version = "0.1.13" diff --git a/tvix/Cargo.nix b/tvix/Cargo.nix index 7d3c4c869..fdc93f248 100644 --- a/tvix/Cargo.nix +++ b/tvix/Cargo.nix @@ -33,6 +33,16 @@ rec { # You can override the features with # workspaceMembers."${crateName}".build.override { features = [ "default" "feature1" ... ]; }. workspaceMembers = { + "derivation" = rec { + packageId = "derivation"; + build = internal.buildRustCrateWithFeatures { + packageId = "derivation"; + }; + + # Debug support which might change between releases. + # File a bug if you depend on any for non-debug work! + debug = internal.debugCrate { inherit packageId; }; + }; "nix-cli" = rec { packageId = "nix-cli"; build = internal.buildRustCrateWithFeatures { @@ -1433,6 +1443,47 @@ rec { } ]; + }; + "derivation" = rec { + crateName = "derivation"; + version = "0.1.0"; + edition = "2021"; + # We can't filter paths with references in Nix 2.4 + # See https://github.com/NixOS/nix/issues/5410 + src = + if (lib.versionOlder builtins.nixVersion "2.4pre20211007") + then lib.cleanSourceWith { filter = sourceFilter; src = ./derivation; } + else ./derivation; + dependencies = [ + { + name = "blake3"; + packageId = "blake3"; + features = [ "rayon" "std" ]; + } + { + name = "maplit"; + packageId = "maplit"; + } + { + name = "prost"; + packageId = "prost"; + } + { + name = "tonic"; + packageId = "tonic"; + } + ]; + buildDependencies = [ + { + name = "prost-build"; + packageId = "prost-build"; + } + { + name = "tonic-build"; + packageId = "tonic-build"; + } + ]; + }; "diff" = rec { crateName = "diff"; @@ -2657,6 +2708,16 @@ rec { "value-bag" = [ "dep:value-bag" ]; }; }; + "maplit" = rec { + crateName = "maplit"; + version = "1.0.2"; + edition = "2015"; + sha256 = "07b5kjnhrrmfhgqm9wprjw8adx6i225lqp49gasgqg74lahnabiy"; + authors = [ + "bluss" + ]; + + }; "matchit" = rec { crateName = "matchit"; version = "0.7.0"; diff --git a/tvix/Cargo.toml b/tvix/Cargo.toml index 3d39be16a..e12976d1f 100644 --- a/tvix/Cargo.toml +++ b/tvix/Cargo.toml @@ -19,6 +19,7 @@ members = [ "cli", + "derivation", "eval", "eval/builtin-macros", "nar", diff --git a/tvix/derivation/Cargo.toml b/tvix/derivation/Cargo.toml new file mode 100644 index 000000000..99dfbb3a1 --- /dev/null +++ b/tvix/derivation/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "derivation" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +glob = "0.3.0" +serde = { version = "1.0", features = ["derive"] } + +[dev-dependencies.test-generator] +# This fork of test-generator adds support for cargo workspaces, see +# also https://github.com/frehberg/test-generator/pull/14 +git = "https://github.com/JamesGuthrie/test-generator.git" +rev = "82e799979980962aec1aa324ec6e0e4cad781f41" + +[dev-dependencies] +serde_json = "1.0" diff --git a/tvix/derivation/src/lib.rs b/tvix/derivation/src/lib.rs new file mode 100644 index 000000000..a0ddee410 --- /dev/null +++ b/tvix/derivation/src/lib.rs @@ -0,0 +1,216 @@ +use serde::{Deserialize, Serialize}; +use std::{collections::BTreeMap, fmt, fmt::Write}; + +#[cfg(test)] +mod tests; + +const DERIVATION_PREFIX: &str = "Derive"; +const PAREN_OPEN: char = '('; +const PAREN_CLOSE: char = ')'; +const BRACKET_OPEN: char = '['; +const BRACKET_CLOSE: char = ']'; +const COMMA: char = ','; +const QUOTE: char = '"'; + +const STRING_ESCAPER: [(char, &str); 5] = [ + ('\\', "\\\\"), + ('\n', "\\n"), + ('\r', "\\r"), + ('\t', "\\t"), + ('\"', "\\\""), +]; + +fn default_resource() -> String { + "".to_string() +} + +#[derive(Serialize, Deserialize)] +pub struct Output { + path: String, + #[serde(default = "default_resource")] + hash_algorithm: String, + #[serde(default = "default_resource")] + hash: String, +} + +#[derive(Serialize, Deserialize)] +pub struct Derivation { + outputs: BTreeMap, + input_sources: Vec, + input_derivations: BTreeMap>, + platform: String, + builder: String, + arguments: Vec, + environment: BTreeMap, +} + +fn escape_string(s: &String) -> String { + let mut s_replaced = s.clone(); + + for escape_sequence in STRING_ESCAPER { + s_replaced = s_replaced.replace(escape_sequence.0, escape_sequence.1); + } + + return format!("\"{}\"", s_replaced); +} + +fn write_array_elements( + writer: &mut impl Write, + quote: bool, + open: &str, + closing: &str, + elements: Vec<&String>, +) -> Result<(), fmt::Error> { + writer.write_str(open)?; + + for (index, element) in elements.iter().enumerate() { + if index > 0 { + writer.write_char(COMMA)?; + } + + if quote { + writer.write_char(QUOTE)?; + } + + writer.write_str(element)?; + + if quote { + writer.write_char(QUOTE)?; + } + } + + writer.write_str(closing)?; + + return Ok(()); +} + +pub fn serialize_derivation( + derivation: Derivation, + writer: &mut impl Write, +) -> Result<(), fmt::Error> { + writer.write_str(DERIVATION_PREFIX)?; + writer.write_char(PAREN_OPEN)?; + + // Step 1: Write outputs + { + writer.write_char(BRACKET_OPEN)?; + for (ii, (output_name, output)) in derivation.outputs.iter().enumerate() { + if ii > 0 { + writer.write_char(COMMA)?; + } + + // TODO(jrhahn) option to strip output + let elements = vec![ + output_name, + &output.path, + &output.hash_algorithm, + &output.hash, + ]; + + write_array_elements( + writer, + true, + &PAREN_OPEN.to_string(), + &PAREN_CLOSE.to_string(), + elements, + )? + } + writer.write_char(BRACKET_CLOSE)?; + } + + // Step 2: Write input_derivations + { + writer.write_char(COMMA)?; + writer.write_char(BRACKET_OPEN)?; + + for (ii, (input_derivation_path, input_derivation)) in + derivation.input_derivations.iter().enumerate() + { + if ii > 0 { + writer.write_char(COMMA)?; + } + + writer.write_char(PAREN_OPEN)?; + writer.write_char(QUOTE)?; + writer.write_str(input_derivation_path.as_str())?; + writer.write_char(QUOTE)?; + writer.write_char(COMMA)?; + + write_array_elements( + writer, + true, + &BRACKET_OPEN.to_string(), + &BRACKET_CLOSE.to_string(), + input_derivation.iter().map(|s| s).collect(), + )?; + + writer.write_char(PAREN_CLOSE)?; + } + + writer.write_char(BRACKET_CLOSE)?; + } + + // Step 3: Write input_sources + { + writer.write_char(COMMA)?; + write_array_elements( + writer, + true, + &BRACKET_OPEN.to_string(), + &BRACKET_CLOSE.to_string(), + derivation.input_sources.iter().map(|s| s).collect(), + )?; + } + + // Step 4: Write platform + { + writer.write_char(COMMA)?; + writer.write_str(&escape_string(&derivation.platform).as_str())?; + } + + // Step 5: Write builder + { + writer.write_char(COMMA)?; + writer.write_str(&escape_string(&derivation.builder).as_str())?; + } + + // Step 6: Write arguments + { + writer.write_char(COMMA)?; + write_array_elements( + writer, + true, + &BRACKET_OPEN.to_string(), + &BRACKET_CLOSE.to_string(), + derivation.arguments.iter().map(|s| s).collect(), + )?; + } + + // Step 7: Write env + { + writer.write_char(COMMA)?; + writer.write_char(BRACKET_OPEN)?; + + for (ii, (key, environment)) in derivation.environment.iter().enumerate() { + if ii > 0 { + writer.write_char(COMMA)?; + } + + // TODO(jrhahn) add strip option + write_array_elements( + writer, + false, + &PAREN_OPEN.to_string(), + &PAREN_CLOSE.to_string(), + vec![&escape_string(key), &escape_string(&environment)], + )?; + } + + writer.write_char(BRACKET_CLOSE)?; + } + + // Step 8: Close Derive call + writer.write_char(PAREN_CLOSE)?; + + return Ok(()); +} diff --git a/tvix/derivation/src/tests/derivation_tests/0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv b/tvix/derivation/src/tests/derivation_tests/0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv new file mode 100644 index 000000000..a4fea3c5f --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv @@ -0,0 +1 @@ +Derive([("out","/nix/store/4q0pg5zpfmznxscq3avycvf9xdvx50n3-bar","r:sha256","08813cbee9903c62be4c5027726a418a300da4500b2d369d3af9286f4815ceba")],[],[],":",":",[],[("builder",":"),("name","bar"),("out","/nix/store/4q0pg5zpfmznxscq3avycvf9xdvx50n3-bar"),("outputHash","08813cbee9903c62be4c5027726a418a300da4500b2d369d3af9286f4815ceba"),("outputHashAlgo","sha256"),("outputHashMode","recursive"),("system",":")]) \ No newline at end of file diff --git a/tvix/derivation/src/tests/derivation_tests/0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv.json b/tvix/derivation/src/tests/derivation_tests/0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv.json new file mode 100644 index 000000000..abaaa8d4a --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv.json @@ -0,0 +1,23 @@ + { + "outputs": { + "out": { + "path": "/nix/store/4q0pg5zpfmznxscq3avycvf9xdvx50n3-bar", + "hash_algorithm": "r:sha256", + "hash": "08813cbee9903c62be4c5027726a418a300da4500b2d369d3af9286f4815ceba" + } + }, + "input_sources": [], + "input_derivations": {}, + "platform": ":", + "builder": ":", + "arguments": [], + "environment": { + "builder": ":", + "name": "bar", + "out": "/nix/store/4q0pg5zpfmznxscq3avycvf9xdvx50n3-bar", + "outputHash": "08813cbee9903c62be4c5027726a418a300da4500b2d369d3af9286f4815ceba", + "outputHashAlgo": "sha256", + "outputHashMode": "recursive", + "system": ":" + } +} diff --git a/tvix/derivation/src/tests/derivation_tests/292w8yzv5nn7nhdpxcs8b7vby2p27s09-nested-json.drv b/tvix/derivation/src/tests/derivation_tests/292w8yzv5nn7nhdpxcs8b7vby2p27s09-nested-json.drv new file mode 100644 index 000000000..f0d9230a5 --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/292w8yzv5nn7nhdpxcs8b7vby2p27s09-nested-json.drv @@ -0,0 +1 @@ +Derive([("out","/nix/store/pzr7lsd3q9pqsnb42r9b23jc5sh8irvn-nested-json","","")],[],[],":",":",[],[("builder",":"),("json","{\"hello\":\"moto\\n\"}"),("name","nested-json"),("out","/nix/store/pzr7lsd3q9pqsnb42r9b23jc5sh8irvn-nested-json"),("system",":")]) \ No newline at end of file diff --git a/tvix/derivation/src/tests/derivation_tests/292w8yzv5nn7nhdpxcs8b7vby2p27s09-nested-json.drv.json b/tvix/derivation/src/tests/derivation_tests/292w8yzv5nn7nhdpxcs8b7vby2p27s09-nested-json.drv.json new file mode 100644 index 000000000..a1b763ec9 --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/292w8yzv5nn7nhdpxcs8b7vby2p27s09-nested-json.drv.json @@ -0,0 +1,19 @@ +{ + "outputs": { + "out": { + "path": "/nix/store/pzr7lsd3q9pqsnb42r9b23jc5sh8irvn-nested-json" + } + }, + "input_sources": [], + "input_derivations": {}, + "platform": ":", + "builder": ":", + "arguments": [], + "environment": { + "builder": ":", + "json": "{\"hello\":\"moto\\n\"}", + "name": "nested-json", + "out": "/nix/store/pzr7lsd3q9pqsnb42r9b23jc5sh8irvn-nested-json", + "system": ":" + } +} diff --git a/tvix/derivation/src/tests/derivation_tests/4wvvbi4jwn0prsdxb7vs673qa5h9gr7x-foo.drv b/tvix/derivation/src/tests/derivation_tests/4wvvbi4jwn0prsdxb7vs673qa5h9gr7x-foo.drv new file mode 100644 index 000000000..a2cf9d31f --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/4wvvbi4jwn0prsdxb7vs673qa5h9gr7x-foo.drv @@ -0,0 +1 @@ +Derive([("out","/nix/store/5vyvcwah9l9kf07d52rcgdk70g2f4y13-foo","","")],[("/nix/store/0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv",["out"])],[],":",":",[],[("bar","/nix/store/4q0pg5zpfmznxscq3avycvf9xdvx50n3-bar"),("builder",":"),("name","foo"),("out","/nix/store/5vyvcwah9l9kf07d52rcgdk70g2f4y13-foo"),("system",":")]) \ No newline at end of file diff --git a/tvix/derivation/src/tests/derivation_tests/4wvvbi4jwn0prsdxb7vs673qa5h9gr7x-foo.drv.json b/tvix/derivation/src/tests/derivation_tests/4wvvbi4jwn0prsdxb7vs673qa5h9gr7x-foo.drv.json new file mode 100644 index 000000000..f6bb5be23 --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/4wvvbi4jwn0prsdxb7vs673qa5h9gr7x-foo.drv.json @@ -0,0 +1,23 @@ +{ + "outputs": { + "out": { + "path": "/nix/store/5vyvcwah9l9kf07d52rcgdk70g2f4y13-foo" + } + }, + "input_sources": [], + "input_derivations": { + "/nix/store/0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv": [ + "out" + ] + }, + "platform": ":", + "builder": ":", + "arguments": [], + "environment": { + "bar": "/nix/store/4q0pg5zpfmznxscq3avycvf9xdvx50n3-bar", + "builder": ":", + "name": "foo", + "out": "/nix/store/5vyvcwah9l9kf07d52rcgdk70g2f4y13-foo", + "system": ":" + } +} diff --git a/tvix/derivation/src/tests/derivation_tests/52a9id8hx688hvlnz4d1n25ml1jdykz0-unicode.drv b/tvix/derivation/src/tests/derivation_tests/52a9id8hx688hvlnz4d1n25ml1jdykz0-unicode.drv new file mode 100644 index 000000000..bbe88c02c --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/52a9id8hx688hvlnz4d1n25ml1jdykz0-unicode.drv @@ -0,0 +1 @@ +Derive([("out","/nix/store/vgvdj6nf7s8kvfbl2skbpwz9kc7xjazc-unicode","","")],[],[],":",":",[],[("builder",":"),("letters","räksmörgås\nrødgrød med fløde\nLübeck\n肥猪\nこんにちは / 今日は\n🌮\n"),("name","unicode"),("out","/nix/store/vgvdj6nf7s8kvfbl2skbpwz9kc7xjazc-unicode"),("system",":")]) \ No newline at end of file diff --git a/tvix/derivation/src/tests/derivation_tests/52a9id8hx688hvlnz4d1n25ml1jdykz0-unicode.drv.json b/tvix/derivation/src/tests/derivation_tests/52a9id8hx688hvlnz4d1n25ml1jdykz0-unicode.drv.json new file mode 100644 index 000000000..bf837b3e8 --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/52a9id8hx688hvlnz4d1n25ml1jdykz0-unicode.drv.json @@ -0,0 +1,19 @@ +{ + "outputs": { + "out": { + "path": "/nix/store/vgvdj6nf7s8kvfbl2skbpwz9kc7xjazc-unicode" + } + }, + "input_sources": [], + "input_derivations": {}, + "platform": ":", + "builder": ":", + "arguments": [], + "environment": { + "builder": ":", + "letters": "räksmörgås\nrødgrød med fløde\nLübeck\n肥猪\nこんにちは / 今日は\n🌮\n", + "name": "unicode", + "out": "/nix/store/vgvdj6nf7s8kvfbl2skbpwz9kc7xjazc-unicode", + "system": ":" + } +} diff --git a/tvix/derivation/src/tests/derivation_tests/9lj1lkjm2ag622mh4h9rpy6j607an8g2-structured-attrs.drv b/tvix/derivation/src/tests/derivation_tests/9lj1lkjm2ag622mh4h9rpy6j607an8g2-structured-attrs.drv new file mode 100644 index 000000000..4b9338c0b --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/9lj1lkjm2ag622mh4h9rpy6j607an8g2-structured-attrs.drv @@ -0,0 +1 @@ +Derive([("out","/nix/store/6a39dl014j57bqka7qx25k0vb20vkqm6-structured-attrs","","")],[],[],":",":",[],[("__json","{\"builder\":\":\",\"name\":\"structured-attrs\",\"system\":\":\"}"),("out","/nix/store/6a39dl014j57bqka7qx25k0vb20vkqm6-structured-attrs")]) \ No newline at end of file diff --git a/tvix/derivation/src/tests/derivation_tests/9lj1lkjm2ag622mh4h9rpy6j607an8g2-structured-attrs.drv.json b/tvix/derivation/src/tests/derivation_tests/9lj1lkjm2ag622mh4h9rpy6j607an8g2-structured-attrs.drv.json new file mode 100644 index 000000000..97f99acdb --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/9lj1lkjm2ag622mh4h9rpy6j607an8g2-structured-attrs.drv.json @@ -0,0 +1,16 @@ +{ + "outputs": { + "out": { + "path": "/nix/store/6a39dl014j57bqka7qx25k0vb20vkqm6-structured-attrs" + } + }, + "input_sources": [], + "input_derivations": {}, + "platform": ":", + "builder": ":", + "arguments": [], + "environment": { + "__json": "{\"builder\":\":\",\"name\":\"structured-attrs\",\"system\":\":\"}", + "out": "/nix/store/6a39dl014j57bqka7qx25k0vb20vkqm6-structured-attrs" + } +} diff --git a/tvix/derivation/src/tests/derivation_tests/ch49594n9avinrf8ip0aslidkc4lxkqv-foo.drv b/tvix/derivation/src/tests/derivation_tests/ch49594n9avinrf8ip0aslidkc4lxkqv-foo.drv new file mode 100644 index 000000000..1699c2a75 --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/ch49594n9avinrf8ip0aslidkc4lxkqv-foo.drv @@ -0,0 +1 @@ +Derive([("out","/nix/store/fhaj6gmwns62s6ypkcldbaj2ybvkhx3p-foo","","")],[("/nix/store/ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv",["out"])],[],":",":",[],[("bar","/nix/store/mp57d33657rf34lzvlbpfa1gjfv5gmpg-bar"),("builder",":"),("name","foo"),("out","/nix/store/fhaj6gmwns62s6ypkcldbaj2ybvkhx3p-foo"),("system",":")]) \ No newline at end of file diff --git a/tvix/derivation/src/tests/derivation_tests/ch49594n9avinrf8ip0aslidkc4lxkqv-foo.drv.json b/tvix/derivation/src/tests/derivation_tests/ch49594n9avinrf8ip0aslidkc4lxkqv-foo.drv.json new file mode 100644 index 000000000..2d7dbeb75 --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/ch49594n9avinrf8ip0aslidkc4lxkqv-foo.drv.json @@ -0,0 +1,23 @@ +{ + "outputs": { + "out": { + "path": "/nix/store/fhaj6gmwns62s6ypkcldbaj2ybvkhx3p-foo" + } + }, + "input_sources": [], + "input_derivations": { + "/nix/store/ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv": [ + "out" + ] + }, + "platform": ":", + "builder": ":", + "arguments": [], + "environment": { + "bar": "/nix/store/mp57d33657rf34lzvlbpfa1gjfv5gmpg-bar", + "builder": ":", + "name": "foo", + "out": "/nix/store/fhaj6gmwns62s6ypkcldbaj2ybvkhx3p-foo", + "system": ":" + } +} diff --git a/tvix/derivation/src/tests/derivation_tests/h32dahq0bx5rp1krcdx3a53asj21jvhk-has-multi-out.drv b/tvix/derivation/src/tests/derivation_tests/h32dahq0bx5rp1krcdx3a53asj21jvhk-has-multi-out.drv new file mode 100644 index 000000000..523612238 --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/h32dahq0bx5rp1krcdx3a53asj21jvhk-has-multi-out.drv @@ -0,0 +1 @@ +Derive([("lib","/nix/store/2vixb94v0hy2xc6p7mbnxxcyc095yyia-has-multi-out-lib","",""),("out","/nix/store/55lwldka5nyxa08wnvlizyqw02ihy8ic-has-multi-out","","")],[],[],":",":",[],[("builder",":"),("lib","/nix/store/2vixb94v0hy2xc6p7mbnxxcyc095yyia-has-multi-out-lib"),("name","has-multi-out"),("out","/nix/store/55lwldka5nyxa08wnvlizyqw02ihy8ic-has-multi-out"),("outputs","out lib"),("system",":")]) \ No newline at end of file diff --git a/tvix/derivation/src/tests/derivation_tests/h32dahq0bx5rp1krcdx3a53asj21jvhk-has-multi-out.drv.json b/tvix/derivation/src/tests/derivation_tests/h32dahq0bx5rp1krcdx3a53asj21jvhk-has-multi-out.drv.json new file mode 100644 index 000000000..12cb34819 --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/h32dahq0bx5rp1krcdx3a53asj21jvhk-has-multi-out.drv.json @@ -0,0 +1,23 @@ +{ + "outputs": { + "lib": { + "path": "/nix/store/2vixb94v0hy2xc6p7mbnxxcyc095yyia-has-multi-out-lib" + }, + "out": { + "path": "/nix/store/55lwldka5nyxa08wnvlizyqw02ihy8ic-has-multi-out" + } + }, + "input_sources": [], + "input_derivations": {}, + "platform": ":", + "builder": ":", + "arguments": [], + "environment": { + "builder": ":", + "lib": "/nix/store/2vixb94v0hy2xc6p7mbnxxcyc095yyia-has-multi-out-lib", + "name": "has-multi-out", + "out": "/nix/store/55lwldka5nyxa08wnvlizyqw02ihy8ic-has-multi-out", + "outputs": "out lib", + "system": ":" + } +} diff --git a/tvix/derivation/src/tests/derivation_tests/ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv b/tvix/derivation/src/tests/derivation_tests/ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv new file mode 100644 index 000000000..559e93ed0 --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv @@ -0,0 +1 @@ +Derive([("out","/nix/store/mp57d33657rf34lzvlbpfa1gjfv5gmpg-bar","r:sha1","0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33")],[],[],":",":",[],[("builder",":"),("name","bar"),("out","/nix/store/mp57d33657rf34lzvlbpfa1gjfv5gmpg-bar"),("outputHash","0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"),("outputHashAlgo","sha1"),("outputHashMode","recursive"),("system",":")]) \ No newline at end of file diff --git a/tvix/derivation/src/tests/derivation_tests/ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv.json b/tvix/derivation/src/tests/derivation_tests/ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv.json new file mode 100644 index 000000000..e159a5d12 --- /dev/null +++ b/tvix/derivation/src/tests/derivation_tests/ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv.json @@ -0,0 +1,23 @@ +{ + "outputs": { + "out": { + "path": "/nix/store/mp57d33657rf34lzvlbpfa1gjfv5gmpg-bar", + "hash_algorithm": "r:sha1", + "hash": "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" + } + }, + "input_sources": [], + "input_derivations": {}, + "platform": ":", + "builder": ":", + "arguments": [], + "environment": { + "builder": ":", + "name": "bar", + "out": "/nix/store/mp57d33657rf34lzvlbpfa1gjfv5gmpg-bar", + "outputHash": "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", + "outputHashAlgo": "sha1", + "outputHashMode": "recursive", + "system": ":" + } +} diff --git a/tvix/derivation/src/tests/mod.rs b/tvix/derivation/src/tests/mod.rs new file mode 100644 index 000000000..9c8ffd061 --- /dev/null +++ b/tvix/derivation/src/tests/mod.rs @@ -0,0 +1,32 @@ +use super::{serialize_derivation, Derivation}; +use std::fs::File; +use std::io::Read; +use std::path::Path; +use test_generator::test_resources; + +fn read_file(path: &str) -> String { + let path = Path::new(path); + let mut file = File::open(path).unwrap(); + let mut data = String::new(); + + file.read_to_string(&mut data).unwrap(); + + return data; +} + +fn assert_derivation_ok(path_to_drv_file: &str) { + let data = read_file(&format!("{}.json", path_to_drv_file)); + let derivation: Derivation = serde_json::from_str(&data).expect("JSON was not well-formatted"); + + let mut serialized_derivation = String::new(); + serialize_derivation(derivation, &mut serialized_derivation).unwrap(); + + let expected = read_file(path_to_drv_file); + + assert_eq!(expected, serialized_derivation); +} + +#[test_resources("src/tests/derivation_tests/*.drv")] +fn derivation_files_ok(path: &str) { + assert_derivation_ok(path); +}