diff --git a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts index 05f6d47e40e6..05d454f612ee 100644 --- a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts +++ b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts @@ -7,14 +7,20 @@ */ import { JsonAstObject, logging } from '@angular-devkit/core'; import { Rule, Tree, UpdateRecorder } from '@angular-devkit/schematics'; -import { posix } from 'path'; +import { dirname, relative } from 'path'; import { findPropertyInAstObject, insertPropertyInAstObjectInOrder, removePropertyInAstObject, } from '../../utility/json-utils'; import { Builders } from '../../utility/workspace-models'; -import { getAllOptions, getTargets, getWorkspace, readJsonFileAsAstObject } from './utils'; +import { + forwardSlashPath, + getAllOptions, + getTargets, + getWorkspace, + readJsonFileAsAstObject, +} from './utils'; /** * Update the tsconfig files for applications @@ -107,15 +113,18 @@ function updateTsConfig(tree: Tree, builderConfig: JsonAstObject, builderName: B const files = findPropertyInAstObject(tsConfigAst, 'files'); if (!files) { const newFiles: string[] = []; + const tsConfigDir = dirname(forwardSlashPath(tsConfigPath)); const mainOption = findPropertyInAstObject(option, 'main'); if (mainOption && mainOption.kind === 'string') { - newFiles.push(posix.relative(posix.dirname(tsConfigPath), mainOption.value)); + newFiles.push( + forwardSlashPath(relative(tsConfigDir, forwardSlashPath(mainOption.value)))); } const polyfillsOption = findPropertyInAstObject(option, 'polyfills'); if (polyfillsOption && polyfillsOption.kind === 'string') { - newFiles.push(posix.relative(posix.dirname(tsConfigPath), polyfillsOption.value)); + newFiles.push( + forwardSlashPath(relative(tsConfigDir, forwardSlashPath(polyfillsOption.value)))); } if (newFiles.length) { diff --git a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts index 2459b8c6f218..840b7c3492ca 100644 --- a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts +++ b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts @@ -8,6 +8,7 @@ import { EmptyTree } from '@angular-devkit/schematics'; import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; +import { getWorkspaceTargets, updateWorkspaceTargets } from './update-workspace-config_spec'; // tslint:disable-next-line: no-any function overrideJsonFile(tree: UnitTestTree, path: string, newContent: object) { @@ -64,6 +65,32 @@ describe('Migration to version 9', () => { expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']); }); + it('should resolve paths correctly even if they are using windows separators', async () => { + const tree2 = await schematicRunner + .runExternalSchematicAsync( + require.resolve('../../collection.json'), + 'application', + { + name: 'another-app', + }, + tree, + ) + .toPromise(); + + const tsCfgPath = 'projects/another-app/tsconfig.app.json'; + overrideJsonFile(tree2, tsCfgPath, defaultTsConfigOptions); + const config = getWorkspaceTargets(tree2, 'another-app'); + config.build.options.main = 'projects\\another-app\\src\\main.ts'; + config.build.options.polyfills = 'projects\\another-app\\src\\polyfills.ts'; + config.build.options.tsConfig = 'projects\\another-app\\tsconfig.app.json'; + updateWorkspaceTargets(tree2, config, 'another-app'); + + const tree3 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree2.branch()).toPromise(); + const { exclude, files } = JSON.parse(tree3.readContent(tsCfgPath)); + expect(exclude).toBeUndefined(); + expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']); + }); + it('should update apps tsConfig when tsconfig has include', async () => { const tsConfigContent = { ...defaultTsConfigOptions, diff --git a/packages/schematics/angular/migrations/update-9/update-workspace-config_spec.ts b/packages/schematics/angular/migrations/update-9/update-workspace-config_spec.ts index 39a10eeffebc..54533ff71138 100644 --- a/packages/schematics/angular/migrations/update-9/update-workspace-config_spec.ts +++ b/packages/schematics/angular/migrations/update-9/update-workspace-config_spec.ts @@ -13,14 +13,17 @@ import { WorkspaceTargets } from '../../utility/workspace-models'; import { ANY_COMPONENT_STYLE_BUDGET } from './update-workspace-config'; // tslint:disable-next-line: no-any -function getWorkspaceTargets(tree: UnitTestTree): any { - return JSON.parse(tree.readContent(workspacePath)) - .projects['migration-test'].architect; +export function getWorkspaceTargets(tree: UnitTestTree, project = 'migration-test'): any { + return JSON.parse(tree.readContent(workspacePath)).projects[project].architect; } -function updateWorkspaceTargets(tree: UnitTestTree, workspaceTargets: WorkspaceTargets) { +export function updateWorkspaceTargets( + tree: UnitTestTree, + workspaceTargets: WorkspaceTargets, + project = 'migration-test', +) { const config = JSON.parse(tree.readContent(workspacePath)); - config.projects['migration-test'].architect = workspaceTargets; + config.projects[project].architect = workspaceTargets; tree.overwrite(workspacePath, JSON.stringify(config, undefined, 2)); } diff --git a/packages/schematics/angular/migrations/update-9/utils.ts b/packages/schematics/angular/migrations/update-9/utils.ts index f80a0dd290d1..8cb4261ac022 100644 --- a/packages/schematics/angular/migrations/update-9/utils.ts +++ b/packages/schematics/angular/migrations/update-9/utils.ts @@ -144,3 +144,9 @@ export function isIvyEnabled(tree: Tree, tsConfigPath: string): boolean { return true; } + +// TS represents paths internally with '/' and expects paths to be in this format. +// angular.json expects paths with '/', but doesn't enforce them. +export function forwardSlashPath(path: string) { + return path.replace(/\\/g, '/'); +}