Skip to content
This repository was archived by the owner on Apr 4, 2025. It is now read-only.

Commit 49e9285

Browse files
committed
fix(@schematics/angular): make first project the default
1 parent 6b8a6e8 commit 49e9285

File tree

5 files changed

+219
-194
lines changed

5 files changed

+219
-194
lines changed

packages/schematics/angular/application/index.ts

Lines changed: 151 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import { JsonObject, normalize, relative, strings, tags } from '@angular-devkit/core';
9-
import { experimental } from '@angular-devkit/core';
109
import {
1110
MergeStrategy,
1211
Rule,
@@ -24,11 +23,15 @@ import {
2423
url,
2524
} from '@angular-devkit/schematics';
2625
import { Schema as E2eOptions } from '../e2e/schema';
27-
import { getWorkspace, getWorkspacePath } from '../utility/config';
26+
import {
27+
WorkspaceProject,
28+
WorkspaceSchema,
29+
addProjectToWorkspace,
30+
getWorkspace,
31+
} from '../utility/config';
2832
import { latestVersions } from '../utility/latest-versions';
2933
import { Schema as ApplicationOptions } from './schema';
3034

31-
type WorkspaceSchema = experimental.workspace.WorkspaceSchema;
3235

3336
// TODO: use JsonAST
3437
// function appendPropertyInAstObject(
@@ -85,171 +88,166 @@ function addDependenciesToPackageJson() {
8588
}
8689

8790
function addAppToWorkspaceFile(options: ApplicationOptions, workspace: WorkspaceSchema): Rule {
88-
return (host: Tree, context: SchematicContext) => {
89-
// TODO: use JsonAST
90-
// const workspacePath = '/angular.json';
91-
// const workspaceBuffer = host.read(workspacePath);
92-
// if (workspaceBuffer === null) {
93-
// throw new SchematicsException(`Configuration file (${workspacePath}) not found.`);
94-
// }
95-
// const workspaceJson = parseJson(workspaceBuffer.toString());
96-
// if (workspaceJson.value === null) {
97-
// throw new SchematicsException(`Unable to parse configuration file (${workspacePath}).`);
98-
// }
99-
let projectRoot = options.projectRoot !== undefined
100-
? options.projectRoot
101-
: `${workspace.newProjectRoot}/${options.name}`;
102-
if (projectRoot !== '' && !projectRoot.endsWith('/')) {
103-
projectRoot += '/';
104-
}
105-
const rootFilesRoot = options.projectRoot === undefined
106-
? projectRoot
107-
: projectRoot + 'src/';
91+
// TODO: use JsonAST
92+
// const workspacePath = '/angular.json';
93+
// const workspaceBuffer = host.read(workspacePath);
94+
// if (workspaceBuffer === null) {
95+
// throw new SchematicsException(`Configuration file (${workspacePath}) not found.`);
96+
// }
97+
// const workspaceJson = parseJson(workspaceBuffer.toString());
98+
// if (workspaceJson.value === null) {
99+
// throw new SchematicsException(`Unable to parse configuration file (${workspacePath}).`);
100+
// }
101+
let projectRoot = options.projectRoot !== undefined
102+
? options.projectRoot
103+
: `${workspace.newProjectRoot}/${options.name}`;
104+
if (projectRoot !== '' && !projectRoot.endsWith('/')) {
105+
projectRoot += '/';
106+
}
107+
const rootFilesRoot = options.projectRoot === undefined
108+
? projectRoot
109+
: projectRoot + 'src/';
108110

109-
const schematics: JsonObject = {};
111+
const schematics: JsonObject = {};
110112

111-
if (options.inlineTemplate === true
112-
|| options.inlineStyle === true
113-
|| options.style !== 'css') {
114-
schematics['@schematics/angular:component'] = {};
115-
if (options.inlineTemplate === true) {
116-
(schematics['@schematics/angular:component'] as JsonObject).inlineTemplate = true;
117-
}
118-
if (options.inlineStyle === true) {
119-
(schematics['@schematics/angular:component'] as JsonObject).inlineStyle = true;
120-
}
121-
if (options.style && options.style !== 'css') {
122-
(schematics['@schematics/angular:component'] as JsonObject).styleext = options.style;
123-
}
113+
if (options.inlineTemplate === true
114+
|| options.inlineStyle === true
115+
|| options.style !== 'css') {
116+
schematics['@schematics/angular:component'] = {};
117+
if (options.inlineTemplate === true) {
118+
(schematics['@schematics/angular:component'] as JsonObject).inlineTemplate = true;
124119
}
125-
126-
if (options.skipTests === true) {
127-
['class', 'component', 'directive', 'guard', 'module', 'pipe', 'service'].forEach((type) => {
128-
if (!(`@schematics/angular:${type}` in schematics)) {
129-
schematics[`@schematics/angular:${type}`] = {};
130-
}
131-
(schematics[`@schematics/angular:${type}`] as JsonObject).spec = false;
132-
});
120+
if (options.inlineStyle === true) {
121+
(schematics['@schematics/angular:component'] as JsonObject).inlineStyle = true;
133122
}
123+
if (options.style && options.style !== 'css') {
124+
(schematics['@schematics/angular:component'] as JsonObject).styleext = options.style;
125+
}
126+
}
134127

135-
// tslint:disable-next-line:no-any
136-
const project: any = {
137-
root: projectRoot,
138-
projectType: 'application',
139-
prefix: options.prefix || 'app',
140-
schematics,
141-
architect: {
142-
build: {
143-
builder: '@angular-devkit/build-angular:browser',
144-
options: {
145-
outputPath: `dist/${options.name}`,
146-
index: `${projectRoot}src/index.html`,
147-
main: `${projectRoot}src/main.ts`,
148-
polyfills: `${projectRoot}src/polyfills.ts`,
149-
tsConfig: `${rootFilesRoot}tsconfig.app.json`,
150-
assets: [
151-
{
152-
glob: 'favicon.ico',
153-
input: `${projectRoot}src`,
154-
output: '/',
155-
},
156-
{
157-
glob: '**/*',
158-
input: `${projectRoot}src/assets`,
159-
output: '/assets',
160-
},
161-
],
162-
styles: [
163-
`${projectRoot}src/styles.${options.style}`,
164-
],
165-
scripts: [],
166-
},
167-
configurations: {
168-
production: {
169-
fileReplacements: [{
170-
replace: `${projectRoot}src/environments/environment.ts`,
171-
with: `${projectRoot}src/environments/environment.prod.ts`,
172-
}],
173-
optimization: true,
174-
outputHashing: 'all',
175-
sourceMap: false,
176-
extractCss: true,
177-
namedChunks: false,
178-
aot: true,
179-
extractLicenses: true,
180-
vendorChunk: false,
181-
buildOptimizer: true,
128+
if (options.skipTests === true) {
129+
['class', 'component', 'directive', 'guard', 'module', 'pipe', 'service'].forEach((type) => {
130+
if (!(`@schematics/angular:${type}` in schematics)) {
131+
schematics[`@schematics/angular:${type}`] = {};
132+
}
133+
(schematics[`@schematics/angular:${type}`] as JsonObject).spec = false;
134+
});
135+
}
136+
137+
const project: WorkspaceProject = {
138+
root: projectRoot,
139+
projectType: 'application',
140+
prefix: options.prefix || 'app',
141+
schematics,
142+
architect: {
143+
build: {
144+
builder: '@angular-devkit/build-angular:browser',
145+
options: {
146+
outputPath: `dist/${options.name}`,
147+
index: `${projectRoot}src/index.html`,
148+
main: `${projectRoot}src/main.ts`,
149+
polyfills: `${projectRoot}src/polyfills.ts`,
150+
tsConfig: `${rootFilesRoot}tsconfig.app.json`,
151+
assets: [
152+
{
153+
glob: 'favicon.ico',
154+
input: `${projectRoot}src`,
155+
output: '/',
182156
},
183-
},
184-
},
185-
serve: {
186-
builder: '@angular-devkit/build-angular:dev-server',
187-
options: {
188-
browserTarget: `${options.name}:build`,
189-
},
190-
configurations: {
191-
production: {
192-
browserTarget: `${options.name}:build:production`,
157+
{
158+
glob: '**/*',
159+
input: `${projectRoot}src/assets`,
160+
output: '/assets',
193161
},
194-
},
162+
],
163+
styles: [
164+
`${projectRoot}src/styles.${options.style}`,
165+
],
166+
scripts: [],
195167
},
196-
'extract-i18n': {
197-
builder: '@angular-devkit/build-angular:extract-i18n',
198-
options: {
199-
browserTarget: `${options.name}:build`,
168+
configurations: {
169+
production: {
170+
fileReplacements: [{
171+
replace: `${projectRoot}src/environments/environment.ts`,
172+
with: `${projectRoot}src/environments/environment.prod.ts`,
173+
}],
174+
optimization: true,
175+
outputHashing: 'all',
176+
sourceMap: false,
177+
extractCss: true,
178+
namedChunks: false,
179+
aot: true,
180+
extractLicenses: true,
181+
vendorChunk: false,
182+
buildOptimizer: true,
200183
},
201184
},
202-
test: {
203-
builder: '@angular-devkit/build-angular:karma',
204-
options: {
205-
main: `${projectRoot}src/test.ts`,
206-
polyfills: `${projectRoot}src/polyfills.ts`,
207-
tsConfig: `${rootFilesRoot}tsconfig.spec.json`,
208-
karmaConfig: `${rootFilesRoot}karma.conf.js`,
209-
styles: [
210-
`${projectRoot}styles.${options.style}`,
211-
],
212-
scripts: [],
213-
assets: [
214-
{
215-
glob: 'favicon.ico',
216-
input: `${projectRoot}src/`,
217-
output: '/',
218-
},
219-
{
220-
glob: '**/*',
221-
input: `${projectRoot}src/assets`,
222-
output: '/assets',
223-
},
224-
],
225-
},
185+
},
186+
serve: {
187+
builder: '@angular-devkit/build-angular:dev-server',
188+
options: {
189+
browserTarget: `${options.name}:build`,
226190
},
227-
lint: {
228-
builder: '@angular-devkit/build-angular:tslint',
229-
options: {
230-
tsConfig: [
231-
`${rootFilesRoot}tsconfig.app.json`,
232-
`${rootFilesRoot}tsconfig.spec.json`,
233-
],
234-
exclude: [
235-
'**/node_modules/**',
236-
],
191+
configurations: {
192+
production: {
193+
browserTarget: `${options.name}:build:production`,
237194
},
238195
},
239196
},
240-
};
241-
// tslint:disable-next-line:no-any
242-
// const projects: JsonObject = (<any> workspaceAst.value).projects || {};
243-
// tslint:disable-next-line:no-any
244-
// if (!(<any> workspaceAst.value).projects) {
245-
// // tslint:disable-next-line:no-any
246-
// (<any> workspaceAst.value).projects = projects;
247-
// }
248-
249-
workspace.projects[options.name] = project;
250-
251-
host.overwrite(getWorkspacePath(host), JSON.stringify(workspace, null, 2));
197+
'extract-i18n': {
198+
builder: '@angular-devkit/build-angular:extract-i18n',
199+
options: {
200+
browserTarget: `${options.name}:build`,
201+
},
202+
},
203+
test: {
204+
builder: '@angular-devkit/build-angular:karma',
205+
options: {
206+
main: `${projectRoot}src/test.ts`,
207+
polyfills: `${projectRoot}src/polyfills.ts`,
208+
tsConfig: `${rootFilesRoot}tsconfig.spec.json`,
209+
karmaConfig: `${rootFilesRoot}karma.conf.js`,
210+
styles: [
211+
`${projectRoot}styles.${options.style}`,
212+
],
213+
scripts: [],
214+
assets: [
215+
{
216+
glob: 'favicon.ico',
217+
input: `${projectRoot}src/`,
218+
output: '/',
219+
},
220+
{
221+
glob: '**/*',
222+
input: `${projectRoot}src/assets`,
223+
output: '/assets',
224+
},
225+
],
226+
},
227+
},
228+
lint: {
229+
builder: '@angular-devkit/build-angular:tslint',
230+
options: {
231+
tsConfig: [
232+
`${rootFilesRoot}tsconfig.app.json`,
233+
`${rootFilesRoot}tsconfig.spec.json`,
234+
],
235+
exclude: [
236+
'**/node_modules/**',
237+
],
238+
},
239+
},
240+
},
252241
};
242+
// tslint:disable-next-line:no-any
243+
// const projects: JsonObject = (<any> workspaceAst.value).projects || {};
244+
// tslint:disable-next-line:no-any
245+
// if (!(<any> workspaceAst.value).projects) {
246+
// // tslint:disable-next-line:no-any
247+
// (<any> workspaceAst.value).projects = projects;
248+
// }
249+
250+
return addProjectToWorkspace(workspace, options.name, project);
253251
}
254252
const projectNameRegexp = /^[a-zA-Z][.0-9a-zA-Z]*(-[.0-9a-zA-Z]*)*$/;
255253
const unsupportedProjectNames = ['test', 'ember', 'ember-cli', 'vendor', 'app'];

packages/schematics/angular/application/index_spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ describe('Application Schematic', () => {
6969
const tree = schematicRunner.runSchematic('application', options, workspaceTree);
7070
const workspace = JSON.parse(tree.readContent('/angular.json'));
7171
expect(workspace.projects.foo).toBeDefined();
72+
expect(workspace.defaultProject).toBe('foo');
7273
});
7374

7475
it('should set the prefix to app if none is set', () => {

0 commit comments

Comments
 (0)