From f2201d8684bdf9fd6dfe7a3fb18e481feb4f4cfe Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Thu, 30 May 2024 18:12:07 -0500 Subject: [PATCH] Add `set dotenv-required` to require an environment file (#2116) --- README.md | 27 +++-- src/error.rs | 4 + src/keyword.rs | 1 + src/load_dotenv.rs | 19 ++-- src/node.rs | 1 + src/parser.rs | 1 + src/setting.rs | 2 + src/settings.rs | 8 +- tests/command.rs | 23 ++-- tests/dotenv.rs | 223 +++++++++++++++++++++++++++++---------- tests/json.rs | 55 ++++++---- tests/misc.rs | 78 -------------- tests/modules.rs | 20 ++-- tests/shell_expansion.rs | 1 + tests/test.rs | 3 +- 15 files changed, 276 insertions(+), 190 deletions(-) diff --git a/README.md b/README.md index b55b431..c651c91 100644 --- a/README.md +++ b/README.md @@ -812,6 +812,7 @@ foo: | `dotenv-filename` | string | - | Load a `.env` file with a custom name, if present. | | `dotenv-load` | boolean | `false` | Load a `.env` file, if present. | | `dotenv-path` | string | - | Load a `.env` file from a custom path and error if not present. Overrides `dotenv-filename`. | +| `dotenv-required` | boolean | `false` | Error if a `.env` file isn't found. | | `export` | boolean | `false` | Export all variables as environment variables. | | `fallback` | boolean | `false` | Search `justfile` in parent directory if the first recipe on the command line is not found. | | `ignore-comments` | boolean | `false` | Ignore recipe lines beginning with `#`. | @@ -877,17 +878,25 @@ bar #### Dotenv Settings -If `dotenv-load`, `dotenv-filename` or `dotenv-path` is set, `just` will load -environment variables from a file. +If any of `dotenv-load`, `dotenv-filename`, `dotenv-path`, or `dotenv-required` +are set, `just` will try to load environment variables from a file. -If `dotenv-path` is set, `just` will look for a file at the given path. It is -an error if a dotenv file is not found at `dotenv-path`, but not an error if a -dotenv file is not found with `dotenv-filename`. +If `dotenv-path` is set, `just` will look for a file at the given path, which +may be absolute, or relative to the working directory. -Otherwise, `just` looks for a file named `.env` by default, unless -`dotenv-filename` set, in which case the value of `dotenv-filename` is used. -This file can be located in the same directory as your `justfile` or in a -parent directory. +If `dotenv-filename` is set `just` will look for a file at the given path, +relative to the working directory and each of its ancestors. + +If `dotenv-filename` is not set, but `dotenv-load` or `dotenv-required` are +set, just will look for a file named `.env`, relative to the working directory +and each of its ancestors. + +`dotenv-filename` and `dotenv-path` and similar, but `dotenv-path` is only +checked relative to the working directory, whereas `dotenv-filename` is checked +relative to the working directory and each of its ancestors. + +It is not an error if an environment file is not found, unless +`dotenv-required` is set. The loaded variables are environment variables, not `just` variables, and so must be accessed using `$VARIABLE_NAME` in recipes and backticks. diff --git a/src/error.rs b/src/error.rs index ed59097..06b0edf 100644 --- a/src/error.rs +++ b/src/error.rs @@ -79,6 +79,7 @@ pub(crate) enum Error<'src> { Dotenv { dotenv_error: dotenvy::Error, }, + DotenvRequired, DumpJson { serde_json_error: serde_json::Error, }, @@ -347,6 +348,9 @@ impl<'src> ColorDisplay for Error<'src> { Dotenv { dotenv_error } => { write!(f, "Failed to load environment file: {dotenv_error}")?; } + DotenvRequired => { + write!(f, "Dotenv file not found")?; + } DumpJson { serde_json_error } => { write!(f, "Failed to dump JSON to stdout: {serde_json_error}")?; } diff --git a/src/keyword.rs b/src/keyword.rs index a2451e1..d5f268a 100644 --- a/src/keyword.rs +++ b/src/keyword.rs @@ -10,6 +10,7 @@ pub(crate) enum Keyword { DotenvFilename, DotenvLoad, DotenvPath, + DotenvRequired, Else, Export, Fallback, diff --git a/src/load_dotenv.rs b/src/load_dotenv.rs index f543d02..c867e97 100644 --- a/src/load_dotenv.rs +++ b/src/load_dotenv.rs @@ -1,7 +1,5 @@ use super::*; -const DEFAULT_DOTENV_FILENAME: &str = ".env"; - pub(crate) fn load_dotenv( config: &Config, settings: &Settings, @@ -17,16 +15,21 @@ pub(crate) fn load_dotenv( .as_ref() .or(settings.dotenv_path.as_ref()); - if !settings.dotenv_load.unwrap_or_default() && dotenv_filename.is_none() && dotenv_path.is_none() + if !settings.dotenv_load + && dotenv_filename.is_none() + && dotenv_path.is_none() + && !settings.dotenv_required { return Ok(BTreeMap::new()); } if let Some(path) = dotenv_path { - return load_from_file(&working_directory.join(path)); + if path.is_file() { + return load_from_file(&working_directory.join(path)); + } } - let filename = dotenv_filename.map_or(DEFAULT_DOTENV_FILENAME, |s| s.as_str()); + let filename = dotenv_filename.map_or(".env", |s| s.as_str()); for directory in working_directory.ancestors() { let path = directory.join(filename); @@ -35,7 +38,11 @@ pub(crate) fn load_dotenv( } } - Ok(BTreeMap::new()) + if settings.dotenv_required { + Err(Error::DotenvRequired) + } else { + Ok(BTreeMap::new()) + } } fn load_from_file(path: &Path) -> RunResult<'static, BTreeMap> { diff --git a/src/node.rs b/src/node.rs index e18c9fb..e4c4d03 100644 --- a/src/node.rs +++ b/src/node.rs @@ -284,6 +284,7 @@ impl<'src> Node<'src> for Set<'src> { Setting::AllowDuplicateRecipes(value) | Setting::AllowDuplicateVariables(value) | Setting::DotenvLoad(value) + | Setting::DotenvRequired(value) | Setting::Export(value) | Setting::Fallback(value) | Setting::PositionalArguments(value) diff --git a/src/parser.rs b/src/parser.rs index 415e9c7..9f7e883 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -917,6 +917,7 @@ impl<'run, 'src> Parser<'run, 'src> { Some(Setting::AllowDuplicateVariables(self.parse_set_bool()?)) } Keyword::DotenvLoad => Some(Setting::DotenvLoad(self.parse_set_bool()?)), + Keyword::DotenvRequired => Some(Setting::DotenvRequired(self.parse_set_bool()?)), Keyword::Export => Some(Setting::Export(self.parse_set_bool()?)), Keyword::Fallback => Some(Setting::Fallback(self.parse_set_bool()?)), Keyword::IgnoreComments => Some(Setting::IgnoreComments(self.parse_set_bool()?)), diff --git a/src/setting.rs b/src/setting.rs index 805bb86..8bf98f2 100644 --- a/src/setting.rs +++ b/src/setting.rs @@ -7,6 +7,7 @@ pub(crate) enum Setting<'src> { DotenvFilename(String), DotenvLoad(bool), DotenvPath(String), + DotenvRequired(bool), Export(bool), Fallback(bool), IgnoreComments(bool), @@ -24,6 +25,7 @@ impl<'src> Display for Setting<'src> { Self::AllowDuplicateRecipes(value) | Self::AllowDuplicateVariables(value) | Self::DotenvLoad(value) + | Self::DotenvRequired(value) | Self::Export(value) | Self::Fallback(value) | Self::IgnoreComments(value) diff --git a/src/settings.rs b/src/settings.rs index 13085ff..ae6c4b1 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -10,8 +10,9 @@ pub(crate) struct Settings<'src> { pub(crate) allow_duplicate_recipes: bool, pub(crate) allow_duplicate_variables: bool, pub(crate) dotenv_filename: Option, - pub(crate) dotenv_load: Option, + pub(crate) dotenv_load: bool, pub(crate) dotenv_path: Option, + pub(crate) dotenv_required: bool, pub(crate) export: bool, pub(crate) fallback: bool, pub(crate) ignore_comments: bool, @@ -39,11 +40,14 @@ impl<'src> Settings<'src> { settings.dotenv_filename = Some(filename); } Setting::DotenvLoad(dotenv_load) => { - settings.dotenv_load = Some(dotenv_load); + settings.dotenv_load = dotenv_load; } Setting::DotenvPath(path) => { settings.dotenv_path = Some(PathBuf::from(path)); } + Setting::DotenvRequired(dotenv_required) => { + settings.dotenv_required = dotenv_required; + } Setting::Export(export) => { settings.export = export; } diff --git a/tests/command.rs b/tests/command.rs index 44bde24..0cf08e6 100644 --- a/tests/command.rs +++ b/tests/command.rs @@ -47,16 +47,21 @@ test! { status: 2, } -test! { - name: env_is_loaded, - justfile: " - set dotenv-load +#[test] +fn env_is_loaded() { + Test::new() + .justfile( + " + set dotenv-load - x: - echo XYZ - ", - args: ("--command", "sh", "-c", "printf $DOTENV_KEY"), - stdout: "dotenv-value", + x: + echo XYZ + ", + ) + .args(["--command", "sh", "-c", "printf $DOTENV_KEY"]) + .write(".env", "DOTENV_KEY=dotenv-value") + .stdout("dotenv-value") + .run(); } test! { diff --git a/tests/dotenv.rs b/tests/dotenv.rs index 43f5e6b..8e50467 100644 --- a/tests/dotenv.rs +++ b/tests/dotenv.rs @@ -12,40 +12,54 @@ fn dotenv() { .run(); } -test! { - name: set_false, - justfile: r#" - set dotenv-load := false +#[test] +fn set_false() { + Test::new() + .justfile( + r#" + set dotenv-load := false - foo: - if [ -n "${DOTENV_KEY+1}" ]; then echo defined; else echo undefined; fi - "#, - stdout: "undefined\n", - stderr: "if [ -n \"${DOTENV_KEY+1}\" ]; then echo defined; else echo undefined; fi\n", + @foo: + if [ -n "${DOTENV_KEY+1}" ]; then echo defined; else echo undefined; fi + "#, + ) + .write(".env", "DOTENV_KEY=dotenv-value") + .stdout("undefined\n") + .run(); } -test! { - name: set_implicit, - justfile: r#" - set dotenv-load +#[test] +fn set_implicit() { + Test::new() + .justfile( + " + set dotenv-load - foo: - echo $DOTENV_KEY - "#, - stdout: "dotenv-value\n", - stderr: "echo $DOTENV_KEY\n", + foo: + echo $DOTENV_KEY + ", + ) + .write(".env", "DOTENV_KEY=dotenv-value") + .stdout("dotenv-value\n") + .stderr("echo $DOTENV_KEY\n") + .run(); } -test! { - name: set_true, - justfile: r#" - set dotenv-load := true +#[test] +fn set_true() { + Test::new() + .justfile( + " + set dotenv-load := true - foo: - echo $DOTENV_KEY - "#, - stdout: "dotenv-value\n", - stderr: "echo $DOTENV_KEY\n", + foo: + echo $DOTENV_KEY + ", + ) + .write(".env", "DOTENV_KEY=dotenv-value") + .stdout("dotenv-value\n") + .stderr("echo $DOTENV_KEY\n") + .run(); } #[test] @@ -53,32 +67,28 @@ fn no_warning() { Test::new() .justfile( " - foo: - echo ${DOTENV_KEY:-unset} - ", + foo: + echo ${DOTENV_KEY:-unset} + ", ) + .write(".env", "DOTENV_KEY=dotenv-value") .stdout("unset\n") .stderr("echo ${DOTENV_KEY:-unset}\n") .run(); } #[test] -fn path_not_found() { +fn dotenv_required() { Test::new() .justfile( " - foo: - echo $JUST_TEST_VARIABLE - ", + set dotenv-required + + foo: + ", ) - .args(["--dotenv-path", ".env.prod"]) - .stderr(if cfg!(windows) { - "error: Failed to load environment file: The system cannot find the file specified. (os \ - error 2)\n" - } else { - "error: Failed to load environment file: No such file or directory (os error 2)\n" - }) - .status(EXIT_FAILURE) + .stderr("error: Dotenv file not found\n") + .status(1) .run(); } @@ -87,9 +97,9 @@ fn path_resolves() { Test::new() .justfile( " - foo: - @echo $JUST_TEST_VARIABLE - ", + foo: + @echo $JUST_TEST_VARIABLE + ", ) .tree(tree! { subdir: { @@ -107,9 +117,9 @@ fn filename_resolves() { Test::new() .justfile( " - foo: - @echo $JUST_TEST_VARIABLE - ", + foo: + @echo $JUST_TEST_VARIABLE + ", ) .tree(tree! { ".env.special": "JUST_TEST_VARIABLE=bar" @@ -145,11 +155,11 @@ fn path_flag_overwrites_no_load() { Test::new() .justfile( " - set dotenv-load := false + set dotenv-load := false - foo: - @echo $JUST_TEST_VARIABLE - ", + foo: + @echo $JUST_TEST_VARIABLE + ", ) .tree(tree! { subdir: { @@ -227,12 +237,12 @@ fn program_argument_has_priority_for_dotenv_filename() { fn program_argument_has_priority_for_dotenv_path() { Test::new() .justfile( - r#" - set dotenv-path := "subdir/.env" + " + set dotenv-path := 'subdir/.env' foo: @echo $JUST_TEST_VARIABLE - "#, + ", ) .tree(tree! { subdir: { @@ -257,8 +267,111 @@ fn dotenv_path_is_relative_to_working_directory() { @echo $DOTENV_KEY ", ) + .write(".env", "DOTENV_KEY=dotenv-value") .tree(tree! { subdir: { } }) .current_dir("subdir") .stdout("dotenv-value\n") .run(); } + +#[test] +fn dotenv_variable_in_recipe() { + Test::new() + .justfile( + " + set dotenv-load + + echo: + echo $DOTENV_KEY + ", + ) + .write(".env", "DOTENV_KEY=dotenv-value") + .stdout("dotenv-value\n") + .stderr("echo $DOTENV_KEY\n") + .run(); +} + +#[test] +fn dotenv_variable_in_backtick() { + Test::new() + .justfile( + " + set dotenv-load + X:=`echo $DOTENV_KEY` + echo: + echo {{X}} + ", + ) + .write(".env", "DOTENV_KEY=dotenv-value") + .stdout("dotenv-value\n") + .stderr("echo dotenv-value\n") + .run(); +} + +#[test] +fn dotenv_variable_in_function_in_recipe() { + Test::new() + .justfile( + " + set dotenv-load + echo: + echo {{env_var_or_default('DOTENV_KEY', 'foo')}} + echo {{env_var('DOTENV_KEY')}} + ", + ) + .write(".env", "DOTENV_KEY=dotenv-value") + .stdout("dotenv-value\ndotenv-value\n") + .stderr("echo dotenv-value\necho dotenv-value\n") + .run(); +} + +#[test] +fn dotenv_variable_in_function_in_backtick() { + Test::new() + .justfile( + " + set dotenv-load + X:=env_var_or_default('DOTENV_KEY', 'foo') + Y:=env_var('DOTENV_KEY') + echo: + echo {{X}} + echo {{Y}} +", + ) + .write(".env", "DOTENV_KEY=dotenv-value") + .stdout("dotenv-value\ndotenv-value\n") + .stderr("echo dotenv-value\necho dotenv-value\n") + .run(); +} + +#[test] +fn no_dotenv() { + Test::new() + .justfile( + " + X:=env_var_or_default('DOTENV_KEY', 'DEFAULT') + echo: + echo {{X}} + ", + ) + .write(".env", "DOTENV_KEY=dotenv-value") + .arg("--no-dotenv") + .stdout("DEFAULT\n") + .stderr("echo DEFAULT\n") + .run(); +} +#[test] +fn dotenv_env_var_override() { + Test::new() + .justfile( + " + echo: + echo $DOTENV_KEY + ", + ) + .write(".env", "DOTENV_KEY=dotenv-value") + .env("DOTENV_KEY", "not-the-dotenv-value") + .stdout("not-the-dotenv-value\n") + .stderr("echo $DOTENV_KEY\n") + .run(); +} diff --git a/tests/json.rs b/tests/json.rs index dd30076..218b625 100644 --- a/tests/json.rs +++ b/tests/json.rs @@ -46,8 +46,9 @@ fn alias() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "positional_arguments": false, @@ -84,8 +85,9 @@ fn assignment() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -136,8 +138,9 @@ fn body() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -200,8 +203,9 @@ fn dependencies() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -302,8 +306,9 @@ fn dependency_argument() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -366,8 +371,9 @@ fn duplicate_recipes() { "allow_duplicate_recipes": true, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -408,8 +414,9 @@ fn duplicate_variables() { "allow_duplicate_recipes": false, "allow_duplicate_variables": true, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -453,8 +460,9 @@ fn doc_comment() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -484,8 +492,9 @@ fn empty_justfile() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -636,8 +645,9 @@ fn parameters() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -721,8 +731,9 @@ fn priors() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -766,8 +777,9 @@ fn private() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -811,8 +823,9 @@ fn quiet() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -870,6 +883,7 @@ fn settings() { "dotenv_filename": "filename", "dotenv_load": true, "dotenv_path": "path", + "dotenv_required": false, "export": true, "fallback": true, "ignore_comments": true, @@ -919,8 +933,9 @@ fn shebang() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -964,8 +979,9 @@ fn simple() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "ignore_comments": false, @@ -1012,8 +1028,9 @@ fn attribute() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "positional_arguments": false, @@ -1073,8 +1090,9 @@ fn module() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "positional_arguments": false, @@ -1093,8 +1111,9 @@ fn module() { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, "dotenv_filename": null, - "dotenv_load": null, + "dotenv_load": false, "dotenv_path": null, + "dotenv_required": false, "export": false, "fallback": false, "positional_arguments": false, diff --git a/tests/misc.rs b/tests/misc.rs index 8b40183..4e30a2d 100644 --- a/tests/misc.rs +++ b/tests/misc.rs @@ -1589,84 +1589,6 @@ echo: stderr: "echo 1\n", } -test! { - name: dotenv_variable_in_recipe, - justfile: " -# -set dotenv-load - -echo: - echo $DOTENV_KEY - ", - stdout: "dotenv-value\n", - stderr: "echo $DOTENV_KEY\n", -} - -test! { - name: dotenv_variable_in_backtick, - justfile: " -# -set dotenv-load -X:=`echo $DOTENV_KEY` -echo: - echo {{X}} - ", - stdout: "dotenv-value\n", - stderr: "echo dotenv-value\n", -} -test! { - name: dotenv_variable_in_function_in_recipe, - justfile: " -# -set dotenv-load -echo: - echo {{env_var_or_default('DOTENV_KEY', 'foo')}} - echo {{env_var('DOTENV_KEY')}} - ", - stdout: "dotenv-value\ndotenv-value\n", - stderr: "echo dotenv-value\necho dotenv-value\n", -} - -test! { - name: dotenv_variable_in_function_in_backtick, - justfile: " -# -set dotenv-load -X:=env_var_or_default('DOTENV_KEY', 'foo') -Y:=env_var('DOTENV_KEY') -echo: - echo {{X}} - echo {{Y}} - ", - stdout: "dotenv-value\ndotenv-value\n", - stderr: "echo dotenv-value\necho dotenv-value\n", -} - -test! { - name: no_dotenv, - justfile: " -# -X:=env_var_or_default('DOTENV_KEY', 'DEFAULT') -echo: - echo {{X}} - ", - args: ("--no-dotenv"), - stdout: "DEFAULT\n", - stderr: "echo DEFAULT\n", -} - -test! { - name: dotenv_env_var_override, - justfile: " -# -echo: - echo $DOTENV_KEY - ", - env: {"DOTENV_KEY": "not-the-dotenv-value",}, - stdout: "not-the-dotenv-value\n", - stderr: "echo $DOTENV_KEY\n", -} - test! { name: invalid_escape_sequence_message, justfile: r#" diff --git a/tests/modules.rs b/tests/modules.rs index b9089ae..5cccf4e 100644 --- a/tests/modules.rs +++ b/tests/modules.rs @@ -515,7 +515,6 @@ fn missing_optional_modules_do_not_conflict() { #[test] fn root_dotenv_is_available_to_submodules() { Test::new() - .write("foo.just", "foo:\n @echo $DOTENV_KEY") .justfile( " set dotenv-load @@ -523,10 +522,10 @@ fn root_dotenv_is_available_to_submodules() { mod foo ", ) + .write("foo.just", "foo:\n @echo $DOTENV_KEY") + .write(".env", "DOTENV_KEY=dotenv-value") .test_round_trip(false) - .arg("--unstable") - .arg("foo") - .arg("foo") + .args(["--unstable", "foo", "foo"]) .stdout("dotenv-value\n") .run(); } @@ -534,10 +533,6 @@ fn root_dotenv_is_available_to_submodules() { #[test] fn dotenv_settings_in_submodule_are_ignored() { Test::new() - .write( - "foo.just", - "set dotenv-load := false\nfoo:\n @echo $DOTENV_KEY", - ) .justfile( " set dotenv-load @@ -545,10 +540,13 @@ fn dotenv_settings_in_submodule_are_ignored() { mod foo ", ) + .write( + "foo.just", + "set dotenv-load := false\nfoo:\n @echo $DOTENV_KEY", + ) + .write(".env", "DOTENV_KEY=dotenv-value") .test_round_trip(false) - .arg("--unstable") - .arg("foo") - .arg("foo") + .args(["--unstable", "foo", "foo"]) .stdout("dotenv-value\n") .run(); } diff --git a/tests/shell_expansion.rs b/tests/shell_expansion.rs index c50ce5b..87086d5 100644 --- a/tests/shell_expansion.rs +++ b/tests/shell_expansion.rs @@ -82,6 +82,7 @@ fn shell_expanded_strings_can_be_used_in_settings() { echo $DOTENV_KEY ", ) + .write(".env", "DOTENV_KEY=dotenv-value") .env("JUST_TEST_VARIABLE", ".env") .stdout("dotenv-value\n") .run(); diff --git a/tests/test.rs b/tests/test.rs index c57a4c4..e241d7e 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -201,9 +201,8 @@ impl Test { } else { self.stdout.clone() }; - let stderr = unindent(&self.stderr); - fs::write(self.tempdir.path().join(".env"), "DOTENV_KEY=dotenv-value").unwrap(); + let stderr = unindent(&self.stderr); let mut command = Command::new(executable_path("just"));