From e4ebf6dad96ee34224ca38e4c9f72850f4de5939 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 30 Mar 2021 17:30:32 -0700 Subject: [PATCH] Warn if `.env` file loaded and `dotenv-load` unset (#784) --- src/analyzer.rs | 2 +- src/justfile.rs | 2 +- src/load_dotenv.rs | 13 +++++++++++-- src/settings.rs | 4 ++-- src/warning.rs | 26 +++++++++++++++++++++++--- tests/dotenv.rs | 26 ++++++++++++++++++++++++++ tests/misc.rs | 6 +++++- tests/test.rs | 43 ++++++++++++++++++++++++++----------------- 8 files changed, 95 insertions(+), 27 deletions(-) diff --git a/src/analyzer.rs b/src/analyzer.rs index c425da7..542125e 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -66,7 +66,7 @@ impl<'src> Analyzer<'src> { for (_, set) in self.sets { match set.value { Setting::DotenvLoad(dotenv_load) => { - settings.dotenv_load = dotenv_load; + settings.dotenv_load = Some(dotenv_load); }, Setting::Export(export) => { settings.export = export; diff --git a/src/justfile.rs b/src/justfile.rs index d17ac5c..7255c67 100644 --- a/src/justfile.rs +++ b/src/justfile.rs @@ -91,7 +91,7 @@ impl<'src> Justfile<'src> { } let dotenv = if config.load_dotenv { - load_dotenv(&search.working_directory, &self.settings)? + load_dotenv(&config, &self.settings, &search.working_directory)? } else { BTreeMap::new() }; diff --git a/src/load_dotenv.rs b/src/load_dotenv.rs index d0c1b3d..94037cc 100644 --- a/src/load_dotenv.rs +++ b/src/load_dotenv.rs @@ -1,14 +1,15 @@ use crate::common::*; pub(crate) fn load_dotenv( - working_directory: &Path, + config: &Config, settings: &Settings, + working_directory: &Path, ) -> RunResult<'static, BTreeMap> { // `dotenv::from_path_iter` should eventually be un-deprecated, see: // https://github.com/dotenv-rs/dotenv/issues/13 #![allow(deprecated)] - if !settings.dotenv_load { + if !settings.dotenv_load.unwrap_or(true) { return Ok(BTreeMap::new()); } @@ -16,6 +17,14 @@ pub(crate) fn load_dotenv( let path = directory.join(".env"); if path.is_file() { + if settings.dotenv_load.is_none() && config.verbosity.loud() { + if config.color.stderr().active() { + eprintln!("{:#}", Warning::DotenvLoad); + } else { + eprintln!("{}", Warning::DotenvLoad); + } + } + let iter = dotenv::from_path_iter(&path)?; let mut dotenv = BTreeMap::new(); for result in iter { diff --git a/src/settings.rs b/src/settings.rs index 2037d33..b86dc24 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -2,7 +2,7 @@ use crate::common::*; #[derive(Debug, PartialEq)] pub(crate) struct Settings<'src> { - pub(crate) dotenv_load: bool, + pub(crate) dotenv_load: Option, pub(crate) export: bool, pub(crate) shell: Option>, } @@ -10,7 +10,7 @@ pub(crate) struct Settings<'src> { impl<'src> Settings<'src> { pub(crate) fn new() -> Settings<'src> { Settings { - dotenv_load: true, + dotenv_load: None, export: false, shell: None, } diff --git a/src/warning.rs b/src/warning.rs index 4ea9b51..23a0850 100644 --- a/src/warning.rs +++ b/src/warning.rs @@ -1,12 +1,15 @@ use crate::common::*; #[derive(Debug, PartialEq)] -pub(crate) enum Warning {} +pub(crate) enum Warning { + DotenvLoad, +} impl Warning { fn context(&self) -> Option<&Token> { - #![allow(clippy::unused_self)] - unreachable!() + match self { + Self::DotenvLoad => None, + } } } @@ -17,6 +20,23 @@ impl Display for Warning { write!(f, "{} {}", warning.paint("warning:"), message.prefix())?; + match self { + Self::DotenvLoad => { + #[rustfmt::skip] + write!(f, "\ +A `.env` file was found and loaded, but this behavior will change in the future. +To silence this warning and continue loading `.env` files, add: + + set dotenv-load := true + +To silence this warning and stop loading `.env` files, add: + + set dotenv-load := false + +See https://github.com/casey/just/issues/469 for more details.")?; + }, + } + write!(f, "{}", message.suffix())?; if let Some(token) = self.context() { diff --git a/tests/dotenv.rs b/tests/dotenv.rs index 50c5b1b..145a2de 100644 --- a/tests/dotenv.rs +++ b/tests/dotenv.rs @@ -37,6 +37,7 @@ test! { "#, stdout: "undefined\n", stderr: "if [ -n \"${DOTENV_KEY+1}\" ]; then echo defined; else echo undefined; fi\n", + dotenv_load: false, } test! { @@ -49,6 +50,7 @@ test! { "#, stdout: "dotenv-value\n", stderr: "echo $DOTENV_KEY\n", + dotenv_load: false, } test! { @@ -61,4 +63,28 @@ test! { "#, stdout: "dotenv-value\n", stderr: "echo $DOTENV_KEY\n", + dotenv_load: false, +} + +test! { + name: warning, + justfile: r#" + foo: + echo $DOTENV_KEY + "#, + stdout: "dotenv-value\n", + stderr: " + warning: A `.env` file was found and loaded, but this behavior will change in the future. + To silence this warning and continue loading `.env` files, add: + + set dotenv-load := true + + To silence this warning and stop loading `.env` files, add: + + set dotenv-load := false + + See https://github.com/casey/just/issues/469 for more details. + echo $DOTENV_KEY + ", + dotenv_load: false, } diff --git a/tests/misc.rs b/tests/misc.rs index bb957fd..e9e3c17 100644 --- a/tests/misc.rs +++ b/tests/misc.rs @@ -2121,11 +2121,15 @@ default stdin = `cat justfile`: default stdin = `cat justfile`: echo {{stdin}} + + set dotenv-load := true ", stderr: " echo ' default stdin = `cat justfile`: - echo '{{stdin}}'' + echo '{{stdin}}' + + set dotenv-load := true' ", } diff --git a/tests/test.rs b/tests/test.rs index 7b50de5..3067e89 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -15,6 +15,7 @@ macro_rules! test { $(stderr: $stderr:expr,)? $(status: $status:expr,)? $(shell: $shell:expr,)? + $(dotenv_load: $dotenv_load:expr,)? ) => { #[test] fn $name() { @@ -31,6 +32,7 @@ macro_rules! test { $(stderr: $stderr,)? $(status: $status,)? $(shell: $shell,)? + $(dotenv_load: $dotenv_load,)? env, ..crate::test::Test::default() }.run(); @@ -39,27 +41,29 @@ macro_rules! test { } pub(crate) struct Test<'a> { - pub(crate) justfile: &'a str, - pub(crate) args: &'a [&'a str], - pub(crate) env: BTreeMap, - pub(crate) stdin: &'a str, - pub(crate) stdout: &'a str, - pub(crate) stderr: &'a str, - pub(crate) status: i32, - pub(crate) shell: bool, + pub(crate) justfile: &'a str, + pub(crate) args: &'a [&'a str], + pub(crate) env: BTreeMap, + pub(crate) stdin: &'a str, + pub(crate) stdout: &'a str, + pub(crate) stderr: &'a str, + pub(crate) status: i32, + pub(crate) shell: bool, + pub(crate) dotenv_load: bool, } impl<'a> Default for Test<'a> { fn default() -> Test<'a> { Test { - justfile: "", - args: &[], - env: BTreeMap::new(), - stdin: "", - stdout: "", - stderr: "", - status: EXIT_SUCCESS, - shell: true, + justfile: "", + args: &[], + env: BTreeMap::new(), + stdin: "", + stdout: "", + stderr: "", + status: EXIT_SUCCESS, + shell: true, + dotenv_load: true, } } } @@ -68,7 +72,12 @@ impl<'a> Test<'a> { pub(crate) fn run(self) { let tmp = tempdir(); - let justfile = unindent(self.justfile); + let mut justfile = unindent(self.justfile); + + if self.dotenv_load { + justfile.push_str("\nset dotenv-load := true\n"); + } + let stdout = unindent(self.stdout); let stderr = unindent(self.stderr);