feat(core): add API entrypoint to register metadata (#22773)

This commit is contained in:
Craigory Coppola 2024-04-23 17:04:51 -04:00 committed by GitHub
parent 99e5c869b3
commit 7bb6e9ee14
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 352 additions and 78 deletions

View File

@ -0,0 +1,25 @@
# Type alias: CreateMetadata\<T\>
Ƭ **CreateMetadata**\<`T`\>: (`graph`: [`ProjectGraph`](../../devkit/documents/ProjectGraph), `options`: `T` \| `undefined`, `context`: [`CreateMetadataContext`](../../devkit/documents/CreateMetadataContext)) => [`ProjectsMetadata`](../../devkit/documents/ProjectsMetadata) \| `Promise`\<[`ProjectsMetadata`](../../devkit/documents/ProjectsMetadata)\>
#### Type parameters
| Name | Type |
| :--- | :-------- |
| `T` | `unknown` |
#### Type declaration
▸ (`graph`, `options`, `context`): [`ProjectsMetadata`](../../devkit/documents/ProjectsMetadata) \| `Promise`\<[`ProjectsMetadata`](../../devkit/documents/ProjectsMetadata)\>
##### Parameters
| Name | Type |
| :-------- | :---------------------------------------------------------------------- |
| `graph` | [`ProjectGraph`](../../devkit/documents/ProjectGraph) |
| `options` | `T` \| `undefined` |
| `context` | [`CreateMetadataContext`](../../devkit/documents/CreateMetadataContext) |
##### Returns
[`ProjectsMetadata`](../../devkit/documents/ProjectsMetadata) \| `Promise`\<[`ProjectsMetadata`](../../devkit/documents/ProjectsMetadata)\>

View File

@ -0,0 +1,10 @@
# Type alias: CreateMetadataContext
Ƭ **CreateMetadataContext**: `Object`
#### Type declaration
| Name | Type |
| :-------------------- | :------------------------------------------------------------------ |
| `nxJsonConfiguration` | [`NxJsonConfiguration`](../../devkit/documents/NxJsonConfiguration) |
| `workspaceRoot` | `string` |

View File

@ -15,5 +15,6 @@ A plugin for Nx which creates nodes and dependencies for the [ProjectGraph](../.
| Name | Type | Description |
| :-------------------- | :------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------- |
| `createDependencies?` | [`CreateDependencies`](../../devkit/documents/CreateDependencies)\<`TOptions`\> | Provides a function to analyze files to create dependencies for the [ProjectGraph](../../devkit/documents/ProjectGraph) |
| `createMetadata?` | [`CreateMetadata`](../../devkit/documents/CreateMetadata)\<`TOptions`\> | Provides a function to create metadata for the [ProjectGraph](../../devkit/documents/ProjectGraph) |
| `createNodes?` | [`CreateNodes`](../../devkit/documents/CreateNodes)\<`TOptions`\> | Provides a file pattern and function that retrieves configuration info from those files. e.g. { '\*_/_.csproj': buildProjectsFromCsProjFile } |
| `name` | `string` | - |

View File

@ -0,0 +1,3 @@
# Type alias: ProjectsMetadata
Ƭ **ProjectsMetadata**: `Record`\<`string`, `Pick`\<[`ProjectConfiguration`](../../devkit/documents/ProjectConfiguration), `"metadata"`\>\>

View File

@ -64,6 +64,8 @@ It only uses language primitives and immutable objects
### Type Aliases
- [CreateDependencies](../../devkit/documents/CreateDependencies)
- [CreateMetadata](../../devkit/documents/CreateMetadata)
- [CreateMetadataContext](../../devkit/documents/CreateMetadataContext)
- [CreateNodes](../../devkit/documents/CreateNodes)
- [CreateNodesFunction](../../devkit/documents/CreateNodesFunction)
- [CustomHasher](../../devkit/documents/CustomHasher)
@ -83,6 +85,7 @@ It only uses language primitives and immutable objects
- [ProjectGraphNode](../../devkit/documents/ProjectGraphNode)
- [ProjectTargetConfigurator](../../devkit/documents/ProjectTargetConfigurator)
- [ProjectType](../../devkit/documents/ProjectType)
- [ProjectsMetadata](../../devkit/documents/ProjectsMetadata)
- [RawProjectGraphDependency](../../devkit/documents/RawProjectGraphDependency)
- [StaticDependency](../../devkit/documents/StaticDependency)
- [StringChange](../../devkit/documents/StringChange)

View File

@ -64,6 +64,8 @@ It only uses language primitives and immutable objects
### Type Aliases
- [CreateDependencies](../../devkit/documents/CreateDependencies)
- [CreateMetadata](../../devkit/documents/CreateMetadata)
- [CreateMetadataContext](../../devkit/documents/CreateMetadataContext)
- [CreateNodes](../../devkit/documents/CreateNodes)
- [CreateNodesFunction](../../devkit/documents/CreateNodesFunction)
- [CustomHasher](../../devkit/documents/CustomHasher)
@ -83,6 +85,7 @@ It only uses language primitives and immutable objects
- [ProjectGraphNode](../../devkit/documents/ProjectGraphNode)
- [ProjectTargetConfigurator](../../devkit/documents/ProjectTargetConfigurator)
- [ProjectType](../../devkit/documents/ProjectType)
- [ProjectsMetadata](../../devkit/documents/ProjectsMetadata)
- [RawProjectGraphDependency](../../devkit/documents/RawProjectGraphDependency)
- [StaticDependency](../../devkit/documents/StaticDependency)
- [StringChange](../../devkit/documents/StringChange)

View File

@ -20,12 +20,24 @@ export default async function* execute(
`;
export const NX_PLUGIN_V2_CONTENTS = `import { basename, dirname } from "path";
import { CreateNodes } from "@nx/devkit";
import { CreateNodes, CreateMetadata, ProjectsMetadata } from "@nx/devkit";
type PluginOptions = {
inferredTags: string[]
}
export const createMetadata: CreateMetadata = (graph) => {
const metadata: ProjectsMetadata = {};
for (const projectNode of Object.values(graph.nodes)) {
metadata[projectNode.name] = {
metadata: {
technologies: ["my-plugin"]
}
}
}
return metadata;
}
export const createNodes: CreateNodes<PluginOptions> = [
"**/my-project-file",
(f, options, ctx) => {

View File

@ -335,6 +335,7 @@ describe('Nx Plugin', () => {
runCLI(`show project ${inferredProject} --json`)
);
expect(configuration.tags).toEqual(['my-tag']);
expect(configuration.metadata.technologies).toEqual(['my-plugin']);
});
it('should be able to use local generators and executors', async () => {

View File

@ -8,10 +8,7 @@ import {
} from '../../config/project-graph';
import { ProjectConfiguration } from '../../config/workspace-json-project-json';
import { hashArray } from '../../hasher/file-hasher';
import {
buildProjectGraphUsingProjectFileMap as buildProjectGraphUsingFileMap,
CreateDependenciesError,
} from '../../project-graph/build-project-graph';
import { buildProjectGraphUsingProjectFileMap as buildProjectGraphUsingFileMap } from '../../project-graph/build-project-graph';
import { updateFileMap } from '../../project-graph/file-map-utils';
import {
FileMapCache,
@ -38,6 +35,7 @@ import { getPlugins } from './plugins';
import {
DaemonProjectGraphError,
ProjectConfigurationsError,
isAggregateProjectGraphError,
} from '../../project-graph/error-types';
interface SerializedProjectGraph {
@ -263,7 +261,7 @@ async function processFilesAndCreateAndSerializeProjectGraph(
const errors = [...(projectConfigurationsError?.errors ?? [])];
if (g.error) {
if (g.error instanceof CreateDependenciesError) {
if (isAggregateProjectGraphError(g.error)) {
errors.push(...g.error.errors);
} else {
return {
@ -344,7 +342,8 @@ async function createAndSerializeProjectGraph({
allWorkspaceFiles,
rustReferences,
currentProjectFileMapCache || readFileMapCache(),
await getPlugins()
await getPlugins(),
sourceMaps
);
currentProjectFileMapCache = projectFileMapCache;

View File

@ -54,6 +54,9 @@ export type {
CreateNodesContext,
CreateDependencies,
CreateDependenciesContext,
CreateMetadata,
CreateMetadataContext,
ProjectsMetadata,
} from './project-graph/plugins';
export type {

View File

@ -9,13 +9,16 @@ import {
extractCachedFileData,
FileMapCache,
shouldRecomputeWholeGraph,
writeCache,
} from './nx-deps-cache';
import { applyImplicitDependencies } from './utils/implicit-project-dependencies';
import { normalizeProjectNodes } from './utils/normalize-project-nodes';
import { LoadedNxPlugin } from './plugins/internal-api';
import { isNxPluginV1, isNxPluginV2 } from './plugins/utils';
import { CreateDependenciesContext } from './plugins';
import {
CreateDependenciesContext,
CreateMetadataContext,
ProjectsMetadata,
} from './plugins';
import { getRootTsConfigPath } from '../plugins/js/utils/typescript';
import {
FileMap,
@ -31,6 +34,17 @@ import { existsSync } from 'fs';
import { PackageJson } from '../utils/package-json';
import { output } from '../utils/output';
import { NxWorkspaceFilesExternals } from '../native';
import {
AggregateProjectGraphError,
CreateMetadataError,
isAggregateProjectGraphError,
ProcessDependenciesError,
ProcessProjectGraphError,
} from './error-types';
import {
ConfigurationSourceMaps,
mergeMetadata,
} from './utils/project-configuration-utils';
let storedFileMap: FileMap | null = null;
let storedAllWorkspaceFiles: FileData[] | null = null;
@ -66,7 +80,8 @@ export async function buildProjectGraphUsingProjectFileMap(
allWorkspaceFiles: FileData[],
rustReferences: NxWorkspaceFilesExternals,
fileMapCache: FileMapCache | null,
plugins: LoadedNxPlugin[]
plugins: LoadedNxPlugin[],
sourceMap: ConfigurationSourceMaps
): Promise<{
projectGraph: ProjectGraph;
projectFileMapCache: FileMapCache;
@ -122,7 +137,8 @@ export async function buildProjectGraphUsingProjectFileMap(
context,
cachedFileData,
projectGraphVersion,
plugins
plugins,
sourceMap
);
const projectFileMapCache = createProjectFileMapCache(
nxJson,
@ -165,7 +181,8 @@ async function buildProjectGraphUsingContext(
ctx: CreateDependenciesContext,
cachedFileData: CachedFileData,
projectGraphVersion: string,
plugins: LoadedNxPlugin[]
plugins: LoadedNxPlugin[],
sourceMap: ConfigurationSourceMaps
) {
performance.mark('build project graph:start');
@ -179,15 +196,16 @@ async function buildProjectGraphUsingContext(
const initProjectGraph = builder.getUpdatedProjectGraph();
let updatedGraph;
let error;
let error: AggregateProjectGraphError;
try {
updatedGraph = await updateProjectGraphWithPlugins(
ctx,
initProjectGraph,
plugins
plugins,
sourceMap
);
} catch (e) {
if (e instanceof CreateDependenciesError) {
if (isAggregateProjectGraphError(e)) {
updatedGraph = e.partialProjectGraph;
error = e;
} else {
@ -228,7 +246,7 @@ async function buildProjectGraphUsingContext(
if (!error) {
return finalGraph;
} else {
throw new CreateDependenciesError(error.errors, finalGraph);
throw new AggregateProjectGraphError(error.errors, finalGraph);
}
}
@ -252,10 +270,13 @@ function createContext(
async function updateProjectGraphWithPlugins(
context: CreateDependenciesContext,
initProjectGraph: ProjectGraph,
plugins: LoadedNxPlugin[]
plugins: LoadedNxPlugin[],
sourceMap: ConfigurationSourceMaps
) {
let graph = initProjectGraph;
const errors: Array<ProcessDependenciesError | ProcessProjectGraphError> = [];
const errors: Array<
ProcessDependenciesError | ProcessProjectGraphError | CreateMetadataError
> = [];
for (const plugin of plugins) {
try {
if (
@ -343,51 +364,26 @@ async function updateProjectGraphWithPlugins(
})
);
const result = builder.getUpdatedProjectGraph();
const graphWithDeps = builder.getUpdatedProjectGraph();
if (errors.length === 0) {
return result;
} else {
throw new CreateDependenciesError(errors, result);
}
}
export class ProcessDependenciesError extends Error {
constructor(public readonly pluginName: string, { cause }) {
super(
`The "${pluginName}" plugin threw an error while creating dependencies:`,
const { errors: metadataErrors, graph: updatedGraph } =
await applyProjectMetadata(
graphWithDeps,
plugins,
{
cause,
}
nxJsonConfiguration: context.nxJsonConfiguration,
workspaceRoot,
},
sourceMap
);
this.name = this.constructor.name;
this.stack = `${this.message}\n ${cause.stack.split('\n').join('\n ')}`;
}
}
export class ProcessProjectGraphError extends Error {
constructor(public readonly pluginName: string, { cause }) {
super(
`The "${pluginName}" plugin threw an error while processing the project graph:`,
{
cause,
}
);
this.name = this.constructor.name;
this.stack = `${this.message}\n ${cause.stack.split('\n').join('\n ')}`;
}
}
errors.push(...metadataErrors);
export class CreateDependenciesError extends Error {
constructor(
public readonly errors: Array<
ProcessDependenciesError | ProcessProjectGraphError
>,
public readonly partialProjectGraph: ProjectGraph
) {
super('Failed to create dependencies. See above for errors');
this.name = this.constructor.name;
if (errors.length > 0) {
throw new AggregateProjectGraphError(errors, updatedGraph);
}
return updatedGraph;
}
function readRootTsConfig() {
@ -400,3 +396,52 @@ function readRootTsConfig() {
return {};
}
}
export async function applyProjectMetadata(
graph: ProjectGraph,
plugins: LoadedNxPlugin[],
context: CreateMetadataContext,
sourceMap: ConfigurationSourceMaps
): Promise<{ graph: ProjectGraph; errors?: CreateMetadataError[] }> {
const results: { metadata: ProjectsMetadata; pluginName: string }[] = [];
const errors: CreateMetadataError[] = [];
const promises = plugins.map(async (plugin) => {
if (isNxPluginV2(plugin) && plugin.createMetadata) {
performance.mark(`${plugin.name}:createMetadata - start`);
try {
const metadata = await plugin.createMetadata(graph, undefined, context);
results.push({ metadata, pluginName: plugin.name });
} catch (e) {
errors.push(new CreateMetadataError(e, plugin.name));
} finally {
performance.mark(`${plugin.name}:createMetadata - end`);
performance.measure(
`${plugin.name}:createMetadata`,
`${plugin.name}:createMetadata - start`,
`${plugin.name}:createMetadata - end`
);
}
}
});
await Promise.all(promises);
for (const { metadata: projectsMetadata, pluginName } of results) {
for (const project in projectsMetadata) {
const projectConfiguration: ProjectConfiguration =
graph.nodes[project]?.data;
if (projectConfiguration) {
projectConfiguration.metadata = mergeMetadata(
sourceMap[project],
[null, pluginName],
'metadata',
projectsMetadata[project].metadata,
projectConfiguration.metadata
);
}
}
}
return { errors, graph };
}

View File

@ -4,16 +4,13 @@ import {
ConfigurationSourceMaps,
} from './utils/project-configuration-utils';
import { ProjectConfiguration } from '../config/workspace-json-project-json';
import {
ProcessDependenciesError,
ProcessProjectGraphError,
} from './build-project-graph';
import { ProjectGraph } from '../config/project-graph';
export class ProjectGraphError extends Error {
readonly #errors: Array<
| CreateNodesError
| MergeNodesError
| CreateMetadataError
| ProjectsWithNoNameError
| ProjectsWithConflictingNamesError
| ProcessDependenciesError
@ -30,6 +27,7 @@ export class ProjectGraphError extends Error {
| ProjectsWithConflictingNamesError
| ProcessDependenciesError
| ProcessProjectGraphError
| CreateMetadataError
>,
partialProjectGraph: ProjectGraph,
partialSourceMaps: ConfigurationSourceMaps
@ -198,6 +196,73 @@ export class MergeNodesError extends Error {
}
}
export class CreateMetadataError extends Error {
constructor(public readonly error: Error, public readonly plugin: string) {
super(`The "${plugin}" plugin threw an error while creating metadata:`, {
cause: error,
});
this.name = this.constructor.name;
}
}
export class ProcessDependenciesError extends Error {
constructor(public readonly pluginName: string, { cause }) {
super(
`The "${pluginName}" plugin threw an error while creating dependencies:`,
{
cause,
}
);
this.name = this.constructor.name;
this.stack = `${this.message}\n ${cause.stack.split('\n').join('\n ')}`;
}
}
export class ProcessProjectGraphError extends Error {
constructor(public readonly pluginName: string, { cause }) {
super(
`The "${pluginName}" plugin threw an error while processing the project graph:`,
{
cause,
}
);
this.name = this.constructor.name;
this.stack = `${this.message}\n ${cause.stack.split('\n').join('\n ')}`;
}
}
export class AggregateProjectGraphError extends Error {
constructor(
public readonly errors: Array<
CreateMetadataError | ProcessDependenciesError | ProcessProjectGraphError
>,
public readonly partialProjectGraph: ProjectGraph
) {
super('Failed to create project graph. See above for errors');
this.name = this.constructor.name;
}
}
export function isAggregateProjectGraphError(
e: unknown
): e is AggregateProjectGraphError {
return (
e instanceof AggregateProjectGraphError ||
(typeof e === 'object' &&
'name' in e &&
e?.name === AggregateProjectGraphError.prototype.name)
);
}
export function isCreateMetadataError(e: unknown): e is CreateMetadataError {
return (
e instanceof CreateMetadataError ||
(typeof e === 'object' &&
'name' in e &&
e?.name === CreateMetadataError.prototype.name)
);
}
export function isCreateNodesError(e: unknown): e is CreateNodesError {
return (
e instanceof CreateNodesError ||

View File

@ -11,11 +11,16 @@ import { shouldMergeAngularProjects } from '../../adapter/angular-json';
import {
CreateDependencies,
CreateDependenciesContext,
CreateMetadata,
CreateMetadataContext,
CreateNodesContext,
CreateNodesResult,
NxPluginV2,
} from './public-api';
import { ProjectGraphProcessor } from '../../config/project-graph';
import {
ProjectGraph,
ProjectGraphProcessor,
} from '../../config/project-graph';
import { runCreateNodesInParallel } from './utils';
import { loadNxPluginInIsolation } from './isolation';
import { loadNxPlugin, unregisterPluginTSTranspiler } from './loader';
@ -34,6 +39,10 @@ export class LoadedNxPlugin {
readonly createDependencies?: (
context: CreateDependenciesContext
) => ReturnType<CreateDependencies>;
readonly createMetadata?: (
graph: ProjectGraph,
context: CreateMetadataContext
) => ReturnType<CreateMetadata>;
readonly processProjectGraph?: ProjectGraphProcessor;
readonly options?: unknown;
@ -61,6 +70,11 @@ export class LoadedNxPlugin {
plugin.createDependencies(this.options, context);
}
if (plugin.createMetadata) {
this.createMetadata = (graph, context) =>
plugin.createMetadata(graph, this.options, context);
}
this.processProjectGraph = plugin.processProjectGraph;
}
}

View File

@ -3,7 +3,11 @@ import {
ProjectGraphProcessorContext,
} from '../../../config/project-graph';
import { PluginConfiguration } from '../../../config/nx-json';
import { CreateDependenciesContext, CreateNodesContext } from '../public-api';
import {
CreateDependenciesContext,
CreateMetadataContext,
CreateNodesContext,
} from '../public-api';
import { LoadedNxPlugin } from '../internal-api';
import { Serializable } from 'child_process';
@ -23,6 +27,7 @@ export interface PluginWorkerLoadResult {
createNodesPattern: string;
hasCreateDependencies: boolean;
hasProcessProjectGraph: boolean;
hasCreateMetadata: boolean;
success: true;
}
| {
@ -63,6 +68,15 @@ export interface PluginCreateDependenciesMessage {
};
}
export interface PluginCreateMetadataMessage {
type: 'createMetadata';
payload: {
graph: ProjectGraph;
context: CreateMetadataContext;
tx: string;
};
}
export interface PluginCreateDependenciesResult {
type: 'createDependenciesResult';
payload:
@ -78,6 +92,21 @@ export interface PluginCreateDependenciesResult {
};
}
export interface PluginCreateMetadataResult {
type: 'createMetadataResult';
payload:
| {
metadata: ReturnType<LoadedNxPlugin['createMetadata']>;
success: true;
tx: string;
}
| {
success: false;
error: string;
tx: string;
};
}
export interface PluginWorkerProcessProjectGraphMessage {
type: 'processProjectGraph';
payload: {
@ -106,13 +135,15 @@ export type PluginWorkerMessage =
| PluginWorkerLoadMessage
| PluginWorkerCreateNodesMessage
| PluginCreateDependenciesMessage
| PluginWorkerProcessProjectGraphMessage;
| PluginWorkerProcessProjectGraphMessage
| PluginCreateMetadataMessage;
export type PluginWorkerResult =
| PluginWorkerLoadResult
| PluginWorkerCreateNodesResult
| PluginCreateDependenciesResult
| PluginWorkerProcessProjectGraphResult;
| PluginWorkerProcessProjectGraphResult
| PluginCreateMetadataResult;
export function isPluginWorkerMessage(
message: Serializable

View File

@ -153,6 +153,18 @@ function createWorkerHandler(
});
}
: undefined,
createMetadata: result.hasCreateMetadata
? (graph, ctx) => {
const tx =
pluginName + ':createMetadata:' + performance.now();
return registerPendingPromise(tx, pending, () => {
worker.send({
type: 'createMetadata',
payload: { graph, context: ctx, tx },
});
});
}
: undefined,
});
} else if (result.success === false) {
onloadError(result.error);
@ -182,6 +194,14 @@ function createWorkerHandler(
rejector(result.error);
}
},
createMetadataResult: ({ tx, ...result }) => {
const { resolver, rejector } = pending.get(tx);
if (result.success) {
resolver(result.metadata);
} else if (result.success === false) {
rejector(result.error);
}
},
});
};
}

View File

@ -27,6 +27,8 @@ process.on('message', async (message: Serializable) => {
'createDependencies' in plugin && !!plugin.createDependencies,
hasProcessProjectGraph:
'processProjectGraph' in plugin && !!plugin.processProjectGraph,
hasCreateMetadata:
'createMetadata' in plugin && !!plugin.createMetadata,
success: true,
},
};
@ -94,5 +96,19 @@ process.on('message', async (message: Serializable) => {
};
}
},
createMetadata: async ({ graph, context, tx }) => {
try {
const result = await plugin.createMetadata(graph, context);
return {
type: 'createMetadataResult',
payload: { metadata: result, success: true, tx },
};
} catch (e) {
return {
type: 'createMetadataResult',
payload: { success: false, error: e.stack, tx },
};
}
},
});
});

View File

@ -98,6 +98,22 @@ export type CreateDependencies<T = unknown> = (
context: CreateDependenciesContext
) => RawProjectGraphDependency[] | Promise<RawProjectGraphDependency[]>;
export type CreateMetadataContext = {
readonly nxJsonConfiguration: NxJsonConfiguration;
readonly workspaceRoot: string;
};
export type ProjectsMetadata = Record<
string,
Pick<ProjectConfiguration, 'metadata'>
>;
export type CreateMetadata<T = unknown> = (
graph: ProjectGraph,
options: T | undefined,
context: CreateMetadataContext
) => ProjectsMetadata | Promise<ProjectsMetadata>;
/**
* A plugin for Nx which creates nodes and dependencies for the {@link ProjectGraph}
*/
@ -110,11 +126,15 @@ export type NxPluginV2<TOptions = unknown> = {
*/
createNodes?: CreateNodes<TOptions>;
// Todo(@AgentEnder): This shouldn't be a full processor, since its only responsible for defining edges between projects. What do we want the API to be?
/**
* Provides a function to analyze files to create dependencies for the {@link ProjectGraph}
*/
createDependencies?: CreateDependencies<TOptions>;
/**
* Provides a function to create metadata for the {@link ProjectGraph}
*/
createMetadata?: CreateMetadata<TOptions>;
};
/**

View File

@ -1,4 +1,5 @@
import { performance } from 'perf_hooks';
import { readNxJson } from '../config/nx-json';
import { ProjectGraph } from '../config/project-graph';
import {
@ -11,17 +12,18 @@ import { fileExists } from '../utils/fileutils';
import { output } from '../utils/output';
import { stripIndents } from '../utils/strip-indents';
import { workspaceRoot } from '../utils/workspace-root';
import { buildProjectGraphUsingProjectFileMap } from './build-project-graph';
import {
CreateDependenciesError,
buildProjectGraphUsingProjectFileMap,
} from './build-project-graph';
AggregateProjectGraphError,
isAggregateProjectGraphError,
ProjectConfigurationsError,
ProjectGraphError,
} from './error-types';
import {
readFileMapCache,
readProjectGraphCache,
writeCache,
} from './nx-deps-cache';
import { ProjectConfigurationsError, ProjectGraphError } from './error-types';
import { loadNxPlugins } from './plugins/internal-api';
import { ConfigurationResult } from './utils/project-configuration-utils';
import {
@ -120,7 +122,7 @@ export async function buildProjectGraphAndSourceMapsWithoutDaemon() {
const cacheEnabled = process.env.NX_CACHE_PROJECT_GRAPH !== 'false';
performance.mark('build-project-graph-using-project-file-map:start');
let createDependenciesError: CreateDependenciesError;
let projectGraphError: AggregateProjectGraphError;
let projectGraphResult: Awaited<
ReturnType<typeof buildProjectGraphUsingProjectFileMap>
>;
@ -132,15 +134,16 @@ export async function buildProjectGraphAndSourceMapsWithoutDaemon() {
allWorkspaceFiles,
rustReferences,
cacheEnabled ? readFileMapCache() : null,
plugins
plugins,
sourceMaps
);
} catch (e) {
if (e instanceof CreateDependenciesError) {
if (isAggregateProjectGraphError(e)) {
projectGraphResult = {
projectGraph: e.partialProjectGraph,
projectFileMapCache: null,
};
createDependenciesError = e;
projectGraphError = e;
} else {
throw e;
}
@ -155,7 +158,7 @@ export async function buildProjectGraphAndSourceMapsWithoutDaemon() {
const errors = [
...(projectConfigurationsError?.errors ?? []),
...(createDependenciesError?.errors ?? []),
...(projectGraphError?.errors ?? []),
];
if (errors.length > 0) {

View File

@ -32,7 +32,7 @@ import {
isProjectsWithNoNameError,
} from '../error-types';
export type SourceInformation = [file: string, plugin: string];
export type SourceInformation = [file: string | null, plugin: string];
export type ConfigurationSourceMaps = Record<
string,
Record<string, SourceInformation>
@ -224,7 +224,7 @@ export function mergeProjectConfigurationIntoRootMap(
updatedProjectConfiguration;
}
function mergeMetadata<T = ProjectMetadata | TargetMetadata>(
export function mergeMetadata<T = ProjectMetadata | TargetMetadata>(
sourceMap: Record<string, [file: string, plugin: string]>,
sourceInformation: [file: string, plugin: string],
baseSourceMapPath: string,