From ed9ed4f589325eff4e0daf1f2dfad0b2e4715553 Mon Sep 17 00:00:00 2001 From: steven-omaha <35634100+steven-omaha@users.noreply.github.com> Date: Thu, 23 Feb 2023 13:12:25 +0100 Subject: [PATCH] show transition information when new version runs for first time --- TODO.md | 1 - crates/main/main.rs | 38 ++++++++++++++++++-------------- crates/pacdef_core/src/config.rs | 13 ++++++----- crates/pacdef_core/src/lib.rs | 3 +-- crates/pacdef_core/src/path.rs | 20 +++++++++++++++-- 5 files changed, 48 insertions(+), 27 deletions(-) diff --git a/TODO.md b/TODO.md index 1d5e33a..d6c7dad 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,4 @@ # To Do -- make transition for existing user easier - tutorial - update completion for new subcommands (WIP) diff --git a/crates/main/main.rs b/crates/main/main.rs index 2ee6ed8..8dfe352 100644 --- a/crates/main/main.rs +++ b/crates/main/main.rs @@ -17,9 +17,10 @@ Main program for `pacdef`. All internal logic happens in [`pacdef_core`]. use std::process::{ExitCode, Termination}; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result}; -use pacdef_core::{get_args, get_config_path, get_group_dir, Config, Group, Pacdef}; +use pacdef_core::path::{get_config_path, get_config_path_old_version, get_group_dir}; +use pacdef_core::{get_args, Config, Group, Pacdef}; fn main() -> ExitCode { handle_final_result(main_inner()) @@ -45,7 +46,17 @@ fn main_inner() -> Result<()> { let args = get_args(); let config_file = get_config_path().context("getting config file")?; - let config = load_config(config_file)?; + + let config = Config::load(&config_file) + .or_else(|_| { + get_config_path_old_version()? + .exists() + .then(show_transition_link); + let default = Config::default(); + default.save(&config_file)?; + Ok::(default) + }) + .context("loading config")?; let group_dir = get_group_dir().context("resolving group dir")?; let groups = Group::load(&group_dir, config.warn_not_symlinks) @@ -55,18 +66,11 @@ fn main_inner() -> Result<()> { pacdef.run_action_from_arg().context("running action") } -fn load_config(config_file: std::path::PathBuf) -> Result { - let config = match Config::load(&config_file) - .with_context(|| format!("loading config file {}", config_file.to_string_lossy())) - { - Ok(config) => config, - Err(e) => { - let e = e.root_cause().downcast_ref::(); - match e { - Some(pacdef_core::Error::ConfigFileNotFound) => Config::default(), - _ => bail!("huh"), - } - } - }; - Ok(config) +fn show_transition_link() { + println!("VERSION UPGRADE"); + println!("You seem to have used version 0.x of pacdef before."); + println!("Version 1.x changes the syntax of the config files and the command line arguments."); + println!("Check out https://github.com/steven-omaha/pacdef for new syntax information."); + println!("This message will not appear again."); + println!("------"); } diff --git a/crates/pacdef_core/src/config.rs b/crates/pacdef_core/src/config.rs index bd8f2b2..c1bcfe6 100644 --- a/crates/pacdef_core/src/config.rs +++ b/crates/pacdef_core/src/config.rs @@ -38,10 +38,13 @@ impl Config { serde_yaml::from_str(&content).context("parsing yaml config") } - fn use_default_and_save_to(file: &Path) -> Result { - let result = Self::default(); - - let content = serde_yaml::to_string(&result).context("converting Config to yaml")?; + /// Save the instance of [`Config`] to disk. + /// + /// # Errors + /// + /// This function will return an error if the config file cannot be saved to disk. + pub fn save(&self, file: &Path) -> Result<()> { + let content = serde_yaml::to_string(&self).context("converting Config to yaml")?; let parent = file.parent().context("getting parent of config dir")?; if !parent.is_dir() { @@ -52,7 +55,7 @@ impl Config { let mut output = File::create(file).context("creating default config file")?; write!(output, "{content}").context("writing default config")?; - Ok(result) + Ok(()) } } diff --git a/crates/pacdef_core/src/lib.rs b/crates/pacdef_core/src/lib.rs index 5f53f71..c1ba70c 100644 --- a/crates/pacdef_core/src/lib.rs +++ b/crates/pacdef_core/src/lib.rs @@ -30,7 +30,7 @@ mod core; mod env; mod errors; mod grouping; -mod path; +pub mod path; mod review; mod search; mod ui; @@ -41,6 +41,5 @@ pub use crate::core::Pacdef; pub use crate::errors::Error; pub use crate::grouping::Group; pub(crate) use crate::grouping::Package; -pub use crate::path::{get_config_path, get_group_dir}; extern crate pacdef_macros; diff --git a/crates/pacdef_core/src/path.rs b/crates/pacdef_core/src/path.rs index 7103369..eb6c7ec 100644 --- a/crates/pacdef_core/src/path.rs +++ b/crates/pacdef_core/src/path.rs @@ -1,9 +1,14 @@ +/*! +All functions related to `pacdef`'s internal paths. +*/ + use std::env; use std::path::PathBuf; use anyhow::{Context, Result}; const CONFIG_FILE_NAME: &str = "pacdef.yaml"; +const CONFIG_FILE_NAME_OLD: &str = "pacdef.conf"; /// Get the group directory where all group files are located. This is /// `$XDG_CONFIG_HOME/pacdef/groups`, which defaults to `$HOME/.config/pacdef/groups`. @@ -17,7 +22,7 @@ pub fn get_group_dir() -> Result { Ok(result) } -pub fn get_pacdef_base_dir() -> Result { +pub(crate) fn get_pacdef_base_dir() -> Result { let mut dir = get_xdg_config_home().context("getting XDG_CONFIG_HOME")?; dir.push("pacdef"); Ok(dir) @@ -33,7 +38,7 @@ fn get_xdg_config_home() -> Result { } } -pub fn get_home_dir() -> Result { +pub(crate) fn get_home_dir() -> Result { Ok(env::var("HOME").context("getting $HOME variable")?.into()) } @@ -47,3 +52,14 @@ pub fn get_config_path() -> Result { file.push(CONFIG_FILE_NAME); Ok(file) } + +/// Get the path to the pacdef config file. This is `$XDG_CONFIG_HOME/pacdef/pacdef.yaml`. +/// +/// # Errors +/// +/// This function returns an error if both `$XDG_CONFIG_HOME` and `$HOME` are undefined. +pub fn get_config_path_old_version() -> Result { + let mut file = get_pacdef_base_dir().context("getting pacdef base dir for config file")?; + file.push(CONFIG_FILE_NAME_OLD); + Ok(file) +}