Update the tvix cli's -I option so that it aligns more closely with
nix's behavior: prepending entries to the list of lookup paths provided
by the NIX_PATH environment variable. Before this commit, using the -I
option would instead override and ignore the NIX_PATH variable.
Additionally, update the option's long name and help text to match the
new behavior.
While the tvix cli's interface does not appear to be attempting to mimic
nix exactly, I think this particular case of the -I option's diverging
behavior will inevitably surprise users because it's name, presumably
short for "include" and being similar to gcc's flag, evokes additivity.
The prior implementation hinted at this difference with the help text
and the long name, --nix-search-path, but I still suspect users will be
confused on first usage (at least I was). If we're willing to pay the
maintenance costs of additional code, we can avoid this and provide a
slightly smoother user experience.
Changes were tested by buiding the tvix cli, adding it to the PATH, and
executing simple tests as in the following bash script
mg build //tvix/cli
PATH="$PWD/result/bin:$PATH"
one=$(mktemp) && echo "=> $one :: path" > "$one"
two=$(mktemp) && echo "=> $two :: path" > "$two"
dir1=$(mktemp -d) && file1="$dir1/file1" && echo "=> $file1 :: path" > "$file1"
dir2=$(mktemp -d) && file2="$dir2/file2" && echo "=> $file2 :: path" > "$file2"
# NIX_PATH works with a single non-prefixed lookup path.
NIX_PATH="$dir1" tvix -E "<file1>" | cmp - "$file1"
# NIX_PATH works with multiple non-prefixed lookup paths.
NIX_PATH="$dir1:$dir2" tvix -E "<file2>" | cmp - "$file2"
# NIX_PATH works with a single prefixed lookup path.
NIX_PATH="one=$one" tvix -E "<one>" | cmp - "$one"
# NIX_PATH works with multiple prefixed lookup paths.
NIX_PATH="one=$one:two=$two" tvix -E "<one>" | cmp - "$one"
NIX_PATH="one=$one:two=$two" tvix -E "<two>" | cmp - "$two"
# NIX_PATH first entry takes precedence.
NIX_PATH="one=$one:one=$two" tvix -E "<one>" | cmp - "$one"
# The -I option works with a single non-prefixed lookup path.
tvix -I "$dir1" -E "<file1>" | cmp - "$file1"
# The -I option works with multiple non-prefixed lookup paths.
tvix -I "$dir1" -I "$dir2" -E "<file2>" | cmp - "$file2"
# The -I option works with a single prefixed lookup path.
tvix -I "one=$one" -E "<one>" | cmp - "$one"
# The --extra-nix-path option works with a single prefixed lookup path.
tvix --extra-nix-path "one=$one" -E "<one>" | cmp - "$one"
# The -I options works when passed multiple times with prefixed lookup paths.
tvix -I "one=$one" -I "two=$two" -E "<one>" | cmp - "$one"
tvix -I "one=$one" -I "two=$two" -E "<two>" | cmp - "$two"
# The first -I option takes precedence.
tvix -I "one=$one" -I "one=$two" -E "<one>" | cmp - "$one"
# Both NIX_PATH and the -I option work together and are additive.
NIX_PATH="one=$one" tvix -I "two=$two" -E "<one>" | cmp - "$one"
NIX_PATH="one=$one" tvix -I "two=$two" -E "<two>" | cmp - "$two"
# The -I option takes precedence over NIX_PATH.
NIX_PATH="one=$one" tvix -I "one=$two" -E "<one>" | cmp - "$two"
rm "$one"
rm "$two"
rm "$file1" && rmdir "$dir1"
rm "$file2" && rmdir "$dir2"
The above script assumes it's being run from inside the depot.
Change-Id: I153e6de57939c0eeca1f9e479d807862ab69b2de
Reviewed-on: https://cl.tvl.fyi/c/depot/+/13189
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
98 lines
2.2 KiB
Rust
98 lines
2.2 KiB
Rust
use std::ffi::OsString;
|
|
|
|
use clap::Parser;
|
|
use expect_test::expect;
|
|
use tvix_cli::init_io_handle;
|
|
|
|
macro_rules! test_repl {
|
|
($name:ident() {$($send:expr => $expect:expr;)*}) => {
|
|
#[test]
|
|
fn $name() {
|
|
let tokio_runtime = tokio::runtime::Runtime::new().unwrap();
|
|
let args = tvix_cli::Args::parse_from(vec![
|
|
OsString::from("tvix"),
|
|
OsString::from("--extra-nix-path"),
|
|
OsString::from("nixpkgs=/tmp"),
|
|
]);
|
|
let mut repl = tvix_cli::Repl::new(init_io_handle(&tokio_runtime, &args), &args);
|
|
$({
|
|
let result = repl.send($send.into());
|
|
$expect.assert_eq(result.output())
|
|
;
|
|
})*
|
|
}
|
|
}
|
|
}
|
|
|
|
test_repl!(simple_expr_eval() {
|
|
"1" => expect![[r#"
|
|
=> 1 :: int
|
|
"#]];
|
|
});
|
|
|
|
test_repl!(multiline_input() {
|
|
"{ x = 1; " => expect![[""]];
|
|
"y = 2; }" => expect![[r#"
|
|
=> { x = 1; y = 2; } :: set
|
|
"#]];
|
|
});
|
|
|
|
test_repl!(bind_literal() {
|
|
"x = 1" => expect![[""]];
|
|
"x" => expect![[r#"
|
|
=> 1 :: int
|
|
"#]];
|
|
});
|
|
|
|
test_repl!(bind_lazy() {
|
|
"x = { z = 1; }" => expect![[""]];
|
|
"x" => expect![[r#"
|
|
=> { z = 1; } :: set
|
|
"#]];
|
|
"x.z" => expect![[r#"
|
|
=> 1 :: int
|
|
"#]];
|
|
"x.z" => expect![[r#"
|
|
=> 1 :: int
|
|
"#]];
|
|
});
|
|
|
|
test_repl!(bind_lazy_errors() {
|
|
r#"x = (_: "x" + 1)"# => expect![[""]];
|
|
"x null" => expect![[""]];
|
|
});
|
|
|
|
test_repl!(bind_referencing_import() {
|
|
"six = import ./tests/six.nix {}" => expect![[""]];
|
|
"six.six" => expect![[r#"
|
|
=> 6 :: int
|
|
"#]];
|
|
"imported = import ./tests/import.nix" => expect![[""]];
|
|
"(imported {}).six" => expect![[r#"
|
|
=> 6 :: int
|
|
"#]];
|
|
});
|
|
|
|
test_repl!(deep_print() {
|
|
"builtins.map (x: x + 1) [ 1 2 3 ]" => expect![[r#"
|
|
=> [ <CODE> <CODE> <CODE> ] :: list
|
|
"#]];
|
|
":p builtins.map (x: x + 1) [ 1 2 3 ]" => expect![[r#"
|
|
=> [ 2 3 4 ] :: list
|
|
"#]];
|
|
});
|
|
|
|
test_repl!(explain() {
|
|
":d { x = 1; y = [ 2 3 4 ]; }" => expect![[r#"
|
|
=> a 2-item attribute set
|
|
"#]];
|
|
});
|
|
|
|
test_repl!(reference_nix_path() {
|
|
"<nixpkgs>" => expect![[r#"
|
|
=> /tmp :: path
|
|
"#]];
|
|
"<nixpkgs>" => expect![[r#"
|
|
=> /tmp :: path
|
|
"#]];
|
|
});
|