From 43f0b753977e65a0f59df54d4aa04c584206dab6 Mon Sep 17 00:00:00 2001 From: Idan Katz Date: Thu, 10 Oct 2019 11:26:00 +0300 Subject: [PATCH] =?UTF-8?q?Allow=20most=20command-line=20options=20to=20be?= =?UTF-8?q?=20configured=20in=20config=20file=E2=80=A6=20(#237)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.example.toml | 17 +++++++++++++- src/config.rs | 54 +++++++++++++++++++++++++++++++-------------- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/config.example.toml b/config.example.toml index 815baff5..4b2b40e6 100644 --- a/config.example.toml +++ b/config.example.toml @@ -4,9 +4,18 @@ # "~/.config/something" #] -# Same options as the command line flag +# Disable specific steps - same options as the command line flag #disable = ["system", "emacs"] +# Run specific steps - same options as the command line flag +#only = ["system", "emacs"] + +# Do not ask to retry failed steps (default: false) +#no_retry = true + +# Run inside tmux +#run_in_tmux = true + # List of remote machines with Topgrade installed on them #remote_topgrades = ["toothless", "pi", "parnas"] @@ -28,3 +37,9 @@ # Custom commands #[commands] #"Python Environment" = "~/dev/.env/bin/pip install -i https://pypi.python.org/simple -U --upgrade-strategy eager jupyter" + +# Output logs +#verbose = true + +# Cleanup temporary or old files +#cleanup = true diff --git a/src/config.rs b/src/config.rs index 32daf9a7..05e35052 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,7 +2,7 @@ use super::error::{Error, ErrorKind}; use super::utils::editor; use directories::BaseDirs; use failure::ResultExt; -use strum::{EnumString, EnumVariantNames}; +use strum::{EnumIter, EnumString, EnumVariantNames, IntoEnumIterator}; use log::{debug, error, LevelFilter}; use pretty_env_logger::formatted_timed_builder; @@ -18,7 +18,7 @@ use toml; type Commands = BTreeMap; -#[derive(EnumString, EnumVariantNames, Debug, Clone, PartialEq, Deserialize)] +#[derive(EnumString, EnumVariantNames, Debug, Clone, PartialEq, Deserialize, EnumIter)] #[serde(rename_all = "lowercase")] #[strum(serialize_all = "snake_case")] pub enum Step { @@ -62,6 +62,11 @@ pub struct ConfigFile { set_title: Option, assume_yes: Option, yay_arguments: Option, + no_retry: Option, + run_in_tmux: Option, + verbose: Option, + cleanup: Option, + only: Option>, } impl ConfigFile { @@ -170,6 +175,7 @@ pub struct CommandLineArgs { pub struct Config { opt: CommandLineArgs, config_file: ConfigFile, + allowed_steps: Vec, } impl Config { @@ -178,18 +184,22 @@ impl Config { /// The function parses the command line arguments and reading the configuration file. pub fn load(base_dirs: &BaseDirs) -> Result { let opt = CommandLineArgs::from_args(); + let config_file = ConfigFile::read(base_dirs)?; let mut builder = formatted_timed_builder(); - if opt.verbose { + if opt.verbose || config_file.verbose.unwrap_or(false) { builder.filter(Some("topgrade"), LevelFilter::Trace); } + let allowed_steps = Self::allowed_steps(&opt, &config_file); + builder.init(); Ok(Self { opt, - config_file: ConfigFile::read(base_dirs)?, + config_file, + allowed_steps, }) } @@ -218,28 +228,38 @@ impl Config { /// If the step appears either in the `--disable` command line argument /// or the `disable` option in the configuration, the function returns false. pub fn should_run(&self, step: Step) -> bool { - if !self.opt.only.is_empty() { - return self.opt.only.contains(&step); - } + self.allowed_steps.contains(&step) + } - !(self - .config_file - .disable - .as_ref() - .map(|d| d.contains(&step)) - .unwrap_or(false) - || self.opt.disable.contains(&step)) + fn allowed_steps(opt: &CommandLineArgs, config_file: &ConfigFile) -> Vec { + let mut enabled_steps: Vec = if !opt.only.is_empty() { + opt.only.clone() + } else { + config_file + .only + .as_ref() + .map_or_else(|| Step::iter().collect(), |v| v.clone()) + }; + + let disabled_steps: Vec = if !opt.disable.is_empty() { + opt.disable.clone() + } else { + config_file.disable.as_ref().map_or_else(|| vec![], |v| v.clone()) + }; + + enabled_steps.retain(|e| !disabled_steps.contains(e)); + enabled_steps } /// Tell whether we should run in tmux. pub fn run_in_tmux(&self) -> bool { - self.opt.run_in_tmux + self.opt.run_in_tmux || self.config_file.run_in_tmux.unwrap_or(false) } /// Tell whether we should perform cleanup steps. #[cfg(not(windows))] pub fn cleanup(&self) -> bool { - self.opt.cleanup + self.opt.cleanup || self.config_file.cleanup.unwrap_or(false) } /// Tell whether we are dry-running. @@ -249,7 +269,7 @@ impl Config { /// Tell whether we should not attempt to retry anything. pub fn no_retry(&self) -> bool { - self.opt.no_retry + self.opt.no_retry || self.config_file.no_retry.unwrap_or(false) } /// List of remote hosts to run Topgrade in