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
This commit is contained in:
Paul Gschwendtner
2019-02-20 02:33:59 +01:00
committed by Jeremy Elbourn
parent 4021929709
commit f2cb837255
2 changed files with 27 additions and 0 deletions
@@ -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'}));
@@ -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,