Skip to content

Commit

Permalink
feat(nx): support to generate visualization graph
Browse files Browse the repository at this point in the history
`npm run dep-graph` outputs a visual dependency graph
  • Loading branch information
Nitin Vericherla authored and vsavkin committed Apr 7, 2018
1 parent eca5259 commit 49525ef
Show file tree
Hide file tree
Showing 18 changed files with 660 additions and 55 deletions.
132 changes: 132 additions & 0 deletions e2e/schematics/command-line.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,4 +286,136 @@ describe('Command line', () => {
},
1000000
);
describe('dep-graph', () => {
beforeEach(() => {
newProject();
newApp('myapp');
newApp('myapp2');
newApp('myapp3');
newLib('mylib');
newLib('mylib2');

updateFile(
'apps/myapp/src/main.ts',
`
import '@proj/mylib';
const s = {loadChildren: '@proj/mylib2'};
`
);

updateFile(
'apps/myapp2/src/app/app.component.spec.ts',
`import '@proj/mylib';`
);

updateFile(
'libs/mylib/src/mylib.module.spec.ts',
`import '@proj/mylib2';`
);
});

it(
'dep-graph should output json (without critical path) to file',
() => {
const file = 'dep-graph.json';

runCommand(`npm run dep-graph -- --file="${file}"`);

expect(() => checkFilesExist(file)).not.toThrow();

const jsonFileContents = readJson(file);

expect(jsonFileContents).toEqual({
deps: {
mylib2: [],
myapp3: [],
myapp2: [
{
projectName: 'mylib',
type: 'es6Import'
}
],
mylib: [
{
projectName: 'mylib2',
type: 'es6Import'
}
],
myapp: [
{
projectName: 'mylib',
type: 'es6Import'
},
{
projectName: 'mylib2',
type: 'loadChildren'
}
]
},
criticalPath: []
});
},
1000000
);

it(
'dep-graph should output json with critical path to file',
() => {
const file = 'dep-graph.json';

runCommand(
`npm run affected:dep-graph -- --files="libs/mylib/index.ts" --file="${file}"`
);

expect(() => checkFilesExist(file)).not.toThrow();

const jsonFileContents = readJson(file);

expect(jsonFileContents.criticalPath).toContain('myapp');
expect(jsonFileContents.criticalPath).toContain('myapp2');
expect(jsonFileContents.criticalPath).toContain('mylib');
expect(jsonFileContents.criticalPath).not.toContain('mylib2');
},
1000000
);

it(
'dep-graph should output dot to file',
() => {
const file = 'dep-graph.dot';

runCommand(
`npm run dep-graph -- --files="libs/mylib/index.ts" --file="${file}"`
);

expect(() => checkFilesExist(file)).not.toThrow();

const fileContents = readFile(file);
expect(fileContents).toContain('"myapp" -> "mylib"');
expect(fileContents).toContain('"myapp2" -> "mylib"');
expect(fileContents).toContain('"mylib" -> "mylib2"');
},
1000000
);

it(
'dep-graph should output html to file',
() => {
const file = 'dep-graph.html';
runCommand(
`npm run dep-graph -- --files="libs/mylib/index.ts" --file="${file}"`
);

expect(() => checkFilesExist(file)).not.toThrow();

const fileContents = readFile(file);
expect(fileContents).toContain('<html>');
expect(fileContents).toContain('<title>myapp&#45;&gt;mylib</title>');
expect(fileContents).toContain('<title>myapp&#45;&gt;mylib2</title>');
expect(fileContents).toContain('<title>mylib&#45;&gt;mylib2</title>');
},
1000000
);
});
});
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
"copy": "./scripts/copy.sh",
"test:schematics": "yarn linknpm fast && ./scripts/test_schematics.sh",
"test:nx": "yarn linknpm fast && ./scripts/test_nx.sh",
"test":
"yarn linknpm fast && ./scripts/test_nx.sh && ./scripts/test_schematics.sh",
"test": "yarn linknpm fast && ./scripts/test_nx.sh && ./scripts/test_schematics.sh",
"checkformat": "prettier \"{packages,e2e}/**/*.ts\" --list-different",
"publish_npm": "./scripts/publish.sh"
},
Expand Down Expand Up @@ -44,6 +43,7 @@
"angular": "1.6.6",
"app-root-path": "^2.0.1",
"cosmiconfig": "^4.0.0",
"graphviz": "^0.0.8",
"husky": "^0.14.3",
"jasmine-core": "~2.8.0",
"jasmine-spec-reporter": "~4.2.1",
Expand All @@ -52,8 +52,9 @@
"karma-chrome-launcher": "~2.2.0",
"karma-jasmine": "~1.1.0",
"karma-webpack": "2.0.4",
"npm-run-all": "4.1.2",
"ng-packagr": "2.2.0",
"npm-run-all": "4.1.2",
"opn": "^5.3.0",
"precise-commits": "1.0.0",
"prettier": "1.10.2",
"rxjs": "^5.5.6",
Expand All @@ -62,6 +63,7 @@
"tmp": "0.0.33",
"tslint": "5.9.1",
"typescript": "2.6.2",
"viz.js": "^1.8.1",
"yargs-parser": "9.0.2",
"zone.js": "^0.8.19",
"fs-extra": "5.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
"affected:apps": "./node_modules/.bin/nx affected apps",
"affected:build": "./node_modules/.bin/nx affected build",
"affected:e2e": "./node_modules/.bin/nx affected e2e",
"affected:dep-graph": "./node_modules/.bin/nx affected dep-graph",
"format": "./node_modules/.bin/nx format write",
"format:write": "./node_modules/.bin/nx format write",
"format:check": "./node_modules/.bin/nx format check",
"update": "./node_modules/.bin/nx update",
"update:check": "./node_modules/.bin/nx update check",
"update:skip": "./node_modules/.bin/nx update skip",
"dep-graph": "./node_modules/.bin/nx dep-graph",
"postinstall": "ngc -p ngc.tsconfig.json"
},
"private": true,
Expand Down
20 changes: 19 additions & 1 deletion packages/bazel/src/utils/fileutils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import * as fs from 'fs';
import * as path from 'path';

export function writeToFile(path: string, str: string) {
fs.writeFileSync(path, str);
}

/**
* This method is specifically for updating a JSON file using the filesystem
*
Expand All @@ -12,7 +16,7 @@ import * as path from 'path';
export function updateJsonFile(path: string, callback: (a: any) => any) {
const json = readJsonFile(path);
callback(json);
fs.writeFileSync(path, JSON.stringify(json, null, 2));
writeToFile(path, JSON.stringify(json, null, 2));
}

export function addApp(apps: any[] | undefined, newApp: any): any[] {
Expand Down Expand Up @@ -59,3 +63,17 @@ export function copyFile(file: string, target: string) {
source.pipe(dest);
source.on('error', e => console.error(e));
}

function directoryExists(name) {
try {
return fs.statSync(name).isDirectory();
} catch (e) {
return false;
}
}

export function createDirectory(name: string) {
if (!directoryExists(name)) {
fs.mkdirSync(name);
}
}
14 changes: 14 additions & 0 deletions packages/schematics/migrations/20180404-adding-dep-graph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { updateJsonFile } from '../src/utils/fileutils';

export default {
description: 'Update npm scripts to use the nx command',
run: () => {
updateJsonFile('package.json', json => {
json.scripts = {
...json.scripts,
'dep-graph': './node_modules/.bin/nx dep-graph',
'affected:dep-graph': './node_modules/.bin/nx affected dep-graph'
};
});
}
};
5 changes: 4 additions & 1 deletion packages/schematics/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
"main": "index.js",
"types": "index.d.js",
"peerDependencies": { },
"peerDependencies": {},
"author": "Victor Savkin",
"license": "MIT",
"bugs": {
Expand All @@ -32,9 +32,12 @@
"@ngrx/schematics": "5.2.0",
"@schematics/angular": "0.4.6",
"app-root-path": "^2.0.1",
"graphviz": "0.0.8",
"npm-run-all": "4.1.2",
"opn": "^5.3.0",
"semver": "5.4.1",
"tmp": "0.0.33",
"viz.js": "^1.8.1",
"yargs-parser": "9.0.2"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,18 @@
"test": "ng test",
"lint": "./node_modules/.bin/nx lint && ng lint",
"e2e": "ng e2e",

"affected:apps": "./node_modules/.bin/nx affected apps",
"affected:build": "./node_modules/.bin/nx affected build",
"affected:e2e": "./node_modules/.bin/nx affected e2e",

"affected:dep-graph": "./node_modules/.bin/nx affected dep-graph",
"format": "./node_modules/.bin/nx format write",
"format:write": "./node_modules/.bin/nx format write",
"format:check": "./node_modules/.bin/nx format check",

"update": "./node_modules/.bin/nx update",
"update:check": "./node_modules/.bin/nx update check",
"update:skip": "./node_modules/.bin/nx update skip",

"workspace-schematic": "./node_modules/.bin/nx workspace-schematic",
"dep-graph": "./node_modules/.bin/nx dep-graph",
"postinstall": "./node_modules/.bin/nx postinstall"
},
"private": true,
Expand All @@ -43,7 +41,8 @@
"@ngrx/router-store": "<%= routerStoreVersion %>",
"@ngrx/store": "<%= ngrxVersion %>",
"@ngrx/store-devtools": "<%= ngrxVersion %>",
"ngrx-store-freeze": "<%= ngrxStoreFreezeVersion %>"
"ngrx-store-freeze": "<%= ngrxStoreFreezeVersion %>",
"viz": "^0.0.1"
},
"devDependencies": {
"@angular/cli": "<%= angularCliVersion %>",
Expand All @@ -52,19 +51,20 @@
"@nrwl/schematics": "<%= schematicsVersion %>",
"@angular/language-service": "<%= angularVersion %>",<% if (!minimal) { %>
"@types/jasmine": "~2.8.3",
"@types/jasminewd2": "~2.0.2",
"@types/node": "~6.0.60",
"codelyzer": "^4.0.1",
"jasmine-core": "~2.8.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~2.0.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.1.2",
"ts-node": "~4.1.0",
"tslint": "~5.9.1",<% } %>
"@types/jasminewd2": "~2.0.2",
"@types/node": "~6.0.60",
"codelyzer": "^4.0.1",
"jasmine-core": "~2.8.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~2.0.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.1.2",
"ts-node": "~4.1.0",
"tslint": "~5.9.1",<%
} %>
"typescript": "<%= typescriptVersion %>",
"prettier": "<%= prettierVersion %>"
}
Expand Down
6 changes: 6 additions & 0 deletions packages/schematics/src/collection/workspace/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ function updatePackageJson() {
'./node_modules/.bin/nx affected build';
packageJson.scripts['affected:e2e'] = './node_modules/.bin/nx affected e2e';

packageJson.scripts['affected:dep-graph'] =
'./node_modules/.bin/nx affected dep-graph';

packageJson.scripts['format'] = './node_modules/.bin/nx format write';
packageJson.scripts['format:write'] = './node_modules/.bin/nx format write';
packageJson.scripts['format:check'] = './node_modules/.bin/nx format check';
Expand All @@ -94,6 +97,9 @@ function updatePackageJson() {
packageJson.scripts['update:skip'] = './node_modules/.bin/nx update skip';

packageJson.scripts['lint'] = './node_modules/.bin/nx lint && ng lint';

packageJson.scripts['dep-graph'] = './node_modules/.bin/nx dep-graph';

packageJson.scripts['postinstall'] = './node_modules/.bin/nx postinstall';
packageJson.scripts['workspace-schematic'] =
'./node_modules/.bin/nx workspace-schematic';
Expand Down
12 changes: 6 additions & 6 deletions packages/schematics/src/command-line/affected-apps.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
affectedApps,
affectedAppNames,
dependencies,
DependencyType,
ProjectType,
Expand Down Expand Up @@ -254,9 +254,9 @@ describe('Calculates Dependencies Between Apps and Libs', () => {
});
});

describe('affectedApps', () => {
describe('affectedAppNames', () => {
it('should return the list of affected files', () => {
const affected = affectedApps(
const affected = affectedAppNames(
'nrwl',
[
{
Expand Down Expand Up @@ -309,7 +309,7 @@ describe('Calculates Dependencies Between Apps and Libs', () => {
});

it('should return app app names if a touched file is not part of a project', () => {
const affected = affectedApps(
const affected = affectedAppNames(
'nrwl',
[
{
Expand Down Expand Up @@ -353,7 +353,7 @@ describe('Calculates Dependencies Between Apps and Libs', () => {
});

it('should handle slashes', () => {
const affected = affectedApps(
const affected = affectedAppNames(
'nrwl',
[
{
Expand All @@ -379,7 +379,7 @@ describe('Calculates Dependencies Between Apps and Libs', () => {
});

it('should handle circular dependencies', () => {
const affected = affectedApps(
const affected = affectedAppNames(
'nrwl',
[
{
Expand Down
Loading

0 comments on commit 49525ef

Please sign in to comment.