mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-29 21:00:54 +00:00
fix(macros): don't mutate environment variables (#3848)
This commit is contained in:
parent
4259862adf
commit
760b3953ba
@ -1,5 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{fs, io};
|
||||
|
||||
@ -74,6 +74,7 @@ struct Metadata {
|
||||
manifest_dir: PathBuf,
|
||||
offline: bool,
|
||||
database_url: Option<String>,
|
||||
offline_dir: Option<String>,
|
||||
workspace_root: Arc<Mutex<Option<PathBuf>>>,
|
||||
}
|
||||
|
||||
@ -114,39 +115,21 @@ static METADATA: Lazy<Mutex<HashMap<String, Metadata>>> = Lazy::new(Default::def
|
||||
fn init_metadata(manifest_dir: &String) -> Metadata {
|
||||
let manifest_dir: PathBuf = manifest_dir.into();
|
||||
|
||||
// If a .env file exists at CARGO_MANIFEST_DIR, load environment variables from this,
|
||||
// otherwise fallback to default dotenv behaviour.
|
||||
let env_path = manifest_dir.join(".env");
|
||||
|
||||
#[cfg_attr(not(procmacro2_semver_exempt), allow(unused_variables))]
|
||||
let env_path = if env_path.exists() {
|
||||
// Load the new environment variables and override the old ones if necessary.
|
||||
let res = dotenvy::from_path_override(&env_path);
|
||||
if let Err(e) = res {
|
||||
panic!("failed to load environment from {env_path:?}, {e}");
|
||||
}
|
||||
|
||||
Some(env_path)
|
||||
} else {
|
||||
dotenvy::dotenv_override().ok()
|
||||
};
|
||||
|
||||
// tell the compiler to watch the `.env` for changes, if applicable
|
||||
#[cfg(procmacro2_semver_exempt)]
|
||||
if let Some(env_path) = env_path.as_ref().and_then(|path| path.to_str()) {
|
||||
proc_macro::tracked_path::path(env_path);
|
||||
}
|
||||
let (database_url, offline, offline_dir) = load_dot_env(&manifest_dir);
|
||||
|
||||
let offline = env("SQLX_OFFLINE")
|
||||
.ok()
|
||||
.or(offline)
|
||||
.map(|s| s.eq_ignore_ascii_case("true") || s == "1")
|
||||
.unwrap_or(false);
|
||||
|
||||
let database_url = env("DATABASE_URL").ok();
|
||||
let database_url = env("DATABASE_URL").ok().or(database_url);
|
||||
|
||||
Metadata {
|
||||
manifest_dir,
|
||||
offline,
|
||||
database_url,
|
||||
offline_dir,
|
||||
workspace_root: Arc::new(Mutex::new(None)),
|
||||
}
|
||||
}
|
||||
@ -182,7 +165,7 @@ pub fn expand_input<'a>(
|
||||
|
||||
// Check SQLX_OFFLINE_DIR, then local .sqlx, then workspace .sqlx.
|
||||
let dirs = [
|
||||
|_: &Metadata| env("SQLX_OFFLINE_DIR").ok().map(PathBuf::from),
|
||||
|meta: &Metadata| meta.offline_dir.as_deref().map(PathBuf::from),
|
||||
|meta: &Metadata| Some(meta.manifest_dir.join(".sqlx")),
|
||||
|meta: &Metadata| Some(meta.workspace_root().join(".sqlx")),
|
||||
];
|
||||
@ -402,3 +385,52 @@ fn env(name: &str) -> Result<String, std::env::VarError> {
|
||||
std::env::var(name)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get `DATABASE_URL`, `SQLX_OFFLINE` and `SQLX_OFFLINE_DIR` from the `.env`.
|
||||
fn load_dot_env(manifest_dir: &Path) -> (Option<String>, Option<String>, Option<String>) {
|
||||
let mut env_path = manifest_dir.join(".env");
|
||||
|
||||
// If a .env file exists at CARGO_MANIFEST_DIR, load environment variables from this,
|
||||
// otherwise fallback to default dotenv file.
|
||||
#[cfg_attr(not(procmacro2_semver_exempt), allow(unused_variables))]
|
||||
let env_file = if env_path.exists() {
|
||||
let res = dotenvy::from_path_iter(&env_path);
|
||||
match res {
|
||||
Ok(iter) => Some(iter),
|
||||
Err(e) => panic!("failed to load environment from {env_path:?}, {e}"),
|
||||
}
|
||||
} else {
|
||||
#[allow(unused_assignments)]
|
||||
{
|
||||
env_path = PathBuf::from(".env");
|
||||
}
|
||||
dotenvy::dotenv_iter().ok()
|
||||
};
|
||||
|
||||
let mut offline = None;
|
||||
let mut database_url = None;
|
||||
let mut offline_dir = None;
|
||||
|
||||
if let Some(env_file) = env_file {
|
||||
// tell the compiler to watch the `.env` for changes.
|
||||
#[cfg(procmacro2_semver_exempt)]
|
||||
if let Some(env_path) = env_path.to_str() {
|
||||
proc_macro::tracked_path::path(env_path);
|
||||
}
|
||||
|
||||
for item in env_file {
|
||||
let Ok((key, value)) = item else {
|
||||
continue;
|
||||
};
|
||||
|
||||
match key.as_str() {
|
||||
"DATABASE_URL" => database_url = Some(value),
|
||||
"SQLX_OFFLINE" => offline = Some(value),
|
||||
"SQLX_OFFLINE_DIR" => offline_dir = Some(value),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
(database_url, offline, offline_dir)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user