Skip to content

Commit d9119f6

Browse files
filipesilvamgechev
authored andcommitted
fix(@schematics/angular): resolve windows paths in tsconfig migration
Fix #16800
1 parent 085e011 commit d9119f6

File tree

4 files changed

+54
-9
lines changed

4 files changed

+54
-9
lines changed

packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,20 @@
77
*/
88
import { JsonAstObject, logging } from '@angular-devkit/core';
99
import { Rule, Tree, UpdateRecorder } from '@angular-devkit/schematics';
10-
import { posix } from 'path';
10+
import { dirname, relative } from 'path';
1111
import {
1212
findPropertyInAstObject,
1313
insertPropertyInAstObjectInOrder,
1414
removePropertyInAstObject,
1515
} from '../../utility/json-utils';
1616
import { Builders } from '../../utility/workspace-models';
17-
import { getAllOptions, getTargets, getWorkspace, readJsonFileAsAstObject } from './utils';
17+
import {
18+
forwardSlashPath,
19+
getAllOptions,
20+
getTargets,
21+
getWorkspace,
22+
readJsonFileAsAstObject,
23+
} from './utils';
1824

1925
/**
2026
* Update the tsconfig files for applications
@@ -107,15 +113,18 @@ function updateTsConfig(tree: Tree, builderConfig: JsonAstObject, builderName: B
107113
const files = findPropertyInAstObject(tsConfigAst, 'files');
108114
if (!files) {
109115
const newFiles: string[] = [];
116+
const tsConfigDir = dirname(forwardSlashPath(tsConfigPath));
110117

111118
const mainOption = findPropertyInAstObject(option, 'main');
112119
if (mainOption && mainOption.kind === 'string') {
113-
newFiles.push(posix.relative(posix.dirname(tsConfigPath), mainOption.value));
120+
newFiles.push(
121+
forwardSlashPath(relative(tsConfigDir, forwardSlashPath(mainOption.value))));
114122
}
115123

116124
const polyfillsOption = findPropertyInAstObject(option, 'polyfills');
117125
if (polyfillsOption && polyfillsOption.kind === 'string') {
118-
newFiles.push(posix.relative(posix.dirname(tsConfigPath), polyfillsOption.value));
126+
newFiles.push(
127+
forwardSlashPath(relative(tsConfigDir, forwardSlashPath(polyfillsOption.value))));
119128
}
120129

121130
if (newFiles.length) {

packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import { EmptyTree } from '@angular-devkit/schematics';
1010
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
11+
import { getWorkspaceTargets, updateWorkspaceTargets } from './update-workspace-config_spec';
1112

1213
// tslint:disable-next-line: no-any
1314
function overrideJsonFile(tree: UnitTestTree, path: string, newContent: object) {
@@ -64,6 +65,32 @@ describe('Migration to version 9', () => {
6465
expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']);
6566
});
6667

68+
it('should resolve paths correctly even if they are using windows separators', async () => {
69+
const tree2 = await schematicRunner
70+
.runExternalSchematicAsync(
71+
require.resolve('../../collection.json'),
72+
'application',
73+
{
74+
name: 'another-app',
75+
},
76+
tree,
77+
)
78+
.toPromise();
79+
80+
const tsCfgPath = 'projects/another-app/tsconfig.app.json';
81+
overrideJsonFile(tree2, tsCfgPath, defaultTsConfigOptions);
82+
const config = getWorkspaceTargets(tree2, 'another-app');
83+
config.build.options.main = 'projects\\another-app\\src\\main.ts';
84+
config.build.options.polyfills = 'projects\\another-app\\src\\polyfills.ts';
85+
config.build.options.tsConfig = 'projects\\another-app\\tsconfig.app.json';
86+
updateWorkspaceTargets(tree2, config, 'another-app');
87+
88+
const tree3 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree2.branch()).toPromise();
89+
const { exclude, files } = JSON.parse(tree3.readContent(tsCfgPath));
90+
expect(exclude).toBeUndefined();
91+
expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']);
92+
});
93+
6794
it('should update apps tsConfig when tsconfig has include', async () => {
6895
const tsConfigContent = {
6996
...defaultTsConfigOptions,

packages/schematics/angular/migrations/update-9/update-workspace-config_spec.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@ import { WorkspaceTargets } from '../../utility/workspace-models';
1313
import { ANY_COMPONENT_STYLE_BUDGET } from './update-workspace-config';
1414

1515
// tslint:disable-next-line: no-any
16-
function getWorkspaceTargets(tree: UnitTestTree): any {
17-
return JSON.parse(tree.readContent(workspacePath))
18-
.projects['migration-test'].architect;
16+
export function getWorkspaceTargets(tree: UnitTestTree, project = 'migration-test'): any {
17+
return JSON.parse(tree.readContent(workspacePath)).projects[project].architect;
1918
}
2019

21-
function updateWorkspaceTargets(tree: UnitTestTree, workspaceTargets: WorkspaceTargets) {
20+
export function updateWorkspaceTargets(
21+
tree: UnitTestTree,
22+
workspaceTargets: WorkspaceTargets,
23+
project = 'migration-test',
24+
) {
2225
const config = JSON.parse(tree.readContent(workspacePath));
23-
config.projects['migration-test'].architect = workspaceTargets;
26+
config.projects[project].architect = workspaceTargets;
2427
tree.overwrite(workspacePath, JSON.stringify(config, undefined, 2));
2528
}
2629

packages/schematics/angular/migrations/update-9/utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,9 @@ export function isIvyEnabled(tree: Tree, tsConfigPath: string): boolean {
144144

145145
return true;
146146
}
147+
148+
// TS represents paths internally with '/' and expects paths to be in this format.
149+
// angular.json expects paths with '/', but doesn't enforce them.
150+
export function forwardSlashPath(path: string) {
151+
return path.replace(/\\/g, '/');
152+
}

0 commit comments

Comments
 (0)