fix(angular): handle inferred projects without project configuration files in migrations (#31633)
## Current Behavior Some Angular migrations collect the Angular projects from the project graph using the dependencies information. When reading the project configuration for those projects, it can throw an error if trying to do it for a completely inferred project (it doesn't have a project configuration file). ## Expected Behavior The Angular migrations collecting Angular projects from the project graph using the dependencies information should gracefully handle projects that were completely inferred when trying to read the project configuration. In fact, the current migrations didn't need to read the project configuration and could use the project graph information directly, so the call to read the project configuration was removed. ## Related Issue(s) Fixes #31607
This commit is contained in:
parent
9406d2bfdb
commit
e1dfe6ea09
@ -25,7 +25,6 @@ const newImportPath = '@ngrx/router-store/data-persistence';
|
|||||||
|
|
||||||
export default async function (tree: Tree): Promise<void> {
|
export default async function (tree: Tree): Promise<void> {
|
||||||
const projects = await getProjectsFilteredByDependencies(
|
const projects = await getProjectsFilteredByDependencies(
|
||||||
tree,
|
|
||||||
angularPluginTargetNames
|
angularPluginTargetNames
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -38,7 +37,7 @@ export default async function (tree: Tree): Promise<void> {
|
|||||||
const cachedFileMap = readFileMapCache().fileMap.projectFileMap;
|
const cachedFileMap = readFileMapCache().fileMap.projectFileMap;
|
||||||
|
|
||||||
const filesWithNxAngularImports: FileData[] = [];
|
const filesWithNxAngularImports: FileData[] = [];
|
||||||
for (const { graphNode } of projects) {
|
for (const graphNode of projects) {
|
||||||
const files = filterFilesWithNxAngularDep(
|
const files = filterFilesWithNxAngularDep(
|
||||||
cachedFileMap[graphNode.name] || []
|
cachedFileMap[graphNode.name] || []
|
||||||
);
|
);
|
||||||
|
|||||||
@ -43,11 +43,11 @@ export default async function (tree: Tree) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const projects = await getProjectsFilteredByDependencies(tree, [
|
const projects = await getProjectsFilteredByDependencies([
|
||||||
'npm:@nguniversal/common',
|
'npm:@nguniversal/common',
|
||||||
'npm:@nguniversal/express-engine',
|
'npm:@nguniversal/express-engine',
|
||||||
]);
|
]);
|
||||||
for (const { project } of projects) {
|
for (const { data: project } of projects) {
|
||||||
if (project.projectType !== 'application') {
|
if (project.projectType !== 'application') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { formatFiles, visitNotIgnoredFiles, type Tree } from '@nx/devkit';
|
|||||||
import { getProjectsFilteredByDependencies } from '../utils/projects';
|
import { getProjectsFilteredByDependencies } from '../utils/projects';
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
export default async function (tree: Tree) {
|
||||||
const angularProjects = await getProjectsFilteredByDependencies(tree, [
|
const angularProjects = await getProjectsFilteredByDependencies([
|
||||||
'npm:@angular/core',
|
'npm:@angular/core',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -13,8 +13,8 @@ export default async function (tree: Tree) {
|
|||||||
const zoneJsImportRegex = /(['"`])zone\.js\/dist\/zone(['"`])/g;
|
const zoneJsImportRegex = /(['"`])zone\.js\/dist\/zone(['"`])/g;
|
||||||
const zoneJsTestingImportRegex =
|
const zoneJsTestingImportRegex =
|
||||||
/(['"`])zone\.js\/dist\/zone-testing(['"`])/g;
|
/(['"`])zone\.js\/dist\/zone-testing(['"`])/g;
|
||||||
for (const { project } of angularProjects) {
|
for (const graphNode of angularProjects) {
|
||||||
visitNotIgnoredFiles(tree, project.root, (file) => {
|
visitNotIgnoredFiles(tree, graphNode.data.root, (file) => {
|
||||||
// we are only interested in .ts files
|
// we are only interested in .ts files
|
||||||
if (!file.endsWith('.ts')) {
|
if (!file.endsWith('.ts')) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -10,13 +10,12 @@ import { getProjectsFilteredByDependencies } from '../utils/projects';
|
|||||||
const preferStandaloneRule = '@angular-eslint/prefer-standalone';
|
const preferStandaloneRule = '@angular-eslint/prefer-standalone';
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
export default async function (tree: Tree) {
|
||||||
const projects = await getProjectsFilteredByDependencies(tree, [
|
const projects = await getProjectsFilteredByDependencies([
|
||||||
'npm:@angular/core',
|
'npm:@angular/core',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (const {
|
for (const graphNode of projects) {
|
||||||
project: { root },
|
const root = graphNode.data.root;
|
||||||
} of projects) {
|
|
||||||
if (!isEslintConfigSupported(tree, root)) {
|
if (!isEslintConfigSupported(tree, root)) {
|
||||||
// ESLint config is not supported, skip
|
// ESLint config is not supported, skip
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -14,14 +14,13 @@ export const rulesToRemove = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
export default async function (tree: Tree) {
|
||||||
const projects = await getProjectsFilteredByDependencies(tree, [
|
const projects = await getProjectsFilteredByDependencies([
|
||||||
'npm:@angular/core',
|
'npm:@angular/core',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let hasRootProject = false;
|
let hasRootProject = false;
|
||||||
for (const {
|
for (const graphNode of projects) {
|
||||||
project: { root },
|
const root = graphNode.data.root;
|
||||||
} of projects) {
|
|
||||||
if (!isEslintConfigSupported(tree, root)) {
|
if (!isEslintConfigSupported(tree, root)) {
|
||||||
// ESLint config is not supported, skip
|
// ESLint config is not supported, skip
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -4,12 +4,12 @@ import { FileChangeRecorder } from '../../utils/file-change-recorder';
|
|||||||
import { getProjectsFilteredByDependencies } from '../utils/projects';
|
import { getProjectsFilteredByDependencies } from '../utils/projects';
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
export default async function (tree: Tree) {
|
||||||
const projects = await getProjectsFilteredByDependencies(tree, [
|
const projects = await getProjectsFilteredByDependencies([
|
||||||
'npm:@angular/ssr',
|
'npm:@angular/ssr',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (const { project } of projects) {
|
for (const graphNode of projects) {
|
||||||
visitNotIgnoredFiles(tree, project.root, (path) => {
|
visitNotIgnoredFiles(tree, graphNode.data.root, (path) => {
|
||||||
if (!path.endsWith('.ts') || path.endsWith('.d.ts')) {
|
if (!path.endsWith('.ts') || path.endsWith('.d.ts')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,6 @@ const newImportPath = '@ngrx/router-store/data-persistence';
|
|||||||
|
|
||||||
export default async function (tree: Tree): Promise<void> {
|
export default async function (tree: Tree): Promise<void> {
|
||||||
const projects = await getProjectsFilteredByDependencies(
|
const projects = await getProjectsFilteredByDependencies(
|
||||||
tree,
|
|
||||||
angularPluginTargetNames
|
angularPluginTargetNames
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -39,7 +38,7 @@ export default async function (tree: Tree): Promise<void> {
|
|||||||
const cachedFileMap = readFileMapCache().fileMap.projectFileMap;
|
const cachedFileMap = readFileMapCache().fileMap.projectFileMap;
|
||||||
|
|
||||||
const filesWithNxAngularImports: FileData[] = [];
|
const filesWithNxAngularImports: FileData[] = [];
|
||||||
for (const { graphNode } of projects) {
|
for (const graphNode of projects) {
|
||||||
const files = filterFilesWithNxAngularDep(
|
const files = filterFilesWithNxAngularDep(
|
||||||
cachedFileMap[graphNode.name] || []
|
cachedFileMap[graphNode.name] || []
|
||||||
);
|
);
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import { angularDevkitVersion } from '../../utils/versions';
|
|||||||
import { getProjectsFilteredByDependencies } from '../utils/projects';
|
import { getProjectsFilteredByDependencies } from '../utils/projects';
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
export default async function (tree: Tree) {
|
||||||
const projects = await getProjectsFilteredByDependencies(tree, [
|
const projects = await getProjectsFilteredByDependencies([
|
||||||
'npm:@angular/platform-server',
|
'npm:@angular/platform-server',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -19,8 +19,8 @@ export default async function (tree: Tree) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let isSsrInstalled = false;
|
let isSsrInstalled = false;
|
||||||
for (const { project } of projects) {
|
for (const graphNode of projects) {
|
||||||
visitNotIgnoredFiles(tree, project.root, (file) => {
|
visitNotIgnoredFiles(tree, graphNode.data.root, (file) => {
|
||||||
if (!file.endsWith('.ts') || file.endsWith('.d.ts')) {
|
if (!file.endsWith('.ts') || file.endsWith('.d.ts')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { FileChangeRecorder } from '../../utils/file-change-recorder';
|
|||||||
import { getProjectsFilteredByDependencies } from '../utils/projects';
|
import { getProjectsFilteredByDependencies } from '../utils/projects';
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
export default async function (tree: Tree) {
|
||||||
const projects = await getProjectsFilteredByDependencies(tree, [
|
const projects = await getProjectsFilteredByDependencies([
|
||||||
'npm:@angular/ssr',
|
'npm:@angular/ssr',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -13,8 +13,8 @@ export default async function (tree: Tree) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const { project } of projects) {
|
for (const graphNode of projects) {
|
||||||
visitNotIgnoredFiles(tree, project.root, (file) => {
|
visitNotIgnoredFiles(tree, graphNode.data.root, (file) => {
|
||||||
if (!file.endsWith('.ts') || file.endsWith('.d.ts')) {
|
if (!file.endsWith('.ts') || file.endsWith('.d.ts')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,12 +12,12 @@ type TsConfig = {
|
|||||||
export default async function (tree: Tree) {
|
export default async function (tree: Tree) {
|
||||||
const uniqueTsConfigs = new Set<string>();
|
const uniqueTsConfigs = new Set<string>();
|
||||||
|
|
||||||
const projects = await getProjectsFilteredByDependencies(tree, [
|
const projects = await getProjectsFilteredByDependencies([
|
||||||
'npm:@angular/core',
|
'npm:@angular/core',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (const { project } of projects) {
|
for (const graphNode of projects) {
|
||||||
for (const [, target] of allProjectTargets(project)) {
|
for (const [, target] of allProjectTargets(graphNode.data)) {
|
||||||
for (const [, options] of allTargetOptions<{ tsConfig?: string }>(
|
for (const [, options] of allTargetOptions<{ tsConfig?: string }>(
|
||||||
target
|
target
|
||||||
)) {
|
)) {
|
||||||
|
|||||||
@ -1,19 +1,9 @@
|
|||||||
import type {
|
import type { ProjectGraphProjectNode } from '@nx/devkit';
|
||||||
ProjectConfiguration,
|
import { createProjectGraphAsync } from '@nx/devkit';
|
||||||
ProjectGraphProjectNode,
|
|
||||||
Tree,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { createProjectGraphAsync, readProjectConfiguration } from '@nx/devkit';
|
|
||||||
|
|
||||||
export async function getProjectsFilteredByDependencies(
|
export async function getProjectsFilteredByDependencies(
|
||||||
tree: Tree,
|
|
||||||
dependencies: string[]
|
dependencies: string[]
|
||||||
): Promise<
|
): Promise<ProjectGraphProjectNode[]> {
|
||||||
Array<{
|
|
||||||
project: ProjectConfiguration;
|
|
||||||
graphNode: ProjectGraphProjectNode;
|
|
||||||
}>
|
|
||||||
> {
|
|
||||||
const projectGraph = await createProjectGraphAsync();
|
const projectGraph = await createProjectGraphAsync();
|
||||||
|
|
||||||
return Object.entries(projectGraph.dependencies)
|
return Object.entries(projectGraph.dependencies)
|
||||||
@ -22,8 +12,5 @@ export async function getProjectsFilteredByDependencies(
|
|||||||
!projectGraph.externalNodes?.[node] &&
|
!projectGraph.externalNodes?.[node] &&
|
||||||
deps.some(({ target }) => dependencies.includes(target))
|
deps.some(({ target }) => dependencies.includes(target))
|
||||||
)
|
)
|
||||||
.map(([projectName]) => ({
|
.map(([projectName]) => projectGraph.nodes[projectName]);
|
||||||
project: readProjectConfiguration(tree, projectName),
|
|
||||||
graphNode: projectGraph.nodes[projectName],
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user