summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2020-06-27 19:47:52 -0400
committerDan Davison <dandavison7@gmail.com>2020-06-27 21:24:34 -0400
commit49c35f79c05d0b180895c8111dfc96a640ebad56 (patch)
treeed707cdf0c96bd90ce72a56417f2c6a317cdbdc2
parent817446b403b147a9486d0d6f6e7b96ab31d9c226 (diff)
Runtime assertion that all options are handled
-rw-r--r--src/cli.rs36
-rw-r--r--src/set_options.rs21
2 files changed, 54 insertions, 3 deletions
diff --git a/src/cli.rs b/src/cli.rs
index 34c5716e..6d62d53a 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -1,7 +1,10 @@
+use std::collections::HashSet;
#[cfg(test)]
use std::ffi::OsString;
use std::path::PathBuf;
+use itertools;
+use lazy_static::lazy_static;
use structopt::clap::AppSettings::{ColorAlways, ColoredHelp, DeriveDisplayOrder};
use structopt::{clap, StructOpt};
@@ -524,4 +527,37 @@ impl Opt {
rewrite_options::apply_rewrite_rules(&mut opt, &arg_matches);
opt
}
+
+ pub fn get_option_or_flag_names<'a>() -> HashSet<&'a str> {
+ let names: HashSet<&str> = itertools::chain(
+ Self::clap().p.opts.iter().filter_map(|opt| opt.s.long),
+ Self::clap().p.flags.iter().filter_map(|opt| opt.s.long),
+ )
+ .collect();
+ &names - &*IGNORED_OPTION_OR_FLAG_NAMES
+ }
+}
+
+// Option names to exclude when listing options to process for various purposes. These are
+// (1) Deprecated options
+// (2) Pseudo-flag commands such as --list-languages
+lazy_static! {
+ static ref IGNORED_OPTION_OR_FLAG_NAMES: HashSet<&'static str> = vec![
+ "commit-color",
+ "file-color",
+ "highlight-removed",
+ "hunk-color",
+ "hunk-style",
+ "list-languages",
+ "list-syntax-themes",
+ "minus-color",
+ "minus-emph-color",
+ "plus-color",
+ "plus-emph-color",
+ "show-config",
+ "show-syntax-themes",
+ "theme",
+ ]
+ .into_iter()
+ .collect();
}
diff --git a/src/set_options.rs b/src/set_options.rs
index 229da832..c141e666 100644
--- a/src/set_options.rs
+++ b/src/set_options.rs
@@ -1,4 +1,4 @@
-use std::collections::VecDeque;
+use std::collections::{HashSet, VecDeque};
use structopt::clap;
@@ -10,6 +10,7 @@ use crate::git_config;
macro_rules! set_options {
([$( ($option_name:expr, $field_ident:ident) ),* ],
$opt:expr, $builtin_features:expr, $git_config:expr, $arg_matches:expr) => {
+ let mut option_names = HashSet::new();
$(
if !$crate::config::user_supplied_option($option_name, $arg_matches) {
if let Some(value) = $crate::get_option_value::get_option_value(
@@ -21,7 +22,21 @@ macro_rules! set_options {
$opt.$field_ident = value;
}
};
+ option_names.insert($option_name);
)*
+ option_names.extend(&[
+ "diff-highlight", // Does not exist as a flag on config
+ "diff-so-fancy", // Does not exist as a flag on config
+ "features",
+ "no-gitconfig",
+ ]);
+ let expected_option_names = $crate::cli::Opt::get_option_or_flag_names();
+ if option_names != expected_option_names {
+ $crate::config::delta_unreachable(
+ &format!("Error processing options.\nUnhandled names: {:?}\nInvalid names: {:?}.\n",
+ &expected_option_names - &option_names,
+ &option_names - &expected_option_names));
+ }
};
}
@@ -55,6 +70,7 @@ pub fn set_options(
set_options!(
[
+ ("24-bit-color", true_color),
("color-only", color_only),
("commit-decoration-style", commit_decoration_style),
("commit-style", commit_style),
@@ -89,7 +105,7 @@ pub fn set_options(
("line-numbers-right-format", line_numbers_right_format),
("line-numbers-right-style", line_numbers_right_style),
("line-numbers-zero-style", line_numbers_zero_style),
- ("paging-mode", paging_mode),
+ ("paging", paging_mode),
// Hack: plus-style must come before plus-*emph-style because the latter default
// dynamically to the value of the former.
("plus-style", plus_style),
@@ -98,7 +114,6 @@ pub fn set_options(
("plus-non-emph-style", plus_non_emph_style),
("syntax-theme", syntax_theme),
("tabs", tab_width),
- ("true-color", true_color),
("whitespace-error-style", whitespace_error_style),
("width", width),
("word-diff-regex", tokenization_regex),