feat(schematics): add lint check for circular deps

This commit is contained in:
Thomas Skalnik 2018-03-13 23:12:01 +01:00 committed by Victor Savkin
parent 4f052bb3e6
commit 53175f925e
2 changed files with 47 additions and 0 deletions

View File

@ -321,6 +321,41 @@ describe('Enforce Module Boundaries', () => {
);
expect(failures[0].getFailure()).toEqual('imports of apps are forbidden');
});
it('should error when circular dependency detected', () => {
const failures = runRule(
{},
`${process.cwd()}/proj/libs/anotherlib/src/main.ts`,
'import "@mycompany/mylib"',
[
{
name: 'mylib',
root: 'libs/mylib/src',
type: ProjectType.lib,
tags: [],
files: [`libs/mylib/src/main.ts`]
},
{
name: 'anotherlib',
root: 'libs/anotherlib/src',
type: ProjectType.lib,
tags: [],
files: [`libs/anotherlib/src/main.ts`]
},
{
name: 'myapp',
root: 'apps/myapp/src',
type: ProjectType.app,
tags: [],
files: [`apps/myapp/index.ts`]
}
],
{
mylib: [{ projectName: 'anotherlib', type: DependencyType.es6Import }]
}
);
expect(failures[0].getFailure()).toEqual('Circular dependency between \"anotherlib\" and \"mylib\" detected');
});
});
function runRule(

View File

@ -98,6 +98,13 @@ class EnforceModuleBoundariesWalker extends Lint.RuleWalker {
return;
}
// check for circular dependency
if (this.isCircular(sourceProject, targetProject)) {
const error = `Circular dependency between "${sourceProject.name}" and "${targetProject.name}" detected`;
this.addFailureAt(node.getStart(), node.getWidth(), error);
return;
}
// same project => allow
if (sourceProject === targetProject) {
super.visitImportDeclaration(node);
@ -146,6 +153,11 @@ class EnforceModuleBoundariesWalker extends Lint.RuleWalker {
super.visitImportDeclaration(node);
}
private isCircular(sourceProject: ProjectNode, targetProject: ProjectNode): boolean {
if (!this.deps[targetProject.name]) return false;
return this.deps[targetProject.name].some(dep => dep.projectName == sourceProject.name);
}
private onlyLoadChildren(sourceProjectName: string, targetProjectName: string, visited: string[]) {
if (visited.indexOf(sourceProjectName) > -1) return false;
return (this.deps[sourceProjectName] || []).filter(d => {