Skip to content

Commit

Permalink
Added behavior to ignore matching directories (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
flickyiyo authored Oct 18, 2022
1 parent db4bd5b commit ce97c61
Show file tree
Hide file tree
Showing 15 changed files with 1,221 additions and 1,030 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ serde_bytes = "0.11.5"
serde = { version = "1.0.117", features = ["rc"]}
serde_json = "1.0.59"
void = "1.0.2"
regex = "1"
relative-path = "1.7.2"
glob = "0.3.0"
pathdiff = "0.2.0"
Expand Down
25 changes: 23 additions & 2 deletions __test__/index.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,31 @@ import test from 'ava'
import {goodFences} from '../index.js'

test('run tests/good_fences_integration through napi', (t) => {
t.assert(
t.is(
goodFences({
paths: ["tests/good_fences_integration/src"],
project: "tests/good_fences_integration/tsconfig.json",
}).length === 4
}).length, 6
)
})

test('run tests/good_fences_integration through napi ignoring componentA', (t) => {
t.is(
goodFences({
paths: ["tests/good_fences_integration/src"],
project: "tests/good_fences_integration/tsconfig.json",
ignoredDirs: ['componentA']
}).length, 2
)
})

test('run tests/good_fences_integration through napi ignoring componentA and complexComponentA', (t) => {
t.is(
goodFences({
paths: ["tests/good_fences_integration/src"],
project: "tests/good_fences_integration/tsconfig.json",
ignoredDirs: ['componentA', 'complexComponentA'],
}).length, 1
)
})

10 changes: 6 additions & 4 deletions good-fences.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,20 @@
.option('-o, --output <string>', 'path to write found violations')
.option('--baseUrl <string>', "Overrides `compilerOptions.baseUrl` property read from '--project' argument")
.option('--ignoreExternalFences', 'Ignore external fences (e.g. those in `node_modules`)', false)
.option('--ignoredDirs [pathRegexs...]', 'Directories matching given regular expressions are excluded from fence evaluation (e.g. `--ignoreDirs lib` will not evaluate source files in all dirs named `lib`', [])
.arguments('<path> [morePaths...]', 'Dirs to look for fence and source files')
program.parse(process.argv);

const options = program.opts();
const args = program.args;
const options = program.opts();
const args = program.args;

const result = goodFences({
paths: args,
project: options.project,
baseUrl: options.baseUrl,
errOutputPath: options.errOutputPath,
ignoreExternalFences: options.ignoreExternalFences ? 1 : 0
ignoreExternalFences: options.ignoreExternalFences ? 1 : 0,
ignoredDirs: options.ignoredDirs
});
result.forEach(r => {
console.error(r.detailedMessage);
Expand Down
21 changes: 21 additions & 0 deletions src/evaluate_fences.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,15 @@ pub fn evaluate_fences<'fencecollectionlifetime, 'sourcefilelifetime>(
source_files: &HashMap<String, SourceFile>,
tsconfig_paths_json: &TsconfigPathsJson,
source_file: &'sourcefilelifetime SourceFile,
ignored_dirs: Option<&Vec<regex::Regex>>,
) -> Result<Option<Vec<ImportRuleViolation<'fencecollectionlifetime, 'sourcefilelifetime>>>, String>
{
for reg in ignored_dirs.unwrap_or(&Vec::new()) {
if reg.is_match(&source_file.source_file_path.as_str()) {
return Ok(None);
}
}

let mut violations = Vec::<ImportRuleViolation>::new();
let source_fences: Vec<&'fencecollectionlifetime Fence> =
fence_collection.get_fences_for_path(&PathBuf::from(source_file.source_file_path.clone()));
Expand Down Expand Up @@ -384,6 +391,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/index").unwrap(),
Some(&Vec::new()),
);

assert_eq!(
Expand Down Expand Up @@ -421,6 +429,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/index").unwrap(),
Some(&Vec::new()),
);

assert_eq!(
Expand Down Expand Up @@ -458,6 +467,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/index").unwrap(),
Some(&Vec::new()),
);

assert_eq!(
Expand Down Expand Up @@ -495,6 +505,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/index").unwrap(),
Some(&Vec::new()),
);

assert_eq!(
Expand Down Expand Up @@ -538,6 +549,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/friend/index").unwrap(),
Some(&Vec::new()),
);

assert_eq!(violations, Ok(None));
Expand Down Expand Up @@ -568,6 +580,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/index").unwrap(),
Some(&Vec::new()),
);

let d = ExportRule {
Expand Down Expand Up @@ -615,6 +628,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/index").unwrap(),
Some(&Vec::new()),
);

let d = ExportRule {
Expand Down Expand Up @@ -668,6 +682,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/friend/index").unwrap(),
Some(&Vec::new()),
);

assert_eq!(violations, Ok(None));
Expand All @@ -689,6 +704,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/index").unwrap(),
Some(&Vec::new()),
);

assert_eq!(
Expand Down Expand Up @@ -722,6 +738,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/index").unwrap(),
Some(&Vec::new()),
);

assert_eq!(violations, Ok(None));
Expand All @@ -748,6 +765,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/index").unwrap(),
Some(&Vec::new()),
);

let d = DependencyRule {
Expand Down Expand Up @@ -799,6 +817,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/friend/index").unwrap(),
Some(&Vec::new()),
);

assert_eq!(violations, Ok(None));
Expand Down Expand Up @@ -833,6 +852,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/friend/index").unwrap(),
Some(&Vec::new()),
);

let r = DependencyRule {
Expand Down Expand Up @@ -888,6 +908,7 @@ mod test {
&SOURCE_FILES,
&TSCONFIG_PATHS_JSON,
SOURCE_FILES.get("path/to/source/friend/index").unwrap(),
Some(&Vec::new()),
);

assert_eq!(violations, Ok(None));
Expand Down
123 changes: 121 additions & 2 deletions src/good_fences_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,23 @@ impl GoodFencesRunner {

pub fn find_import_violations<'a>(
&'a self,
ignored_dirs: Option<Vec<String>>,
) -> Vec<Result<ImportRuleViolation<'a, 'a>, String>> {
println!("Evaluating {} files", self.source_files.keys().len());
let mut all_violations: Vec<Result<ImportRuleViolation<'a, 'a>, String>> = vec![];
let ignored_dirs = match ignored_dirs {
Some(dirs) => dirs,
None => vec![],
};

let ignored_dirs_regexs: Vec<regex::Regex> = ignored_dirs
.iter()
.map(|id| {
regex::Regex::new(&id.as_str())
.expect(&format!("unable to create regex from --ignoredDirs {}", &id).as_str())
})
.collect();

let violation_results = self
.source_files
.par_iter()
Expand All @@ -99,6 +114,7 @@ impl GoodFencesRunner {
&self.source_files,
&self.tsconfig_paths_json,
&source_file,
Some(&ignored_dirs_regexs),
)
})
.collect::<Vec<_>>();
Expand Down Expand Up @@ -192,7 +208,7 @@ impl GoodFencesRunner {
mod test {
extern crate text_diff;
use crate::evaluate_fences::{ImportRuleViolation, ViolatedFenceClause};
use crate::fence::{ExportRule, Fence, ParsedFence};
use crate::fence::{DependencyRule, ExportRule, Fence, ParsedFence};
use crate::fence_collection::FenceCollection;
use crate::good_fences_runner::{GoodFencesRunner, UndefinedTagReference};
use crate::import_resolver::{TsconfigPathsCompilerOptions, TsconfigPathsJson};
Expand Down Expand Up @@ -245,6 +261,59 @@ mod test {
},
fence_collection: FenceCollection {
fences_map: map!(
"tests/good_fences_integration/src/componentB/someDeep/complexComponentA/fence.json" => Fence {
fence_path: "tests/good_fences_integration/src/componentB/someDeep/complexComponentA/fence.json".to_owned(),
fence: ParsedFence {
tags: Some(
vec!["tagB".to_owned()]
),
exports: None,
dependencies: Some(
vec![
DependencyRule {
dependency: "fs".to_owned(),
accessible_to: vec!["*".to_owned()]
}
]
),
imports: None
}
},
"tests/good_fences_integration/src/componentB/someDeep/componentA/fence.json" => Fence {
fence_path:"tests/good_fences_integration/src/componentB/someDeep/componentA/fence.json".to_owned(),
fence: ParsedFence {
tags: Some(
vec!["tagB".to_owned()]
),
exports: None,
dependencies: Some(
vec![
DependencyRule {
dependency: "fs".to_owned(),
accessible_to: vec!["*".to_owned()]
}
]
),
imports: None
}
},

"tests/good_fences_integration/src/componentC/fence.json" => Fence {
fence_path: "tests/good_fences_integration/src/componentC/fence.json".to_owned(),
fence: ParsedFence {
tags: Some(vec!["tagC".to_owned()]),
exports: Some(
vec![
ExportRule {
accessible_to:vec!["tagA".to_owned()],
modules: "helperC1".to_owned()
}
]
),
dependencies: None,
imports: None
}
},
"tests/good_fences_integration/src/componentA/fence.json" => Fence {
fence_path: "tests/good_fences_integration/src/componentA/fence.json".to_owned(),
fence: ParsedFence {
Expand Down Expand Up @@ -300,6 +369,25 @@ mod test {
),
},
source_files: map!(
"tests/good_fences_integration/src/componentB/someDeep/complexComponentA/index" => SourceFile {
source_file_path: "tests/good_fences_integration/src/componentB/someDeep/complexComponentA/index.ts".to_owned(),
tags: set!("tagB".to_owned()),
imports: map!(
"../../../componentC/helperC1" => Some(set!("default".to_owned()))
)
},
"tests/good_fences_integration/src/componentB/someDeep/componentA/index" => SourceFile {
source_file_path: "tests/good_fences_integration/src/componentB/someDeep/componentA/index.ts".to_owned(),
tags: set!("tagB".to_owned()),
imports: map!(
"../../../componentC/helperC1" => Some(set!("default".to_owned()))
)
},
"tests/good_fences_integration/src/componentC/helperC1" => SourceFile {
source_file_path: "tests/good_fences_integration/src/componentC/helperC1.ts".to_owned(),
tags: set!("tagC".to_owned()),
imports: HashMap::new(),
},
"tests/good_fences_integration/src/requireImportTest" => SourceFile {
source_file_path:"tests/good_fences_integration/src/requireImportTest.ts".to_owned(),
tags: HashSet::new(),
Expand Down Expand Up @@ -439,14 +527,45 @@ mod test {
ExternalFences::Ignore,
);

let mut violations = good_fences_runner.find_import_violations();
let mut violations = good_fences_runner.find_import_violations(Some(vec![]));
violations.sort_by(compare_violations);

let rule = ExportRule {
accessible_to: vec!["tagA".to_owned()],
modules: "componentB".to_owned(),
};

let rule_complex = ExportRule {
accessible_to: vec!["tagA".to_owned()],
modules: "helperC1".to_owned(),
};
let mut expected_violations = vec![
Ok(
ImportRuleViolation {
violating_file_path: "tests/good_fences_integration/src/componentB/someDeep/componentA/index.ts",
violating_fence: good_fences_runner
.fence_collection
.fences_map
.get("tests/good_fences_integration/src/componentC/fence.json")
.unwrap(),
violating_fence_clause: ViolatedFenceClause::ExportRule(Some(&rule_complex)),
violating_import_specifier: "../../../componentC/helperC1",
violating_imported_name: None,
},
),
Ok(
ImportRuleViolation {
violating_file_path: "tests/good_fences_integration/src/componentB/someDeep/complexComponentA/index.ts",
violating_fence: good_fences_runner
.fence_collection
.fences_map
.get("tests/good_fences_integration/src/componentC/fence.json")
.unwrap(),
violating_fence_clause: ViolatedFenceClause::ExportRule(Some(&rule_complex)),
violating_import_specifier: "../../../componentC/helperC1",
violating_imported_name: None,
},
),
Ok(ImportRuleViolation {
violating_file_path: "tests/good_fences_integration/src/componentA/helperA1.ts",
violating_fence: good_fences_runner
Expand Down
6 changes: 4 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ pub mod walk_dirs;
pub fn good_fences(opts: GoodFencesOptions) -> Vec<GoodFencesError> {
let start = Instant::now();
let tsconfig_path = opts.project;
let mut tsconfig = import_resolver::TsconfigPathsJson::from_path(tsconfig_path).unwrap();
let mut tsconfig = import_resolver::TsconfigPathsJson::from_path(tsconfig_path)
.expect("Unable to find --project path");

if opts.base_url.is_some() {
tsconfig.compiler_options.base_url = opts.base_url;
Expand All @@ -36,7 +37,7 @@ pub fn good_fences(opts: GoodFencesOptions) -> Vec<GoodFencesError> {
);

println!("beginning fence evaluations");
let violations = good_fences_runner.find_import_violations();
let violations = good_fences_runner.find_import_violations(opts.ignored_dirs);
let elapsed = start.elapsed();

// Print results and statistics
Expand Down Expand Up @@ -79,6 +80,7 @@ pub struct GoodFencesOptions {
pub base_url: Option<String>,
pub err_output_path: Option<String>,
pub ignore_external_fences: Option<ExternalFences>,
pub ignored_dirs: Option<Vec<String>>,
}

#[napi]
Expand Down
Loading

0 comments on commit ce97c61

Please sign in to comment.