2020-10-05 07:41:58 +00:00
use std ::path ::PathBuf ;
2021-06-15 01:42:50 +00:00
use tracing ::warn ;
2020-10-05 07:41:58 +00:00
2020-10-05 08:56:28 +00:00
const VELOREN_USERDATA_ENV : & str = " VELOREN_USERDATA " ;
2020-10-05 07:41:58 +00:00
2020-10-05 08:56:28 +00:00
// TODO: consider expanding this to a general install strategy variable that is
// also used for finding assets
2021-04-13 22:05:47 +00:00
// TODO: Ensure there are no NUL (\0) characters in userdata_dir (possible on
// MacOS but not Windows or Linux) as SQLite requires the database path does not
// include this character.
2020-10-05 07:41:58 +00:00
/// # `VELOREN_USERDATA_STRATEGY` environment variable
/// Read during compilation
/// Useful to set when compiling for distribution
/// "system" => system specific project data directory
/// "executable" => <executable dir>/userdata
/// Note: case insensitive
/// Determines common user data directory used by veloren frontends
/// The first specified in this list is used
/// 1. The VELOREN_USERDATA environment variable
/// 2. The VELOREN_USERDATA_STRATEGY environment variable
2020-10-05 08:56:28 +00:00
/// 3. The CARGO_MANIFEST_DIR/userdata or CARGO_MANIFEST_DIR/../userdata
/// depending on if a workspace if being used
2020-10-05 07:41:58 +00:00
pub fn userdata_dir ( workspace : bool , strategy : Option < & str > , manifest_dir : & str ) -> PathBuf {
// 1. The VELOREN_USERDATA environment variable
std ::env ::var_os ( VELOREN_USERDATA_ENV )
. map ( PathBuf ::from )
// 2. The VELOREN_USERDATA_STRATEGY environment variable
. or_else ( | | match strategy {
// "system" => system specific project data directory
2020-10-13 06:29:32 +00:00
Some ( s ) if s . eq_ignore_ascii_case ( " system " ) = > Some ( directories_next ::ProjectDirs ::from ( " net " , " veloren " , " veloren " )
2020-10-05 07:41:58 +00:00
. expect ( " System's $HOME directory path not found! " )
. data_dir ( )
2020-10-13 06:29:32 +00:00
. join ( " userdata " )
2020-10-05 07:41:58 +00:00
) ,
// "executable" => <executable dir>/userdata
Some ( s ) if s . eq_ignore_ascii_case ( " executable " ) = > {
let mut path = std ::env ::current_exe ( )
2020-10-13 06:29:32 +00:00
. expect ( " Failed to retrieve executable path! " ) ;
2020-10-05 07:41:58 +00:00
path . pop ( ) ;
path . push ( " userdata " ) ;
Some ( path )
} ,
Some ( _ ) = > None , // TODO: panic? catch during compilation?
_ = > None ,
} )
// 3. The CARGO_MANIFEST_DIR/userdata or CARGO_MANIFEST_DIR/../userdata depending on if a
// workspace if being used
2020-10-05 08:56:28 +00:00
. unwrap_or_else ( | | {
2020-10-05 07:41:58 +00:00
let mut path = PathBuf ::from ( manifest_dir ) ;
if workspace {
path . pop ( ) ;
}
2020-10-13 06:29:32 +00:00
let exe_path = std ::env ::current_exe ( )
. expect ( " Failed to retrieve executable path! " ) ;
2021-06-15 01:42:50 +00:00
// If this path exists
// and the binary path is prefixed by this path
// put the userdata folder there
if path . exists ( ) & & exe_path . starts_with ( & path ) {
path . push ( " userdata " ) ;
path
} else {
// otherwise warn and fallback to the executable strategy
warn! ( " This binary was moved to outside the project folder where it was compiled and was not compiled with VELOREN_USERDATA_STRATEGY set to \" system \" or \" executable \" . Falling back the to the \" executable \" strategy (the userdata folder will be placed in the same folder as the executable) " ) ;
let mut path = exe_path ;
path . pop ( ) ;
path . push ( " userdata " ) ;
path
2020-10-13 06:29:32 +00:00
}
2020-10-05 07:41:58 +00:00
} )
}
#[ macro_export ]
macro_rules ! userdata_dir_workspace {
( ) = > {
2021-03-08 22:40:02 +00:00
$crate ::userdata_dir ::userdata_dir (
2020-10-05 07:41:58 +00:00
true ,
2020-10-05 08:56:28 +00:00
option_env! ( " VELOREN_USERDATA_STRATEGY " ) ,
env! ( " CARGO_MANIFEST_DIR " ) ,
2020-10-05 07:41:58 +00:00
)
} ;
}
#[ macro_export ]
macro_rules ! userdata_dir_no_workspace {
( ) = > {
2021-03-08 22:40:02 +00:00
$crate ::userdata_dir ::userdata_dir (
2020-10-05 07:41:58 +00:00
false ,
2020-10-05 08:56:28 +00:00
option_env! ( " VELOREN_USERDATA_STRATEGY " ) ,
env! ( " CARGO_MANIFEST_DIR " ) ,
2020-10-05 07:41:58 +00:00
)
} ;
2020-10-05 08:56:28 +00:00
}