Skip to content

Commit

Permalink
Add compare-flag
Browse files Browse the repository at this point in the history
  • Loading branch information
mstruebing committed Oct 27, 2020
1 parent a5903f9 commit 2d56d5b
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 0 deletions.
1 change: 1 addition & 0 deletions .env.local
@@ -0,0 +1 @@
HELLO=value
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
### 馃殌 Added
- Add `compare`-flag [#282](https://github.com/dotenv-linter/dotenv-linter/pull/282) ([@mstruebing](https://github.com/mstruebing))
- Display linted files when run [#311](https://github.com/dotenv-linter/dotenv-linter/pull/311) ([@Anthuang](https://github.com/anthuang))

### 馃敡 Changed
Expand Down
76 changes: 76 additions & 0 deletions src/lib.rs
@@ -1,5 +1,6 @@
use crate::common::*;

use std::collections::HashSet;
use std::error::Error;
use std::path::PathBuf;

Expand All @@ -16,6 +17,11 @@ pub fn run(args: &clap::ArgMatches, current_dir: &PathBuf) -> Result<Vec<Output>
let mut skip_checks: Vec<&str> = Vec::new();
let mut excluded_paths: Vec<PathBuf> = Vec::new();

if args.is_present("compare") {
let files = args.values_of("compare");
println!("files: {:?}", files);
}

let is_recursive = args.is_present("recursive");

if let Some(skip) = args.values_of("skip") {
Expand Down Expand Up @@ -90,6 +96,76 @@ pub fn print_outputs(outputs: Vec<Output>) {
}
}

// A structure used to compare environment files
#[derive(Debug)]
struct CompareFileType {
pub path: PathBuf,
pub keys: Vec<String>,
}

// Compares if different environment files contains the same variables and
// returns warnings if not
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> = vec![].into_iter().collect();

// determine which files to compare
if let Some(inputs) = args.values_of("compare") {
file_paths = inputs
.filter_map(|f| fs_utils::canonicalize(f).ok())
.collect();
}

// create CompareFileType structures for each file
for path in file_paths {
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) {
if let Some(key) = line.get_key() {
all_keys.insert(key.clone());
keys.push(key)
}
}

let file_to_compare: CompareFileType = CompareFileType {
path: relative_path,
keys,
};

files_to_compare.push(file_to_compare);
}

// create warnings if any file misses any key
for file in files_to_compare {
// copy all keys
let mut missing_keys = all_keys.clone();
missing_keys.retain(|key| !file.keys.contains(key));

if !missing_keys.is_empty() {
warnings.push(format!(
"file: {:?} is missing keys: {:?}",
file.path, missing_keys
))
}
}

Ok(warnings)
}

fn get_file_paths(
dir_entries: Vec<PathBuf>,
excludes: &[PathBuf],
Expand Down
20 changes: 20 additions & 0 deletions src/main.rs
Expand Up @@ -7,6 +7,17 @@ fn main() -> Result<(), Box<dyn Error>> {
let current_dir = env::current_dir()?;
let args = get_args(current_dir.as_os_str());

if args.is_present("compare") {
if let Ok(warnings) = dotenv_linter::compare(&args, &current_dir) {
for warning in warnings {
println!("{}", warning);
process::exit(1);
}
}

process::exit(0);
}

if args.is_present("show-checks") {
dotenv_linter::available_check_names()
.iter()
Expand Down Expand Up @@ -83,6 +94,15 @@ fn get_args(current_dir: &OsStr) -> clap::ArgMatches {
.required(true)
.multiple(true),
)
.arg(
Arg::with_name("compare")
.short("c")
.long("compare")
.value_name("FILE_NAME")
.help("Compare keys of files")
.multiple(true)
.takes_value(true),
)
.arg(
Arg::with_name("exclude")
.short("e")
Expand Down

0 comments on commit 2d56d5b

Please sign in to comment.