From c90459000d9019335f975f2f0e535592cef6462b Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Tue, 19 Feb 2019 22:38:35 +0100 Subject: [PATCH] fix(schematics): do not generate invalid stylesheet files Currently whenever someone specified Stylus or Sass as the default style extension for their Angular CLI project, the CDK/ Material schematics incorrectly generate files with that given extension. This is problematic because the schematic style templates are written in CSS and therefore are not compatible with Stylus or Sass (which are not supersets of CSS unlike less, scss) Fixes #15164 --- .../schematics/ng-generate/drag-drop/index.spec.ts | 13 +++++++++++++ src/cdk/schematics/utils/build-component.ts | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/cdk/schematics/ng-generate/drag-drop/index.spec.ts b/src/cdk/schematics/ng-generate/drag-drop/index.spec.ts index 1109fba33a93..78ae11b187b4 100644 --- a/src/cdk/schematics/ng-generate/drag-drop/index.spec.ts +++ b/src/cdk/schematics/ng-generate/drag-drop/index.spec.ts @@ -46,6 +46,19 @@ describe('CDK drag-drop schematic', () => { expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss'); }); + it('should not generate invalid stylesheets', () => { + const tree = runner.runSchematic( + 'drag-drop', {styleext: 'styl', ...baseOptions}, createTestApp(runner)); + + // In this case we expect the schematic to generate a plain "css" file because + // the component schematics are using CSS style templates which are not compatible + // with all CLI supported styles (e.g. Stylus or Sass) + expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.css', + 'Expected the schematic to generate a plain "css" file.'); + expect(tree.files).not.toContain('/projects/material/src/app/foo/foo.component.styl', + 'Expected the schematic to not generate a "stylus" file'); + }); + it('should fall back to the @schematics/angular:component option value', () => { const tree = runner.runSchematic( 'drag-drop', baseOptions, createTestApp(runner, {style: 'less'})); diff --git a/src/cdk/schematics/utils/build-component.ts b/src/cdk/schematics/utils/build-component.ts index 71c547c3843a..83fa3eba582f 100644 --- a/src/cdk/schematics/utils/build-component.ts +++ b/src/cdk/schematics/utils/build-component.ts @@ -40,6 +40,12 @@ import {getProjectFromWorkspace} from './get-project'; import {getDefaultComponentOptions} from './schematic-options'; import {ts} from './version-agnostic-typescript'; +/** + * List of style extensions which are CSS compatible. All supported CLI style extensions can be + * found here: angular/angular-cli/master/packages/schematics/angular/ng-new/schema.json#L118-L122 + */ +const supportedCssExtensions = ['css', 'scss', 'less']; + function readIntoSourceFile(host: Tree, modulePath: string) { const text = host.read(modulePath); if (text === null) { @@ -195,6 +201,14 @@ export function buildComponent(options: ComponentOptions, validateName(options.name); validateHtmlSelector(options.selector!); + // In case the specified style extension is not part of the supported CSS supersets, + // we generate the stylesheets with the "css" extension. This ensures that we don't + // accidentally generate invalid stylesheets (e.g. drag-drop-comp.styl) which will + // break the Angular CLI project. See: https://github.com/angular/material2/issues/15164 + if (!supportedCssExtensions.includes(options.styleext!)) { + options.styleext = 'css'; + } + // Object that will be used as context for the EJS templates. const baseTemplateContext = { ...strings,