Skip to content

Commit

Permalink
feat(schematics): add support for tagged libs
Browse files Browse the repository at this point in the history
  • Loading branch information
vsavkin committed Mar 13, 2018
1 parent 56788ba commit 2842cb9
Show file tree
Hide file tree
Showing 17 changed files with 347 additions and 89 deletions.
11 changes: 10 additions & 1 deletion e2e/schematics/command-line.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ describe('Command line', () => {
'lint should ensure module boundaries',
() => {
newProject();
newApp('myapp');
newApp('myapp --tags=validtag');
newApp('myapp2');
newLib('mylib');
newLib('lazylib');
newLib('invalidtaglib --tags=invalidtag');
newLib('validtaglib --tags=validtag');

const tslint = JSON.parse(readFile('tslint.json'));
tslint.rules["nx-enforce-module-boundaries"][1].depConstraints = [
{ "sourceTag": "validtag", "onlyDependOnLibsWithTags": ["validtag"] },
...tslint.rules["nx-enforce-module-boundaries"][1].depConstraints
];
updateFile('tslint.json', JSON.stringify(tslint, null, 2));

updateFile(
Expand All @@ -20,6 +26,8 @@ describe('Command line', () => {
import '@proj/lazylib';
import '@proj/mylib/deep';
import '@proj/myapp2';
import '@proj/invalidtaglib';
import '@proj/validtaglib';
const s = {loadChildren: '@proj/lazylib'};
`
Expand All @@ -30,6 +38,7 @@ describe('Command line', () => {
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');
expect(out).toContain('A project tagged with "validtag" can only depend on libs tagged with "validtag"');
},
1000000
);
Expand Down
19 changes: 19 additions & 0 deletions packages/schematics/migrations/20180313-add-tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {updateJsonFile} from '../../shared/fileutils';

export default {
description: 'Add tags to all app and libs',
run: async () => {
updateJsonFile('.angular-cli.json', json => {
json.apps = json.apps.map(app => ({...app, tags: []}));
});

updateJsonFile('tslint.json', json => {
if (json.rules["nx-enforce-module-boundaries"]) {
json.rules["nx-enforce-module-boundaries"][1].depConstraints = [
{ "sourceTag": "*", "onlyDependOnLibsWithTags": ["*"] }
];
json.rules["nx-enforce-module-boundaries"][1].lazyLoad = undefined;
}
});
}
};
10 changes: 10 additions & 0 deletions packages/schematics/src/collection/app/app.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ describe('app', () => {
root: 'apps/my-app/src',
scripts: [],
styles: ['styles.css'],
tags: [],
test: '../../../test.js',
testTsconfig: '../../../tsconfig.spec.json',
tsconfig: 'tsconfig.app.json'
Expand Down Expand Up @@ -88,6 +89,7 @@ describe('app', () => {
root: 'apps/my-dir/my-app/src',
scripts: [],
styles: ['styles.css'],
tags: [],
test: '../../../../test.js',
testTsconfig: '../../../../tsconfig.spec.json',
tsconfig: 'tsconfig.app.json'
Expand Down Expand Up @@ -169,4 +171,12 @@ describe('app', () => {
);
});
});

describe('tags', () => {
it('should split tags by a comma', () => {
const tree = schematicRunner.runSchematic('app', { name: 'myApp', npmScope: 'nrwl', tags: 'one,two' }, appTree);
const updatedAngularCLIJson = JSON.parse(getFileContent(tree, '/.angular-cli.json'));
expect(updatedAngularCLIJson.apps[0].tags).toEqual(['one', 'two']);
});
});
});
4 changes: 3 additions & 1 deletion packages/schematics/src/collection/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ function addAppToAngularCliJson(options: NormalizedSchema): Rule {
throw new Error('Missing .angular-cli.json');
}

const tags = options.tags ? options.tags.split(',').map(s => s.trim()) : [];
const sourceText = host.read('.angular-cli.json')!.toString('utf-8');
const json = JSON.parse(sourceText);
json.apps = addApp(json.apps, {
Expand All @@ -82,7 +83,8 @@ function addAppToAngularCliJson(options: NormalizedSchema): Rule {
environments: {
dev: 'environments/environment.ts',
prod: 'environments/environment.prod.ts'
}
},
tags
});

json.lint = [
Expand Down
1 change: 1 addition & 0 deletions packages/schematics/src/collection/app/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export interface Schema {
skipTests?: boolean;
prefix?: string;
style?: string;
tags?: string;
}
4 changes: 4 additions & 0 deletions packages/schematics/src/collection/app/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
"description": "The file extension to be used for style files.",
"type": "string",
"default": "css"
},
"tags": {
"type": "string",
"description": "Add tags to the application (used for linting)"
}
},
"required": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@
"nx-enforce-module-boundaries": [
true,
{
"allow": []
"allow": [],
"depConstraints": [
{ "sourceTag": "*", "onlyDependOnLibsWithTags": ["*"] }
]
}
]
}
Expand Down
21 changes: 3 additions & 18 deletions packages/schematics/src/collection/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ interface NormalizedSchema extends Schema {

function addLibToAngularCliJson(options: NormalizedSchema): Rule {
return (host: Tree) => {
const tags = options.tags ? options.tags.split(',').map(s => s.trim()) : [];
const json = cliConfig(host);
json.apps = addApp(json.apps, {
name: options.fullName,
root: options.fullPath,
test: `${offsetFromRoot(options.fullPath)}test.js`,
appRoot: ''
appRoot: '',
tags
});

host.overwrite('.angular-cli.json', serializeJson(json));
Expand Down Expand Up @@ -141,22 +143,6 @@ function addChildren(schema: NormalizedSchema): Rule {
};
}

function updateTsLint(schema: NormalizedSchema): Rule {
return (host: Tree) => {
const tsLint = JSON.parse(host.read('tslint.json')!.toString('utf-8'));
if (
tsLint['rules'] &&
tsLint['rules']['nx-enforce-module-boundaries'] &&
tsLint['rules']['nx-enforce-module-boundaries'][1] &&
tsLint['rules']['nx-enforce-module-boundaries'][1]['lazyLoad']
) {
tsLint['rules']['nx-enforce-module-boundaries'][1]['lazyLoad'].push(toFileName(schema.fullName));
host.overwrite('tslint.json', serializeJson(tsLint));
}
return host;
};
}

export default function(schema: Schema): Rule {
return wrapIntoFormat(() => {
const options = normalizeOptions(schema);
Expand Down Expand Up @@ -185,7 +171,6 @@ export default function(schema: Schema): Rule {
branchAndMerge(chain([mergeWith(templateSource)])),
addLibToAngularCliJson(options),
options.routing && options.lazy ? addLazyLoadedRouterConfiguration(modulePath) : noop(),
options.routing && options.lazy ? updateTsLint(options) : noop(),
options.routing && options.lazy && options.parentModule ? addLoadChildren(options) : noop(),

options.routing && !options.lazy ? addRouterConfiguration(options, indexFile, moduleFileName, modulePath) : noop(),
Expand Down
20 changes: 10 additions & 10 deletions packages/schematics/src/collection/lib/lib.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe('lib', () => {
appRoot: '',
name: 'my-lib',
root: 'libs/my-lib/src',
tags: [],
test: '../../../test.js'
}
]);
Expand Down Expand Up @@ -57,6 +58,7 @@ describe('lib', () => {
appRoot: '',
name: 'my-dir/my-lib',
root: 'libs/my-dir/my-lib/src',
tags: [],
test: '../../../../test.js'
}
]);
Expand Down Expand Up @@ -148,16 +150,6 @@ describe('lib', () => {
'../../../libs/my-dir/my-lib2/index.ts'
]);
});

it('should register the module as lazy loaded in tslint.json', () => {
const tree = schematicRunner.runSchematic(
'lib',
{ name: 'myLib', directory: 'myDir', routing: true, lazy: true },
appTree
);
const tslint = JSON.parse(getFileContent(tree, 'tslint.json'));
expect(tslint['rules']['nx-enforce-module-boundaries'][1]['lazyLoad']).toEqual(['my-dir/my-lib']);
});
});

describe('eager', () => {
Expand Down Expand Up @@ -192,5 +184,13 @@ describe('lib', () => {
);
});
});

describe('tags', () => {
it('should split tags by a comma', () => {
const tree = schematicRunner.runSchematic('lib', { name: 'myLib', tags: 'one,two' }, appTree);
const updatedAngularCLIJson = JSON.parse(getFileContent(tree, '/.angular-cli.json'));
expect(updatedAngularCLIJson.apps[0].tags).toEqual(['one', 'two']);
});
});
});
});
1 change: 1 addition & 0 deletions packages/schematics/src/collection/lib/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export interface Schema {
routing?: boolean;
lazy?: boolean;
parentModule?: string;
tags?: string;
}
4 changes: 4 additions & 0 deletions packages/schematics/src/collection/lib/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
"parentModule": {
"type": "string",
"description": "Update the router configuration of the parent module using loadChildren or children, depending on what `lazy` is set to."
},
"tags": {
"type": "string",
"description": "Add tags to the library (used for linting)"
}
},
"required": [
Expand Down
11 changes: 10 additions & 1 deletion packages/schematics/src/collection/workspace/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ function updateAngularCLIJson(options: Schema) {
app.test = '../../../test.js';
app.testTsconfig = '../../../tsconfig.spec.json';
app.scripts = app.scripts.map(p => path.join('../../', p));
app.tags = [];
if (!angularCliJson.defaults) {
angularCliJson.defaults = {};
}
Expand Down Expand Up @@ -187,7 +188,15 @@ function updateTsLintJson(options: Schema) {
json[key] = undefined;
});
json.rulesDirectory.push('node_modules/@nrwl/schematics/src/tslint');
json['nx-enforce-module-boundaries'] = [true, { allow: [] }];
json['nx-enforce-module-boundaries'] = [
true,
{
"allow": [],
"depConstraints": [
{ "sourceTag": "*", "onlyDependOnLibsWithTags": ["*"] }
]
}
];
});
return host;
};
Expand Down
Loading

0 comments on commit 2842cb9

Please sign in to comment.