From 2d0ff0a5d39c4a13eeba78b7129b2672bd9eaa18 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Fri, 4 Jun 2021 16:57:07 +0200 Subject: [PATCH] ci: add lint error for files with missing trailing new-line (#42478) For quite a while it is an unspoken convention to add a trailing new-line files within the Angular repository. This was never enforced automatically, but has been frequently raised in pull requests through manual review. This commit sets up a lint rule so that this is "officially" enforced and doesn't require manual review. PR Close #42478 --- packages/common/http/src/context.ts | 2 +- packages/compiler-cli/src/ngtsc/core/index.ts | 2 +- .../compiler-cli/src/ngtsc/incremental/test/incremental_spec.ts | 2 +- packages/compiler-cli/src/ngtsc/scope/index.ts | 2 +- packages/compiler-cli/src/ngtsc/scope/src/api.ts | 2 +- packages/compiler-cli/src/transformers/program.ts | 2 +- .../schematics/migrations/can-activate-with-redirect-to/util.ts | 2 +- .../migrations/relative-link-resolution/update_recorder.ts | 2 +- packages/core/schematics/migrations/xhr-factory/index.ts | 2 +- packages/core/src/di/injector_marker.ts | 2 +- packages/core/src/linker/element_ref.ts | 2 +- packages/core/src/linker/query_list.ts | 2 +- packages/core/src/render3/node_assert.ts | 2 +- packages/core/src/util/assert.ts | 2 +- packages/core/src/util/dom.ts | 2 +- packages/core/test/acceptance/security_spec.ts | 2 +- packages/core/test/di/inject_flags_spec.ts | 2 +- packages/core/test/render3/interfaces/node_spec.ts | 2 +- packages/core/test/render3/is_shape_of.ts | 2 +- packages/core/test/render3/is_shape_of_spec.ts | 2 +- packages/core/test/render3/jit/declare_ng_module_spec.ts | 2 +- packages/core/test/render3/matchers.ts | 2 +- packages/core/test/render3/matchers_spec.ts | 2 +- packages/core/test/render3/view_fixture.ts | 2 +- packages/forms/src/directives/control_value_accessor.ts | 2 +- packages/language-service/ivy/language_service.ts | 2 +- packages/language-service/ivy/references_and_rename.ts | 2 +- packages/language-service/ivy/references_and_rename_utils.ts | 2 +- packages/language-service/ivy/testing/src/util.ts | 2 +- packages/language-service/ivy/utils.ts | 2 +- .../src/tools/src/extract/translation_files/xml_file.ts | 2 +- .../tools/test/extract/translation_files/icu_parsing_spec.ts | 2 +- packages/router/src/directives/router_link_active.ts | 2 +- packages/router/src/utils/config.ts | 2 +- tslint.json | 2 ++ 35 files changed, 36 insertions(+), 34 deletions(-) diff --git a/packages/common/http/src/context.ts b/packages/common/http/src/context.ts index 50a9858330..6f1c208abd 100644 --- a/packages/common/http/src/context.ts +++ b/packages/common/http/src/context.ts @@ -96,4 +96,4 @@ export class HttpContext { keys(): IterableIterator> { return this.map.keys(); } -} \ No newline at end of file +} diff --git a/packages/compiler-cli/src/ngtsc/core/index.ts b/packages/compiler-cli/src/ngtsc/core/index.ts index a9eba8a032..62fd84cc24 100644 --- a/packages/compiler-cli/src/ngtsc/core/index.ts +++ b/packages/compiler-cli/src/ngtsc/core/index.ts @@ -7,4 +7,4 @@ */ export * from './src/compiler'; -export {NgCompilerHost} from './src/host'; \ No newline at end of file +export {NgCompilerHost} from './src/host'; diff --git a/packages/compiler-cli/src/ngtsc/incremental/test/incremental_spec.ts b/packages/compiler-cli/src/ngtsc/incremental/test/incremental_spec.ts index cd2b92676f..5eae81e0a1 100644 --- a/packages/compiler-cli/src/ngtsc/incremental/test/incremental_spec.ts +++ b/packages/compiler-cli/src/ngtsc/incremental/test/incremental_spec.ts @@ -38,4 +38,4 @@ runInEachFileSystem(() => { expect(secondCompilation.safeToSkipEmit(fooSf)).toBeFalse(); }); }); -}); \ No newline at end of file +}); diff --git a/packages/compiler-cli/src/ngtsc/scope/index.ts b/packages/compiler-cli/src/ngtsc/scope/index.ts index 920f8dba8a..7904cd224b 100644 --- a/packages/compiler-cli/src/ngtsc/scope/index.ts +++ b/packages/compiler-cli/src/ngtsc/scope/index.ts @@ -10,4 +10,4 @@ export {ExportScope, ScopeData} from './src/api'; export {ComponentScopeReader, CompoundComponentScopeReader} from './src/component_scope'; export {DtsModuleScopeResolver, MetadataDtsModuleScopeResolver} from './src/dependency'; export {DeclarationData, LocalModuleScope, LocalModuleScopeRegistry, LocalNgModuleData} from './src/local'; -export {TypeCheckScope, TypeCheckScopeRegistry} from './src/typecheck'; \ No newline at end of file +export {TypeCheckScope, TypeCheckScopeRegistry} from './src/typecheck'; diff --git a/packages/compiler-cli/src/ngtsc/scope/src/api.ts b/packages/compiler-cli/src/ngtsc/scope/src/api.ts index 70ba24bc13..d04fdac1e7 100644 --- a/packages/compiler-cli/src/ngtsc/scope/src/api.ts +++ b/packages/compiler-cli/src/ngtsc/scope/src/api.ts @@ -62,4 +62,4 @@ export interface RemoteScope { * Those pipes used by the component that requires this scope to be set remotely. */ pipes: Reference[]; -} \ No newline at end of file +} diff --git a/packages/compiler-cli/src/transformers/program.ts b/packages/compiler-cli/src/transformers/program.ts index b0266def9d..c048865101 100644 --- a/packages/compiler-cli/src/transformers/program.ts +++ b/packages/compiler-cli/src/transformers/program.ts @@ -1127,4 +1127,4 @@ function isIvyNgModule(clazz: ts.ClassDeclaration): boolean { // No Ivy 'ɵmod' property found. return false; -} \ No newline at end of file +} diff --git a/packages/core/schematics/migrations/can-activate-with-redirect-to/util.ts b/packages/core/schematics/migrations/can-activate-with-redirect-to/util.ts index 63a6684317..04d33e185d 100644 --- a/packages/core/schematics/migrations/can-activate-with-redirect-to/util.ts +++ b/packages/core/schematics/migrations/can-activate-with-redirect-to/util.ts @@ -59,4 +59,4 @@ function hasProperty(node: ts.ObjectLiteralExpression, propertyName: string): bo } } return false; -} \ No newline at end of file +} diff --git a/packages/core/schematics/migrations/relative-link-resolution/update_recorder.ts b/packages/core/schematics/migrations/relative-link-resolution/update_recorder.ts index 6796262346..82e1787968 100644 --- a/packages/core/schematics/migrations/relative-link-resolution/update_recorder.ts +++ b/packages/core/schematics/migrations/relative-link-resolution/update_recorder.ts @@ -16,4 +16,4 @@ import * as ts from 'typescript'; export interface UpdateRecorder { updateNode(node: ts.Node, newText: string): void; commitUpdate(): void; -} \ No newline at end of file +} diff --git a/packages/core/schematics/migrations/xhr-factory/index.ts b/packages/core/schematics/migrations/xhr-factory/index.ts index db04963e6f..919b56e1d5 100644 --- a/packages/core/schematics/migrations/xhr-factory/index.ts +++ b/packages/core/schematics/migrations/xhr-factory/index.ts @@ -129,4 +129,4 @@ function getNamedImports(importDeclaration: ts.ImportDeclaration|undefined): ts. } return undefined; -} \ No newline at end of file +} diff --git a/packages/core/src/di/injector_marker.ts b/packages/core/src/di/injector_marker.ts index ff13f93b72..ca8ef57a29 100644 --- a/packages/core/src/di/injector_marker.ts +++ b/packages/core/src/di/injector_marker.ts @@ -21,4 +21,4 @@ export const enum InjectorMarkers { * Marks that the current type is `Injector` */ Injector = -1 -} \ No newline at end of file +} diff --git a/packages/core/src/linker/element_ref.ts b/packages/core/src/linker/element_ref.ts index c66ca02265..5c91db7bc4 100644 --- a/packages/core/src/linker/element_ref.ts +++ b/packages/core/src/linker/element_ref.ts @@ -95,4 +95,4 @@ export class ElementRef { */ export function unwrapElementRef(value: T|ElementRef): T|R { return value instanceof ElementRef ? value.nativeElement : value; -} \ No newline at end of file +} diff --git a/packages/core/src/linker/query_list.ts b/packages/core/src/linker/query_list.ts index 26c12e5b24..d0353b168c 100644 --- a/packages/core/src/linker/query_list.ts +++ b/packages/core/src/linker/query_list.ts @@ -202,4 +202,4 @@ interface QueryListInternal extends QueryList { length: number; last: T; first: T; -} \ No newline at end of file +} diff --git a/packages/core/src/render3/node_assert.ts b/packages/core/src/render3/node_assert.ts index 5305c90a26..41dbccca47 100644 --- a/packages/core/src/render3/node_assert.ts +++ b/packages/core/src/render3/node_assert.ts @@ -31,4 +31,4 @@ export function assertPureTNodeType(type: TNodeType) { throwError(`Expected TNodeType to have only a single type selected, but got ${ toTNodeTypeAsString(type)}.`); } -} \ No newline at end of file +} diff --git a/packages/core/src/util/assert.ts b/packages/core/src/util/assert.ts index bf1092a99b..f907beaa7d 100644 --- a/packages/core/src/util/assert.ts +++ b/packages/core/src/util/assert.ts @@ -129,4 +129,4 @@ export function assertOneOf(value: any, ...validValues: any[]) { if (validValues.indexOf(value) !== -1) return true; throwError(`Expected value to be one of ${JSON.stringify(validValues)} but was ${ JSON.stringify(value)}.`); -} \ No newline at end of file +} diff --git a/packages/core/src/util/dom.ts b/packages/core/src/util/dom.ts index f55098583e..4d03fe5e8e 100644 --- a/packages/core/src/util/dom.ts +++ b/packages/core/src/util/dom.ts @@ -48,4 +48,4 @@ const COMMENT_DELIMITER_ESCAPED = '\u200B$1\u200B'; export function escapeCommentText(value: string): string { return value.replace( COMMENT_DISALLOWED, (text) => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED)); -} \ No newline at end of file +} diff --git a/packages/core/test/acceptance/security_spec.ts b/packages/core/test/acceptance/security_spec.ts index afc8b9ccd4..28a26c2946 100644 --- a/packages/core/test/acceptance/security_spec.ts +++ b/packages/core/test/acceptance/security_spec.ts @@ -40,4 +40,4 @@ describe('comment node text escaping', () => { expect(script).toBeFalsy(); }); }); -}); \ No newline at end of file +}); diff --git a/packages/core/test/di/inject_flags_spec.ts b/packages/core/test/di/inject_flags_spec.ts index b680ff8c5f..ba939417d7 100644 --- a/packages/core/test/di/inject_flags_spec.ts +++ b/packages/core/test/di/inject_flags_spec.ts @@ -16,4 +16,4 @@ describe('InjectFlags', () => { expect(InjectFlags.SkipSelf).toEqual(InternalInjectFlags.SkipSelf as number); expect(InjectFlags.Optional).toEqual(InternalInjectFlags.Optional as number); }); -}); \ No newline at end of file +}); diff --git a/packages/core/test/render3/interfaces/node_spec.ts b/packages/core/test/render3/interfaces/node_spec.ts index 8107af523c..d00cd3b6a2 100644 --- a/packages/core/test/render3/interfaces/node_spec.ts +++ b/packages/core/test/render3/interfaces/node_spec.ts @@ -25,4 +25,4 @@ describe('node interfaces', () => { .toEqual('Element|Container|ElementContainer|Projection|IcuContainer'); }); }); -}); \ No newline at end of file +}); diff --git a/packages/core/test/render3/is_shape_of.ts b/packages/core/test/render3/is_shape_of.ts index 7248ccbd1f..babdb59211 100644 --- a/packages/core/test/render3/is_shape_of.ts +++ b/packages/core/test/render3/is_shape_of.ts @@ -199,4 +199,4 @@ export function isDOMElement(obj: any): obj is Element { */ export function isDOMText(obj: any): obj is Text { return obj instanceof Text; -} \ No newline at end of file +} diff --git a/packages/core/test/render3/is_shape_of_spec.ts b/packages/core/test/render3/is_shape_of_spec.ts index 43818a396d..b757cffb7e 100644 --- a/packages/core/test/render3/is_shape_of_spec.ts +++ b/packages/core/test/render3/is_shape_of_spec.ts @@ -34,4 +34,4 @@ describe('isShapeOf', () => { expect(isShapeOf({required: true, extra: 'is ok'}, {required: true, missing: true})) .toBeFalse(); }); -}); \ No newline at end of file +}); diff --git a/packages/core/test/render3/jit/declare_ng_module_spec.ts b/packages/core/test/render3/jit/declare_ng_module_spec.ts index 8463a747e0..a15f0671d0 100644 --- a/packages/core/test/render3/jit/declare_ng_module_spec.ts +++ b/packages/core/test/render3/jit/declare_ng_module_spec.ts @@ -116,4 +116,4 @@ function expectNgModuleDef( function unwrap(values: Type[]|(() => Type[])): Type[] { return typeof values === 'function' ? values() : values; -} \ No newline at end of file +} diff --git a/packages/core/test/render3/matchers.ts b/packages/core/test/render3/matchers.ts index 8fefab7515..8b6e7e6fec 100644 --- a/packages/core/test/render3/matchers.ts +++ b/packages/core/test/render3/matchers.ts @@ -252,4 +252,4 @@ export function matchI18nMutableOpCodes(expectedMutableOpCodes: string[]): }; return matcher; -} \ No newline at end of file +} diff --git a/packages/core/test/render3/matchers_spec.ts b/packages/core/test/render3/matchers_spec.ts index 01964b9140..88a6c024e0 100644 --- a/packages/core/test/render3/matchers_spec.ts +++ b/packages/core/test/render3/matchers_spec.ts @@ -93,4 +93,4 @@ describe('render3 matchers', () => { expect(matcher.jasmineToString!()).toEqual(`[#TEXT: "myText" != #TEXT: "other text"]`); }); }); -}); \ No newline at end of file +}); diff --git a/packages/core/test/render3/view_fixture.ts b/packages/core/test/render3/view_fixture.ts index f330e3f76c..e7dd36706b 100644 --- a/packages/core/test/render3/view_fixture.ts +++ b/packages/core/test/render3/view_fixture.ts @@ -81,4 +81,4 @@ export class ViewFixture { this.leaveView(); } } -} \ No newline at end of file +} diff --git a/packages/forms/src/directives/control_value_accessor.ts b/packages/forms/src/directives/control_value_accessor.ts index 228c666196..01ac0d2741 100644 --- a/packages/forms/src/directives/control_value_accessor.ts +++ b/packages/forms/src/directives/control_value_accessor.ts @@ -210,4 +210,4 @@ export class BuiltInControlValueAccessor extends BaseControlValueAccessor { * @publicApi */ export const NG_VALUE_ACCESSOR = - new InjectionToken>('NgValueAccessor'); \ No newline at end of file + new InjectionToken>('NgValueAccessor'); diff --git a/packages/language-service/ivy/language_service.ts b/packages/language-service/ivy/language_service.ts index 4bf096f5c7..8e913c144d 100644 --- a/packages/language-service/ivy/language_service.ts +++ b/packages/language-service/ivy/language_service.ts @@ -575,4 +575,4 @@ function getUniqueLocations(locations: readonly T[]): uniqueLocations.set(createLocationKey(location), location); } return Array.from(uniqueLocations.values()); -} \ No newline at end of file +} diff --git a/packages/language-service/ivy/references_and_rename.ts b/packages/language-service/ivy/references_and_rename.ts index 74b85be19f..eb024a0553 100644 --- a/packages/language-service/ivy/references_and_rename.ts +++ b/packages/language-service/ivy/references_and_rename.ts @@ -413,4 +413,4 @@ function getRenameRequestPosition(renameRequest: RenameRequest): FilePosition { renameRequest.requestNode.getStart() : renameRequest.renamePosition.position; return {fileName, position}; -} \ No newline at end of file +} diff --git a/packages/language-service/ivy/references_and_rename_utils.ts b/packages/language-service/ivy/references_and_rename_utils.ts index 274f89837e..9f1df82d14 100644 --- a/packages/language-service/ivy/references_and_rename_utils.ts +++ b/packages/language-service/ivy/references_and_rename_utils.ts @@ -294,4 +294,4 @@ export function getParentClassMeta(requestNode: ts.Node, compiler: NgCompiler): return null; } return compiler.getMeta(parentClass); -} \ No newline at end of file +} diff --git a/packages/language-service/ivy/testing/src/util.ts b/packages/language-service/ivy/testing/src/util.ts index a17c880195..09bfb0cc5e 100644 --- a/packages/language-service/ivy/testing/src/util.ts +++ b/packages/language-service/ivy/testing/src/util.ts @@ -101,4 +101,4 @@ function last(array: T[]): T { throw new Error(`last() called on empty array`); } return array[array.length - 1]; -} \ No newline at end of file +} diff --git a/packages/language-service/ivy/utils.ts b/packages/language-service/ivy/utils.ts index 977d49be78..08a3ce69e4 100644 --- a/packages/language-service/ivy/utils.ts +++ b/packages/language-service/ivy/utils.ts @@ -374,4 +374,4 @@ export function getTemplateLocationFromShimLocation( return null; } return {templateUrl, span}; -} \ No newline at end of file +} diff --git a/packages/localize/src/tools/src/extract/translation_files/xml_file.ts b/packages/localize/src/tools/src/extract/translation_files/xml_file.ts index a38ca3b11e..1d402cb419 100644 --- a/packages/localize/src/tools/src/extract/translation_files/xml_file.ts +++ b/packages/localize/src/tools/src/extract/translation_files/xml_file.ts @@ -103,4 +103,4 @@ const _ESCAPED_CHARS: [RegExp, string][] = [ function escapeXml(text: string): string { return _ESCAPED_CHARS.reduce( (text: string, entry: [RegExp, string]) => text.replace(entry[0], entry[1]), text); -} \ No newline at end of file +} diff --git a/packages/localize/src/tools/test/extract/translation_files/icu_parsing_spec.ts b/packages/localize/src/tools/test/extract/translation_files/icu_parsing_spec.ts index 092cdf6bc5..392ff81522 100644 --- a/packages/localize/src/tools/test/extract/translation_files/icu_parsing_spec.ts +++ b/packages/localize/src/tools/test/extract/translation_files/icu_parsing_spec.ts @@ -73,4 +73,4 @@ describe('extractIcuPlaceholders()', () => { '}\n }}\n}', ]); }); -}); \ No newline at end of file +}); diff --git a/packages/router/src/directives/router_link_active.ts b/packages/router/src/directives/router_link_active.ts index 8617cb2e2c..8670469a7f 100644 --- a/packages/router/src/directives/router_link_active.ts +++ b/packages/router/src/directives/router_link_active.ts @@ -181,4 +181,4 @@ export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit this.linkWithHref && isActiveCheckFn(this.linkWithHref) || this.links.some(isActiveCheckFn) || this.linksWithHrefs.some(isActiveCheckFn); } -} \ No newline at end of file +} diff --git a/packages/router/src/utils/config.ts b/packages/router/src/utils/config.ts index fd284e5b4d..2ae61f646e 100644 --- a/packages/router/src/utils/config.ts +++ b/packages/router/src/utils/config.ts @@ -136,4 +136,4 @@ export function sortByMatchingOutlets(routes: Routes, outletName: string): Route const sortedConfig = routes.filter(r => getOutlet(r) === outletName); sortedConfig.push(...routes.filter(r => getOutlet(r) !== outletName)); return sortedConfig; -} \ No newline at end of file +} diff --git a/tslint.json b/tslint.json index 8a7f55bd89..9c0ccf7fc3 100644 --- a/tslint.json +++ b/tslint.json @@ -6,6 +6,7 @@ "node_modules/tslint-no-toplevel-property-access/rules" ], "rules": { + "eofline": true, "file-header": [ true, { @@ -56,6 +57,7 @@ ] }, "jsRules": { + "eofline": true, "file-header": [ true, {