From db0d133dbc56e8489ca3fcfa05946c4372debb98 Mon Sep 17 00:00:00 2001 From: Brandon Roberts Date: Mon, 16 Dec 2019 16:14:44 -0600 Subject: [PATCH] fix(angular): support ng add with missing e2e, lint, test targets --- .../src/schematics/init/init.spec.ts | 44 +++++++++ .../workspace/src/schematics/init/init.ts | 96 ++++++++++++------- 2 files changed, 104 insertions(+), 36 deletions(-) diff --git a/packages/workspace/src/schematics/init/init.spec.ts b/packages/workspace/src/schematics/init/init.spec.ts index 9dd63bbc6b..f128455184 100644 --- a/packages/workspace/src/schematics/init/init.spec.ts +++ b/packages/workspace/src/schematics/init/init.spec.ts @@ -183,4 +183,48 @@ describe('workspace', () => { const tree = await runSchematic('ng-add', { name: 'myApp' }, appTree); expect(tree.exists('/apps/myApp/tsconfig.app.json')).toBe(true); }); + + it('should work with missing e2e, lint, or test targets', async () => { + appTree.create('/package.json', JSON.stringify({})); + appTree.create( + '/angular.json', + JSON.stringify({ + version: 1, + defaultProject: 'myApp', + projects: { + myApp: { + root: '', + sourceRoot: 'src', + architect: { + build: { + options: { + tsConfig: 'tsconfig.app.json' + }, + configurations: {} + } + } + } + } + }) + ); + appTree.create( + '/tsconfig.app.json', + '{"extends": "../tsconfig.json", "compilerOptions": {}}' + ); + appTree.create( + '/tsconfig.spec.json', + '{"extends": "../tsconfig.json", "compilerOptions": {}}' + ); + appTree.create('/tsconfig.json', '{"compilerOptions": {}}'); + appTree.create('/tslint.json', '{"rules": {}}'); + appTree.create('/e2e/protractor.conf.js', '// content'); + appTree.create('/src/app/app.module.ts', '// content'); + appTree.create('/karma.conf.js', '// content'); + + const tree = await runSchematic('ng-add', { name: 'myApp' }, appTree); + + expect(tree.exists('/apps/myApp/tsconfig.app.json')).toBe(true); + expect(tree.exists('/apps/myApp/karma.conf.js')).toBe(true); + expect(tree.exists('/karma.conf.js')).toBe(true); + }); }); diff --git a/packages/workspace/src/schematics/init/init.ts b/packages/workspace/src/schematics/init/init.ts index e75daf085b..63d1a38db6 100755 --- a/packages/workspace/src/schematics/init/init.ts +++ b/packages/workspace/src/schematics/init/init.ts @@ -129,25 +129,32 @@ function updateAngularCLIJson(options: Schema): Rule { config => convertBuildOptions(config) ); - const testOptions = defaultProject.targets.get('test').options; - testOptions.main = testOptions.main && convertAsset(testOptions.main); - testOptions.polyfills = - testOptions.polyfills && convertAsset(testOptions.polyfills); - testOptions.tsConfig = join(newRoot, 'tsconfig.spec.json'); - testOptions.karmaConfig = join(newRoot, 'karma.conf.js'); - testOptions.assets = - testOptions.assets && (testOptions.assets as JsonArray).map(convertAsset); - testOptions.styles = - testOptions.styles && (testOptions.styles as JsonArray).map(convertAsset); - testOptions.scripts = - testOptions.scripts && - (testOptions.scripts as JsonArray).map(convertAsset); + if (defaultProject.targets.has('test')) { + const testOptions = defaultProject.targets.get('test').options; + testOptions.main = testOptions.main && convertAsset(testOptions.main); + testOptions.polyfills = + testOptions.polyfills && convertAsset(testOptions.polyfills); + testOptions.tsConfig = join(newRoot, 'tsconfig.spec.json'); + testOptions.karmaConfig = join(newRoot, 'karma.conf.js'); + testOptions.assets = + testOptions.assets && + (testOptions.assets as JsonArray).map(convertAsset); + testOptions.styles = + testOptions.styles && + (testOptions.styles as JsonArray).map(convertAsset); + testOptions.scripts = + testOptions.scripts && + (testOptions.scripts as JsonArray).map(convertAsset); + } const lintTarget = defaultProject.targets.get('lint'); - lintTarget.options.tsConfig = [ - join(newRoot, 'tsconfig.app.json'), - join(newRoot, 'tsconfig.spec.json') - ]; + + if (lintTarget) { + lintTarget.options.tsConfig = [ + join(newRoot, 'tsconfig.app.json'), + join(newRoot, 'tsconfig.spec.json') + ]; + } function convertServerOptions(serverOptions) { serverOptions.outputPath = @@ -190,6 +197,7 @@ function updateAngularCLIJson(options: Schema): Rule { } if (defaultProject.targets.get('e2e')) { + const lintTargetOptions = lintTarget ? lintTarget.options : {}; const e2eProject = workspace.projects.add({ name: e2eName, root: e2eRoot, @@ -202,7 +210,7 @@ function updateAngularCLIJson(options: Schema): Rule { name: 'lint', builder: '@angular-devkit/build-angular:tslint', options: { - ...lintTarget.options, + ...lintTargetOptions, tsConfig: join(e2eRoot, 'tsconfig.json') } }); @@ -236,11 +244,13 @@ function updateTsConfigsJson(options: Schema) { return json; }), - updateJsonInTree(app.architect.test.options.tsConfig, json => { - json.extends = `${offset}tsconfig.json`; - json.compilerOptions.outDir = `${offset}dist/out-tsc`; - return json; - }), + app.architect.test + ? updateJsonInTree(app.architect.test.options.tsConfig, json => { + json.extends = `${offset}tsconfig.json`; + json.compilerOptions.outDir = `${offset}dist/out-tsc`; + return json; + }) + : noop(), app.architect.server ? updateJsonInTree(app.architect.server.options.tsConfig, json => { @@ -360,24 +370,38 @@ function moveExistingFiles(options: Schema) { // No context is passed because it should not be required to have a browserslist moveOutOfSrc(host, options.name, 'browserslist'); - moveOutOfSrc( - host, - options.name, - app.architect.test.options.karmaConfig, - context - ); moveOutOfSrc( host, options.name, app.architect.build.options.tsConfig, context ); - moveOutOfSrc( - host, - options.name, - app.architect.test.options.tsConfig, - context - ); + + if (app.architect.test) { + moveOutOfSrc( + host, + options.name, + app.architect.test.options.karmaConfig, + context + ); + moveOutOfSrc( + host, + options.name, + app.architect.test.options.tsConfig, + context + ); + } else { + // there could still be a karma.conf.js file in the root + // so move to new location + if (host.exists('karma.conf.js')) { + context.logger.info( + 'No test configuration, but root Karma config file found' + ); + + moveOutOfSrc(host, options.name, 'karma.conf.js', context); + } + } + if (app.architect.server) { moveOutOfSrc( host, @@ -543,8 +567,8 @@ export default function(schema: Schema): Rule { ]); return chain([ checkCanConvertToWorkspace(options), - mergeWith(templateSource), moveExistingFiles(options), + mergeWith(templateSource), createAdditionalFiles(options), updatePackageJson(), updateAngularCLIJson(options),