From 49c35f79c05d0b180895c8111dfc96a640ebad56 Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Sat, 27 Jun 2020 19:47:52 -0400 Subject: Runtime assertion that all options are handled --- src/cli.rs | 36 ++++++++++++++++++++++++++++++++++++ src/set_options.rs | 21 ++++++++++++++++++--- 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), -- cgit v1.2.3