veloren/common/base/src/userdata_dir.rs
Ben Wallis 1de94a9979 * Replaced diesel with rusqlite and refinery
* Added "migration of migrations" to transfer the data from the __diesel_schema_migrations table to the refinery_schema_history table
* Removed all down migrations as refinery does not support down migrations
* Changed all diesel up migrations to refinery naming format
* Added --sql-log-mode parameter to veloren-server-cli to allow SQL tracing and profiling
* Added /disconnect_all_players admin command
* Added disconnectall CLI command
* Fixes for several potential persistence-related race conditions
2021-04-13 22:05:47 +00:00

87 lines
3.3 KiB
Rust

use std::path::PathBuf;
const VELOREN_USERDATA_ENV: &str = "VELOREN_USERDATA";
// TODO: consider expanding this to a general install strategy variable that is
// also used for finding assets
// 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.
/// # `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
/// 3. The CARGO_MANIFEST_DIR/userdata or CARGO_MANIFEST_DIR/../userdata
/// depending on if a workspace if being used
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
Some(s) if s.eq_ignore_ascii_case("system") => Some(directories_next::ProjectDirs::from("net", "veloren", "veloren")
.expect("System's $HOME directory path not found!")
.data_dir()
.join("userdata")
),
// "executable" => <executable dir>/userdata
Some(s) if s.eq_ignore_ascii_case("executable") => {
let mut path = std::env::current_exe()
.expect("Failed to retrieve executable path!");
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
.unwrap_or_else(|| {
let mut path = PathBuf::from(manifest_dir);
if workspace {
path.pop();
}
let exe_path = std::env::current_exe()
.expect("Failed to retrieve executable path!");
// Ensure this path exists
// Ensure that the binary path is prefixed by this path
if !path.exists() || !exe_path.starts_with(&path) {
panic!("Recompile with VELOREN_USERDATA_STRATEGY set to \"system\" or \"executable\" to run the binary outside of the project folder");
}
path.push("userdata");
path
})
}
#[macro_export]
macro_rules! userdata_dir_workspace {
() => {
$crate::userdata_dir::userdata_dir(
true,
option_env!("VELOREN_USERDATA_STRATEGY"),
env!("CARGO_MANIFEST_DIR"),
)
};
}
#[macro_export]
macro_rules! userdata_dir_no_workspace {
() => {
$crate::userdata_dir::userdata_dir(
false,
option_env!("VELOREN_USERDATA_STRATEGY"),
env!("CARGO_MANIFEST_DIR"),
)
};
}