feat(schematics): change upgrade-module and downgrade-module schematics to work with CLI6

This commit is contained in:
Victor Savkin 2018-05-08 12:14:48 -04:00
parent 7c330163bd
commit af0c7acc4f
15 changed files with 437 additions and 458 deletions

View File

@ -1,6 +1,6 @@
import { newApp, newProject, runCLI, updateFile } from '../utils';
xdescribe('DowngradeModule', () => {
describe('DowngradeModule', () => {
it(
'should generate a downgradeModule setup',
() => {
@ -12,10 +12,12 @@ xdescribe('DowngradeModule', () => {
`window.angular.module('legacy', []);`
);
runCLI('generate downgrade-module legacy --angularJsImport=./legacy');
runCLI(
'generate downgrade-module legacy --angularJsImport=./legacy --project=myapp'
);
runCLI('build');
expect(runCLI('test --no-watch')).toContain('Executed 1 of 1 SUCCESS');
expect(runCLI('test --no-watch')).toContain('Executed 3 of 3 SUCCESS');
},
1000000
);

View File

@ -1,7 +1,7 @@
import { newApp, newProject, runCLI, updateFile } from '../utils';
xdescribe('Upgrade', () => {
it(
describe('Upgrade', () => {
fit(
'should generate an UpgradeModule setup',
() => {
newProject();
@ -28,7 +28,7 @@ xdescribe('Upgrade', () => {
runCLI(
'generate upgrade-module legacy --angularJsImport=./legacy ' +
'--angularJsCmpSelector=rootLegacyCmp'
'--angularJsCmpSelector=rootLegacyCmp --project=myapp'
);
runCLI('build');

View File

@ -5,7 +5,7 @@ import { createApp, createEmptyWorkspace } from '../../utils/testing-utils';
import { getFileContent } from '@schematics/angular/utility/test';
import { readJsonInTree } from '../../utils/ast-utils';
xdescribe('downgrade-module', () => {
describe('downgrade-module', () => {
const schematicRunner = new SchematicTestRunner(
'@nrwl/schematics',
path.join(__dirname, '../../collection.json')
@ -23,7 +23,8 @@ xdescribe('downgrade-module', () => {
const tree = schematicRunner.runSchematic(
'downgrade-module',
{
name: 'legacy'
name: 'legacy',
project: 'myapp'
},
appTree
);
@ -40,7 +41,8 @@ xdescribe('downgrade-module', () => {
const tree = schematicRunner.runSchematic(
'downgrade-module',
{
name: 'legacy'
name: 'legacy',
project: 'myapp'
},
appTree
);
@ -64,7 +66,8 @@ xdescribe('downgrade-module', () => {
const tree = schematicRunner.runSchematic(
'downgrade-module',
{
name: 'legacy'
name: 'legacy',
project: 'myapp'
},
appTree
);
@ -88,7 +91,8 @@ xdescribe('downgrade-module', () => {
'downgrade-module',
{
name: 'legacy',
skipPackageJson: true
skipPackageJson: true,
project: 'myapp'
},
appTree
);
@ -102,7 +106,8 @@ xdescribe('downgrade-module', () => {
'downgrade-module',
{
name: 'legacy',
angularJsImport: 'legacy-app'
angularJsImport: 'legacy-app',
project: 'myapp'
},
appTree
);

View File

@ -18,7 +18,7 @@ function updateMain(angularJsImport: string, options: Schema): Rule {
moduleSpec,
bootstrapComponentClassName,
bootstrapComponentFileName
} = readBootstrapInfo(host, options.app);
} = readBootstrapInfo(host, options.project);
host.overwrite(
mainPath,
@ -27,7 +27,7 @@ function updateMain(angularJsImport: string, options: Schema): Rule {
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import * as angular from 'angular';
import { downgradeComponent, downgradeModule, setAngularLib } from '@angular/upgrade/static';
import { downgradeComponent, downgradeModule, setAngularJSGlobal } from '@angular/upgrade/static';
import { ${moduleClassName} } from '${moduleSpec}';
import { environment } from './environments/environment';
@ -35,7 +35,7 @@ import '${angularJsImport}';
import { ${bootstrapComponentClassName} } from '${bootstrapComponentFileName}';
export function bootstrapAngular(extra: StaticProvider[]): any {
setAngularLib(angular);
setAngularJSGlobal(angular);
if (environment.production) {
enableProdMode();
}
@ -59,7 +59,7 @@ function rewriteBootstrapLogic(options: Schema): Rule {
return (host: Tree) => {
const { modulePath, moduleSource, moduleClassName } = readBootstrapInfo(
host,
options.app
options.project
);
insert(host, modulePath, [
...addMethod(moduleSource, modulePath, {
@ -78,7 +78,7 @@ function addEntryComponentsToModule(options: Schema): Rule {
modulePath,
moduleSource,
bootstrapComponentClassName
} = readBootstrapInfo(host, options.app);
} = readBootstrapInfo(host, options.project);
insert(
host,
modulePath,

View File

@ -2,5 +2,5 @@ export interface Schema {
angularJsImport: string;
name: string;
skipPackageJson: boolean;
app: string;
project: string;
}

View File

@ -4,13 +4,17 @@
"title": "Generates downgradeModule setup",
"type": "object",
"properties": {
"app": {
"project": {
"type": "string",
"description": "The name of the application"
"description": "The name of the project"
},
"name": {
"type": "string",
"description": "The name of the main AngularJS module."
"description": "The name of the main AngularJS module.",
"$default": {
"$source": "argv",
"index": 0
}
},
"angularJsImport": {
"type": "string",
@ -23,6 +27,6 @@
}
},
"required": [
"name"
"project"
]
}

View File

@ -1,5 +1,5 @@
import {Directive, ElementRef, Injector} from '@angular/core';
import {setAngularLib, UpgradeComponent, downgradeComponent, UpgradeModule} from '@angular/upgrade/static';
import {setAngularJSGlobal, UpgradeComponent, downgradeComponent, UpgradeModule} from '@angular/upgrade/static';
<% if (router) { %>
import {Router} from '@angular/router';
import {setUpLocationSync} from '@angular/router/upgrade';
@ -35,7 +35,7 @@ export const upgradedComponents = [];
// additional configuration invoked right before bootstrap
export function configure<%= className %>(i: Injector) {
setAngularLib(angular);
setAngularJSGlobal(angular);
// Insert additional configuration here
<% if (router) { %>
angular.module('downgraded').run(() => {

View File

@ -34,7 +34,7 @@ function addImportsToModule(options: Schema): Rule {
return (host: Tree) => {
const { moduleClassName, modulePath, moduleSource } = readBootstrapInfo(
host,
options.app
options.project
);
insert(host, modulePath, [
@ -71,7 +71,7 @@ function addNgDoBootstrapToModule(options: Schema): Rule {
return (host: Tree) => {
const { moduleClassName, modulePath, moduleSource } = readBootstrapInfo(
host,
options.app
options.project
);
insert(host, modulePath, [
@ -102,7 +102,7 @@ function createFiles(angularJsImport: string, options: Schema): Rule {
moduleSpec,
bootstrapComponentClassName,
bootstrapComponentFileName
} = readBootstrapInfo(host, options.app);
} = readBootstrapInfo(host, options.project);
const dir = path.dirname(mainPath);
const templateSource = apply(url('./files'), [

View File

@ -1,5 +1,5 @@
export interface Schema {
app: string;
project: string;
angularJsImport: string;
angularJsCmpSelector: string;
name: string;

View File

@ -4,13 +4,17 @@
"title": "Generates UpgradeModule setup",
"type": "object",
"properties": {
"app": {
"project": {
"type": "string",
"description": "The name of the application"
"description": "The name of the project"
},
"name": {
"type": "string",
"description": "The name of the main AngularJS module."
"description": "The name of the main AngularJS module.",
"$default": {
"$source": "argv",
"index": 0
}
},
"angularJsImport": {
"type": "string",
@ -32,6 +36,6 @@
}
},
"required": [
"name"
"project"
]
}

View File

@ -5,7 +5,7 @@ import { createApp, createEmptyWorkspace } from '../../utils/testing-utils';
import { getFileContent } from '@schematics/angular/utility/test';
import { readJsonInTree } from '../../utils/ast-utils';
xdescribe('upgrade-module', () => {
describe('upgrade-module', () => {
const schematicRunner = new SchematicTestRunner(
'@nrwl/schematics',
path.join(__dirname, '../../collection.json')
@ -23,7 +23,8 @@ xdescribe('upgrade-module', () => {
const tree = schematicRunner.runSchematic(
'upgrade-module',
{
name: 'legacy'
name: 'legacy',
project: 'myapp'
},
appTree
);
@ -53,7 +54,8 @@ xdescribe('upgrade-module', () => {
const tree = schematicRunner.runSchematic(
'upgrade-module',
{
name: 'legacy'
name: 'legacy',
project: 'myapp'
},
appTree
);
@ -77,7 +79,8 @@ xdescribe('upgrade-module', () => {
'upgrade-module',
{
name: 'legacy',
skipPackageJson: true
skipPackageJson: true,
project: 'myapp'
},
appTree
);
@ -91,7 +94,8 @@ xdescribe('upgrade-module', () => {
'upgrade-module',
{
name: 'legacy',
router: true
router: true,
project: 'myapp'
},
appTree
);
@ -105,7 +109,8 @@ xdescribe('upgrade-module', () => {
'upgrade-module',
{
name: 'legacy',
angularJsImport: 'legacy-app'
angularJsImport: 'legacy-app',
project: 'myapp'
},
appTree
);

View File

@ -1,383 +1,351 @@
import {
apply,
branchAndMerge,
chain,
mergeWith,
Rule,
SchematicContext,
Tree,
url
} from '@angular-devkit/schematics';
import { chain, Rule } from '@angular-devkit/schematics';
import { Schema } from './schema';
import * as path from 'path';
import { join } from 'path';
import {
angularCliSchema,
angularCliVersion,
latestMigration,
ngrxStoreFreezeVersion,
ngrxVersion,
nxVersion,
prettierVersion,
routerStoreVersion,
schematicsVersion
} from '../../lib-versions';
import * as fs from 'fs';
import { updateJsonFile } from '../../utils/fileutils';
import { toFileName } from '../../utils/name-utils';
import {
getAngularCliConfig,
insert,
updateJsonInTree
} from '../../utils/ast-utils';
import { stripIndents } from '@angular-devkit/core/src/utils/literals';
import { InsertChange } from '@schematics/angular/utility/change';
function updatePackageJson() {
return updateJsonInTree('package.json', packageJson => {
if (!packageJson.devDependencies) {
packageJson.devDependencies = {};
}
if (!packageJson.dependencies) {
packageJson.dependencies = {};
}
if (!packageJson.scripts) {
packageJson.scripts = {};
}
if (!packageJson.dependencies['@nrwl/nx']) {
packageJson.dependencies['@nrwl/nx'] = nxVersion;
}
if (!packageJson.dependencies['@ngrx/store']) {
packageJson.dependencies['@ngrx/store'] = ngrxVersion;
}
if (!packageJson.dependencies['@ngrx/router-store']) {
packageJson.dependencies['@ngrx/router-store'] = routerStoreVersion;
}
if (!packageJson.dependencies['@ngrx/effects']) {
packageJson.dependencies['@ngrx/effects'] = ngrxVersion;
}
if (!packageJson.dependencies['@ngrx/store-devtools']) {
packageJson.dependencies['@ngrx/store-devtools'] = ngrxVersion;
}
if (!packageJson.dependencies['ngrx-store-freeze']) {
packageJson.dependencies['ngrx-store-freeze'] = ngrxStoreFreezeVersion;
}
if (!packageJson.devDependencies['@nrwl/schematics']) {
packageJson.devDependencies['@nrwl/schematics'] = schematicsVersion;
}
if (!packageJson.dependencies['@angular/cli']) {
packageJson.dependencies['@angular/cli'] = angularCliVersion;
}
if (!packageJson.devDependencies['prettier']) {
packageJson.devDependencies['prettier'] = prettierVersion;
}
packageJson.scripts['affected:apps'] =
'./node_modules/.bin/nx affected:apps';
packageJson.scripts['affected:build'] =
'./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';
packageJson.scripts['update'] = './node_modules/.bin/nx update';
packageJson.scripts['update:check'] = './node_modules/.bin/nx update:check';
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';
return packageJson;
});
}
function updateAngularCLIJson(options: Schema): Rule {
return updateJsonInTree('.angular-cli.json', angularCliJson => {
angularCliJson.$schema = angularCliSchema;
angularCliJson.project.npmScope = npmScope(options);
angularCliJson.project.latestMigration = latestMigration;
if (angularCliJson.apps.length !== 1) {
throw new Error('Can only convert projects with one app');
}
const app = angularCliJson.apps[0];
app.name = options.name;
app.root = path.join('apps', options.name, app.root);
app.outDir = path.join('dist', 'apps', options.name);
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 = {};
}
if (!angularCliJson.defaults.schematics) {
angularCliJson.defaults.schematics = {};
}
angularCliJson.defaults.schematics['collection'] = '@nrwl/schematics';
angularCliJson.defaults.schematics['postGenerate'] = 'npm run format';
angularCliJson.defaults.schematics['newProject'] = ['app', 'lib'];
angularCliJson.lint = [
{
project: `${app.root}/tsconfig.app.json`,
exclude: '**/node_modules/**'
},
{
project: './tsconfig.spec.json',
exclude: '**/node_modules/**'
},
{
project: join('apps', options.name, 'e2e', 'tsconfig.e2e.json'),
exclude: '**/node_modules/**'
}
];
return angularCliJson;
});
}
function updateTsConfig(options: Schema): Rule {
return updateJsonInTree('tsconfig.json', tsConfigJson =>
setUpCompilerOptions(tsConfigJson, npmScope(options), '')
);
}
function updateTsConfigsJson(options: Schema) {
return (host: Tree) => {
const angularCliJson = getAngularCliConfig(host);
const app = angularCliJson.apps[0];
// This has to stay using fs since it is created with fs
const offset = '../../../';
updateJsonFile(`${app.root}/tsconfig.app.json`, json => {
json.extends = `${offset}tsconfig.json`;
json.compilerOptions.outDir = `${offset}dist/out-tsc/apps/${
options.name
}`;
if (!json.exclude) json.exclude = [];
json.exclude = dedup(json.exclude.concat(['**/*.spec.ts']));
if (!json.include) json.include = [];
json.include = dedup(json.include.concat(['**/*.ts']));
});
// This has to stay using fs since it is created with fs
updateJsonFile('tsconfig.spec.json', json => {
json.extends = './tsconfig.json';
json.compilerOptions.outDir = `./dist/out-tsc/spec`;
if (!json.exclude) json.exclude = [];
json.files = ['test.js'];
json.include = ['**/*.ts'];
json.exclude = dedup(
json.exclude.concat([
'**/e2e/*.ts',
'**/*.e2e-spec.ts',
'**/*.po.ts',
'node_modules',
'tmp'
])
);
});
// This has to stay using fs since it is created with fs
updateJsonFile(`apps/${options.name}/e2e/tsconfig.e2e.json`, json => {
json.extends = `${offset}tsconfig.json`;
json.compilerOptions.outDir = `${offset}dist/out-tsc/e2e/${options.name}`;
if (!json.exclude) json.exclude = [];
json.exclude = dedup(json.exclude.concat(['**/*.spec.ts']));
if (!json.include) json.include = [];
json.include = dedup(json.include.concat(['../**/*.ts']));
});
return host;
};
}
function updateTsLint() {
return updateJsonInTree('tslint.json', tslintJson => {
[
'no-trailing-whitespace',
'one-line',
'quotemark',
'typedef-whitespace',
'whitespace'
].forEach(key => {
tslintJson[key] = undefined;
});
tslintJson.rulesDirectory = tslintJson.rulesDirectory || [];
tslintJson.rulesDirectory.push('node_modules/@nrwl/schematics/src/tslint');
tslintJson['nx-enforce-module-boundaries'] = [
true,
{
allow: [],
depConstraints: [{ sourceTag: '*', onlyDependOnLibsWithTags: ['*'] }]
}
];
return tslintJson;
});
}
function npmScope(options: Schema): string {
return options && options.npmScope ? options.npmScope : options.name;
}
function updateKarmaConf() {
return (host: Tree, context: SchematicContext) => {
const angularCliJson = getAngularCliConfig(host);
const karmaConfig = angularCliJson.test!.karma;
if (!karmaConfig) {
return;
}
const karmaConfPath = karmaConfig.config;
const contents = host.read(karmaConfPath).toString();
const change = new InsertChange(
karmaConfPath,
contents.indexOf('module.exports ='),
stripIndents`
const { makeSureNoAppIsSelected } = require('@nrwl/schematics/src/utils/cli-config-utils');
// Nx only supports running unit tests for all apps and libs.
makeSureNoAppIsSelected();
` + '\n\n'
);
insert(host, karmaConfPath, [change]);
return host;
};
}
function updateProtractorConf() {
return (host: Tree) => {
if (!host.exists('protractor.conf.js')) {
throw new Error('Cannot find protractor.conf.js');
}
const protractorConf = host.read('protractor.conf.js')!.toString('utf-8');
const updatedConf = protractorConf
.replace(`'./e2e/**/*.e2e-spec.ts'`, `appDir + '/e2e/**/*.e2e-spec.ts'`)
.replace(`'e2e/tsconfig.e2e.json'`, `appDir + '/e2e/tsconfig.e2e.json'`)
.replace(
`exports.config = {`,
`
const { getAppDirectoryUsingCliConfig } = require('@nrwl/schematics/src/utils/cli-config-utils');
const appDir = getAppDirectoryUsingCliConfig();
exports.config = {
`
);
host.overwrite('protractor.conf.js', updatedConf);
return host;
};
}
function setUpCompilerOptions(
tsconfig: any,
npmScope: string,
offset: string
): any {
if (!tsconfig.compilerOptions.paths) {
tsconfig.compilerOptions.paths = {};
}
tsconfig.compilerOptions.baseUrl = '.';
tsconfig.compilerOptions.paths[`@${npmScope}/*`] = [`${offset}libs/*`];
return tsconfig;
}
function moveExistingFiles(options: Schema) {
return (host: Tree) => {
const angularCliJson = getAngularCliConfig(host);
const app = angularCliJson.apps[0];
fs.mkdirSync('apps');
fs.mkdirSync('libs');
fs.unlinkSync(path.join(app.root, app.test));
fs.mkdirSync(path.join('apps', options.name));
fs.renameSync(path.join(app.root, app.testTsconfig), 'tsconfig.spec.json');
fs.renameSync(app.root, join('apps', options.name, app.root));
fs.renameSync('e2e', join('apps', options.name, 'e2e'));
return host;
};
}
function createAdditionalFiles(options: Schema) {
return (host: Tree, _context: SchematicContext) => {
// if the user does not already have a prettier configuration
// of any kind, create one
// return fromPromise(resolveUserExistingPrettierConfig()).pipe(
// tap(resolvedExistingConfig => {
// if (!resolvedExistingConfig) {
// fs.writeFileSync(
// '.prettierrc',
// JSON.stringify(DEFAULT_NRWL_PRETTIER_CONFIG, null, 2)
// );
// }
// }),
// map(() => host)
// );
};
}
function dedup(array: any[]): any[] {
const res = [];
array.forEach(a => {
if (res.indexOf(a) === -1) {
res.push(a);
}
});
return res;
}
function checkCanConvertToWorkspace(options: Schema) {
return (host: Tree) => {
if (!host.exists('package.json')) {
throw new Error('Cannot find package.json');
}
if (!host.exists('protractor.conf.js')) {
throw new Error('Cannot find protractor.conf.js');
}
const angularCliJson = getAngularCliConfig(host);
if (angularCliJson.apps.length !== 1) {
throw new Error('Can only convert projects with one app');
}
return host;
};
}
// function updatePackageJson() {
// return updateJsonInTree('package.json', packageJson => {
// if (!packageJson.devDependencies) {
// packageJson.devDependencies = {};
// }
// if (!packageJson.dependencies) {
// packageJson.dependencies = {};
// }
// if (!packageJson.scripts) {
// packageJson.scripts = {};
// }
// if (!packageJson.dependencies['@nrwl/nx']) {
// packageJson.dependencies['@nrwl/nx'] = nxVersion;
// }
// if (!packageJson.dependencies['@ngrx/store']) {
// packageJson.dependencies['@ngrx/store'] = ngrxVersion;
// }
// if (!packageJson.dependencies['@ngrx/router-store']) {
// packageJson.dependencies['@ngrx/router-store'] = routerStoreVersion;
// }
// if (!packageJson.dependencies['@ngrx/effects']) {
// packageJson.dependencies['@ngrx/effects'] = ngrxVersion;
// }
// if (!packageJson.dependencies['@ngrx/store-devtools']) {
// packageJson.dependencies['@ngrx/store-devtools'] = ngrxVersion;
// }
// if (!packageJson.dependencies['ngrx-store-freeze']) {
// packageJson.dependencies['ngrx-store-freeze'] = ngrxStoreFreezeVersion;
// }
// if (!packageJson.devDependencies['@nrwl/schematics']) {
// packageJson.devDependencies['@nrwl/schematics'] = schematicsVersion;
// }
// if (!packageJson.dependencies['@angular/cli']) {
// packageJson.dependencies['@angular/cli'] = angularCliVersion;
// }
// if (!packageJson.devDependencies['prettier']) {
// packageJson.devDependencies['prettier'] = prettierVersion;
// }
//
// packageJson.scripts['affected:apps'] =
// './node_modules/.bin/nx affected:apps';
// packageJson.scripts['affected:build'] =
// './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';
//
// packageJson.scripts['update'] = './node_modules/.bin/nx update';
// packageJson.scripts['update:check'] = './node_modules/.bin/nx update:check';
// 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';
//
// return packageJson;
// });
// }
//
// function updateAngularCLIJson(options: Schema): Rule {
// return updateJsonInTree('.angular-cli.json', angularCliJson => {
// angularCliJson.$schema = angularCliSchema;
// angularCliJson.project.npmScope = npmScope(options);
// angularCliJson.project.latestMigration = latestMigration;
//
// if (angularCliJson.apps.length !== 1) {
// throw new Error('Can only convert projects with one app');
// }
//
// const app = angularCliJson.apps[0];
// app.name = options.name;
// app.root = path.join('apps', options.name, app.root);
// app.outDir = path.join('dist', 'apps', options.name);
// 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 = {};
// }
// if (!angularCliJson.defaults.schematics) {
// angularCliJson.defaults.schematics = {};
// }
// angularCliJson.defaults.schematics['collection'] = '@nrwl/schematics';
// angularCliJson.defaults.schematics['postGenerate'] = 'npm run format';
// angularCliJson.defaults.schematics['newProject'] = ['app', 'lib'];
//
// angularCliJson.lint = [
// {
// project: `${app.root}/tsconfig.app.json`,
// exclude: '**/node_modules/**'
// },
// {
// project: './tsconfig.spec.json',
// exclude: '**/node_modules/**'
// },
// {
// project: join('apps', options.name, 'e2e', 'tsconfig.e2e.json'),
// exclude: '**/node_modules/**'
// }
// ];
//
// return angularCliJson;
// });
// }
//
// function updateTsConfig(options: Schema): Rule {
// return updateJsonInTree('tsconfig.json', tsConfigJson =>
// setUpCompilerOptions(tsConfigJson, npmScope(options), '')
// );
// }
//
// function updateTsConfigsJson(options: Schema) {
// return (host: Tree) => {
// const angularCliJson = getAngularCliConfig(host);
// const app = angularCliJson.apps[0];
//
// // This has to stay using fs since it is created with fs
// const offset = '../../../';
// updateJsonFile(`${app.root}/tsconfig.app.json`, json => {
// json.extends = `${offset}tsconfig.json`;
// json.compilerOptions.outDir = `${offset}dist/out-tsc/apps/${
// options.name
// }`;
// if (!json.exclude) json.exclude = [];
// json.exclude = dedup(json.exclude.concat(['**/*.spec.ts']));
//
// if (!json.include) json.include = [];
// json.include = dedup(json.include.concat(['**/*.ts']));
// });
//
// // This has to stay using fs since it is created with fs
// updateJsonFile('tsconfig.spec.json', json => {
// json.extends = './tsconfig.json';
// json.compilerOptions.outDir = `./dist/out-tsc/spec`;
//
// if (!json.exclude) json.exclude = [];
// json.files = ['test.js'];
// json.include = ['**/*.ts'];
// json.exclude = dedup(
// json.exclude.concat([
// '**/e2e/*.ts',
// '**/*.e2e-spec.ts',
// '**/*.po.ts',
// 'node_modules',
// 'tmp'
// ])
// );
// });
//
// // This has to stay using fs since it is created with fs
// updateJsonFile(`apps/${options.name}/e2e/tsconfig.e2e.json`, json => {
// json.extends = `${offset}tsconfig.json`;
// json.compilerOptions.outDir = `${offset}dist/out-tsc/e2e/${options.name}`;
// if (!json.exclude) json.exclude = [];
// json.exclude = dedup(json.exclude.concat(['**/*.spec.ts']));
//
// if (!json.include) json.include = [];
// json.include = dedup(json.include.concat(['../**/*.ts']));
// });
//
// return host;
// };
// }
//
// function updateTsLint() {
// return updateJsonInTree('tslint.json', tslintJson => {
// [
// 'no-trailing-whitespace',
// 'one-line',
// 'quotemark',
// 'typedef-whitespace',
// 'whitespace'
// ].forEach(key => {
// tslintJson[key] = undefined;
// });
// tslintJson.rulesDirectory = tslintJson.rulesDirectory || [];
// tslintJson.rulesDirectory.push('node_modules/@nrwl/schematics/src/tslint');
// tslintJson['nx-enforce-module-boundaries'] = [
// true,
// {
// allow: [],
// depConstraints: [{ sourceTag: '*', onlyDependOnLibsWithTags: ['*'] }]
// }
// ];
// return tslintJson;
// });
// }
//
// function npmScope(options: Schema): string {
// return options && options.npmScope ? options.npmScope : options.name;
// }
//
// function updateKarmaConf() {
// return (host: Tree, context: SchematicContext) => {
// const angularCliJson = getAngularCliConfig(host);
//
// const karmaConfig = angularCliJson.test!.karma;
//
// if (!karmaConfig) {
// return;
// }
//
// const karmaConfPath = karmaConfig.config;
//
// const contents = host.read(karmaConfPath).toString();
//
// const change = new InsertChange(
// karmaConfPath,
// contents.indexOf('module.exports ='),
// stripIndents`
// const { makeSureNoAppIsSelected } = require('@nrwl/schematics/src/utils/cli-config-utils');
// // Nx only supports running unit tests for all apps and libs.
// makeSureNoAppIsSelected();
// ` + '\n\n'
// );
//
// insert(host, karmaConfPath, [change]);
//
// return host;
// };
// }
//
// function updateProtractorConf() {
// return (host: Tree) => {
// if (!host.exists('protractor.conf.js')) {
// throw new Error('Cannot find protractor.conf.js');
// }
// const protractorConf = host.read('protractor.conf.js')!.toString('utf-8');
// const updatedConf = protractorConf
// .replace(`'./e2e/**/*.e2e-spec.ts'`, `appDir + '/e2e/**/*.e2e-spec.ts'`)
// .replace(`'e2e/tsconfig.e2e.json'`, `appDir + '/e2e/tsconfig.e2e.json'`)
// .replace(
// `exports.config = {`,
// `
// const { getAppDirectoryUsingCliConfig } = require('@nrwl/schematics/src/utils/cli-config-utils');
// const appDir = getAppDirectoryUsingCliConfig();
// exports.config = {
// `
// );
//
// host.overwrite('protractor.conf.js', updatedConf);
//
// return host;
// };
// }
//
// function setUpCompilerOptions(
// tsconfig: any,
// npmScope: string,
// offset: string
// ): any {
// if (!tsconfig.compilerOptions.paths) {
// tsconfig.compilerOptions.paths = {};
// }
// tsconfig.compilerOptions.baseUrl = '.';
// tsconfig.compilerOptions.paths[`@${npmScope}/*`] = [`${offset}libs/*`];
//
// return tsconfig;
// }
//
// function moveExistingFiles(options: Schema) {
// return (host: Tree) => {
// const angularCliJson = getAngularCliConfig(host);
// const app = angularCliJson.apps[0];
//
// fs.mkdirSync('apps');
// fs.mkdirSync('libs');
// fs.unlinkSync(path.join(app.root, app.test));
// fs.mkdirSync(path.join('apps', options.name));
// fs.renameSync(path.join(app.root, app.testTsconfig), 'tsconfig.spec.json');
// fs.renameSync(app.root, join('apps', options.name, app.root));
// fs.renameSync('e2e', join('apps', options.name, 'e2e'));
//
// return host;
// };
// }
//
// function createAdditionalFiles(options: Schema) {
// return (host: Tree, _context: SchematicContext) => {
// // if the user does not already have a prettier configuration
// // of any kind, create one
// // return fromPromise(resolveUserExistingPrettierConfig()).pipe(
// // tap(resolvedExistingConfig => {
// // if (!resolvedExistingConfig) {
// // fs.writeFileSync(
// // '.prettierrc',
// // JSON.stringify(DEFAULT_NRWL_PRETTIER_CONFIG, null, 2)
// // );
// // }
// // }),
// // map(() => host)
// // );
// };
// }
//
// function dedup(array: any[]): any[] {
// const res = [];
//
// array.forEach(a => {
// if (res.indexOf(a) === -1) {
// res.push(a);
// }
// });
// return res;
// }
//
// function checkCanConvertToWorkspace(options: Schema) {
// return (host: Tree) => {
// if (!host.exists('package.json')) {
// throw new Error('Cannot find package.json');
// }
// if (!host.exists('protractor.conf.js')) {
// throw new Error('Cannot find protractor.conf.js');
// }
// const angularCliJson = getAngularCliConfig(host);
// if (angularCliJson.apps.length !== 1) {
// throw new Error('Can only convert projects with one app');
// }
// return host;
// };
// }
export default function(schema: Schema): Rule {
const options = { ...schema, name: toFileName(schema.name) };
// const options = { ...schema, name: toFileName(schema.name) };
return chain([
checkCanConvertToWorkspace(options),
moveExistingFiles(options),
createAdditionalFiles(options),
branchAndMerge(chain([mergeWith(apply(url('./files'), []))])),
updatePackageJson(),
updateAngularCLIJson(options),
updateTsLint(),
updateTsConfig(options),
updateTsConfigsJson(options),
updateKarmaConf(),
updateProtractorConf()
// checkCanConvertToWorkspace(options),
// moveExistingFiles(options),
// createAdditionalFiles(options),
// branchAndMerge(chain([mergeWith(apply(url('./files'), []))])),
// updatePackageJson(),
// updateAngularCLIJson(options),
// updateTsLint(),
// updateTsConfig(options),
// updateTsConfigsJson(options),
// updateKarmaConf(),
// updateProtractorConf()
]);
}

View File

@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT- style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { Tree, Rule } from '@angular-devkit/schematics';
import { Rule, Tree } from '@angular-devkit/schematics';
import {
findNodes,
getDecoratorMetadata,
@ -575,31 +575,14 @@ export function updateJsonInTree<T = any, O = T>(
};
}
// TODO DELETE THIS
/**
* This method is specifically for getting the .angular-cli.json data from a Tree
* @param host The host tree
*/
export function getAngularCliConfig(host: Tree) {
return readJsonInTree(host, '.angular-cli.json');
}
// TODO DELETE THIS
export function getAppConfig(host: Tree, name: string): any {
const angularCliJson = getAngularCliConfig(host);
const apps = angularCliJson.apps;
if (!apps || apps.length === 0) {
throw new Error(`Cannot find app '${name}'`);
}
if (name) {
const appConfig = apps.filter(a => a.name === name)[0];
if (!appConfig) {
throw new Error(`Cannot find app '${name}'`);
function getProjectConfig(host: Tree, name: string): any {
const angularJson = readJsonInTree(host, '/angular.json');
const projectConfig = angularJson.projects[name];
if (!projectConfig) {
throw new Error(`Cannot find project '${name}'`);
} else {
return appConfig;
return projectConfig;
}
}
return apps[0];
}
export function readBootstrapInfo(
@ -614,8 +597,15 @@ export function readBootstrapInfo(
bootstrapComponentClassName: string;
bootstrapComponentFileName: string;
} {
const config = getAppConfig(host, app);
const mainPath = path.join(config.root, config.main);
const config = getProjectConfig(host, app);
let mainPath;
try {
mainPath = config.architect.build.options.main;
} catch (e) {
throw new Error('Main file cannot be located');
}
if (!host.exists(mainPath)) {
throw new Error('Main file cannot be located');
}

View File

@ -96,21 +96,23 @@ export function createApp(
include: ['../**/*.ts']
})
);
// tree.overwrite(
// '/angular.json',
// JSON.stringify({
// projects: {
//
// },
// apps: [
// {
// name: appName,
// root: `apps/${appName}/src`,
// main: 'main.ts',
// index: 'index.html'
// }
// ]
// })
// );
tree.overwrite(
'/angular.json',
JSON.stringify({
newProjectRoot: '',
projects: {
[appName]: {
root: `apps/${appName}/src`,
architect: {
build: {
options: {
main: `apps/${appName}/src/main.ts`
}
}
}
}
}
})
);
return tree;
}

View File

@ -7,7 +7,6 @@
"typeRoots": ["node_modules/@types"],
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"noUnusedLocals": true,
"skipLibCheck": true,
"lib": ["es2017"],
"declaration": true,