diff --git a/packages/angular_devkit/build_optimizer/src/purify/webpack-plugin.ts b/packages/angular_devkit/build_optimizer/src/purify/webpack-plugin.ts index d41bc0b673..030794b781 100644 --- a/packages/angular_devkit/build_optimizer/src/purify/webpack-plugin.ts +++ b/packages/angular_devkit/build_optimizer/src/purify/webpack-plugin.ts @@ -33,4 +33,3 @@ export class PurifyPlugin { }); } } - diff --git a/packages/angular_devkit/build_optimizer/src/transforms/scrub-file_spec.ts b/packages/angular_devkit/build_optimizer/src/transforms/scrub-file_spec.ts index f889f55daa..a5a7467076 100644 --- a/packages/angular_devkit/build_optimizer/src/transforms/scrub-file_spec.ts +++ b/packages/angular_devkit/build_optimizer/src/transforms/scrub-file_spec.ts @@ -203,4 +203,3 @@ describe('scrub-file', () => { }); }); }); - diff --git a/packages/angular_devkit/schematics/src/rules/call.ts b/packages/angular_devkit/schematics/src/rules/call.ts index 51f90bdc42..61f1098f37 100644 --- a/packages/angular_devkit/schematics/src/rules/call.ts +++ b/packages/angular_devkit/schematics/src/rules/call.ts @@ -68,4 +68,3 @@ export function callRule(rule: Rule, } }); } - diff --git a/packages/angular_devkit/schematics/src/sink/dryrun.ts b/packages/angular_devkit/schematics/src/sink/dryrun.ts index 19f8f442d6..fb6add4998 100644 --- a/packages/angular_devkit/schematics/src/sink/dryrun.ts +++ b/packages/angular_devkit/schematics/src/sink/dryrun.ts @@ -114,4 +114,3 @@ export class DryRunSink extends FileSystemSink { return Observable.empty(); } } - diff --git a/packages/angular_devkit/schematics/src/tree/action_spec.ts b/packages/angular_devkit/schematics/src/tree/action_spec.ts index 9903567425..e50e316d09 100644 --- a/packages/angular_devkit/schematics/src/tree/action_spec.ts +++ b/packages/angular_devkit/schematics/src/tree/action_spec.ts @@ -77,4 +77,3 @@ describe('Action', () => { }); }); }); - diff --git a/packages/angular_devkit/schematics/tools/description.ts b/packages/angular_devkit/schematics/tools/description.ts index db3ffa6aea..7a234c990e 100644 --- a/packages/angular_devkit/schematics/tools/description.ts +++ b/packages/angular_devkit/schematics/tools/description.ts @@ -49,4 +49,3 @@ export declare type FileSystemSchematicDesc = SchematicDescription; export declare type FileSystemSchematicContext = TypedSchematicContext; - diff --git a/packages/angular_devkit/schematics/tools/registry-engine-host.ts b/packages/angular_devkit/schematics/tools/registry-engine-host.ts index 64a7deea83..9f81afaa32 100644 --- a/packages/angular_devkit/schematics/tools/registry-engine-host.ts +++ b/packages/angular_devkit/schematics/tools/registry-engine-host.ts @@ -118,4 +118,3 @@ export class RegistryEngineHost extends FileSystemEngineHostBase { return desc as FileSystemSchematicDesc; } } - diff --git a/packages/schematics/angular/class/schema.d.ts b/packages/schematics/angular/class/schema.d.ts index 722281fc5f..6668692550 100644 --- a/packages/schematics/angular/class/schema.d.ts +++ b/packages/schematics/angular/class/schema.d.ts @@ -8,6 +8,7 @@ export interface Schema { name: string; + appRoot?: string; path?: string; sourceDir?: string; /** diff --git a/packages/schematics/angular/class/schema.json b/packages/schematics/angular/class/schema.json index d170dbbbed..c1ba53d608 100644 --- a/packages/schematics/angular/class/schema.json +++ b/packages/schematics/angular/class/schema.json @@ -7,6 +7,9 @@ "name": { "type": "string" }, + "appRoot": { + "type": "string" + }, "path": { "type": "string", "default": "app" diff --git a/packages/schematics/angular/component/schema.d.ts b/packages/schematics/angular/component/schema.d.ts index cd7076154e..864d6882b5 100644 --- a/packages/schematics/angular/component/schema.d.ts +++ b/packages/schematics/angular/component/schema.d.ts @@ -8,6 +8,7 @@ export interface Schema { path?: string; + appRoot?: string; sourceDir?: string; name: string; /** diff --git a/packages/schematics/angular/component/schema.json b/packages/schematics/angular/component/schema.json index 6bc9e7ebca..6ecaa37e15 100644 --- a/packages/schematics/angular/component/schema.json +++ b/packages/schematics/angular/component/schema.json @@ -8,6 +8,9 @@ "type": "string", "default": "app" }, + "appRoot": { + "type": "string" + }, "sourceDir": { "type": "string", "default": "src", diff --git a/packages/schematics/angular/directive/schema.d.ts b/packages/schematics/angular/directive/schema.d.ts index 29b4defe8c..eb5436aade 100644 --- a/packages/schematics/angular/directive/schema.d.ts +++ b/packages/schematics/angular/directive/schema.d.ts @@ -9,6 +9,7 @@ export interface Schema { name: string; path?: string; + appRoot?: string; /** * The prefix to apply to generated selectors. */ diff --git a/packages/schematics/angular/directive/schema.json b/packages/schematics/angular/directive/schema.json index 49ac7a1127..ccf145b978 100644 --- a/packages/schematics/angular/directive/schema.json +++ b/packages/schematics/angular/directive/schema.json @@ -11,6 +11,9 @@ "type": "string", "default": "app" }, + "appRoot": { + "type": "string" + }, "prefix": { "type": "string", "description": "The prefix to apply to generated selectors.", diff --git a/packages/schematics/angular/enum/schema.d.ts b/packages/schematics/angular/enum/schema.d.ts index 804796a93b..9d7ef0fc2c 100644 --- a/packages/schematics/angular/enum/schema.d.ts +++ b/packages/schematics/angular/enum/schema.d.ts @@ -9,5 +9,6 @@ export interface Schema { name: string; path?: string; + appRoot?: string; sourceDir?: string; } diff --git a/packages/schematics/angular/enum/schema.json b/packages/schematics/angular/enum/schema.json index 2304ef9ab5..a4d4a9a2e3 100644 --- a/packages/schematics/angular/enum/schema.json +++ b/packages/schematics/angular/enum/schema.json @@ -11,6 +11,9 @@ "type": "string", "default": "app" }, + "appRoot": { + "type": "string" + }, "sourceDir": { "type": "string", "default": "src" diff --git a/packages/schematics/angular/guard/schema.d.ts b/packages/schematics/angular/guard/schema.d.ts index ac906b3121..e1730bb937 100644 --- a/packages/schematics/angular/guard/schema.d.ts +++ b/packages/schematics/angular/guard/schema.d.ts @@ -15,5 +15,6 @@ export interface Schema { */ module?: string; path?: string; + appRoot?: string; sourceDir?: string; } diff --git a/packages/schematics/angular/guard/schema.json b/packages/schematics/angular/guard/schema.json index 6087e872b4..18c65012f8 100644 --- a/packages/schematics/angular/guard/schema.json +++ b/packages/schematics/angular/guard/schema.json @@ -25,6 +25,9 @@ "type": "string", "default": "app" }, + "appRoot": { + "type": "string" + }, "sourceDir": { "type": "string", "default": "src" diff --git a/packages/schematics/angular/interface/schema.d.ts b/packages/schematics/angular/interface/schema.d.ts index cd432bfaca..1091c0d3c5 100644 --- a/packages/schematics/angular/interface/schema.d.ts +++ b/packages/schematics/angular/interface/schema.d.ts @@ -9,6 +9,7 @@ export interface Schema { name: string; path?: string; + appRoot?: string; sourceDir?: string; /** * Specifies the prefix to use. diff --git a/packages/schematics/angular/interface/schema.json b/packages/schematics/angular/interface/schema.json index 63b04048d8..6d82532e23 100644 --- a/packages/schematics/angular/interface/schema.json +++ b/packages/schematics/angular/interface/schema.json @@ -11,6 +11,9 @@ "type": "string", "default": "app" }, + "appRoot": { + "type": "string" + }, "sourceDir": { "type": "string", "default": "src" diff --git a/packages/schematics/angular/module/schema.d.ts b/packages/schematics/angular/module/schema.d.ts index ca4c305400..d5e6d89ba5 100644 --- a/packages/schematics/angular/module/schema.d.ts +++ b/packages/schematics/angular/module/schema.d.ts @@ -9,8 +9,10 @@ export interface Schema { name: string; path?: string; + appRoot?: string; sourceDir?: string; routing?: boolean; + routingScope?: ('Child' | 'Root'); spec?: boolean; flat?: boolean; commonModule?: boolean; diff --git a/packages/schematics/angular/module/schema.json b/packages/schematics/angular/module/schema.json index d1f14e312b..303c9088c6 100644 --- a/packages/schematics/angular/module/schema.json +++ b/packages/schematics/angular/module/schema.json @@ -11,6 +11,9 @@ "type": "string", "default": "app" }, + "appRoot": { + "type": "string" + }, "sourceDir": { "type": "string", "default": "src" diff --git a/packages/schematics/angular/pipe/schema.d.ts b/packages/schematics/angular/pipe/schema.d.ts index a8050abc42..f8e849e7ef 100644 --- a/packages/schematics/angular/pipe/schema.d.ts +++ b/packages/schematics/angular/pipe/schema.d.ts @@ -9,6 +9,7 @@ export interface Schema { name: string; path?: string; + appRoot?: string; sourceDir?: string; /** * Flag to indicate if a dir is created. diff --git a/packages/schematics/angular/pipe/schema.json b/packages/schematics/angular/pipe/schema.json index 9ff2a317b1..2c5ae12562 100644 --- a/packages/schematics/angular/pipe/schema.json +++ b/packages/schematics/angular/pipe/schema.json @@ -11,6 +11,9 @@ "type": "string", "default": "app" }, + "appRoot": { + "type": "string" + }, "sourceDir": { "type": "string", "default": "src" diff --git a/packages/schematics/angular/service/schema.d.ts b/packages/schematics/angular/service/schema.d.ts index c0e348754d..2cab9fc88f 100644 --- a/packages/schematics/angular/service/schema.d.ts +++ b/packages/schematics/angular/service/schema.d.ts @@ -9,6 +9,7 @@ export interface Schema { name: string; path?: string; + appRoot?: string; sourceDir?: string; /** * Flag to indicate if a dir is created. diff --git a/packages/schematics/angular/service/schema.json b/packages/schematics/angular/service/schema.json index b54589ce99..8e775df491 100644 --- a/packages/schematics/angular/service/schema.json +++ b/packages/schematics/angular/service/schema.json @@ -11,6 +11,9 @@ "type": "string", "default": "app" }, + "appRoot": { + "type": "string" + }, "sourceDir": { "type": "string", "default": "src" diff --git a/packages/schematics/angular/utility/ast-utils.ts b/packages/schematics/angular/utility/ast-utils.ts index 88ddae8970..99f50af774 100644 --- a/packages/schematics/angular/utility/ast-utils.ts +++ b/packages/schematics/angular/utility/ast-utils.ts @@ -399,4 +399,3 @@ export function addBootstrapToModule(source: ts.SourceFile, importPath: string): Change[] { return _addSymbolToNgModuleMetadata(source, modulePath, 'bootstrap', classifiedName, importPath); } - diff --git a/packages/schematics/angular/utility/find-module.ts b/packages/schematics/angular/utility/find-module.ts index 541aaf0c22..da57f0f578 100644 --- a/packages/schematics/angular/utility/find-module.ts +++ b/packages/schematics/angular/utility/find-module.ts @@ -16,6 +16,7 @@ export interface ModuleOptions { sourceDir?: string; path?: string; skipImport?: boolean; + appRoot?: string; } @@ -35,7 +36,7 @@ export function findModuleFromOptions(host: Tree, return normalizePath(findModule(host, pathToCheck)); } else { const modulePath = normalizePath( - options.sourceDir + '/' + options.path + '/' + options.module); + options.sourceDir + '/' + (options.appRoot || options.path) + '/' + options.module); const moduleBaseName = normalizePath(modulePath).split('/').pop(); if (host.exists(modulePath)) { diff --git a/packages/schematics/angular/utility/route-utils.ts b/packages/schematics/angular/utility/route-utils.ts index a360aa8687..7a113026a5 100644 --- a/packages/schematics/angular/utility/route-utils.ts +++ b/packages/schematics/angular/utility/route-utils.ts @@ -87,4 +87,3 @@ export function insertImport(source: ts.SourceFile, fileToEdit: string, symbolNa ts.SyntaxKind.StringLiteral, ); } - diff --git a/rules/singleEofLineRule.ts b/rules/singleEofLineRule.ts new file mode 100644 index 0000000000..b2882e43ff --- /dev/null +++ b/rules/singleEofLineRule.ts @@ -0,0 +1,59 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * 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 * as Lint from 'tslint'; +import * as ts from 'typescript'; + + +export class Rule extends Lint.Rules.AbstractRule { + public static metadata: Lint.IRuleMetadata = { + ruleName: 'single-eof-line', + type: 'style', + description: `Ensure the file ends with a single new line.`, + rationale: `This is similar to eofline, but ensure an exact count instead of just any new + line.`, + options: null, + optionsDescription: `Two integers indicating minimum and maximum number of new lines.`, + typescriptOnly: false, + }; + + public static FAILURE_STRING = 'You need to have a single blank line at end of file.'; + + public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { + const length = sourceFile.text.length; + if (length === 0) { + // Allow empty files. + return []; + } + + const matchEof = /\r?\n((\r?\n)*)$/.exec(sourceFile.text); + if (!matchEof) { + const lines = sourceFile.getLineStarts(); + const fix = Lint.Replacement.appendText( + length, + sourceFile.text[lines[1] - 2] === '\r' ? '\r\n' : '\n', + ); + + return [ + new Lint.RuleFailure(sourceFile, length, length, Rule.FAILURE_STRING, this.ruleName, fix), + ]; + } else if (matchEof[1]) { + const lines = sourceFile.getLineStarts(); + const fix = Lint.Replacement.replaceFromTo( + matchEof.index, + length, + sourceFile.text[lines[1] - 2] === '\r' ? '\r\n' : '\n', + ); + + return [ + new Lint.RuleFailure(sourceFile, length, length, Rule.FAILURE_STRING, this.ruleName, fix), + ]; + } + + return []; + } +} diff --git a/tslint.json b/tslint.json index c3254c57a0..83d27bea6c 100644 --- a/tslint.json +++ b/tslint.json @@ -6,6 +6,8 @@ "import-groups": true, "non-null-operator": true, "no-global-tslint-disable": true, + "single-eof-line": true, + "import-blacklist": [ true,