Skip to content

Commit

Permalink
Accept multiple .env files in --env-file (#8463)
Browse files Browse the repository at this point in the history
Closes #8457.
  • Loading branch information
charliermarsh authored and zanieb committed Oct 24, 2024
1 parent c00e6e6 commit 703ad66
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 115 deletions.
7 changes: 5 additions & 2 deletions crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2633,9 +2633,12 @@ pub struct RunArgs {

/// Load environment variables from a `.env` file.
///
/// Can be provided multiple times, with subsequent files overriding values defined in
/// previous files.
///
/// Defaults to reading `.env` in the current working directory.
#[arg(long, value_parser = parse_file_path, env = EnvVars::UV_ENV_FILE)]
pub env_file: Option<PathBuf>,
#[arg(long, env = EnvVars::UV_ENV_FILE)]
pub env_file: Vec<PathBuf>,

/// Avoid reading environment variables from a `.env` file.
#[arg(long, conflicts_with = "env_file", value_parser = clap::builder::BoolishValueParser::new(), env = EnvVars::UV_NO_ENV_FILE)]
Expand Down
86 changes: 46 additions & 40 deletions crates/uv/src/commands/project/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::path::{Path, PathBuf};
use anstream::eprint;
use anyhow::{anyhow, bail, Context};
use futures::StreamExt;
use itertools::Itertools;
use itertools::{Either, Itertools};
use owo_colors::OwoColorize;
use tokio::process::Command;
use tracing::{debug, warn};
Expand Down Expand Up @@ -79,7 +79,7 @@ pub(crate) async fn run(
native_tls: bool,
cache: &Cache,
printer: Printer,
env_file: Option<PathBuf>,
env_file: Vec<PathBuf>,
no_env_file: bool,
) -> anyhow::Result<ExitStatus> {
// These cases seem quite complex because (in theory) they should change the "current package".
Expand Down Expand Up @@ -109,52 +109,58 @@ pub(crate) async fn run(

// Read from the `.env` file, if necessary.
if !no_env_file {
let env_file_path = env_file.as_deref().unwrap_or_else(|| Path::new(".env"));
match dotenvy::from_path(env_file_path) {
Err(dotenvy::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => {
if env_file.is_none() {
debug!(
"No environment file found at: `{}`",
env_file_path.simplified_display()
let env_file_paths = if env_file.is_empty() {
Either::Left(std::iter::once(Path::new(".env")))
} else {
Either::Right(env_file.iter().rev().map(PathBuf::as_path))
};
for env_file_path in env_file_paths {
match dotenvy::from_path(env_file_path) {
Err(dotenvy::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => {
if env_file.is_empty() {
debug!(
"No environment file found at: `{}`",
env_file_path.simplified_display()
);
} else {
bail!(
"No environment file found at: `{}`",
env_file_path.simplified_display()
);
}
}
Err(dotenvy::Error::Io(err)) => {
if env_file.is_empty() {
debug!(
"Failed to read environment file `{}`: {err}",
env_file_path.simplified_display()
);
} else {
bail!(
"Failed to read environment file `{}`: {err}",
env_file_path.simplified_display()
);
}
}
Err(dotenvy::Error::LineParse(content, position)) => {
warn_user!(
"Failed to parse environment file `{}` at position {position}: {content}",
env_file_path.simplified_display(),
);
} else {
bail!(
"No environment file found at: `{}`",
env_file_path.simplified_display()
}
Err(err) => {
warn_user!(
"Failed to parse environment file `{}`: {err}",
env_file_path.simplified_display(),
);
}
}
Err(dotenvy::Error::Io(err)) => {
if env_file.is_none() {
Ok(()) => {
debug!(
"Failed to read environment file `{}`: {err}",
env_file_path.simplified_display()
);
} else {
bail!(
"Failed to read environment file `{}`: {err}",
"Read environment file at: `{}`",
env_file_path.simplified_display()
);
}
}
Err(dotenvy::Error::LineParse(content, position)) => {
warn_user!(
"Failed to parse environment file `{}` at position {position}: {content}",
env_file_path.simplified_display(),
);
}
Err(err) => {
warn_user!(
"Failed to parse environment file `{}`: {err}",
env_file_path.simplified_display(),
);
}
Ok(()) => {
debug!(
"Read environment file at: `{}`",
env_file_path.simplified_display()
);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/uv/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ pub(crate) struct RunSettings {
pub(crate) python: Option<String>,
pub(crate) refresh: Refresh,
pub(crate) settings: ResolverInstallerSettings,
pub(crate) env_file: Option<PathBuf>,
pub(crate) env_file: Vec<PathBuf>,
pub(crate) no_env_file: bool,
}

Expand Down
Loading

0 comments on commit 703ad66

Please sign in to comment.