in guard/src/commands/validate.rs [117:286]
fn execute(&self, app: &ArgMatches<'_>) -> Result<i32> {
let verbose = if app.is_present("verbose") {
true
} else {
false
};
let data_type = match app.value_of("type") {
Some(t) =>
if t == "CFNTemplate" {
Type::CFNTemplate
} else {
Type::Generic
},
None => Type::Generic
};
let output_type = match app.value_of("output-format") {
Some(o) =>
if o == "single-line-summary" {
OutputFormatType::SingleLineSummary
} else if o == "json" {
OutputFormatType::JSON
} else {
OutputFormatType::YAML
}
None => OutputFormatType::SingleLineSummary
};
let summary_type: BitFlags<SummaryType> = app.values_of("show-summary").map_or(
SummaryType::PASS | SummaryType::FAIL | SummaryType::SKIP,
|v| {
v.fold(BitFlags::empty(), |mut st, elem| {
match elem {
"pass" => st.insert(SummaryType::PASS),
"fail" => st.insert(SummaryType::FAIL),
"skip" => st.insert(SummaryType::SKIP),
"none" => return BitFlags::empty(),
"all" => st.insert(SummaryType::PASS | SummaryType::FAIL | SummaryType::SKIP),
_ => unreachable!()
};
st
})
});
let print_json = app.is_present("print-json");
let show_clause_failures = app.is_present("show-clause-failures");
let mut exit_code = 0;
if app.is_present("rules") {
let file = app.value_of("rules").unwrap();
let cmp = if app.is_present("last-modified") {
last_modified
} else {
alpabetical
};
let files = get_files(file, cmp)?;
let empty_path = Path::new("");
let data_files = match app.value_of("data") {
Some(file_or_dir) => {
let base = PathBuf::from_str(file_or_dir)?;
let selected = get_files(file_or_dir, cmp)?;
let mut streams = Vec::with_capacity(selected.len());
for each in selected {
let mut context = String::new();
let mut reader = BufReader::new(File::open(each.as_path())?);
reader.read_to_string(&mut context)?;
let path = each.as_path();
let relative = match path.strip_prefix(base.as_path()) {
Ok(p) => if p != empty_path {
format!("{}", p.display())
} else { format!("{}", path.file_name().unwrap().to_str().unwrap()) },
Err(_) => format!("{}", path.display()),
};
streams.push((context, relative));
}
streams
},
None => {
let mut context = String::new();
let mut reader = BufReader::new(std::io::stdin());
reader.read_to_string(&mut context);
vec![(context, "STDIN".to_string())]
}
};
let base = PathBuf::from_str(file)?;
for each_file_content in iterate_over(&files, |content, file|
Ok((content, match file.strip_prefix(&base) {
Ok(path) => if path == empty_path {
format!("{}", file.file_name().unwrap().to_str().unwrap())
} else { format!("{}", path.display()) },
Err(_) => format!("{}", file.display()),
}))) {
match each_file_content {
Err(e) => println!("Unable read content from file {}", e),
Ok((file_content, rule_file_name)) => {
match parse_rules(&file_content, &rule_file_name) {
Err(e) => {
println!("Parsing error handling rules file = {}, Error = {}",
rule_file_name.underline(), e);
println!("---");
exit_code = 5;
continue;
},
Ok(rules) => {
match evaluate_against_data_input(
data_type,
output_type,
&data_files,
&rules,
&rule_file_name,
verbose,
print_json,
show_clause_failures,
summary_type.clone())? {
Status::SKIP | Status::PASS => continue,
Status::FAIL => {
exit_code = 5;
}
}
}
}
}
}
}
} else {
let mut context = String::new();
let mut reader = BufReader::new(std::io::stdin());
reader.read_to_string(&mut context);
let payload: Payload = deserialize_payload(&context)?;
let data_collection: Vec<(String, String)> = payload.list_of_data.iter().enumerate().map(|(i, data)|(data.to_string(), format!("DATA_STDIN[{}]", i + 1))).collect();
let rules_collection: Vec<(String, String)> = payload.list_of_rules.iter().enumerate().map(|(i, rules)|(rules.to_string(), format!("RULES_STDIN[{}]", i + 1))).collect();
for (each_rules, location) in rules_collection {
match parse_rules(&each_rules, &location) {
Err(e) => {
println!("Parsing error handling rules = {}, Error = {}",
location.underline(), e);
println!("---");
exit_code = 5;
continue;
},
Ok(rules) => {
match evaluate_against_data_input(
data_type,
output_type,
&data_collection,
&rules,
&location,
verbose,
print_json,
show_clause_failures,
summary_type.clone())? {
Status::SKIP | Status::PASS => continue,
Status::FAIL => {
exit_code = 5;
}
}
}
}
}
}
Ok(exit_code)
}