So far we have written a default config file if we encountered any error when trying to read the one that should exist. That included: * missing key-value-pairs, * empty file, and * a non-existant file. Therefore, when a field is added to the Config struct, the entire config file was overwritten with a default config. This occured during #20. Instead, we now provide default values in form of generator functions to serde. Any value that is present in the config is then parsed and replaces the default value. Only if the config file does not exist we create an empty one. Closes #26.
101 lines
3.0 KiB
Rust
101 lines
3.0 KiB
Rust
/*!
|
|
Main program for `pacdef`. All internal logic happens in [`pacdef_core`].
|
|
*/
|
|
|
|
#![warn(
|
|
clippy::as_conversions,
|
|
clippy::option_if_let_else,
|
|
clippy::redundant_pub_crate,
|
|
clippy::semicolon_if_nothing_returned,
|
|
clippy::unused_self,
|
|
clippy::unwrap_used,
|
|
clippy::use_debug,
|
|
clippy::use_self,
|
|
clippy::wildcard_dependencies,
|
|
missing_docs
|
|
)]
|
|
|
|
use std::path::Path;
|
|
use std::process::{ExitCode, Termination};
|
|
|
|
use anyhow::{bail, Context, Result};
|
|
|
|
use pacdef_core::path::{get_config_path, get_config_path_old_version, get_group_dir};
|
|
use pacdef_core::{get_args, Config, Error as PacdefError, Group, Pacdef};
|
|
|
|
const MAJOR_UPDATE_MESSAGE: &str = "VERSION UPGRADE
|
|
You seem to have used version 0.x of pacdef before.
|
|
Version 1.x changes the syntax of the config files and the command line arguments.
|
|
Check out https://github.com/steven-omaha/pacdef for new syntax information.
|
|
This message will not appear again.
|
|
------";
|
|
|
|
fn main() -> ExitCode {
|
|
handle_final_result(main_inner())
|
|
}
|
|
|
|
/// Skip printing the error chain when searching packages yields no results,
|
|
/// otherwise report error chain.
|
|
#[allow(clippy::option_if_let_else)]
|
|
fn handle_final_result(result: Result<()>) -> ExitCode {
|
|
match result {
|
|
Ok(_) => ExitCode::SUCCESS,
|
|
Err(ref e) => {
|
|
if let Some(root_error) = e.root_cause().downcast_ref::<PacdefError>() {
|
|
eprintln!("{root_error}");
|
|
ExitCode::FAILURE
|
|
} else {
|
|
result.report()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main_inner() -> Result<()> {
|
|
let args = get_args();
|
|
|
|
let config_file = get_config_path().context("getting config file")?;
|
|
|
|
let config = match Config::load(&config_file).context("loading config file") {
|
|
Ok(config) => config,
|
|
Err(e) => {
|
|
if let Some(crate_error) = e.downcast_ref::<PacdefError>() {
|
|
match crate_error {
|
|
PacdefError::ConfigFileNotFound => load_default_config(&config_file)?,
|
|
_ => bail!("unexpected error: {crate_error}"),
|
|
}
|
|
} else {
|
|
bail!("unexpected error: {e:?}");
|
|
}
|
|
}
|
|
};
|
|
|
|
dbg!(&config);
|
|
// .or_else(|_| load_default_config(&config_file))
|
|
// .context("loading config")?;
|
|
|
|
let group_dir = get_group_dir().context("resolving group dir")?;
|
|
let groups = Group::load(&group_dir, config.warn_not_symlinks)
|
|
.with_context(|| format!("loading groups under {}", group_dir.to_string_lossy()))?;
|
|
|
|
let pacdef = Pacdef::new(args, config, groups);
|
|
pacdef.run_action_from_arg().context("running action")
|
|
}
|
|
|
|
fn load_default_config(config_file: &Path) -> Result<Config> {
|
|
if get_config_path_old_version()?.exists() {
|
|
println!("{MAJOR_UPDATE_MESSAGE}");
|
|
}
|
|
|
|
if !config_file.exists() {
|
|
create_empty_config_file(config_file)?;
|
|
}
|
|
|
|
Ok(Config::default())
|
|
}
|
|
|
|
fn create_empty_config_file(config_file: &Path) -> Result<()> {
|
|
std::fs::File::create(config_file).context("creating empty config file")?;
|
|
Ok(())
|
|
}
|