feat(ng-add): respect project default style extension (#12618)

* feat(ng-add): respect project default style extension

* No longer ignores the projects default style extension that has been specified in the `ng new` command (e.g. `new new test --style scss`)

* Address feedback
This commit is contained in:
Paul Gschwendtner
2018-08-14 01:42:43 +02:00
committed by mmalerba
parent 6732414936
commit 5144aa790d
12 changed files with 97 additions and 42 deletions
+1 -2
View File
@@ -58,8 +58,7 @@
},
"styleext": {
"description": "The file extension to be used for style files.",
"type": "string",
"default": "css"
"type": "string"
},
"spec": {
"type": "boolean",
+17 -7
View File
@@ -5,13 +5,10 @@ import {Schema} from './schema';
describe('material-dashboard-schematic', () => {
let runner: SchematicTestRunner;
const options: Schema = {
const baseOptions: Schema = {
name: 'foo',
project: 'material',
changeDetection: 'Default',
styleext: 'css',
spec: true,
export: false,
};
beforeEach(() => {
@@ -19,7 +16,7 @@ describe('material-dashboard-schematic', () => {
});
it('should create dashboard files and add them to module', () => {
const tree = runner.runSchematic('dashboard', { ...options }, createTestApp());
const tree = runner.runSchematic('dashboard', baseOptions, createTestApp());
const files = tree.files;
expect(files).toContain('/projects/material/src/app/foo/foo.component.css');
@@ -33,7 +30,7 @@ describe('material-dashboard-schematic', () => {
});
it('should add dashboard imports to module', () => {
const tree = runner.runSchematic('dashboard', { ...options }, createTestApp());
const tree = runner.runSchematic('dashboard', baseOptions, createTestApp());
const moduleContent = getFileContent(tree, '/projects/material/src/app/app.module.ts');
expect(moduleContent).toContain('MatGridListModule');
@@ -47,4 +44,17 @@ describe('material-dashboard-schematic', () => {
`import { MatGridListModule, MatCardModule, MatMenuModule, MatIconModule, MatButtonModule } from '@angular/material';`);
});
it('should support passing the style extension option', () => {
const tree = runner.runSchematic(
'dashboard', {styleext: 'scss', ...baseOptions}, createTestApp());
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
});
it('should fallback to the default angular:component style extension', () => {
const tree = runner.runSchematic('dashboard', baseOptions, createTestApp({style: 'less'}));
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.less');
});
});
+1 -2
View File
@@ -58,8 +58,7 @@
},
"styleext": {
"description": "The file extension to be used for style files.",
"type": "string",
"default": "css"
"type": "string"
},
"spec": {
"type": "boolean",
+5 -1
View File
@@ -41,7 +41,11 @@ describe('material-install-schematic', () => {
'./node_modules/@angular/material/prebuilt-themes/indigo-pink.css');
});
it('should add custom theme', () => {
it('should support adding a custom theme', () => {
// TODO(devversion): currently a "custom" theme does only work for projects using SCSS.
// TODO(devversion): Throw an error if a custom theme is being installed in a CSS project.
appTree = createTestApp({style: 'scss'});
const tree = runner.runSchematic('ng-add', {theme: 'custom'}, appTree);
const workspace = getWorkspace(tree);
+14 -7
View File
@@ -6,13 +6,9 @@ import {collectionPath, createTestApp} from '../test-setup/test-app';
describe('material-nav-schematic', () => {
let runner: SchematicTestRunner;
const options: Schema = {
const baseOptions: Schema = {
name: 'foo',
project: 'material',
changeDetection: 'Default',
styleext: 'css',
spec: true,
export: false,
};
beforeEach(() => {
@@ -20,7 +16,7 @@ describe('material-nav-schematic', () => {
});
it('should create nav files and add them to module', () => {
const tree = runner.runSchematic('nav', { ...options }, createTestApp());
const tree = runner.runSchematic('nav', baseOptions, createTestApp());
const files = tree.files;
expect(files).toContain('/projects/material/src/app/foo/foo.component.css');
@@ -34,7 +30,7 @@ describe('material-nav-schematic', () => {
});
it('should add nav imports to module', () => {
const tree = runner.runSchematic('nav', { ...options }, createTestApp());
const tree = runner.runSchematic('nav', baseOptions, createTestApp());
const moduleContent = getFileContent(tree, '/projects/material/src/app/app.module.ts');
expect(moduleContent).toContain('LayoutModule');
@@ -50,4 +46,15 @@ describe('material-nav-schematic', () => {
`MatListModule } from '@angular/material';`);
});
it('should support passing the style extension option', () => {
const tree = runner.runSchematic('nav', {styleext: 'scss', ...baseOptions}, createTestApp());
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
});
it('should fallback to the default angular:component style extension', () => {
const tree = runner.runSchematic('nav', baseOptions, createTestApp({style: 'less'}));
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.less');
});
});
+1 -2
View File
@@ -58,8 +58,7 @@
},
"styleext": {
"description": "The file extension to be used for style files.",
"type": "string",
"default": "css"
"type": "string"
},
"spec": {
"type": "boolean",
+15 -7
View File
@@ -6,13 +6,9 @@ import {collectionPath, createTestApp} from '../test-setup/test-app';
describe('material-table-schematic', () => {
let runner: SchematicTestRunner;
const options: Schema = {
const baseOptions: Schema = {
name: 'foo',
project: 'material',
changeDetection: 'Default',
styleext: 'css',
spec: true,
export: false,
};
beforeEach(() => {
@@ -20,7 +16,7 @@ describe('material-table-schematic', () => {
});
it('should create table files and add them to module', () => {
const tree = runner.runSchematic('table', { ...options }, createTestApp());
const tree = runner.runSchematic('table', baseOptions, createTestApp());
const files = tree.files;
expect(files).toContain('/projects/material/src/app/foo/foo.component.css');
@@ -45,8 +41,20 @@ describe('material-table-schematic', () => {
expect(componentContent).toContain('FooDataSource');
});
it('should support passing the style extension option', () => {
const tree = runner.runSchematic('table', {styleext: 'scss', ...baseOptions}, createTestApp());
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
});
it('should fallback to the default angular:component style extension', () => {
const tree = runner.runSchematic('table', baseOptions, createTestApp({style: 'less'}));
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.less');
});
it('should add table imports to module', () => {
const tree = runner.runSchematic('table', { ...options }, createTestApp());
const tree = runner.runSchematic('table', baseOptions, createTestApp());
const moduleContent = getFileContent(tree, '/projects/material/src/app/app.module.ts');
expect(moduleContent).toContain('MatTableModule');
+1 -2
View File
@@ -58,8 +58,7 @@
},
"styleext": {
"description": "The file extension to be used for style files.",
"type": "string",
"default": "css"
"type": "string"
},
"spec": {
"type": "boolean",
+3 -9
View File
@@ -16,7 +16,7 @@ export const collectionPath = join(__dirname, '..', 'collection.json');
export const migrationCollection = join(__dirname, '..', 'migration.json');
/** Create a base app used for testing. */
export function createTestApp(): UnitTestTree {
export function createTestApp(appOptions = {}): UnitTestTree {
const baseRunner = new SchematicTestRunner('material-schematics', collectionPath);
const workspaceTree = baseRunner.runExternalSchematic('@schematics/angular', 'workspace', {
@@ -25,12 +25,6 @@ export function createTestApp(): UnitTestTree {
newProjectRoot: 'projects',
});
return baseRunner.runExternalSchematic('@schematics/angular', 'application', {
name: 'material',
inlineStyle: false,
inlineTemplate: false,
routing: false,
style: 'scss',
skipTests: false,
}, workspaceTree);
return baseRunner.runExternalSchematic('@schematics/angular', 'application',
{...appOptions, name: 'material'}, workspaceTree);
}
+1 -2
View File
@@ -58,8 +58,7 @@
},
"styleext": {
"description": "The file extension to be used for style files.",
"type": "string",
"default": "css"
"type": "string"
},
"spec": {
"type": "boolean",
+7 -1
View File
@@ -39,6 +39,7 @@ import {validateHtmlSelector, validateName} from '@schematics/angular/utility/va
import {resolve, dirname, join} from 'path';
import {readFileSync} from 'fs';
import * as ts from 'typescript';
import {determineDefaultStyleExt} from './default-style-ext';
function readIntoSourceFile(host: Tree, modulePath: string): ts.SourceFile {
const text = host.read(modulePath);
@@ -137,7 +138,7 @@ function buildSelector(options: ComponentOptions, projectPrefix: string) {
*/
function indentTextContent(text: string, numSpaces: number): string {
// In the Material project there should be only LF line-endings, but the schematic files
// are not being linted and therefore there can be also use CRLF or just CR line-endings.
// are not being linted and therefore there can be also CRLF or just CR line-endings.
return text.replace(/(\r\n|\r|\n)/g, `$1${' '.repeat(numSpaces)}`);
}
@@ -160,6 +161,10 @@ export function buildComponent(options: ComponentOptions,
const schematicFilesPath = resolve(dirname(context.schematic.description.path),
schematicFilesUrl);
if (!options.styleext) {
options.styleext = determineDefaultStyleExt(project);
}
if (options.path === undefined) {
options.path = buildDefaultPath(project);
}
@@ -167,6 +172,7 @@ export function buildComponent(options: ComponentOptions,
options.module = findModuleFromOptions(host, options);
const parsedPath = parseName(options.path, options.name);
options.name = parsedPath.name;
options.path = parsedPath.path;
options.selector = options.selector || buildSelector(options, project.prefix);
@@ -0,0 +1,31 @@
/**
* @license
* Copyright Google LLC 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 {WorkspaceProject} from '@schematics/angular/utility/config';
/**
* Style extension that will be used if no default style extension for the CLI project
* could be determined.
*/
const fallbackStyleExtension = 'css';
/**
* Determines the default style extension in the Angular CLI project by looking for the default
* component schematic options. This is necessary for now because when creating CLI projects,
* the CLI only makes the default `--style` option available for the `angular:component` schematic.
*/
export function determineDefaultStyleExt(project: WorkspaceProject): string | null {
if (project.schematics &&
project.schematics['@schematics/angular:component'] &&
project.schematics['@schematics/angular:component']['styleext']) {
return project.schematics['@schematics/angular:component']['styleext'];
}
return fallbackStyleExtension;
}