Allow most command-line options to be configured in config file… (#237)
This commit is contained in:
committed by
Roey Darwish Dror
parent
6bed2f66c5
commit
43f0b75397
@@ -4,9 +4,18 @@
|
|||||||
# "~/.config/something"
|
# "~/.config/something"
|
||||||
#]
|
#]
|
||||||
|
|
||||||
# Same options as the command line flag
|
# Disable specific steps - same options as the command line flag
|
||||||
#disable = ["system", "emacs"]
|
#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
|
# List of remote machines with Topgrade installed on them
|
||||||
#remote_topgrades = ["toothless", "pi", "parnas"]
|
#remote_topgrades = ["toothless", "pi", "parnas"]
|
||||||
|
|
||||||
@@ -28,3 +37,9 @@
|
|||||||
# Custom commands
|
# Custom commands
|
||||||
#[commands]
|
#[commands]
|
||||||
#"Python Environment" = "~/dev/.env/bin/pip install -i https://pypi.python.org/simple -U --upgrade-strategy eager jupyter"
|
#"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
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use super::error::{Error, ErrorKind};
|
|||||||
use super::utils::editor;
|
use super::utils::editor;
|
||||||
use directories::BaseDirs;
|
use directories::BaseDirs;
|
||||||
use failure::ResultExt;
|
use failure::ResultExt;
|
||||||
use strum::{EnumString, EnumVariantNames};
|
use strum::{EnumIter, EnumString, EnumVariantNames, IntoEnumIterator};
|
||||||
|
|
||||||
use log::{debug, error, LevelFilter};
|
use log::{debug, error, LevelFilter};
|
||||||
use pretty_env_logger::formatted_timed_builder;
|
use pretty_env_logger::formatted_timed_builder;
|
||||||
@@ -18,7 +18,7 @@ use toml;
|
|||||||
|
|
||||||
type Commands = BTreeMap<String, String>;
|
type Commands = BTreeMap<String, String>;
|
||||||
|
|
||||||
#[derive(EnumString, EnumVariantNames, Debug, Clone, PartialEq, Deserialize)]
|
#[derive(EnumString, EnumVariantNames, Debug, Clone, PartialEq, Deserialize, EnumIter)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
pub enum Step {
|
pub enum Step {
|
||||||
@@ -62,6 +62,11 @@ pub struct ConfigFile {
|
|||||||
set_title: Option<bool>,
|
set_title: Option<bool>,
|
||||||
assume_yes: Option<bool>,
|
assume_yes: Option<bool>,
|
||||||
yay_arguments: Option<String>,
|
yay_arguments: Option<String>,
|
||||||
|
no_retry: Option<bool>,
|
||||||
|
run_in_tmux: Option<bool>,
|
||||||
|
verbose: Option<bool>,
|
||||||
|
cleanup: Option<bool>,
|
||||||
|
only: Option<Vec<Step>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConfigFile {
|
impl ConfigFile {
|
||||||
@@ -170,6 +175,7 @@ pub struct CommandLineArgs {
|
|||||||
pub struct Config {
|
pub struct Config {
|
||||||
opt: CommandLineArgs,
|
opt: CommandLineArgs,
|
||||||
config_file: ConfigFile,
|
config_file: ConfigFile,
|
||||||
|
allowed_steps: Vec<Step>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@@ -178,18 +184,22 @@ impl Config {
|
|||||||
/// The function parses the command line arguments and reading the configuration file.
|
/// The function parses the command line arguments and reading the configuration file.
|
||||||
pub fn load(base_dirs: &BaseDirs) -> Result<Self, Error> {
|
pub fn load(base_dirs: &BaseDirs) -> Result<Self, Error> {
|
||||||
let opt = CommandLineArgs::from_args();
|
let opt = CommandLineArgs::from_args();
|
||||||
|
let config_file = ConfigFile::read(base_dirs)?;
|
||||||
|
|
||||||
let mut builder = formatted_timed_builder();
|
let mut builder = formatted_timed_builder();
|
||||||
|
|
||||||
if opt.verbose {
|
if opt.verbose || config_file.verbose.unwrap_or(false) {
|
||||||
builder.filter(Some("topgrade"), LevelFilter::Trace);
|
builder.filter(Some("topgrade"), LevelFilter::Trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let allowed_steps = Self::allowed_steps(&opt, &config_file);
|
||||||
|
|
||||||
builder.init();
|
builder.init();
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
opt,
|
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
|
/// If the step appears either in the `--disable` command line argument
|
||||||
/// or the `disable` option in the configuration, the function returns false.
|
/// or the `disable` option in the configuration, the function returns false.
|
||||||
pub fn should_run(&self, step: Step) -> bool {
|
pub fn should_run(&self, step: Step) -> bool {
|
||||||
if !self.opt.only.is_empty() {
|
self.allowed_steps.contains(&step)
|
||||||
return self.opt.only.contains(&step);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
!(self
|
fn allowed_steps(opt: &CommandLineArgs, config_file: &ConfigFile) -> Vec<Step> {
|
||||||
.config_file
|
let mut enabled_steps: Vec<Step> = if !opt.only.is_empty() {
|
||||||
.disable
|
opt.only.clone()
|
||||||
.as_ref()
|
} else {
|
||||||
.map(|d| d.contains(&step))
|
config_file
|
||||||
.unwrap_or(false)
|
.only
|
||||||
|| self.opt.disable.contains(&step))
|
.as_ref()
|
||||||
|
.map_or_else(|| Step::iter().collect(), |v| v.clone())
|
||||||
|
};
|
||||||
|
|
||||||
|
let disabled_steps: Vec<Step> = 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.
|
/// Tell whether we should run in tmux.
|
||||||
pub fn run_in_tmux(&self) -> bool {
|
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.
|
/// Tell whether we should perform cleanup steps.
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
pub fn cleanup(&self) -> bool {
|
pub fn cleanup(&self) -> bool {
|
||||||
self.opt.cleanup
|
self.opt.cleanup || self.config_file.cleanup.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tell whether we are dry-running.
|
/// Tell whether we are dry-running.
|
||||||
@@ -249,7 +269,7 @@ impl Config {
|
|||||||
|
|
||||||
/// Tell whether we should not attempt to retry anything.
|
/// Tell whether we should not attempt to retry anything.
|
||||||
pub fn no_retry(&self) -> bool {
|
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
|
/// List of remote hosts to run Topgrade in
|
||||||
|
|||||||
Reference in New Issue
Block a user