Skip to content

Commit

Permalink
fix(tslint): disallow importing apps
Browse files Browse the repository at this point in the history
  • Loading branch information
vsavkin committed Jan 5, 2018
1 parent df5bd08 commit 912fc81
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 10 deletions.
5 changes: 4 additions & 1 deletion e2e/schematics/command-line.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ describe('Command line', () => {
import '../../../libs/mylib';
import '@nrwl/lazylib';
import '@nrwl/mylib/deep';
import '@nrwl/myapp';
import '@nrwl/myapp/main';
`
);

const out = runCLI('lint --type-check', { silenceError: true });
expect(out).toContain('library imports must start with @nrwl/');
expect(out).toContain('import of lazy-loaded libraries are forbidden');
expect(out).toContain('imports of lazy-loaded libraries are forbidden');
expect(out).toContain('deep imports into libraries are forbidden');
expect(out).toContain('imports of apps are forbidden');
},
1000000
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,30 @@ describe('Enforce Module Boundaries', () => {
const failures = runRule({ lazyLoad: ['mylib'] }, `import '@mycompany/mylib';`);

expect(failures.length).toEqual(1);
expect(failures[0].getFailure()).toEqual('import of lazy-loaded libraries are forbidden');
expect(failures[0].getFailure()).toEqual('imports of lazy-loaded libraries are forbidden');
});

it('should error on importing an app', () => {
const failures = runRule({ lazyLoad: ['mylib'] }, `import '@mycompany/myapp';`, [], ['myapp']);

expect(failures.length).toEqual(1);
expect(failures[0].getFailure()).toEqual('imports of apps are forbidden');
});
});

function runRule(ruleArguments: any, content: string, appNames: string[] = ['mylib']): RuleFailure[] {
function runRule(
ruleArguments: any,
content: string,
libNames: string[] = ['mylib'],
appNames: string[] = []
): RuleFailure[] {
const options: any = {
ruleArguments: [ruleArguments],
ruleSeverity: 'error',
ruleName: 'enforceModuleBoundaries'
};

const sourceFile = ts.createSourceFile('proj/apps/myapp/src/main.ts', content, ts.ScriptTarget.Latest, true);
const rule = new Rule(options, 'proj', 'mycompany', appNames);
const rule = new Rule(options, 'proj', 'mycompany', libNames, appNames);
return rule.apply(sourceFile);
}
35 changes: 29 additions & 6 deletions packages/schematics/src/tslint/nxEnforceModuleBoundariesRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,33 @@ import * as ts from 'typescript';
import { readFileSync } from 'fs';

export class Rule extends Lint.Rules.AbstractRule {
constructor(options: IOptions, private path?: string, private npmScope?: string, private appNames?: string[]) {
constructor(
options: IOptions,
private path?: string,
private npmScope?: string,
private libNames?: string[],
private appNames?: string[]
) {
super(options);
if (!path) {
const cliConfig = this.readCliConfig();
this.path = process.cwd();
this.npmScope = cliConfig.project.npmScope;
this.appNames = cliConfig.apps.map(a => a.name);
this.libNames = cliConfig.apps.filter(p => p.root.startsWith('libs/')).map(a => a.name);
this.appNames = cliConfig.apps.filter(p => p.root.startsWith('apps/')).map(a => a.name);
}
}

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(
new EnforceModuleBoundariesWalker(sourceFile, this.getOptions(), this.path, this.npmScope, this.appNames)
new EnforceModuleBoundariesWalker(
sourceFile,
this.getOptions(),
this.path,
this.npmScope,
this.libNames,
this.appNames
)
);
}

Expand All @@ -32,6 +46,7 @@ class EnforceModuleBoundariesWalker extends Lint.RuleWalker {
options: IOptions,
private projectPath: string,
private npmScope: string,
private libNames: string[],
private appNames: string[]
) {
super(sourceFile, options);
Expand All @@ -52,9 +67,9 @@ class EnforceModuleBoundariesWalker extends Lint.RuleWalker {
return;
}

const lazyLoaded = lazyLoad.filter(a => imp.startsWith(`@${this.npmScope}/${a}`))[0];
const lazyLoaded = lazyLoad.filter(l => imp.startsWith(`@${this.npmScope}/${l}`))[0];
if (lazyLoaded) {
this.addFailureAt(node.getStart(), node.getWidth(), 'import of lazy-loaded libraries are forbidden');
this.addFailureAt(node.getStart(), node.getWidth(), 'imports of lazy-loaded libraries are forbidden');
return;
}

Expand All @@ -63,12 +78,20 @@ class EnforceModuleBoundariesWalker extends Lint.RuleWalker {
return;
}

const deepImport = this.appNames.filter(a => imp.startsWith(`@${this.npmScope}/${a}/`))[0];
const deepImport = this.libNames.filter(l => imp.startsWith(`@${this.npmScope}/${l}/`))[0];
if (deepImport) {
this.addFailureAt(node.getStart(), node.getWidth(), 'deep imports into libraries are forbidden');
return;
}

const appImport = this.appNames.filter(
a => imp.startsWith(`@${this.npmScope}/${a}/`) || imp === `@${this.npmScope}/${a}`
)[0];
if (appImport) {
this.addFailureAt(node.getStart(), node.getWidth(), 'imports of apps are forbidden');
return;
}

super.visitImportDeclaration(node);
}

Expand Down

0 comments on commit 912fc81

Please sign in to comment.