refactor(cli): Prepare for merging im config file

This commit is contained in:
Ed Page 2019-08-07 09:40:06 -05:00
parent f15191de14
commit 8d96a2ad1d
2 changed files with 162 additions and 34 deletions

126
src/config.rs Normal file
View file

@ -0,0 +1,126 @@
pub trait ConfigSource {
/// Skip hidden files and directories.
fn ignore_hidden(&self) -> Option<bool> {
None
}
/// Respect ignore files.
fn ignore_files(&self) -> Option<bool> {
None
}
/// Respect .ignore files.
fn ignore_dot(&self) -> Option<bool> {
None
}
/// Respect ignore files in vcs directories.
fn ignore_vcs(&self) -> Option<bool> {
None
}
/// Respect global ignore files.
fn ignore_global(&self) -> Option<bool> {
None
}
/// Respect ignore files in parent directories.
fn ignore_parent(&self) -> Option<bool> {
None
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields, default)]
#[serde(rename_all = "kebab-case")]
pub struct Config {
pub ignore_hidden: Option<bool>,
pub ignore_files: Option<bool>,
pub ignore_dot: Option<bool>,
pub ignore_vcs: Option<bool>,
pub ignore_global: Option<bool>,
pub ignore_parent: Option<bool>,
}
impl Config {
pub fn update(&mut self, source: &dyn ConfigSource) {
if let Some(source) = source.ignore_hidden() {
self.ignore_hidden = Some(source);
}
if let Some(source) = source.ignore_files() {
self.ignore_files = Some(source);
self.ignore_dot = None;
self.ignore_vcs = None;
self.ignore_global = None;
self.ignore_parent = None;
}
if let Some(source) = source.ignore_dot() {
self.ignore_dot = Some(source);
}
if let Some(source) = source.ignore_vcs() {
self.ignore_vcs = Some(source);
self.ignore_global = None;
}
if let Some(source) = source.ignore_global() {
self.ignore_global = Some(source);
}
if let Some(source) = source.ignore_parent() {
self.ignore_parent = Some(source);
}
}
pub fn ignore_hidden(&self) -> bool {
self.ignore_hidden.unwrap_or(true)
}
pub fn ignore_dot(&self) -> bool {
self.ignore_dot
.or_else(|| self.ignore_files)
.unwrap_or(true)
}
pub fn ignore_vcs(&self) -> bool {
self.ignore_vcs
.or_else(|| self.ignore_files)
.unwrap_or(true)
}
pub fn ignore_global(&self) -> bool {
self.ignore_global
.or_else(|| self.ignore_vcs)
.or_else(|| self.ignore_files)
.unwrap_or(true)
}
pub fn ignore_parent(&self) -> bool {
self.ignore_parent
.or_else(|| self.ignore_files)
.unwrap_or(true)
}
}
impl ConfigSource for Config {
fn ignore_hidden(&self) -> Option<bool> {
self.ignore_hidden
}
fn ignore_files(&self) -> Option<bool> {
self.ignore_files
}
fn ignore_dot(&self) -> Option<bool> {
self.ignore_dot
}
fn ignore_vcs(&self) -> Option<bool> {
self.ignore_vcs
}
fn ignore_global(&self) -> Option<bool> {
self.ignore_global
}
fn ignore_parent(&self) -> Option<bool> {
self.ignore_parent
}
}

View file

@ -6,6 +6,8 @@ use std::io::Write;
use structopt::StructOpt;
mod config;
arg_enum! {
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Format {
@ -167,8 +169,10 @@ impl Options {
(_, _) => unreachable!("StructOpt should make this impossible"),
}
}
}
pub fn ignore_hidden(&self) -> Option<bool> {
impl config::ConfigSource for Options {
fn ignore_hidden(&self) -> Option<bool> {
match (self.hidden, self.no_hidden) {
(true, false) => Some(false),
(false, true) => Some(true),
@ -177,49 +181,44 @@ impl Options {
}
}
pub fn ignore_dot(&self) -> Option<bool> {
fn ignore_files(&self) -> Option<bool> {
match (self.no_ignore, self.ignore) {
(true, false) => Some(false),
(false, true) => Some(true),
(false, false) => None,
(_, _) => unreachable!("StructOpt should make this impossible"),
}
}
fn ignore_dot(&self) -> Option<bool> {
match (self.no_ignore_dot, self.ignore_dot) {
(true, false) => Some(false),
(false, true) => Some(true),
(false, false) => None,
(_, _) => unreachable!("StructOpt should make this impossible"),
}
.or_else(|| self.ignore_files())
}
pub fn ignore_global(&self) -> Option<bool> {
match (self.no_ignore_global, self.ignore_global) {
(true, false) => Some(false),
(false, true) => Some(true),
(false, false) => None,
(_, _) => unreachable!("StructOpt should make this impossible"),
}
.or_else(|| self.ignore_vcs())
.or_else(|| self.ignore_files())
}
pub fn ignore_parent(&self) -> Option<bool> {
match (self.no_ignore_parent, self.ignore_parent) {
(true, false) => Some(false),
(false, true) => Some(true),
(false, false) => None,
(_, _) => unreachable!("StructOpt should make this impossible"),
}
.or_else(|| self.ignore_files())
}
pub fn ignore_vcs(&self) -> Option<bool> {
fn ignore_vcs(&self) -> Option<bool> {
match (self.no_ignore_vcs, self.ignore_vcs) {
(true, false) => Some(false),
(false, true) => Some(true),
(false, false) => None,
(_, _) => unreachable!("StructOpt should make this impossible"),
}
.or_else(|| self.ignore_files())
}
fn ignore_files(&self) -> Option<bool> {
match (self.no_ignore, self.ignore) {
fn ignore_global(&self) -> Option<bool> {
match (self.no_ignore_global, self.ignore_global) {
(true, false) => Some(false),
(false, true) => Some(true),
(false, false) => None,
(_, _) => unreachable!("StructOpt should make this impossible"),
}
}
fn ignore_parent(&self) -> Option<bool> {
match (self.no_ignore_parent, self.ignore_parent) {
(true, false) => Some(false),
(false, true) => Some(true),
(false, false) => None,
@ -252,6 +251,9 @@ pub fn get_logging(level: log::Level) -> env_logger::Builder {
fn run() -> Result<i32, failure::Error> {
let options = Options::from_args().infer();
let mut config = config::Config::default();
config.update(&options);
let mut builder = get_logging(options.verbose.log_level());
builder.init();
@ -280,12 +282,12 @@ fn run() -> Result<i32, failure::Error> {
for path in &options.path[1..] {
walk.add(path);
}
walk.hidden(options.ignore_hidden().unwrap_or(true))
.ignore(options.ignore_dot().unwrap_or(true))
.git_global(options.ignore_global().unwrap_or(true))
.git_ignore(options.ignore_vcs().unwrap_or(true))
.git_exclude(options.ignore_vcs().unwrap_or(true))
.parents(options.ignore_parent().unwrap_or(true));
walk.hidden(config.ignore_hidden())
.ignore(config.ignore_dot())
.git_global(config.ignore_global())
.git_ignore(config.ignore_vcs())
.git_exclude(config.ignore_vcs())
.parents(config.ignore_parent());
let mut typos_found = false;
for entry in walk.build() {
let entry = entry?;