feat: support user preview configuration and document UI
This commit is contained in:
51
rust/main.rs
51
rust/main.rs
@@ -7,7 +7,7 @@ use std::{
|
||||
fs::{self, OpenOptions},
|
||||
io,
|
||||
os::unix::fs::{MetadataExt, OpenOptionsExt},
|
||||
path::PathBuf,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use clap::Parser;
|
||||
@@ -34,8 +34,8 @@ const BUILD_TIME: &str = env!("LATCHD_BUILD_TIME");
|
||||
)]
|
||||
struct Cli {
|
||||
/// Configuration TOML path.
|
||||
#[arg(short, long, default_value = "/etc/latchd/config.toml")]
|
||||
config: PathBuf,
|
||||
#[arg(short, long)]
|
||||
config: Option<PathBuf>,
|
||||
/// Optional variable TOML path.
|
||||
#[arg(short = 'v', long)]
|
||||
variables: Option<PathBuf>,
|
||||
@@ -79,17 +79,7 @@ fn run() -> Result<(), Error> {
|
||||
println!("version={BUILD_VERSION}\ncommit={BUILD_COMMIT}\nepoch={BUILD_TIME}");
|
||||
return Ok(());
|
||||
}
|
||||
let config_path = if cli.config.exists() {
|
||||
Some(cli.config.as_path())
|
||||
} else {
|
||||
if cli.config.as_os_str() != "/etc/latchd/config.toml" {
|
||||
return Err(Error::Config(format!(
|
||||
"configuration does not exist: {}",
|
||||
cli.config.display()
|
||||
)));
|
||||
}
|
||||
None
|
||||
};
|
||||
let config_path = resolve_config_path(cli.config.as_deref(), cli.preview)?;
|
||||
if let Some(path) = cli.variables.as_deref() {
|
||||
if !path.exists() {
|
||||
return Err(Error::Config(format!(
|
||||
@@ -100,7 +90,7 @@ fn run() -> Result<(), Error> {
|
||||
}
|
||||
let variables_path = cli.variables.as_deref();
|
||||
if !cli.preview {
|
||||
if let Some(path) = config_path {
|
||||
if let Some(path) = config_path.as_deref() {
|
||||
config::validate_source(path, "configuration")?;
|
||||
}
|
||||
if let Some(path) = variables_path {
|
||||
@@ -109,7 +99,7 @@ fn run() -> Result<(), Error> {
|
||||
}
|
||||
let mut config = Config::default();
|
||||
if config_path.is_some() || variables_path.is_some() {
|
||||
config = config::load(config_path, variables_path)?;
|
||||
config = config::load(config_path.as_deref(), variables_path)?;
|
||||
}
|
||||
if let Some(tty) = cli.tty {
|
||||
if tty == 0 {
|
||||
@@ -148,7 +138,7 @@ fn run() -> Result<(), Error> {
|
||||
"already inside a session; use --preview".into(),
|
||||
));
|
||||
}
|
||||
if unsafe { libc::geteuid() } != 0 {
|
||||
if !running_as_root() {
|
||||
return Err(Error::Config("latchd must run as root".into()));
|
||||
}
|
||||
validate_terminal()?;
|
||||
@@ -212,6 +202,33 @@ fn run() -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn resolve_config_path(explicit: Option<&Path>, preview: bool) -> Result<Option<PathBuf>, Error> {
|
||||
if let Some(path) = explicit {
|
||||
if path.exists() {
|
||||
return Ok(Some(path.to_owned()));
|
||||
}
|
||||
return Err(Error::Config(format!(
|
||||
"configuration does not exist: {}",
|
||||
path.display()
|
||||
)));
|
||||
}
|
||||
|
||||
let system_path = Path::new(config::SYSTEM_CONFIG_PATH);
|
||||
if !preview {
|
||||
return Ok(system_path.exists().then(|| system_path.to_owned()));
|
||||
}
|
||||
|
||||
if let Some(path) = config::user_config_path().filter(|path| path.exists()) {
|
||||
return Ok(Some(path));
|
||||
}
|
||||
Ok(system_path.exists().then(|| system_path.to_owned()))
|
||||
}
|
||||
|
||||
fn running_as_root() -> bool {
|
||||
// SAFETY: `geteuid` has no pointer arguments or memory preconditions.
|
||||
unsafe { libc::geteuid() == 0 }
|
||||
}
|
||||
|
||||
fn setup_logging(path: &std::path::Path) -> Result<(), Error> {
|
||||
const MAX_LOG_BYTES: u64 = 64 * 1024 * 1024;
|
||||
let parent = path
|
||||
|
||||
Reference in New Issue
Block a user