mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(ng-update): do not fail if @schematics/angular version is outdated (#13929)
* Currently the `ng update` could potentially fail if the version of `@schematics/angular` is outdated on the given project. We should avoid to depend on `@schematics/angular` for the `ng-update` schematic.
* No longer fails if the workspace configuration could not be found. It's very uncommon that someone tries to update a CLI project that still uses `.angular-cli.json` because:
1) The CLI version for the project doesn't support `ng update` with custom downstream migrations
2) In case the developer runs a different CLI version for _that_ outdated project, the CLI technically does run for an invalid project.
Even though, this is a rare case, it doesn't hurt not throwing if the workspace configuration couldn't be found when running `ng update`.
This commit is contained in:
committed by
Jeremy Elbourn
parent
62f35dd67c
commit
ece6b2d6be
@@ -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']);
|
||||
});
|
||||
});
|
||||
@@ -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<any>(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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user