Use standard paths for a possible config location
Check several possible standard paths when there is no path to the configuration file given as argument. To find the configuration file following paths are used. The local directory `./config.toml`, the user global configuration directory `$XDG_CONFIG_HOME/whakarite/config.toml` and the system wide configuration directory `/etc/whakarite/config.toml`. Note that in the later two cases the directory which contains the `config.toml` receives its name from the `$CARGO_BIN_NAME` environment variable at compile time.
This commit is contained in:
parent
21396daf83
commit
0434505b2d
5 changed files with 124 additions and 9 deletions
79
Cargo.lock
generated
79
Cargo.lock
generated
|
@ -124,6 +124,26 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"redox_users",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "email-encoding"
|
name = "email-encoding"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -218,6 +238,17 @@ dependencies = [
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
|
@ -632,6 +663,17 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"redox_syscall",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "remove_dir_all"
|
name = "remove_dir_all"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
|
@ -805,6 +847,26 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.38"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.38"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thread_local"
|
name = "thread_local"
|
||||||
version = "1.1.4"
|
version = "1.1.4"
|
||||||
|
@ -987,6 +1049,12 @@ version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "whakarite"
|
name = "whakarite"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -995,12 +1063,12 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"diesel",
|
"diesel",
|
||||||
"lettre",
|
"lettre",
|
||||||
"log",
|
|
||||||
"serde",
|
"serde",
|
||||||
"time",
|
"time",
|
||||||
"toml",
|
"toml",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
|
"xdg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1090,3 +1158,12 @@ name = "windows_x86_64_msvc"
|
||||||
version = "0.42.1"
|
version = "0.42.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xdg"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c4583db5cbd4c4c0303df2d15af80f0539db703fa1c68802d4cbbd2dd0f88f6"
|
||||||
|
dependencies = [
|
||||||
|
"dirs",
|
||||||
|
]
|
||||||
|
|
|
@ -11,7 +11,6 @@ categories = ["utility"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
log = "0.4"
|
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = "0.3"
|
tracing-subscriber = "0.3"
|
||||||
time = "0.3"
|
time = "0.3"
|
||||||
|
@ -20,3 +19,4 @@ diesel = { version = "2", features = ["postgres", "r2d2", "time"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
toml = "0.6"
|
toml = "0.6"
|
||||||
clap = { version = "4", features = ["derive"] }
|
clap = { version = "4", features = ["derive"] }
|
||||||
|
xdg = "2"
|
||||||
|
|
|
@ -7,7 +7,7 @@ use tracing::Level;
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
/// Use a custom config file
|
/// Use a custom config file
|
||||||
#[arg(short, long, value_name = "FILE")]
|
#[arg(short, long, value_name = "FILE")]
|
||||||
config: Option<PathBuf>,
|
pub config: Option<PathBuf>,
|
||||||
|
|
||||||
/// Set a log level
|
/// Set a log level
|
||||||
#[arg(short, long, value_name = "LEVEL", default_value_t = Level::INFO)]
|
#[arg(short, long, value_name = "LEVEL", default_value_t = Level::INFO)]
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
use anyhow::{bail, Result};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use std::{env, fs, path::PathBuf};
|
||||||
|
use tracing::{error, info, trace};
|
||||||
|
|
||||||
fn default_host() -> String {
|
fn default_host() -> String {
|
||||||
"localhost".to_string()
|
"localhost".to_string()
|
||||||
|
@ -45,3 +48,43 @@ pub struct Config {
|
||||||
/// Database configuration
|
/// Database configuration
|
||||||
pub database: Database,
|
pub database: Database,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
fn try_paths() -> Result<(PathBuf, String)> {
|
||||||
|
let file = "config.toml";
|
||||||
|
info!(?file, "loading configuration");
|
||||||
|
if let Ok(config) = fs::read_to_string(&file) {
|
||||||
|
return Ok((file.into(), config));
|
||||||
|
}
|
||||||
|
|
||||||
|
let user_file =
|
||||||
|
xdg::BaseDirectories::with_prefix(env!("CARGO_BIN_NAME"))?.get_config_file(file);
|
||||||
|
info!(file = ?user_file, "loading configuration");
|
||||||
|
if let Ok(config) = fs::read_to_string(&user_file) {
|
||||||
|
return Ok((user_file, config));
|
||||||
|
}
|
||||||
|
|
||||||
|
let global_file = format!("/etc/{}/{}", env!("CARGO_BIN_NAME"), file);
|
||||||
|
info!(file = ?global_file, "loading configuration");
|
||||||
|
if let Ok(config) = fs::read_to_string(&global_file) {
|
||||||
|
return Ok((global_file.into(), config));
|
||||||
|
}
|
||||||
|
|
||||||
|
error!("no configuration file found");
|
||||||
|
bail!("no configuration file found");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_config(file: Option<PathBuf>) -> Result<Self> {
|
||||||
|
if let Some(file) = file {
|
||||||
|
info!(?file, "loading configuration");
|
||||||
|
let config: Config = toml::from_str(&fs::read_to_string(&file)?)?;
|
||||||
|
trace!(?file, ?config, "loaded configuration");
|
||||||
|
Ok(config)
|
||||||
|
} else {
|
||||||
|
let (file, config) = Self::try_paths()?;
|
||||||
|
let config = toml::from_str(&config)?;
|
||||||
|
trace!(?file, ?config, "loaded configuration");
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -71,12 +71,7 @@ fn main() -> Result<()> {
|
||||||
env!("CARGO_PKG_VERSION")
|
env!("CARGO_PKG_VERSION")
|
||||||
);
|
);
|
||||||
|
|
||||||
let config_path = "./config.toml";
|
let config = Config::load_config(args.config)?;
|
||||||
|
|
||||||
let config: Config = toml::from_str(&std::fs::read_to_string(config_path)?)?;
|
|
||||||
|
|
||||||
trace!(?config, config_path, "loaded config");
|
|
||||||
|
|
||||||
let db_pool = Pool::builder().build(ConnectionManager::<PgConnection>::new(format!(
|
let db_pool = Pool::builder().build(ConnectionManager::<PgConnection>::new(format!(
|
||||||
"postgresql://{}:{}@{}:{}/{}",
|
"postgresql://{}:{}@{}:{}/{}",
|
||||||
config.database.user,
|
config.database.user,
|
||||||
|
|
Loading…
Reference in a new issue