Skip to content

Commit

Permalink
Revert "Bumping up clap-rs (#294)" (#299)
Browse files Browse the repository at this point in the history
This reverts commit 5481fa7.

Co-authored-by: Akshay Rane <raneaks@amazon.com>
  • Loading branch information
akshayrane and Akshay Rane committed Nov 4, 2022
1 parent 68cde2f commit e64fa55
Show file tree
Hide file tree
Showing 11 changed files with 308 additions and 340 deletions.
68 changes: 33 additions & 35 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions guard/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ nom_locate = "2.0.0"
indexmap = { version = "1.6.0", features = ["serde-1"] }
regex = "1.5.5"
simple_logger = "1.3.0"
clap = "4.0.18"
clap_complete = "4.0.3"
clap = "2.29.0"
serde = { version = "1.0", features = ["derive"] }
#serde_json = "1.0.57"
serde_yaml = "0.9.10"
Expand Down
4 changes: 2 additions & 2 deletions guard/src/command.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use clap::ArgMatches;
use clap::{App, ArgMatches};

use crate::rules::errors::Error;

pub trait Command {
fn name(&self) -> &'static str;
fn command(&self) -> clap::Command;
fn command(&self) -> App<'static, 'static>;
fn execute(&self, args: &ArgMatches) -> Result<i32, Error>;
}
65 changes: 33 additions & 32 deletions guard/src/commands/migrate.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
use std::collections::{HashMap, HashSet};
use std::fmt::Write as FmtWrite;
use clap::{App, Arg, ArgMatches};


use crate::command::Command;
use crate::commands::files::read_file_content;
use crate::rules::Result;
use crate::migrate::parser::{parse_rules_file, RuleLineType, Rule, TypeName, Clause};
use std::fs::File;
use std::fmt::Write as FmtWrite;
use std::io::Write as IoWrite;
use std::collections::{HashSet, HashMap};
use crate::rules::errors::{Error, ErrorKind};
use std::path::PathBuf;
use std::str::FromStr;

use clap::{Arg, ArgMatches};
use itertools::Itertools;

use crate::command::Command;
use crate::commands::{MIGRATE, OUTPUT, RULES};
use crate::commands::files::read_file_content;
use crate::migrate::parser::{Clause, parse_rules_file, Rule, RuleLineType, TypeName};
use crate::rules::errors::{Error, ErrorKind};
use crate::rules::Result;

#[cfg(test)]
#[path = "migrate_tests.rs"]
mod migrate_tests;



#[derive(Clone, Copy, Eq, PartialEq)]
pub(crate) struct Migrate {}

impl Migrate {
pub(crate) fn new() -> Self {
Migrate {}
Migrate{}
}
}

Expand All @@ -35,44 +36,43 @@ impl Command for Migrate {
}


fn command(&self) -> clap::Command {
clap::Command::new(MIGRATE)
fn command(&self) -> App<'static, 'static> {
App::new(MIGRATE)
.about(r#"Migrates 1.0 rules to 2.0 compatible rules.
"#)
.arg(Arg::new(RULES.0).long(RULES.0).short(RULES.1).help("Provide a rules file").required(true))
.arg(Arg::new(OUTPUT.0).long(OUTPUT.0).short(OUTPUT.1).help("Write migrated rules to output file").required(false))
.arg(Arg::with_name(RULES.0).long(RULES.0).short(RULES.1).takes_value(true).help("Provide a rules file").required(true))
.arg(Arg::with_name(OUTPUT.0).long(OUTPUT.0).short(OUTPUT.1).takes_value(true).help("Write migrated rules to output file").required(false))
}

fn execute(&self, app: &ArgMatches) -> Result<i32> {
let file_input = app.get_one::<&str>(RULES.0).unwrap();
fn execute(&self, app: &ArgMatches<'_>) -> Result<i32> {
let file_input = app.value_of(RULES.0).unwrap();
let path = PathBuf::from_str(file_input).unwrap();
let file_name = path.to_str().unwrap_or("").to_string();
let file = File::open(file_input)?;

let mut out = match app.get_one::<String>(OUTPUT.0) {
let mut out= match app.value_of(OUTPUT.0) {
Some(file) => Box::new(File::create(file)?) as Box<dyn std::io::Write>,
None => Box::new(std::io::stdout()) as Box<dyn std::io::Write>
};

match read_file_content(file) {
Err(e) => {
println!("Unable read content from file {}", e);
Err(Error::new(ErrorKind::IoError(e)))
}
},
Ok(file_content) => {
match parse_rules_file(&file_content, &file_name) {
Err(e) => {
println!("Could not parse 1.0 rule file: {}. Please ensure the file is valid with the old version of the tool and try again.", file_name);
Err(e)
}
},
Ok(rules) => {
let migrated_rules = migrate_rules(rules)?;
let span = crate::rules::parser::Span::new_extra(&migrated_rules, "");
match crate::rules::parser::rules_file(span) {
Ok(_rules) => {
write!(out, "{}", migrated_rules)?;
Ok(0_i32)
}
write!(out,"{}", migrated_rules)?;
Ok(0 as i32)
},
Err(e) => {
println!("Could not parse migrated ruleset for file: '{}': {}", &file_name, e);
Err(e)
Expand All @@ -94,11 +94,11 @@ pub(crate) fn migrated_rules_by_type(rules: &[RuleLineType],
}
}

let mut types = by_type.keys().cloned().collect_vec();
let mut types = by_type.keys().map(|elem| elem.clone()).collect_vec();
types.sort();
for each_type in &types {
writeln!(&mut migrated, "let {} = Resources.*[ Type == \"{}\" ]", each_type, each_type.type_name)?;
writeln!(&mut migrated, "rule {name}_checks WHEN %{name} NOT EMPTY {{", name = each_type)?;
writeln!(&mut migrated, "rule {name}_checks WHEN %{name} NOT EMPTY {{", name=each_type)?;
writeln!(&mut migrated, " %{} {{", each_type)?;
for each_clause in by_type.get(each_type).unwrap() {
writeln!(&mut migrated, " {}", *each_clause)?;
Expand All @@ -115,27 +115,28 @@ pub(crate) fn aggregate_by_type(rules: &Vec<RuleLineType>) -> HashMap<TypeName,
for each in &clause.rules {
match each {
Rule::Basic(br) => {
by_type.entry(br.type_name.clone()).or_insert_with(indexmap::IndexSet::new)
by_type.entry(br.type_name.clone()).or_insert(indexmap::IndexSet::new())
.insert(clause);
}
},
Rule::Conditional(br) => {
by_type.entry(br.type_name.clone()).or_insert_with(indexmap::IndexSet::new)
by_type.entry(br.type_name.clone()).or_insert(indexmap::IndexSet::new())
.insert(clause);
}
}

}
}
}
by_type
}

pub(crate) fn get_resource_types_in_ruleset(rules: &Vec<RuleLineType>) -> Result<Vec<TypeName>> {
pub (crate) fn get_resource_types_in_ruleset(rules: &Vec<RuleLineType>) -> Result<Vec<TypeName>> {
let mut resource_types = HashSet::new();
for rule in rules {
if let RuleLineType::Clause(clause) = rule.clone() {
clause.rules.into_iter().for_each(|rule|
match rule {
Rule::Basic(basic_rule) => { resource_types.insert(basic_rule.type_name); }
Rule::Basic(basic_rule) => { resource_types.insert(basic_rule.type_name); },
Rule::Conditional(conditional_rule) => { resource_types.insert(conditional_rule.type_name); }
}
);
Expand All @@ -146,7 +147,7 @@ pub(crate) fn get_resource_types_in_ruleset(rules: &Vec<RuleLineType>) -> Result
Ok(resource_types_list)
}

pub(crate) fn migrate_rules(rules: Vec<RuleLineType>) -> Result<String> {
pub (crate) fn migrate_rules(rules: Vec<RuleLineType>) -> Result<String> {
let aggr_by_type = aggregate_by_type(&rules);
let migrated_rules = migrated_rules_by_type(&rules, &aggr_by_type)?;

Expand Down
68 changes: 33 additions & 35 deletions guard/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,51 +15,49 @@ mod common_test_helpers;
//
// Application metadata
pub const APP_NAME: &str = "cfn-guard";
pub const APP_VERSION: &str = env!("CARGO_PKG_VERSION");
pub const APP_VERSION: &'static str = env!("CARGO_PKG_VERSION");
// Commands
pub(crate) const MIGRATE: &str = "migrate";
pub(crate) const PARSE_TREE: &str = "parse-tree";
pub(crate) const MIGRATE: &str = "migrate";
pub(crate) const PARSE_TREE: &str = "parse-tree";
pub(crate) const RULEGEN: &str = "rulegen";
pub(crate) const TEST: &str = "test";
pub(crate) const TEST: &str = "test";
pub const VALIDATE: &str = "validate";
// Arguments for validate
pub(crate) const ALPHABETICAL: (&str, char) = ("alphabetical", 'a');
pub const DATA: (&str, char) = ("data", 'd');
pub(crate) const LAST_MODIFIED: (&str, char) = ("last-modified", 'm');
pub(crate) const OUTPUT_FORMAT: (&str, char) = ("output-format", 'o');
pub const INPUT_PARAMETERS: (&str, char) = ("input-parameters", 'i');
pub(crate) const PAYLOAD: (&str, char) = ("payload", 'P');
pub(crate) const PREVIOUS_ENGINE: (&str, char) = ("previous-engine", 'E');
pub(crate) const PRINT_JSON: (&str, char) = ("print-json", 'p');
pub(crate) const SHOW_CLAUSE_FAILURES: (&str, char) = ("show-clause-failures", 's');
pub(crate) const SHOW_SUMMARY: (&str, char) = ("show-summary", 'S');
pub(crate) const TYPE: (&str, char) = ("type", 't');
pub(crate) const VERBOSE: (&str, char) = ("verbose", 'v');
pub(crate) const ALPHABETICAL: (&str, &str) = ("alphabetical", "a");
pub const DATA: (&str, &str) = ("data", "d");
pub(crate) const LAST_MODIFIED: (&str, &str) = ("last-modified", "m");
pub(crate) const OUTPUT_FORMAT: (&str, &str) = ("output-format", "o");
pub const INPUT_PARAMETERS: (&str, &str) = ("input-parameters", "i");
pub(crate) const PAYLOAD: (&str, &str) = ("payload", "P");
pub(crate) const PREVIOUS_ENGINE: (&str, &str) = ("previous-engine","E");
pub(crate) const PRINT_JSON: (&str, &str) = ("print-json", "p");
pub(crate) const SHOW_CLAUSE_FAILURES: (&str, &str) = ("show-clause-failures", "s");
pub(crate) const SHOW_SUMMARY: (&str, &str) = ("show-summary", "S");
pub(crate) const TYPE: (&str, &str) = ("type", "t");
pub(crate) const VERBOSE: (&str, &str) = ("verbose", "v");
// Arguments for validate, migrate, parse tree
pub const RULES: (&str, char) = ("rules", 'r');
pub const RULES: (&str, &str) = ("rules", "r");
// Arguments for migrate, parse-tree, rulegen
pub(crate) const OUTPUT: (&str, char) = ("output", 'o');
pub(crate) const OUTPUT: (&str, &str) = ("output", "o");
// Arguments for parse-tree
pub(crate) const PRINT_YAML: (&str, char) = ("print-yaml", 'y');
pub(crate) const PRINT_YAML: (&str, &str) = ("print-yaml", "y");
// Arguments for test
pub(crate) const RULES_FILE: (&str, char) = ("rules-file", 'r');
pub(crate) const TEST_DATA: (&str, char) = ("test-data", 't');
pub(crate) const DIRECTORY: (&str, char) = ("dir", 'd');
pub(crate) const RULES_FILE: (&str, &str) = ("rules-file", "r");
pub(crate) const TEST_DATA: (&str, &str) = ("test-data", "t");
pub(crate) const DIRECTORY: (&str, &str) = ("dir", "d");
// Arguments for rulegen
pub(crate) const TEMPLATE: (&str, char) = ("template", 'a');
pub(crate) const TEMPLATE: (&str, &str) = ("template", "t");
// Arg group for validate
pub(crate) const REQUIRED_FLAGS: &str = "required_flags";
pub(crate) const REQUIRED_FLAGS: &str = "required_flags";
// Arg group for test
pub(crate) const RULES_AND_TEST_FILE: &str = "rules-and-test-file";
pub(crate) const DIRECTORY_ONLY: &str = "directory-only";
pub(crate) const RULES_AND_TEST_FILE: &str = "rules-and-test-file";
pub(crate) const DIRECTORY_ONLY: &str = "directory-only";


pub(crate) const DATA_FILE_SUPPORTED_EXTENSIONS: [&str; 5] = [
".yaml",
".yml",
".json",
".jsn",
".template"
];
pub(crate) const RULE_FILE_SUPPORTED_EXTENSIONS: [&str; 2] = [".guard",
".ruleset"];
pub(crate) const DATA_FILE_SUPPORTED_EXTENSIONS: [&'static str; 5] = [".yaml",
".yml",
".json",
".jsn",
".template"];
pub(crate) const RULE_FILE_SUPPORTED_EXTENSIONS: [&'static str; 2] = [".guard",
".ruleset"];

0 comments on commit e64fa55

Please sign in to comment.