Skip to content

Commit

Permalink
restructure code
Browse files Browse the repository at this point in the history
  • Loading branch information
mstruebing committed Nov 24, 2020
1 parent 33a5df1 commit e5601f1
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 40 deletions.
2 changes: 2 additions & 0 deletions src/common.rs
Expand Up @@ -10,7 +10,9 @@ pub use compare::CompareFileType;
pub use file_entry::FileEntry;
pub use line_entry::LineEntry;
pub use output::check::CheckOutput;
pub use output::compare::CompareOutput;
pub use output::fix::FixOutput;
pub use warning::CompareWarning;
pub use warning::Warning;

pub const LF: &str = "\n";
Expand Down
7 changes: 7 additions & 0 deletions src/common/compare.rs
Expand Up @@ -5,4 +5,11 @@ use std::path::PathBuf;
pub struct CompareFileType {
pub path: PathBuf,
pub keys: Vec<String>,
pub missing: Vec<String>,
}

#[derive(Debug)]
pub struct CompareWarning {
pub path: PathBuf,
pub missing_keys: Vec<String>,
}
24 changes: 24 additions & 0 deletions src/common/output/compare.rs
@@ -0,0 +1,24 @@
use crate::common::{CompareWarning, FileEntry};

pub struct CompareOutput {
// Quiet program output mode
is_quiet_mode: bool,
}

impl CompareOutput {
pub fn new(is_quiet_mode: bool) -> Self {
CompareOutput { is_quiet_mode }
}

/// Prints information about a file in process
pub fn print_processing_info(&self, file: &FileEntry) {
if !self.is_quiet_mode {
println!("Collecting keys of file {}", file);
}
}

/// Prints warnings without any additional information
pub fn print_warnings(&self, warnings: &[CompareWarning]) {
warnings.iter().for_each(|w| println!("{}", w.as_str()));
}
}
1 change: 1 addition & 0 deletions src/common/output/mod.rs
@@ -1,2 +1,3 @@
pub mod check;
pub mod compare;
pub mod fix;
21 changes: 21 additions & 0 deletions src/common/warning.rs
@@ -1,7 +1,28 @@
use std::fmt;
use std::path::PathBuf;

use crate::common::*;

#[derive(Debug)]
pub struct CompareWarning {
pub path: PathBuf,
pub missing_keys: Vec<String>,
}

impl CompareWarning {
pub fn as_str(&self) -> String {
format!(
"{:?} is missing keys: {:?}",
self.path,
self.missing_keys
.clone()
.into_iter()
.collect::<Vec<_>>()
.join(", ")
)
}
}

#[derive(Clone, Debug, PartialEq)]
pub struct Warning {
pub check_name: String,
Expand Down
50 changes: 24 additions & 26 deletions src/lib.rs
Expand Up @@ -10,6 +10,7 @@ mod fixes;
mod fs_utils;

pub use checks::available_check_names;
use common::CompareWarning;

pub fn check(args: &clap::ArgMatches, current_dir: &PathBuf) -> Result<usize, Box<dyn Error>> {
let mut warnings_count = 0;
Expand Down Expand Up @@ -142,41 +143,35 @@ pub fn compare(
args: &clap::ArgMatches,
current_dir: &PathBuf,
) -> Result<Vec<String>, Box<dyn Error>> {
let mut warnings: Vec<String> = Vec::new();
let mut file_paths: Vec<PathBuf> = Vec::new();
let mut files_to_compare: Vec<CompareFileType> = Vec::new();
let mut all_keys: HashSet<String> = HashSet::new();
let lines_map = get_lines(args, current_dir)?;
let output = CompareOutput::new(args.is_present("quiet"));

// determine which files to compare
if let Some(inputs) = args.values_of("files") {
file_paths = inputs
.filter_map(|f| fs_utils::canonicalize(f).ok())
.collect();
let mut warnings: Vec<CompareWarning> = Vec::new();
let mut files_to_compare: Vec<CompareFileType> = Vec::new();

// Nothing to check
if lines_map.is_empty() {
return Ok(warnings.iter().map(|w| w.as_str()).collect());
}

// create CompareFileType structures for each file
for path in file_paths {
// // create CompareFileType structures for each file
for (_, (fe, strings)) in lines_map.into_iter().enumerate() {
output.print_processing_info(&fe);
let lines = get_line_entries(&fe, strings);
let mut keys: Vec<String> = Vec::new();
let relative_path = match fs_utils::get_relative_path(&path, &current_dir) {
Some(p) => p,
None => continue,
};

let (fe, strs) = match FileEntry::from(relative_path.clone()) {
Some(f) => f,
None => continue,
};

for line in get_line_entries(&fe, strs) {
for line in lines {
if let Some(key) = line.get_key() {
all_keys.insert(key.clone());
keys.push(key)
}
}

let file_to_compare: CompareFileType = CompareFileType {
path: relative_path,
path: fe.path,
keys,
missing: Vec::new(),
};

files_to_compare.push(file_to_compare);
Expand All @@ -190,14 +185,17 @@ pub fn compare(
.collect();

if !missing_keys.is_empty() {
warnings.push(format!(
"file: {:?} is missing keys: {:?}",
file.path, missing_keys
))
let warning = CompareWarning {
path: file.path,
missing_keys: missing_keys.iter().map(|k| k.to_string()).collect(),
};

warnings.push(warning)
}
}

Ok(warnings)
output.print_warnings(&warnings);
Ok(warnings.iter().map(|w| w.as_str()).collect())
}

fn get_file_paths(
Expand Down
23 changes: 12 additions & 11 deletions src/main.rs
Expand Up @@ -3,6 +3,13 @@ use std::error::Error;
use std::ffi::OsStr;
use std::{env, process};

fn quiet_flag() -> clap::Arg<'static, 'static> {
Arg::with_name("quiet")
.short("q")
.long("quiet")
.help("Doesn't display additional information")
}

fn main() -> Result<(), Box<dyn Error>> {
#[cfg(windows)]
colored::control::set_virtual_terminal(true).ok();
Expand Down Expand Up @@ -35,10 +42,6 @@ fn main() -> Result<(), Box<dyn Error>> {
}
("compare", Some(files)) => {
if let Ok(warnings) = dotenv_linter::compare(&files, &current_dir) {
for warning in warnings.clone() {
println!("{}", warning);
}

if warnings.is_empty() {
process::exit(0);
}
Expand Down Expand Up @@ -86,13 +89,14 @@ fn get_args(current_dir: &OsStr) -> clap::ArgMatches {
SubCommand::with_name("compare")
.setting(AppSettings::ColoredHelp)
.visible_alias("c")
.arg(
Arg::with_name("files")
.args(&vec![
Arg::with_name("input")
.help("Files to compare")
.multiple(true)
.min_values(2)
.required(true),
)
quiet_flag(),
])
.about("Compares if files have the same keys")
.usage("dotenv-linter compare <files>..."),
)
Expand Down Expand Up @@ -128,9 +132,6 @@ fn common_args(current_dir: &OsStr) -> Vec<Arg> {
Arg::with_name("no-color")
.long("no-color")
.help("Turns off the colored output"),
Arg::with_name("quiet")
.short("q")
.long("quiet")
.help("Doesn't display additional information"),
quiet_flag(),
]
}
6 changes: 3 additions & 3 deletions tests/compare/compare.rs
@@ -1,11 +1,11 @@
use crate::common::{check_output, TestDir};
use crate::common::TestDir;

#[test]
fn files_with_same_environment_variables() {
let test_dir = TestDir::new();
let testfile_one = test_dir.create_testfile(".env1", "FOO=abc\nBAR=def");
let testfile_two = test_dir.create_testfile(".env2", "FOO=abc\nBAR=def");
let expected_output = check_output(&[]);
let expected_output = format!("Collecting keys of file .env1\nCollecting keys of file .env2\n");

test_dir.test_command_success_with_args(
&["compare", testfile_one.as_str(), testfile_two.as_str()],
Expand All @@ -18,7 +18,7 @@ fn files_with_different_environment_variables() {
let test_dir = TestDir::new();
let testfile_one = test_dir.create_testfile(".env1", "FOO=abc");
let testfile_two = test_dir.create_testfile(".env2", "FOO=abc\nBAR=def");
let expected_output = "file: \".env1\" is missing keys: [\"BAR\"]\n".to_owned();
let expected_output = format!("Collecting keys of file .env1\nCollecting keys of file .env2\n\".env1\" is missing keys: \"BAR\"\n");

test_dir.test_command_fail_with_args(
&["compare", testfile_one.as_str(), testfile_two.as_str()],
Expand Down

0 comments on commit e5601f1

Please sign in to comment.