refactor(schematics): use schematic context to format the generated code

This commit is contained in:
vsavkin 2018-02-25 18:48:23 -05:00
parent acdeb1b71c
commit e7481a790f
8 changed files with 169 additions and 142 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
node_modules node_modules
.idea .idea
.vscode
dist dist
build build
.DS_Store .DS_Store

View File

@ -11,7 +11,8 @@ import {
Rule, Rule,
template, template,
Tree, Tree,
url url,
SchematicContext
} from '@angular-devkit/schematics'; } from '@angular-devkit/schematics';
import { Schema } from './schema'; import { Schema } from './schema';
import {strings} from '@angular-devkit/core'; import {strings} from '@angular-devkit/core';
@ -22,6 +23,7 @@ import { insertImport } from '@schematics/angular/utility/route-utils';
import { addApp, serializeJson, cliConfig, readCliConfigFile } from '../utility/fileutils'; import { addApp, serializeJson, cliConfig, readCliConfigFile } from '../utility/fileutils';
import { addImportToTestBed } from '../utility/ast-utils'; import { addImportToTestBed } from '../utility/ast-utils';
import { offsetFromRoot } from '../utility/common'; import { offsetFromRoot } from '../utility/common';
import {FormatFiles, wrapIntoFormat} from '../utility/tasks';
interface NormalizedSchema extends Schema { interface NormalizedSchema extends Schema {
fullName: string; fullName: string;
@ -154,52 +156,55 @@ function updateComponentTemplate(options: NormalizedSchema): Rule {
} }
export default function(schema: Schema): Rule { export default function(schema: Schema): Rule {
let npmScope = schema.npmScope; return wrapIntoFormat(() => {
if (!npmScope) { let npmScope = schema.npmScope;
npmScope = readCliConfigFile().project.npmScope; if (!npmScope) {
} npmScope = readCliConfigFile().project.npmScope;
}
const options = normalizeOptions(schema); const options = normalizeOptions(schema);
const templateSource = apply(url('./files'), [ const templateSource = apply(url('./files'), [
template({ template({
utils: strings, utils: strings,
dot: '.', dot: '.',
tmpl: '', tmpl: '',
offsetFromRoot: offsetFromRoot(options.fullPath), offsetFromRoot: offsetFromRoot(options.fullPath),
...(options as object), ...(options as object),
npmScope npmScope
}) })
]); ]);
const selector = `${options.prefix}-root`; const selector = `${options.prefix}-root`;
return chain([
branchAndMerge(chain([mergeWith(templateSource)])), return chain([
externalSchematic('@schematics/angular', 'module', { branchAndMerge(chain([mergeWith(templateSource)])),
name: 'app', externalSchematic('@schematics/angular', 'module', {
commonModule: false, name: 'app',
flat: true, commonModule: false,
routing: false, flat: true,
sourceDir: options.fullPath, routing: false,
spec: false sourceDir: options.fullPath,
}), spec: false
externalSchematic('@schematics/angular', 'component', { }),
name: 'app', externalSchematic('@schematics/angular', 'component', {
selector: selector, name: 'app',
sourceDir: options.fullPath, selector: selector,
flat: true, sourceDir: options.fullPath,
inlineStyle: options.inlineStyle, flat: true,
inlineTemplate: options.inlineTemplate, inlineStyle: options.inlineStyle,
spec: !options.skipTests, inlineTemplate: options.inlineTemplate,
styleext: options.style, spec: !options.skipTests,
viewEncapsulation: options.viewEncapsulation, styleext: options.style,
changeDetection: options.changeDetection viewEncapsulation: options.viewEncapsulation,
}), changeDetection: options.changeDetection
updateComponentTemplate(options), }),
addBootstrap(options.fullPath), updateComponentTemplate(options),
addNxModule(options.fullPath), addBootstrap(options.fullPath),
addAppToAngularCliJson(options), addNxModule(options.fullPath),
options.routing ? addRouterRootConfiguration(options.fullPath) : noop() addAppToAngularCliJson(options),
]); options.routing ? addRouterRootConfiguration(options.fullPath) : noop()
]);
});
} }
function normalizeOptions(options: Schema): NormalizedSchema { function normalizeOptions(options: Schema): NormalizedSchema {

View File

@ -1,19 +1,21 @@
import { apply, branchAndMerge, chain, mergeWith, move, Rule, template, Tree, url } from '@angular-devkit/schematics'; import {apply, branchAndMerge, chain, mergeWith, Rule, template, url} from '@angular-devkit/schematics';
import { Schema } from './schema'; import {Schema} from './schema';
import {strings} from '@angular-devkit/core'; import {strings} from '@angular-devkit/core';
import { libVersions } from '../utility/lib-versions'; import {libVersions} from '../utility/lib-versions';
import {wrapIntoFormat} from '../utility/tasks';
export default function(options: Schema): Rule { export default function(options: Schema): Rule {
const npmScope = options.npmScope ? options.npmScope : options.name; return wrapIntoFormat(() => {
const templateSource = apply(url('./files'), [ const npmScope = options.npmScope ? options.npmScope : options.name;
template({ const templateSource = apply(url('./files'), [
utils: strings, template({
dot: '.', utils: strings,
...libVersions, dot: '.',
...(options as object), ...libVersions,
npmScope ...(options as object),
}) npmScope
]); })
]);
return chain([branchAndMerge(chain([mergeWith(templateSource)]))]); return chain([branchAndMerge(chain([mergeWith(templateSource)]))]);
});
} }

View File

@ -1,7 +1,8 @@
import { chain, noop, Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import {chain, noop, Rule, Tree} from '@angular-devkit/schematics';
import { addEntryComponents, addMethod, insert, readBootstrapInfo, removeFromNgModule } from '../utility/ast-utils'; import {addEntryComponents, addMethod, insert, readBootstrapInfo, removeFromNgModule} from '../utility/ast-utils';
import { Schema } from './schema'; import {Schema} from './schema';
import { addUpgradeToPackageJson } from '../utility/common'; import {addUpgradeToPackageJson} from '../utility/common';
import {wrapIntoFormat} from '../utility/tasks';
function updateMain(angularJsImport: string, options: Schema): Rule { function updateMain(angularJsImport: string, options: Schema): Rule {
return (host: Tree) => { return (host: Tree) => {
@ -71,12 +72,14 @@ function addEntryComponentsToModule(options: Schema): Rule {
} }
export default function(options: Schema): Rule { export default function(options: Schema): Rule {
const angularJsImport = options.angularJsImport ? options.angularJsImport : options.name; return wrapIntoFormat(() => {
const angularJsImport = options.angularJsImport ? options.angularJsImport : options.name;
return chain([ return chain([
updateMain(angularJsImport, options), updateMain(angularJsImport, options),
addEntryComponentsToModule(options), addEntryComponentsToModule(options),
rewriteBootstrapLogic(options), rewriteBootstrapLogic(options),
options.skipPackageJson ? noop() : addUpgradeToPackageJson() options.skipPackageJson ? noop() : addUpgradeToPackageJson()
]); ]);
});
} }

View File

@ -1,24 +1,13 @@
import { import {apply, branchAndMerge, chain, mergeWith, noop, Rule, template, Tree, url} from '@angular-devkit/schematics';
apply, import {Schema} from './schema';
branchAndMerge, import {addImportToModule, insert, names, toClassName, toFileName, toPropertyName} from '@nrwl/schematics';
chain,
externalSchematic,
mergeWith,
move,
noop,
Rule,
template,
Tree,
url
} from '@angular-devkit/schematics';
import { Schema } from './schema';
import { addImportToModule, insert, names, toClassName, toFileName, toPropertyName } from '@nrwl/schematics';
import * as path from 'path'; import * as path from 'path';
import { serializeJson, addApp, cliConfig, updateJsonFile } from '../utility/fileutils'; import {addApp, cliConfig, serializeJson} from '../utility/fileutils';
import { insertImport } from '@schematics/angular/utility/route-utils'; import {insertImport} from '@schematics/angular/utility/route-utils';
import * as ts from 'typescript'; import * as ts from 'typescript';
import { addGlobal, addIncludeToTsConfig, addReexport, addRoute, offset } from '../utility/ast-utils'; import {addGlobal, addIncludeToTsConfig, addReexport, addRoute} from '../utility/ast-utils';
import { offsetFromRoot } from '../utility/common'; import {offsetFromRoot} from '../utility/common';
import {wrapIntoFormat} from '../utility/tasks';
interface NormalizedSchema extends Schema { interface NormalizedSchema extends Schema {
name: string; name: string;
@ -169,38 +158,40 @@ function updateTsLint(schema: NormalizedSchema): Rule {
} }
export default function(schema: Schema): Rule { export default function(schema: Schema): Rule {
const options = normalizeOptions(schema); return wrapIntoFormat(() => {
const moduleFileName = `${toFileName(options.name)}.module`; const options = normalizeOptions(schema);
const modulePath = `${options.fullPath}/${moduleFileName}.ts`; const moduleFileName = `${toFileName(options.name)}.module`;
const indexFile = `libs/${toFileName(options.fullName)}/index.ts`; const modulePath = `${options.fullPath}/${moduleFileName}.ts`;
const indexFile = `libs/${toFileName(options.fullName)}/index.ts`;
if (options.routing && options.nomodule) { if (options.routing && options.nomodule) {
throw new Error(`nomodule and routing cannot be used together`); throw new Error(`nomodule and routing cannot be used together`);
} }
if (!options.routing && options.lazy) { if (!options.routing && options.lazy) {
throw new Error(`routing must be set`); throw new Error(`routing must be set`);
} }
const templateSource = apply(url(options.nomodule ? './files' : './ngfiles'), [ const templateSource = apply(url(options.nomodule ? './files' : './ngfiles'), [
template({ template({
...names(options.name), ...names(options.name),
dot: '.', dot: '.',
tmpl: '', tmpl: '',
...(options as object) ...(options as object)
}) })
]); ]);
return chain([ return chain([
branchAndMerge(chain([mergeWith(templateSource)])), branchAndMerge(chain([mergeWith(templateSource)])),
addLibToAngularCliJson(options), addLibToAngularCliJson(options),
options.routing && options.lazy ? addLazyLoadedRouterConfiguration(modulePath) : noop(), options.routing && options.lazy ? addLazyLoadedRouterConfiguration(modulePath) : noop(),
options.routing && options.lazy ? updateTsLint(options) : noop(), options.routing && options.lazy ? updateTsLint(options) : noop(),
options.routing && options.lazy && options.parentModule ? addLoadChildren(options) : noop(), options.routing && options.lazy && options.parentModule ? addLoadChildren(options) : noop(),
options.routing && !options.lazy ? addRouterConfiguration(options, indexFile, moduleFileName, modulePath) : noop(), options.routing && !options.lazy ? addRouterConfiguration(options, indexFile, moduleFileName, modulePath) : noop(),
options.routing && !options.lazy && options.parentModule ? addChildren(options) : noop() options.routing && !options.lazy && options.parentModule ? addChildren(options) : noop()
]); ]);
});
} }
function normalizeOptions(options: Schema): NormalizedSchema { function normalizeOptions(options: Schema): NormalizedSchema {

View File

@ -11,15 +11,15 @@ import {
url url
} from '@angular-devkit/schematics'; } from '@angular-devkit/schematics';
import { names, toClassName, toFileName, toPropertyName } from '../utility/name-utils'; import {names, toClassName, toFileName, toPropertyName} from '../utility/name-utils';
import * as path from 'path'; import * as path from 'path';
import * as ts from 'typescript'; import * as ts from 'typescript';
import { addImportToModule, addProviderToModule, insert, offset } from '../utility/ast-utils'; import {addImportToModule, addProviderToModule, insert} from '../utility/ast-utils';
import { insertImport } from '@schematics/angular/utility/route-utils'; import {insertImport} from '@schematics/angular/utility/route-utils';
import { Schema } from './schema'; import {Schema} from './schema';
import { InsertChange } from '@schematics/angular/utility/change';
import {ngrxVersion, routerStoreVersion} from '../utility/lib-versions'; import {ngrxVersion, routerStoreVersion} from '../utility/lib-versions';
import { serializeJson } from '../utility/fileutils'; import {serializeJson} from '../utility/fileutils';
import {wrapIntoFormat} from '../utility/tasks';
function addImportsToModule(name: string, options: Schema): Rule { function addImportsToModule(name: string, options: Schema): Rule {
return (host: Tree) => { return (host: Tree) => {
@ -129,17 +129,19 @@ function addNgRxToPackageJson() {
} }
export default function(options: Schema): Rule { export default function(options: Schema): Rule {
const name = options.name; return wrapIntoFormat(() => {
const moduleDir = path.dirname(options.module); const name = options.name;
const moduleDir = path.dirname(options.module);
if (options.onlyEmptyRoot) { if (options.onlyEmptyRoot) {
return chain([addImportsToModule(name, options), options.skipPackageJson ? noop() : addNgRxToPackageJson()]); return chain([addImportsToModule(name, options), options.skipPackageJson ? noop() : addNgRxToPackageJson()]);
} else { } else {
const templateSource = apply(url('./files'), [template({ ...options, tmpl: '', ...names(name) }), move(moduleDir)]); const templateSource = apply(url('./files'), [template({...options, tmpl: '', ...names(name)}), move(moduleDir)]);
return chain([ return chain([
branchAndMerge(chain([mergeWith(templateSource)])), branchAndMerge(chain([mergeWith(templateSource)])),
addImportsToModule(name, options), addImportsToModule(name, options),
options.skipPackageJson ? noop() : addNgRxToPackageJson() options.skipPackageJson ? noop() : addNgRxToPackageJson()
]); ]);
} }
});
} }

View File

@ -31,6 +31,7 @@ import { insertImport } from '@schematics/angular/utility/route-utils';
import { Schema } from './schema'; import { Schema } from './schema';
import { angularJsVersion } from '../utility/lib-versions'; import { angularJsVersion } from '../utility/lib-versions';
import { addUpgradeToPackageJson } from '../utility/common'; import { addUpgradeToPackageJson } from '../utility/common';
import {wrapIntoFormat} from '../utility/tasks';
function addImportsToModule(options: Schema): Rule { function addImportsToModule(options: Schema): Rule {
return (host: Tree) => { return (host: Tree) => {
@ -108,12 +109,14 @@ function createFiles(angularJsImport: string, options: Schema): Rule {
} }
export default function(options: Schema): Rule { export default function(options: Schema): Rule {
const angularJsImport = options.angularJsImport ? options.angularJsImport : options.name; return wrapIntoFormat(() => {
const angularJsImport = options.angularJsImport ? options.angularJsImport : options.name;
return chain([ return chain([
createFiles(angularJsImport, options), createFiles(angularJsImport, options),
addImportsToModule(options), addImportsToModule(options),
addNgDoBootstrapToModule(options), addNgDoBootstrapToModule(options),
options.skipPackageJson ? noop() : addUpgradeToPackageJson() options.skipPackageJson ? noop() : addUpgradeToPackageJson()
]); ]);
});
} }

View File

@ -0,0 +1,20 @@
import {TaskConfigurationGenerator, TaskConfiguration, Tree, SchematicContext} from "@angular-devkit/schematics";
export class FormatFiles implements TaskConfigurationGenerator<any> {
toConfiguration(): TaskConfiguration<any> {
return {
name: 'node-package',
options: {
command: 'run format',
quiet: true
},
};
}
}
export function wrapIntoFormat(fn: Function): any {
return (host: Tree, context: SchematicContext) => {
context.addTask(new FormatFiles());
return fn()(host, context);
};
}