From f2cb83725566a993c8fc86e9797f43079289c790 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Wed, 20 Feb 2019 02:33:59 +0100 Subject: [PATCH] fix(schematics): do not generate invalid stylesheet files (#15235) 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 1109fba33a9..78ae11b187b 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 71c547c3843..83fa3eba582 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,