@@ -74,6 +74,7 @@ struct Metadata {
7474 manifest_dir : PathBuf ,
7575 offline : bool ,
7676 database_url : Option < String > ,
77+ offline_dir : Option < String > ,
7778 workspace_root : Arc < Mutex < Option < PathBuf > > > ,
7879}
7980
@@ -114,39 +115,21 @@ static METADATA: Lazy<Mutex<HashMap<String, Metadata>>> = Lazy::new(Default::def
114115fn init_metadata ( manifest_dir : & String ) -> Metadata {
115116 let manifest_dir: PathBuf = manifest_dir. into ( ) ;
116117
117- // If a .env file exists at CARGO_MANIFEST_DIR, load environment variables from this,
118- // otherwise fallback to default dotenv behaviour.
119- let env_path = manifest_dir. join ( ".env" ) ;
120-
121- #[ cfg_attr( not( procmacro2_semver_exempt) , allow( unused_variables) ) ]
122- let env_path = if env_path. exists ( ) {
123- // Load the new environment variables and override the old ones if necessary.
124- let res = dotenvy:: from_path_override ( & env_path) ;
125- if let Err ( e) = res {
126- panic ! ( "failed to load environment from {env_path:?}, {e}" ) ;
127- }
128-
129- Some ( env_path)
130- } else {
131- dotenvy:: dotenv_override ( ) . ok ( )
132- } ;
133-
134- // tell the compiler to watch the `.env` for changes, if applicable
135- #[ cfg( procmacro2_semver_exempt) ]
136- if let Some ( env_path) = env_path. as_ref ( ) . and_then ( |path| path. to_str ( ) ) {
137- proc_macro:: tracked_path:: path ( env_path) ;
138- }
118+ let ( database_url, offline, offline_dir) = load_dot_env ( & manifest_dir) ;
139119
140120 let offline = env ( "SQLX_OFFLINE" )
121+ . ok ( )
122+ . or ( offline)
141123 . map ( |s| s. eq_ignore_ascii_case ( "true" ) || s == "1" )
142124 . unwrap_or ( false ) ;
143125
144- let database_url = env ( "DATABASE_URL" ) . ok ( ) ;
126+ let database_url = env ( "DATABASE_URL" ) . ok ( ) . or ( database_url ) ;
145127
146128 Metadata {
147129 manifest_dir,
148130 offline,
149131 database_url,
132+ offline_dir,
150133 workspace_root : Arc :: new ( Mutex :: new ( None ) ) ,
151134 }
152135}
@@ -182,7 +165,7 @@ pub fn expand_input<'a>(
182165
183166 // Check SQLX_OFFLINE_DIR, then local .sqlx, then workspace .sqlx.
184167 let dirs = [
185- |_ : & Metadata | env ( "SQLX_OFFLINE_DIR" ) . ok ( ) . map ( PathBuf :: from) ,
168+ |meta : & Metadata | meta . offline_dir . as_deref ( ) . map ( PathBuf :: from) ,
186169 |meta : & Metadata | Some ( meta. manifest_dir . join ( ".sqlx" ) ) ,
187170 |meta : & Metadata | Some ( meta. workspace_root ( ) . join ( ".sqlx" ) ) ,
188171 ] ;
@@ -402,3 +385,52 @@ fn env(name: &str) -> Result<String, std::env::VarError> {
402385 std:: env:: var ( name)
403386 }
404387}
388+
389+ /// Get `DATABASE_URL`, `SQLX_OFFLINE` and `SQLX_OFFLINE_DIR` from the `.env`.
390+ fn load_dot_env ( manifest_dir : & PathBuf ) -> ( Option < String > , Option < String > , Option < String > ) {
391+ let mut env_path = manifest_dir. join ( ".env" ) ;
392+
393+ // If a .env file exists at CARGO_MANIFEST_DIR, load environment variables from this,
394+ // otherwise fallback to default dotenv file.
395+ #[ cfg_attr( not( procmacro2_semver_exempt) , allow( unused_variables) ) ]
396+ let env_file = if env_path. exists ( ) {
397+ let res = dotenvy:: from_path_iter ( & env_path) ;
398+ match res {
399+ Ok ( iter) => Some ( iter) ,
400+ Err ( e) => panic ! ( "failed to load environment from {env_path:?}, {e}" ) ,
401+ }
402+ } else {
403+ #[ allow( unused_assignments) ]
404+ {
405+ env_path = PathBuf :: from ( ".env" ) ;
406+ }
407+ dotenvy:: dotenv_iter ( ) . ok ( )
408+ } ;
409+
410+ let mut offline = None ;
411+ let mut database_url = None ;
412+ let mut offline_dir = None ;
413+
414+ if let Some ( env_file) = env_file {
415+ // tell the compiler to watch the `.env` for changes.
416+ #[ cfg( procmacro2_semver_exempt) ]
417+ if let Some ( env_path) = env_path. to_str ( ) {
418+ proc_macro:: tracked_path:: path ( env_path) ;
419+ }
420+
421+ for item in env_file {
422+ let Ok ( ( key, value) ) = item else {
423+ continue ;
424+ } ;
425+
426+ match key. as_str ( ) {
427+ "DATABASE_URL" => database_url = Some ( value) ,
428+ "SQLX_OFFLINE" => offline = Some ( value) ,
429+ "SQLX_OFFLINE_DIR" => offline_dir = Some ( value) ,
430+ _ => { }
431+ } ;
432+ }
433+ }
434+
435+ ( database_url, offline, offline_dir)
436+ }
0 commit comments