Skip .env
items which are set in environment (#656)
If an environment variable exists with the same key as a variable from a `.env` file, skip the variable from the `.env` file in favor fo the key from the environment.
This commit is contained in:
parent
cea4a16081
commit
837b6e6a00
@ -149,7 +149,7 @@ impl<'src> Justfile<'src> {
|
|||||||
while let Some((argument, mut tail)) = rest.split_first() {
|
while let Some((argument, mut tail)) = rest.split_first() {
|
||||||
if let Some(recipe) = self.get_recipe(argument) {
|
if let Some(recipe) = self.get_recipe(argument) {
|
||||||
if recipe.parameters.is_empty() {
|
if recipe.parameters.is_empty() {
|
||||||
grouped.push((recipe, &tail[0..0]));
|
grouped.push((recipe, &[][..]));
|
||||||
} else {
|
} else {
|
||||||
let argument_range = recipe.argument_range();
|
let argument_range = recipe.argument_range();
|
||||||
let argument_count = cmp::min(tail.len(), recipe.max_arguments());
|
let argument_count = cmp::min(tail.len(), recipe.max_arguments());
|
||||||
|
@ -678,7 +678,7 @@ impl<'src> Lexer<'src> {
|
|||||||
match self.next {
|
match self.next {
|
||||||
Some('\'') => break,
|
Some('\'') => break,
|
||||||
None => return Err(self.error(UnterminatedString)),
|
None => return Err(self.error(UnterminatedString)),
|
||||||
_ => {},
|
Some(_) => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
self.advance()?;
|
self.advance()?;
|
||||||
|
@ -3,29 +3,28 @@
|
|||||||
clippy::comparison_chain,
|
clippy::comparison_chain,
|
||||||
clippy::else_if_without_else,
|
clippy::else_if_without_else,
|
||||||
clippy::enum_glob_use,
|
clippy::enum_glob_use,
|
||||||
|
clippy::expect_used,
|
||||||
clippy::filter_map,
|
clippy::filter_map,
|
||||||
clippy::if_not_else,
|
clippy::if_not_else,
|
||||||
clippy::implicit_return,
|
clippy::implicit_return,
|
||||||
clippy::indexing_slicing,
|
clippy::indexing_slicing,
|
||||||
clippy::integer_arithmetic,
|
clippy::integer_arithmetic,
|
||||||
clippy::let_underscore_must_use,
|
clippy::let_underscore_must_use,
|
||||||
|
clippy::map_unwrap_or,
|
||||||
clippy::match_same_arms,
|
clippy::match_same_arms,
|
||||||
clippy::missing_docs_in_private_items,
|
clippy::missing_docs_in_private_items,
|
||||||
clippy::missing_errors_doc,
|
clippy::missing_errors_doc,
|
||||||
clippy::missing_inline_in_public_items,
|
clippy::missing_inline_in_public_items,
|
||||||
clippy::needless_pass_by_value,
|
clippy::needless_pass_by_value,
|
||||||
clippy::non_ascii_literal,
|
clippy::non_ascii_literal,
|
||||||
clippy::option_expect_used,
|
|
||||||
clippy::option_map_unwrap_or,
|
|
||||||
clippy::option_unwrap_used,
|
|
||||||
clippy::panic,
|
clippy::panic,
|
||||||
clippy::print_stdout,
|
clippy::print_stdout,
|
||||||
clippy::result_expect_used,
|
|
||||||
clippy::shadow_unrelated,
|
clippy::shadow_unrelated,
|
||||||
clippy::string_add,
|
clippy::string_add,
|
||||||
clippy::struct_excessive_bools,
|
clippy::struct_excessive_bools,
|
||||||
clippy::too_many_lines,
|
clippy::too_many_lines,
|
||||||
clippy::unreachable,
|
clippy::unreachable,
|
||||||
|
clippy::unwrap_used,
|
||||||
clippy::use_debug,
|
clippy::use_debug,
|
||||||
clippy::wildcard_enum_match_arm,
|
clippy::wildcard_enum_match_arm,
|
||||||
clippy::wildcard_imports
|
clippy::wildcard_imports
|
||||||
|
@ -6,8 +6,14 @@ pub(crate) fn load_dotenv() -> RunResult<'static, BTreeMap<String, String>> {
|
|||||||
#![allow(deprecated)]
|
#![allow(deprecated)]
|
||||||
match dotenv::dotenv_iter() {
|
match dotenv::dotenv_iter() {
|
||||||
Ok(iter) => {
|
Ok(iter) => {
|
||||||
let result: dotenv::Result<BTreeMap<String, String>> = iter.collect();
|
let mut dotenv = BTreeMap::new();
|
||||||
result.map_err(|dotenv_error| RuntimeError::Dotenv { dotenv_error })
|
for result in iter {
|
||||||
|
let (key, value) = result.map_err(|dotenv_error| RuntimeError::Dotenv { dotenv_error })?;
|
||||||
|
if env::var_os(&key).is_none() {
|
||||||
|
dotenv.insert(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(dotenv)
|
||||||
},
|
},
|
||||||
Err(dotenv_error) =>
|
Err(dotenv_error) =>
|
||||||
if dotenv_error.not_found() {
|
if dotenv_error.not_found() {
|
||||||
|
@ -101,8 +101,7 @@ impl<'text> Tree<'text> {
|
|||||||
|
|
||||||
/// Like `push`, but modify self in-place
|
/// Like `push`, but modify self in-place
|
||||||
pub(crate) fn push_mut(&mut self, tree: impl Into<Tree<'text>>) {
|
pub(crate) fn push_mut(&mut self, tree: impl Into<Tree<'text>>) {
|
||||||
let tree = mem::replace(self, Tree::List(Vec::new())).push(tree.into());
|
*self = mem::replace(self, Tree::List(Vec::new())).push(tree.into());
|
||||||
mem::replace(self, tree);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
collections::BTreeMap,
|
||||||
env, fs,
|
env, fs,
|
||||||
io::Write,
|
io::Write,
|
||||||
path::Path,
|
path::Path,
|
||||||
@ -16,6 +17,9 @@ macro_rules! test {
|
|||||||
name: $name:ident,
|
name: $name:ident,
|
||||||
justfile: $justfile:expr,
|
justfile: $justfile:expr,
|
||||||
$(args: ($($arg:tt)*),)?
|
$(args: ($($arg:tt)*),)?
|
||||||
|
$(env: {
|
||||||
|
$($env_key:literal : $env_value:literal,)*
|
||||||
|
},)?
|
||||||
$(stdin: $stdin:expr,)?
|
$(stdin: $stdin:expr,)?
|
||||||
$(stdout: $stdout:expr,)?
|
$(stdout: $stdout:expr,)?
|
||||||
$(stderr: $stderr:expr,)?
|
$(stderr: $stderr:expr,)?
|
||||||
@ -24,6 +28,11 @@ macro_rules! test {
|
|||||||
) => {
|
) => {
|
||||||
#[test]
|
#[test]
|
||||||
fn $name() {
|
fn $name() {
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
let mut env = BTreeMap::new();
|
||||||
|
|
||||||
|
$($(env.insert($env_key.to_string(), $env_value.to_string());)*)?
|
||||||
|
|
||||||
Test {
|
Test {
|
||||||
justfile: $justfile,
|
justfile: $justfile,
|
||||||
$(args: &[$($arg)*],)?
|
$(args: &[$($arg)*],)?
|
||||||
@ -32,6 +41,7 @@ macro_rules! test {
|
|||||||
$(stderr: $stderr,)?
|
$(stderr: $stderr,)?
|
||||||
$(status: $status,)?
|
$(status: $status,)?
|
||||||
$(shell: $shell,)?
|
$(shell: $shell,)?
|
||||||
|
env,
|
||||||
..Test::default()
|
..Test::default()
|
||||||
}.run();
|
}.run();
|
||||||
}
|
}
|
||||||
@ -41,6 +51,7 @@ macro_rules! test {
|
|||||||
struct Test<'a> {
|
struct Test<'a> {
|
||||||
justfile: &'a str,
|
justfile: &'a str,
|
||||||
args: &'a [&'a str],
|
args: &'a [&'a str],
|
||||||
|
env: BTreeMap<String, String>,
|
||||||
stdin: &'a str,
|
stdin: &'a str,
|
||||||
stdout: &'a str,
|
stdout: &'a str,
|
||||||
stderr: &'a str,
|
stderr: &'a str,
|
||||||
@ -53,6 +64,7 @@ impl<'a> Default for Test<'a> {
|
|||||||
Test {
|
Test {
|
||||||
justfile: "",
|
justfile: "",
|
||||||
args: &[],
|
args: &[],
|
||||||
|
env: BTreeMap::new(),
|
||||||
stdin: "",
|
stdin: "",
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "",
|
stderr: "",
|
||||||
@ -86,6 +98,7 @@ impl<'a> Test<'a> {
|
|||||||
|
|
||||||
let mut child = command
|
let mut child = command
|
||||||
.args(self.args)
|
.args(self.args)
|
||||||
|
.envs(self.env)
|
||||||
.current_dir(tmp.path())
|
.current_dir(tmp.path())
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
@ -2070,6 +2083,18 @@ echo:
|
|||||||
stderr: "echo 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! {
|
test! {
|
||||||
name: invalid_escape_sequence_message,
|
name: invalid_escape_sequence_message,
|
||||||
justfile: r#"
|
justfile: r#"
|
||||||
|
Loading…
Reference in New Issue
Block a user