mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-17 15:51:23 +01:00
follow xdg base dirs spec by default
This commit is contained in:
parent
c46eaed0e0
commit
85e77832e9
6 changed files with 69 additions and 7 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -876,6 +876,7 @@ dependencies = [
|
||||||
"tracing-opentelemetry",
|
"tracing-opentelemetry",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"trust-dns-resolver",
|
"trust-dns-resolver",
|
||||||
|
"xdg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3660,6 +3661,12 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xdg"
|
||||||
|
version = "2.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yap"
|
name = "yap"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,7 @@ tracing-flame = "0.2.0"
|
||||||
tracing-opentelemetry = "0.24.0"
|
tracing-opentelemetry = "0.24.0"
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||||
trust-dns-resolver = "0.23.2"
|
trust-dns-resolver = "0.23.2"
|
||||||
|
xdg = "2.5.2"
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
nix = { version = "0.29", features = ["resource"] }
|
nix = { version = "0.29", features = ["resource"] }
|
||||||
|
|
|
||||||
22
src/args.rs
22
src/args.rs
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::{CommandFactory as _, FromArgMatches as _, Parser};
|
||||||
|
|
||||||
/// Command line arguments
|
/// Command line arguments
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
|
|
@ -10,10 +10,26 @@ use clap::Parser;
|
||||||
pub(crate) struct Args {
|
pub(crate) struct Args {
|
||||||
/// Path to the configuration file
|
/// Path to the configuration file
|
||||||
#[clap(long, short)]
|
#[clap(long, short)]
|
||||||
pub(crate) config: PathBuf,
|
pub(crate) config: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse command line arguments into structured data
|
/// Parse command line arguments into structured data
|
||||||
pub(crate) fn parse() -> Args {
|
pub(crate) fn parse() -> Args {
|
||||||
Args::parse()
|
let mut command = Args::command().mut_arg("config", |x| {
|
||||||
|
let help = "Set the path to the configuration file";
|
||||||
|
x.help(help).long_help(format!(
|
||||||
|
"{}\n\nIf this option is specified, the provided value is used \
|
||||||
|
as-is.\n\nIf this option is not specified, then the XDG Base \
|
||||||
|
Directory Specification is followed, searching for the path `{}` \
|
||||||
|
in the configuration directories.
|
||||||
|
",
|
||||||
|
help,
|
||||||
|
crate::config::DEFAULT_PATH.display(),
|
||||||
|
))
|
||||||
|
});
|
||||||
|
|
||||||
|
match Args::from_arg_matches(&command.get_matches_mut()) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(e) => e.format(&mut command).exit(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
use std::{
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
net::{IpAddr, Ipv4Addr},
|
net::{IpAddr, Ipv4Addr},
|
||||||
path::Path,
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use ruma::{OwnedServerName, RoomVersionId};
|
use ruma::{OwnedServerName, RoomVersionId};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
|
@ -14,6 +16,10 @@ mod proxy;
|
||||||
use env_filter_clone::EnvFilterClone;
|
use env_filter_clone::EnvFilterClone;
|
||||||
use proxy::ProxyConfig;
|
use proxy::ProxyConfig;
|
||||||
|
|
||||||
|
/// The default configuration file path
|
||||||
|
pub(crate) static DEFAULT_PATH: Lazy<PathBuf> =
|
||||||
|
Lazy::new(|| [env!("CARGO_PKG_NAME"), "config.toml"].iter().collect());
|
||||||
|
|
||||||
#[allow(clippy::struct_excessive_bools)]
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub(crate) struct Config {
|
pub(crate) struct Config {
|
||||||
|
|
@ -163,13 +169,29 @@ pub(crate) fn default_default_room_version() -> RoomVersionId {
|
||||||
RoomVersionId::V10
|
RoomVersionId::V10
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load the configuration from the given path
|
/// Search default locations for a configuration file
|
||||||
pub(crate) async fn load<P>(path: P) -> Result<Config, error::Config>
|
///
|
||||||
|
/// If one isn't found, the list of tried paths is returned.
|
||||||
|
fn search() -> Result<PathBuf, error::ConfigSearch> {
|
||||||
|
use error::ConfigSearch as Error;
|
||||||
|
|
||||||
|
xdg::BaseDirectories::new()?
|
||||||
|
.find_config_file(&*DEFAULT_PATH)
|
||||||
|
.ok_or(Error::NotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load the configuration from the given path or XDG Base Directories
|
||||||
|
pub(crate) async fn load<P>(path: Option<P>) -> Result<Config, error::Config>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
use error::Config as Error;
|
use error::Config as Error;
|
||||||
|
|
||||||
|
let path = match path.as_ref().map(AsRef::as_ref) {
|
||||||
|
Some(x) => Cow::Borrowed(x),
|
||||||
|
None => Cow::Owned(search()?),
|
||||||
|
};
|
||||||
|
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
|
|
||||||
toml::from_str(
|
toml::from_str(
|
||||||
|
|
|
||||||
16
src/error.rs
16
src/error.rs
|
|
@ -75,9 +75,25 @@ pub(crate) enum Observability {
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub(crate) enum Config {
|
pub(crate) enum Config {
|
||||||
|
#[error("failed to find configuration file")]
|
||||||
|
Search(#[from] ConfigSearch),
|
||||||
|
|
||||||
#[error("failed to read configuration file {1:?}")]
|
#[error("failed to read configuration file {1:?}")]
|
||||||
Read(#[source] std::io::Error, PathBuf),
|
Read(#[source] std::io::Error, PathBuf),
|
||||||
|
|
||||||
#[error("failed to parse configuration file {1:?}")]
|
#[error("failed to parse configuration file {1:?}")]
|
||||||
Parse(#[source] toml::de::Error, PathBuf),
|
Parse(#[source] toml::de::Error, PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Errors that can occur while searching for a config file
|
||||||
|
// Missing docs are allowed here since that kind of information should be
|
||||||
|
// encoded in the error messages themselves anyway.
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub(crate) enum ConfigSearch {
|
||||||
|
#[error("XDG Base Directory error")]
|
||||||
|
Xdg(#[from] xdg::BaseDirectoriesError),
|
||||||
|
|
||||||
|
#[error("no relevant configuration files found in XDG Base Directories")]
|
||||||
|
NotFound,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ async fn try_main() -> Result<(), error::Main> {
|
||||||
|
|
||||||
let args = args::parse();
|
let args = args::parse();
|
||||||
|
|
||||||
let config = config::load(&args.config).await?;
|
let config = config::load(args.config.as_ref()).await?;
|
||||||
|
|
||||||
let _guard = observability::init(&config);
|
let _guard = observability::init(&config);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue