diff --git a/src/cdk/schematics/ng-update/upgrade-rules/project-tsconfig-paths.spec.ts b/src/cdk/schematics/ng-update/upgrade-rules/project-tsconfig-paths.spec.ts new file mode 100644 index 00000000000..633b2f4526f --- /dev/null +++ b/src/cdk/schematics/ng-update/upgrade-rules/project-tsconfig-paths.spec.ts @@ -0,0 +1,59 @@ +import {HostTree} from '@angular-devkit/schematics'; +import {UnitTestTree} from '@angular-devkit/schematics/testing'; +import {getProjectTsConfigPaths} from './project-tsconfig-paths'; + +describe('ng-update project-tsconfig-paths', () => { + + let testTree: UnitTestTree; + + beforeEach(() => { + testTree = new UnitTestTree(new HostTree()); + }); + + it('should detect build tsconfig path inside of angular.json file', () => { + testTree.create('/my-custom-config.json', ''); + testTree.create('/angular.json', JSON.stringify({ + projects: { + my_name: { + architect: { + build: { + options: { + tsConfig: './my-custom-config.json' + } + } + } + } + } + })); + + expect(getProjectTsConfigPaths(testTree)).toEqual(['./my-custom-config.json']); + }); + + it('should detect test tsconfig path inside of .angular.json file', () => { + testTree.create('/my-test-config.json', ''); + testTree.create('/.angular.json', JSON.stringify({ + projects: { + with_tests: { + architect: { + test: { + options: { + tsConfig: './my-test-config.json' + } + } + } + } + } + })); + + expect(getProjectTsConfigPaths(testTree)).toEqual(['./my-test-config.json']); + }); + + it('should detect common tsconfigs if no workspace config could be found', () => { + testTree.create('/tsconfig.json', ''); + testTree.create('/src/tsconfig.json', ''); + testTree.create('/src/tsconfig.app.json', ''); + + expect(getProjectTsConfigPaths(testTree)) + .toEqual(['./tsconfig.json', './src/tsconfig.json', './src/tsconfig.app.json']); + }); +}); diff --git a/src/cdk/schematics/ng-update/upgrade-rules/project-tsconfig-paths.ts b/src/cdk/schematics/ng-update/upgrade-rules/project-tsconfig-paths.ts index 46b085eeebb..f65897025c0 100644 --- a/src/cdk/schematics/ng-update/upgrade-rules/project-tsconfig-paths.ts +++ b/src/cdk/schematics/ng-update/upgrade-rules/project-tsconfig-paths.ts @@ -7,7 +7,6 @@ */ import {Tree} from '@angular-devkit/schematics'; -import {getWorkspace} from '@schematics/angular/utility/config'; /** * Gets all tsconfig paths from a CLI project by reading the workspace configuration @@ -22,26 +21,52 @@ export function getProjectTsConfigPaths(tree: Tree): string[] { ]); // Add any tsconfig directly referenced in a build or test task of the angular.json workspace. - const workspace = getWorkspace(tree); + const workspace = getWorkspaceConfigGracefully(tree); - for (const project of Object.values(workspace.projects)) { - ['build', 'test'].forEach(targetName => { - if (project.targets && - project.targets[targetName] && - project.targets[targetName].options && - project.targets[targetName].options.tsConfig) { - tsconfigPaths.add(project.targets[targetName].options.tsConfig); - } + if (workspace) { + for (const project of Object.values(workspace.projects)) { + ['build', 'test'].forEach(targetName => { + if (project.targets && + project.targets[targetName] && + project.targets[targetName].options && + project.targets[targetName].options.tsConfig) { + tsconfigPaths.add(project.targets[targetName].options.tsConfig); + } - if (project.architect && - project.architect[targetName] && - project.architect[targetName].options && - project.architect[targetName].options.tsConfig) { - tsconfigPaths.add(project.architect[targetName].options.tsConfig); - } - }); + if (project.architect && + project.architect[targetName] && + project.architect[targetName].options && + project.architect[targetName].options.tsConfig) { + tsconfigPaths.add(project.architect[targetName].options.tsConfig); + } + }); + } } // Filter out tsconfig files that don't exist in the CLI project. return Array.from(tsconfigPaths).filter(p => tree.exists(p)); } + +/** Name of the default Angular CLI workspace configuration files. */ +const defaultWorkspaceConfigPaths = ['/angular.json', '/.angular.json']; + +/** + * Resolve the workspace configuration of the specified tree gracefully. We cannot use the utility + * functions from the default Angular schematics because those might not be present in older + * versions of the CLI. Also it's important to resolve the workspace gracefully because + * the CLI project could be still using `.angular-cli.json` instead of thew new config. + */ +function getWorkspaceConfigGracefully(tree: Tree): any { + const path = defaultWorkspaceConfigPaths.filter(filePath => tree.exists(filePath))[0]; + const configBuffer = tree.read(path); + + if (!path || !configBuffer) { + return null; + } + + try { + return JSON.parse(configBuffer.toString()); + } catch { + return null; + } +}