From 826a0b1056f9000425e189bad5a5d63966c3a704 Mon Sep 17 00:00:00 2001 From: vsavkin Date: Tue, 2 Jan 2018 15:33:47 -0500 Subject: [PATCH] feat(schematics): add format:check and format:write commands --- e2e/schematics/affected.test.ts | 36 ------ e2e/schematics/command-line.test.ts | 114 ++++++++++++++++++ e2e/schematics/migrator.test.ts | 29 ----- e2e/schematics/tslint.test.ts | 32 ----- .../20180103-update-command-line-scripts.ts | 25 ++++ .../files/__directory__/package.json | 19 ++- .../src/collection/utility/lib-versions.ts | 2 +- .../affected-apps.spec.ts} | 2 +- .../affected-apps.ts} | 0 .../affected.ts} | 2 +- .../schematics/src/command-line/format.ts | 65 ++++++++++ .../nx-migrate.ts} | 0 12 files changed, 221 insertions(+), 105 deletions(-) delete mode 100644 e2e/schematics/affected.test.ts create mode 100644 e2e/schematics/command-line.test.ts delete mode 100644 e2e/schematics/migrator.test.ts delete mode 100644 e2e/schematics/tslint.test.ts create mode 100644 packages/schematics/migrations/20180103-update-command-line-scripts.ts rename packages/schematics/src/{affected/affected.spec.ts => command-line/affected-apps.spec.ts} (98%) rename packages/schematics/src/{affected/affected.ts => command-line/affected-apps.ts} (100%) rename packages/schematics/src/{affected/run-affected.ts => command-line/affected.ts} (98%) create mode 100644 packages/schematics/src/command-line/format.ts rename packages/schematics/src/{migrator/migrator.ts => command-line/nx-migrate.ts} (100%) diff --git a/e2e/schematics/affected.test.ts b/e2e/schematics/affected.test.ts deleted file mode 100644 index e68a525ec95cb..0000000000000 --- a/e2e/schematics/affected.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { newApp, newLib, newProject, readFile, runCLI, runCommand, updateFile } from '../utils'; - -describe('Affected', () => { - fit( - 'should print, build, and test affected apps', - () => { - newProject(); - newApp('myapp'); - newApp('myapp2'); - newLib('mylib'); - - updateFile('apps/myapp/src/app/app.component.spec.ts', `import '@nrwl/mylib';`); - - updateRunAffectedToWorkInE2ESetup(); - - const affectedApps = runCommand('npm run apps:affected -- --files="libs/mylib/index.ts"'); - expect(affectedApps).toContain('myapp'); - expect(affectedApps).not.toContain('myapp2'); - - const build = runCommand('npm run build:affected -- --files="libs/mylib/index.ts"'); - expect(build).toContain('Building myapp'); - - const e2e = runCommand('npm run e2e:affected -- --files="libs/mylib/index.ts"'); - expect(e2e).toContain('should display welcome message'); - }, - 1000000 - ); -}); - -function updateRunAffectedToWorkInE2ESetup() { - const runAffected = readFile('node_modules/@nrwl/schematics/src/affected/run-affected.js'); - const newRunAffected = runAffected - .replace('ng build', '../../node_modules/.bin/ng build') - .replace('ng e2e', '../../node_modules/.bin/ng e2e'); - updateFile('node_modules/@nrwl/schematics/src/affected/run-affected.js', newRunAffected); -} diff --git a/e2e/schematics/command-line.test.ts b/e2e/schematics/command-line.test.ts new file mode 100644 index 0000000000000..6384570022541 --- /dev/null +++ b/e2e/schematics/command-line.test.ts @@ -0,0 +1,114 @@ +import { newApp, newLib, newProject, readFile, runCLI, runCommand, updateFile } from '../utils'; + +describe('Command line', () => { + it( + 'lint should ensure module boundaries', + () => { + newProject(); + newApp('myapp'); + newLib('mylib'); + newLib('lazylib'); + + const tslint = JSON.parse(readFile('tslint.json')); + tslint.rules['nx-enforce-module-boundaries'][1].lazyLoad.push('lazylib'); + updateFile('tslint.json', JSON.stringify(tslint, null, 2)); + + updateFile( + 'apps/myapp/src/main.ts', + ` + import '../../../libs/mylib'; + import '@nrwl/lazylib'; + import '@nrwl/mylib/deep'; + ` + ); + + 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('deep imports into libraries are forbidden'); + }, + 1000000 + ); + + it( + 'nx-migrate should run migrations', + () => { + newProject(); + updateFile( + 'node_modules/@nrwl/schematics/migrations/20200101-test-migration.js', + ` + exports.default = { + description: 'Test migration', + run: function() { + console.log('Running test migration'); + } + }; + ` + ); + const out = runCommand('npm run nx-migrate'); + expect(out).toContain('Test migration'); + expect(out).toContain('Running test migration'); + expect(out).toContain('All migrations run successfully'); + + expect(runCommand('npm run nx-migrate')).toContain('No migrations to run'); + }, + 1000000 + ); + + it( + 'affected should print, build, and test affected apps', + () => { + newProject(); + newApp('myapp'); + newApp('myapp2'); + newLib('mylib'); + + updateFile('apps/myapp/src/app/app.component.spec.ts', `import '@nrwl/mylib';`); + + updateRunAffectedToWorkInE2ESetup(); + + const affectedApps = runCommand('npm run affected:apps -- --files="libs/mylib/index.ts"'); + expect(affectedApps).toContain('myapp'); + expect(affectedApps).not.toContain('myapp2'); + + const build = runCommand('npm run affected:build -- --files="libs/mylib/index.ts"'); + expect(build).toContain('Building myapp'); + + const e2e = runCommand('npm run affected:e2e -- --files="libs/mylib/index.ts"'); + expect(e2e).toContain('should display welcome message'); + }, + 1000000 + ); + + it( + 'format should check and reformat the code', + () => { + newProject(); + newApp('myapp'); + updateFile( + 'apps/myapp/src/main.ts', + ` + const x = 3232; + ` + ); + + try { + runCommand('npm run -s format:check'); + fail('boom'); + } catch (e) { + expect(e.stdout.toString()).toContain('apps/myapp/src/main.ts'); + } + runCommand('npm run format:write'); + expect(runCommand('npm run -s format:check')).toEqual(''); + }, + 1000000 + ); +}); + +function updateRunAffectedToWorkInE2ESetup() { + const runAffected = readFile('node_modules/@nrwl/schematics/src/command-line/affected.js'); + const newRunAffected = runAffected + .replace('ng build', '../../node_modules/.bin/ng build') + .replace('ng e2e', '../../node_modules/.bin/ng e2e'); + updateFile('node_modules/@nrwl/schematics/src/command-line/affected.js', newRunAffected); +} diff --git a/e2e/schematics/migrator.test.ts b/e2e/schematics/migrator.test.ts deleted file mode 100644 index c86eda3651233..0000000000000 --- a/e2e/schematics/migrator.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { newProject, runCommand, updateFile } from '../utils'; -import { updateJsonFile } from '../../packages/schematics/src/collection/utility/fileutils'; - -describe('Migrator', () => { - it( - 'should run migrations', - () => { - newProject(); - updateFile( - 'node_modules/@nrwl/schematics/migrations/20200101-test-migration.js', - ` - exports.default = { - description: 'Test migration', - run: function() { - console.log('Running test migration'); - } - }; - ` - ); - const out = runCommand('npm run nx-migrate'); - expect(out).toContain('Test migration'); - expect(out).toContain('Running test migration'); - expect(out).toContain('All migrations run successfully'); - - expect(runCommand('npm run nx-migrate')).toContain('No migrations to run'); - }, - 1000000 - ); -}); diff --git a/e2e/schematics/tslint.test.ts b/e2e/schematics/tslint.test.ts deleted file mode 100644 index 2b6b5c60a3f10..0000000000000 --- a/e2e/schematics/tslint.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { newApp, newLib, newProject, readFile, runCLI, updateFile } from '../utils'; - -describe('Lint', () => { - it( - 'should ensure module boundaries', - () => { - newProject(); - newApp('myapp'); - newLib('mylib'); - newLib('lazylib'); - - const tslint = JSON.parse(readFile('tslint.json')); - tslint.rules['nx-enforce-module-boundaries'][1].lazyLoad.push('lazylib'); - updateFile('tslint.json', JSON.stringify(tslint, null, 2)); - - updateFile( - 'apps/myapp/src/main.ts', - ` - import '../../../libs/mylib'; - import '@nrwl/lazylib'; - import '@nrwl/mylib/deep'; - ` - ); - - 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('deep imports into libraries are forbidden'); - }, - 1000000 - ); -}); diff --git a/packages/schematics/migrations/20180103-update-command-line-scripts.ts b/packages/schematics/migrations/20180103-update-command-line-scripts.ts new file mode 100644 index 0000000000000..ef6d3fdb16986 --- /dev/null +++ b/packages/schematics/migrations/20180103-update-command-line-scripts.ts @@ -0,0 +1,25 @@ +import { updateJsonFile } from '../src/collection/utility/fileutils'; + +export default { + description: 'Add format:write and format:check to npm scripts', + run: () => { + updateJsonFile('package.json', json => { + json.scripts = { + ...json.scripts, + 'apps:affected': 'node ./node_modules/@nrwl/schematics/src/command-line/affected.js apps', + 'build:affected': 'node ./node_modules/@nrwl/schematics/src/command-line/affected.js build', + 'e2e:affected': 'node ./node_modules/@nrwl/schematics/src/command-line/affected.js e2e', + + 'affected:apps': 'node ./node_modules/@nrwl/schematics/src/command-line/affected.js apps', + 'affected:build': 'node ./node_modules/@nrwl/schematics/src/command-line/affected.js build', + 'affected:e2e': 'node ./node_modules/@nrwl/schematics/src/command-line/affected.js e2e', + + format: 'node ./node_modules/@nrwl/schematics/src/command-line/format.js write', + 'format:write': 'node ./node_modules/@nrwl/schematics/src/command-line/format.js write', + 'format:check': 'node ./node_modules/@nrwl/schematics/src/command-line/format.js check', + + 'nx-migrate': 'node ./node_modules/@nrwl/schematics/src/command-line/nx-migrate.js' + }; + }); + } +}; diff --git a/packages/schematics/src/collection/application/files/__directory__/package.json b/packages/schematics/src/collection/application/files/__directory__/package.json index 360e9bc0028a6..d6131d57a9f5f 100644 --- a/packages/schematics/src/collection/application/files/__directory__/package.json +++ b/packages/schematics/src/collection/application/files/__directory__/package.json @@ -9,11 +9,20 @@ "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", - "apps:affected": "node ./node_modules/@nrwl/schematics/src/affected/run-affected.js apps", - "build:affected": "node ./node_modules/@nrwl/schematics/src/affected/run-affected.js build", - "e2e:affected": "node ./node_modules/@nrwl/schematics/src/affected/run-affected.js e2e", - "format": "node ./node_modules/prettier/bin/prettier.js --single-quote --print-width 120 --write \"{apps,libs}/**/*.ts\"", - "nx-migrate": "node ./node_modules/@nrwl/schematics/src/migrator/migrator.js" + + "apps:affected": "node ./node_modules/@nrwl/schematics/src/command-line/affected.js apps", + "build:affected": "node ./node_modules/@nrwl/schematics/src/command-line/affected.js build", + "e2e:affected": "node ./node_modules/@nrwl/schematics/src/command-line/affected.js e2e", + + "affected:apps": "node ./node_modules/@nrwl/schematics/src/command-line/affected.js apps", + "affected:build": "node ./node_modules/@nrwl/schematics/src/command-line/affected.js build", + "affected:e2e": "node ./node_modules/@nrwl/schematics/src/command-line/affected.js e2e", + + "format": "node ./node_modules/@nrwl/schematics/src/command-line/format.js write", + "format:write": "node ./node_modules/@nrwl/schematics/src/command-line/format.js write", + "format:check": "node ./node_modules/@nrwl/schematics/src/command-line/format.js check", + + "nx-migrate": "node ./node_modules/@nrwl/schematics/src/command-line/nx-migrate.js" }, "private": true, "dependencies": { diff --git a/packages/schematics/src/collection/utility/lib-versions.ts b/packages/schematics/src/collection/utility/lib-versions.ts index 6f23cff610dc1..cb8fbafc2c5b5 100644 --- a/packages/schematics/src/collection/utility/lib-versions.ts +++ b/packages/schematics/src/collection/utility/lib-versions.ts @@ -4,7 +4,7 @@ export const angularJsVersion = '1.6.6'; export const ngrxVersion = '4.1.1'; export const nxVersion = '*'; export const schematicsVersion = '*'; -export const latestMigration = '20171219-add-affected-commands'; +export const latestMigration = '20180103-update-command-line-scripts'; export const prettierVersion = '^1.9.0'; export const typescriptVersion = '2.5.3'; export const rxjsVersion = '^5.5.2'; diff --git a/packages/schematics/src/affected/affected.spec.ts b/packages/schematics/src/command-line/affected-apps.spec.ts similarity index 98% rename from packages/schematics/src/affected/affected.spec.ts rename to packages/schematics/src/command-line/affected-apps.spec.ts index e55854e2c042a..d41519d794944 100644 --- a/packages/schematics/src/affected/affected.spec.ts +++ b/packages/schematics/src/command-line/affected-apps.spec.ts @@ -1,4 +1,4 @@ -import { affectedApps, dependencies } from './affected'; +import { affectedApps, dependencies } from './affected-apps'; describe('Calculates Dependencies Between Apps and Libs', () => { describe('dependencies', () => { diff --git a/packages/schematics/src/affected/affected.ts b/packages/schematics/src/command-line/affected-apps.ts similarity index 100% rename from packages/schematics/src/affected/affected.ts rename to packages/schematics/src/command-line/affected-apps.ts diff --git a/packages/schematics/src/affected/run-affected.ts b/packages/schematics/src/command-line/affected.ts similarity index 98% rename from packages/schematics/src/affected/run-affected.ts rename to packages/schematics/src/command-line/affected.ts index 54262bd127e70..0fa43f872410b 100644 --- a/packages/schematics/src/affected/run-affected.ts +++ b/packages/schematics/src/command-line/affected.ts @@ -1,4 +1,4 @@ -import { affectedApps } from './affected'; +import { affectedApps } from './affected-apps'; import { execSync } from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; diff --git a/packages/schematics/src/command-line/format.ts b/packages/schematics/src/command-line/format.ts new file mode 100644 index 0000000000000..ed8e5c76b0483 --- /dev/null +++ b/packages/schematics/src/command-line/format.ts @@ -0,0 +1,65 @@ +import { execSync } from 'child_process'; +import * as fs from 'fs'; +import * as path from 'path'; + +const command = process.argv[2]; +const files = parseFiles(); + +switch (command) { + case 'write': + write(files); + break; + case 'check': + check(files); + break; +} + +function parseFiles() { + const args = process.argv.slice(3); + if (args.length === 0) { + return '"{apps,libs}/**/*.ts"'; + } + const dashDashFiles = args.filter(a => a.startsWith('--files='))[0]; + if (dashDashFiles) { + args.splice(args.indexOf(dashDashFiles), 1); + return `"${parseDashDashFiles(dashDashFiles).join(',')}"`; + } else { + const withoutShahs = args.slice(2); + return `"${getFilesFromShash(args[0], args[1]).join(',')}"`; + } +} + +function parseDashDashFiles(dashDashFiles: string): string[] { + let f = dashDashFiles.substring(8); // remove --files= + if (f.startsWith('"') || f.startsWith("'")) { + f = f.substring(1, f.length - 1); + } + return f.split(',').map(f => f.trim()); +} + +function getFilesFromShash(sha1: string, sha2: string): string[] { + return execSync(`git diff --name-only ${sha1} ${sha2}`) + .toString('utf-8') + .split('\n') + .map(a => a.trim()) + .filter(a => a.length > 0); +} + +function write(files: string) { + execSync(`node ./node_modules/prettier/bin/prettier.js --single-quote --print-width 120 --write ${files}`, { + stdio: [0, 1, 2] + }); +} + +function check(files: string) { + try { + execSync( + `node ./node_modules/prettier/bin/prettier.js --single-quote --print-width 120 --list-different ${files}`, + { + stdio: [0, 1, 2] + } + ); + } catch (e) { + process.exit(1); + } +} diff --git a/packages/schematics/src/migrator/migrator.ts b/packages/schematics/src/command-line/nx-migrate.ts similarity index 100% rename from packages/schematics/src/migrator/migrator.ts rename to packages/schematics/src/command-line/nx-migrate.ts