diff --git a/docs/generated/devkit/BaseFileData.md b/docs/generated/devkit/BaseFileData.md new file mode 100644 index 00000000000000..dfd77d2c21efb1 --- /dev/null +++ b/docs/generated/devkit/BaseFileData.md @@ -0,0 +1,30 @@ +# Interface: BaseFileData + +Some metadata about a file + +## Hierarchy + +- **`BaseFileData`** + + ↳ [`ProjectFileData`](../../devkit/documents/ProjectFileData) + + ↳ [`NonProjectFileData`](../../devkit/documents/NonProjectFileData) + +## Table of contents + +### Properties + +- [file](../../devkit/documents/BaseFileData#file): string +- [hash](../../devkit/documents/BaseFileData#hash): string + +## Properties + +### file + +• **file**: `string` + +--- + +### hash + +• **hash**: `string` diff --git a/docs/generated/devkit/FileData.md b/docs/generated/devkit/FileData.md index d56c3ebad6cf22..efb4f4e4f76e5c 100644 --- a/docs/generated/devkit/FileData.md +++ b/docs/generated/devkit/FileData.md @@ -1,29 +1,3 @@ -# Interface: FileData +# Type alias: FileData -Some metadata about a file - -## Table of contents - -### Properties - -- [deps](../../devkit/documents/FileData#deps): (string | [string, string])[] -- [file](../../devkit/documents/FileData#file): string -- [hash](../../devkit/documents/FileData#hash): string - -## Properties - -### deps - -• `Optional` **deps**: (`string` \| [`string`, `string`])[] - ---- - -### file - -• **file**: `string` - ---- - -### hash - -• **hash**: `string` +Ƭ **FileData**: [`ProjectFileData`](../../devkit/documents/ProjectFileData) \| [`NonProjectFileData`](../../devkit/documents/NonProjectFileData) diff --git a/docs/generated/devkit/NonProjectFileData.md b/docs/generated/devkit/NonProjectFileData.md new file mode 100644 index 00000000000000..511f65654b835b --- /dev/null +++ b/docs/generated/devkit/NonProjectFileData.md @@ -0,0 +1,45 @@ +# Interface: NonProjectFileData + +Represents metadata about a file that **does not** belong to a project. + +## Hierarchy + +- [`BaseFileData`](../../devkit/documents/BaseFileData) + + ↳ **`NonProjectFileData`** + +## Table of contents + +### Properties + +- [deps](../../devkit/documents/NonProjectFileData#deps): ProjectGraphDependency[] +- [file](../../devkit/documents/NonProjectFileData#file): string +- [hash](../../devkit/documents/NonProjectFileData#hash): string + +## Properties + +### deps + +• `Optional` **deps**: [`ProjectGraphDependency`](../../devkit/documents/ProjectGraphDependency)[] + +Dependencies which were created with this file as the source file. + +--- + +### file + +• **file**: `string` + +#### Inherited from + +[BaseFileData](../../devkit/documents/BaseFileData).[file](../../devkit/documents/BaseFileData#file) + +--- + +### hash + +• **hash**: `string` + +#### Inherited from + +[BaseFileData](../../devkit/documents/BaseFileData).[hash](../../devkit/documents/BaseFileData#hash) diff --git a/docs/generated/devkit/ProjectFileData.md b/docs/generated/devkit/ProjectFileData.md new file mode 100644 index 00000000000000..acbef02f5877f3 --- /dev/null +++ b/docs/generated/devkit/ProjectFileData.md @@ -0,0 +1,48 @@ +# Interface: ProjectFileData + +Represents metadata about a file that belongs to a project. + +## Hierarchy + +- [`BaseFileData`](../../devkit/documents/BaseFileData) + + ↳ **`ProjectFileData`** + +## Table of contents + +### Properties + +- [deps](../../devkit/documents/ProjectFileData#deps): (string | [target: string, type: string])[] +- [file](../../devkit/documents/ProjectFileData#file): string +- [hash](../../devkit/documents/ProjectFileData#hash): string + +## Properties + +### deps + +• `Optional` **deps**: (`string` \| [target: string, type: string])[] + +An array of dependencies. If an element is just a string, +the dependency is assumed to be a static dependency targetting +that string. If the element is a tuple, the first element inside of it +is the target project, with the second element being the type of dependency. + +--- + +### file + +• **file**: `string` + +#### Inherited from + +[BaseFileData](../../devkit/documents/BaseFileData).[file](../../devkit/documents/BaseFileData#file) + +--- + +### hash + +• **hash**: `string` + +#### Inherited from + +[BaseFileData](../../devkit/documents/BaseFileData).[hash](../../devkit/documents/BaseFileData#hash) diff --git a/docs/generated/devkit/ProjectFileMap.md b/docs/generated/devkit/ProjectFileMap.md index 86efa81a5fdb33..936e0acb351a1a 100644 --- a/docs/generated/devkit/ProjectFileMap.md +++ b/docs/generated/devkit/ProjectFileMap.md @@ -4,4 +4,4 @@ A list of files separated by the project they belong to ## Indexable -▪ [projectName: `string`]: [`FileData`](../../devkit/documents/FileData)[] +▪ [projectName: `string`]: [`ProjectFileData`](../../devkit/documents/ProjectFileData)[] diff --git a/docs/generated/devkit/ProjectGraphBuilder.md b/docs/generated/devkit/ProjectGraphBuilder.md index 7e0669d961a8fe..3d42a4072eaa75 100644 --- a/docs/generated/devkit/ProjectGraphBuilder.md +++ b/docs/generated/devkit/ProjectGraphBuilder.md @@ -14,7 +14,9 @@ The ProjectGraphProcessor has been deprecated. Use a [CreateNodes](../../devkit/ ### Properties +- [allWorkspaceFiles](../../devkit/documents/ProjectGraphBuilder#allworkspacefiles): FileData[] - [graph](../../devkit/documents/ProjectGraphBuilder#graph): ProjectGraph +- [nonProjectFiles](../../devkit/documents/ProjectGraphBuilder#nonprojectfiles): NonProjectFileData[] - [projectFileMap](../../devkit/documents/ProjectGraphBuilder#projectfilemap): ProjectFileMap - [removedEdges](../../devkit/documents/ProjectGraphBuilder#removededges): Object @@ -40,23 +42,36 @@ The ProjectGraphProcessor has been deprecated. Use a [CreateNodes](../../devkit/ ### constructor -• **new ProjectGraphBuilder**(`graph?`, `fileMap?`) +• **new ProjectGraphBuilder**(`graph?`, `projectFileMap?`, `nonProjectFiles?`) #### Parameters -| Name | Type | -| :--------- | :-------------------------------------------------------- | -| `graph?` | [`ProjectGraph`](../../devkit/documents/ProjectGraph) | -| `fileMap?` | [`ProjectFileMap`](../../devkit/documents/ProjectFileMap) | +| Name | Type | +| :----------------- | :------------------------------------------------------------------ | +| `graph?` | [`ProjectGraph`](../../devkit/documents/ProjectGraph) | +| `projectFileMap?` | [`ProjectFileMap`](../../devkit/documents/ProjectFileMap) | +| `nonProjectFiles?` | [`NonProjectFileData`](../../devkit/documents/NonProjectFileData)[] | ## Properties +### allWorkspaceFiles + +• `Private` `Readonly` **allWorkspaceFiles**: [`FileData`](../../devkit/documents/FileData)[] + +--- + ### graph • `Readonly` **graph**: [`ProjectGraph`](../../devkit/documents/ProjectGraph) --- +### nonProjectFiles + +• `Private` `Readonly` **nonProjectFiles**: [`NonProjectFileData`](../../devkit/documents/NonProjectFileData)[] + +--- + ### projectFileMap • `Private` `Readonly` **projectFileMap**: [`ProjectFileMap`](../../devkit/documents/ProjectFileMap) diff --git a/docs/generated/devkit/README.md b/docs/generated/devkit/README.md index 0bea288f58861d..e7c6dbcbad607b 100644 --- a/docs/generated/devkit/README.md +++ b/docs/generated/devkit/README.md @@ -23,13 +23,13 @@ It only uses language primitives and immutable objects ### Interfaces +- [BaseFileData](../../devkit/documents/BaseFileData) - [CreateDependenciesContext](../../devkit/documents/CreateDependenciesContext) - [CreateNodesContext](../../devkit/documents/CreateNodesContext) - [DefaultTasksRunnerOptions](../../devkit/documents/DefaultTasksRunnerOptions) - [ExecutorContext](../../devkit/documents/ExecutorContext) - [ExecutorsJson](../../devkit/documents/ExecutorsJson) - [FileChange](../../devkit/documents/FileChange) -- [FileData](../../devkit/documents/FileData) - [GeneratorsJson](../../devkit/documents/GeneratorsJson) - [Hash](../../devkit/documents/Hash) - [HasherContext](../../devkit/documents/HasherContext) @@ -37,9 +37,11 @@ It only uses language primitives and immutable objects - [JsonParseOptions](../../devkit/documents/JsonParseOptions) - [JsonSerializeOptions](../../devkit/documents/JsonSerializeOptions) - [MigrationsJson](../../devkit/documents/MigrationsJson) +- [NonProjectFileData](../../devkit/documents/NonProjectFileData) - [NxAffectedConfig](../../devkit/documents/NxAffectedConfig) - [NxJsonConfiguration](../../devkit/documents/NxJsonConfiguration) - [ProjectConfiguration](../../devkit/documents/ProjectConfiguration) +- [ProjectFileData](../../devkit/documents/ProjectFileData) - [ProjectFileMap](../../devkit/documents/ProjectFileMap) - [ProjectGraph](../../devkit/documents/ProjectGraph) - [ProjectGraphDependency](../../devkit/documents/ProjectGraphDependency) @@ -67,6 +69,7 @@ It only uses language primitives and immutable objects - [CustomHasher](../../devkit/documents/CustomHasher) - [DynamicDependency](../../devkit/documents/DynamicDependency) - [Executor](../../devkit/documents/Executor) +- [FileData](../../devkit/documents/FileData) - [Generator](../../devkit/documents/Generator) - [GeneratorCallback](../../devkit/documents/GeneratorCallback) - [Hasher](../../devkit/documents/Hasher) diff --git a/docs/generated/packages/devkit/documents/nx_devkit.md b/docs/generated/packages/devkit/documents/nx_devkit.md index 0bea288f58861d..e7c6dbcbad607b 100644 --- a/docs/generated/packages/devkit/documents/nx_devkit.md +++ b/docs/generated/packages/devkit/documents/nx_devkit.md @@ -23,13 +23,13 @@ It only uses language primitives and immutable objects ### Interfaces +- [BaseFileData](../../devkit/documents/BaseFileData) - [CreateDependenciesContext](../../devkit/documents/CreateDependenciesContext) - [CreateNodesContext](../../devkit/documents/CreateNodesContext) - [DefaultTasksRunnerOptions](../../devkit/documents/DefaultTasksRunnerOptions) - [ExecutorContext](../../devkit/documents/ExecutorContext) - [ExecutorsJson](../../devkit/documents/ExecutorsJson) - [FileChange](../../devkit/documents/FileChange) -- [FileData](../../devkit/documents/FileData) - [GeneratorsJson](../../devkit/documents/GeneratorsJson) - [Hash](../../devkit/documents/Hash) - [HasherContext](../../devkit/documents/HasherContext) @@ -37,9 +37,11 @@ It only uses language primitives and immutable objects - [JsonParseOptions](../../devkit/documents/JsonParseOptions) - [JsonSerializeOptions](../../devkit/documents/JsonSerializeOptions) - [MigrationsJson](../../devkit/documents/MigrationsJson) +- [NonProjectFileData](../../devkit/documents/NonProjectFileData) - [NxAffectedConfig](../../devkit/documents/NxAffectedConfig) - [NxJsonConfiguration](../../devkit/documents/NxJsonConfiguration) - [ProjectConfiguration](../../devkit/documents/ProjectConfiguration) +- [ProjectFileData](../../devkit/documents/ProjectFileData) - [ProjectFileMap](../../devkit/documents/ProjectFileMap) - [ProjectGraph](../../devkit/documents/ProjectGraph) - [ProjectGraphDependency](../../devkit/documents/ProjectGraphDependency) @@ -67,6 +69,7 @@ It only uses language primitives and immutable objects - [CustomHasher](../../devkit/documents/CustomHasher) - [DynamicDependency](../../devkit/documents/DynamicDependency) - [Executor](../../devkit/documents/Executor) +- [FileData](../../devkit/documents/FileData) - [Generator](../../devkit/documents/Generator) - [GeneratorCallback](../../devkit/documents/GeneratorCallback) - [Hasher](../../devkit/documents/Hasher) diff --git a/packages/angular/src/migrations/update-16-2-0/switch-data-persistence-operators-imports-to-ngrx-router-store.ts b/packages/angular/src/migrations/update-16-2-0/switch-data-persistence-operators-imports-to-ngrx-router-store.ts index e9b138255245c3..0697b000b59ef4 100644 --- a/packages/angular/src/migrations/update-16-2-0/switch-data-persistence-operators-imports-to-ngrx-router-store.ts +++ b/packages/angular/src/migrations/update-16-2-0/switch-data-persistence-operators-imports-to-ngrx-router-store.ts @@ -9,7 +9,7 @@ import type { ImportDeclaration, ImportSpecifier, Node } from 'typescript'; import { FileChangeRecorder } from '../../utils/file-change-recorder'; import { ngrxVersion } from '../../utils/versions'; import { getProjectsFilteredByDependencies } from '../utils/projects'; -import { readProjectFileMapCache } from 'nx/src/project-graph/nx-deps-cache'; +import { readFileMapCache } from 'nx/src/project-graph/nx-deps-cache'; import { fileDataDepTarget } from 'nx/src/config/project-graph'; let tsquery: typeof import('@phenomnomnominal/tsquery').tsquery; @@ -35,7 +35,7 @@ export default async function (tree: Tree): Promise { ensureTypescript(); tsquery = require('@phenomnomnominal/tsquery').tsquery; - const cachedFileMap = readProjectFileMapCache().projectFileMap; + const cachedFileMap = readFileMapCache().fileMap.projectFileMap; const filesWithNxAngularImports: FileData[] = []; for (const { graphNode } of projects) { diff --git a/packages/eslint-plugin/src/utils/graph-utils.ts b/packages/eslint-plugin/src/utils/graph-utils.ts index 063bd96e7774a4..bb4ef5107f192d 100644 --- a/packages/eslint-plugin/src/utils/graph-utils.ts +++ b/packages/eslint-plugin/src/utils/graph-utils.ts @@ -149,7 +149,7 @@ export function findFilesInCircularPath( for (let i = 0; i < circularPath.length - 1; i++) { const next = circularPath[i + 1].name; - const files: FileData[] = projectFileMap[circularPath[i].name] || []; + const files = projectFileMap[circularPath[i].name] || []; filePathChain.push( files .filter( diff --git a/packages/eslint-plugin/src/utils/project-graph-utils.ts b/packages/eslint-plugin/src/utils/project-graph-utils.ts index b7ffe82af53291..27afc607e85d1c 100644 --- a/packages/eslint-plugin/src/utils/project-graph-utils.ts +++ b/packages/eslint-plugin/src/utils/project-graph-utils.ts @@ -11,7 +11,7 @@ import { } from 'nx/src/project-graph/utils/find-project-for-path'; import { readNxJson } from 'nx/src/config/configuration'; import { TargetProjectLocator } from '@nx/js/src/internal'; -import { readProjectFileMapCache } from 'nx/src/project-graph/nx-deps-cache'; +import { readFileMapCache } from 'nx/src/project-graph/nx-deps-cache'; export function ensureGlobalProjectGraph(ruleName: string) { /** @@ -37,7 +37,7 @@ export function ensureGlobalProjectGraph(ruleName: string) { globalThis.projectRootMappings = createProjectRootMappings( projectGraph.nodes ); - globalThis.projectFileMap = readProjectFileMapCache().projectFileMap; + globalThis.projectFileMap = readFileMapCache().fileMap.projectFileMap; globalThis.targetProjectLocator = new TargetProjectLocator( projectGraph.nodes, projectGraph.externalNodes diff --git a/packages/js/src/utils/package-json/update-package-json.ts b/packages/js/src/utils/package-json/update-package-json.ts index 74cd9cb0f2fe11..41630fc895be20 100644 --- a/packages/js/src/utils/package-json/update-package-json.ts +++ b/packages/js/src/utils/package-json/update-package-json.ts @@ -25,7 +25,7 @@ import { writeFileSync } from 'fs-extra'; import { fileExists } from 'nx/src/utils/fileutils'; import type { PackageJson } from 'nx/src/utils/package-json'; import { existsSync } from 'fs'; -import { readProjectFileMapCache } from 'nx/src/project-graph/nx-deps-cache'; +import { readFileMapCache } from 'nx/src/project-graph/nx-deps-cache'; import { getRelativeDirectoryToProjectRoot } from '../get-main-file-dir'; @@ -57,7 +57,7 @@ export function updatePackageJson( ): void { let packageJson: PackageJson; if (fileMap == null) { - fileMap = readProjectFileMapCache()?.projectFileMap || {}; + fileMap = readFileMapCache()?.fileMap?.projectFileMap || {}; } if (options.updateBuildableProjectDepsInPackageJson) { diff --git a/packages/nx/src/config/project-graph.ts b/packages/nx/src/config/project-graph.ts index 14b90a7e1f65bc..d445d86ce6fa6c 100644 --- a/packages/nx/src/config/project-graph.ts +++ b/packages/nx/src/config/project-graph.ts @@ -8,14 +8,44 @@ import { NxJsonConfiguration } from './nx-json'; /** * Some metadata about a file */ -export interface FileData { +export interface BaseFileData { file: string; hash: string; - deps?: (string | [string, string])[]; } -export function fileDataDepTarget(dep: string | [string, string]) { - return typeof dep === 'string' ? dep : dep[0]; +/** + * Represents metadata about a file that belongs to a project. + */ +export interface ProjectFileData extends BaseFileData { + /** + * An array of dependencies. If an element is just a string, + * the dependency is assumed to be a static dependency targetting + * that string. If the element is a tuple, the first element inside of it + * is the target project, with the second element being the type of dependency. + */ + deps?: (string | [target: string, type: string])[]; +} + +/** + * Represents metadata about a file that **does not** belong to a project. + */ +export interface NonProjectFileData extends BaseFileData { + /** + * Dependencies which were created with this file as the source file. + */ + deps?: ProjectGraphDependency[]; +} + +export type FileData = ProjectFileData | NonProjectFileData; + +export function fileDataDepTarget( + dep: string | [string, string] | ProjectGraphDependency +) { + return typeof dep === 'string' + ? dep + : Array.isArray(dep) + ? dep[0] + : dep.target; } export function fileDataDepType(dep: string | [string, string]) { @@ -23,7 +53,7 @@ export function fileDataDepType(dep: string | [string, string]) { } export interface FileMap { - nonProjectFiles: FileData[]; + nonProjectFiles: NonProjectFileData[]; projectFileMap: ProjectFileMap; } @@ -31,7 +61,7 @@ export interface FileMap { * A list of files separated by the project they belong to */ export interface ProjectFileMap { - [projectName: string]: FileData[]; + [projectName: string]: ProjectFileData[]; } /** diff --git a/packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts b/packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts index fb6bf04b75a165..57792806bab3c7 100644 --- a/packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts +++ b/packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts @@ -247,7 +247,7 @@ async function processFilesAndCreateAndSerializeProjectGraph() { } } -function copyFileData(d: FileData[]) { +function copyFileData(d: T[]) { return d.map((t) => ({ ...t })); } diff --git a/packages/nx/src/devkit-exports.ts b/packages/nx/src/devkit-exports.ts index 59094ed2d5ba89..add8146eaf1dff 100644 --- a/packages/nx/src/devkit-exports.ts +++ b/packages/nx/src/devkit-exports.ts @@ -146,6 +146,9 @@ export { export type { ProjectFileMap, FileData, + ProjectFileData, + BaseFileData, + NonProjectFileData, ProjectGraph, ProjectGraphDependency, ProjectGraphNode, diff --git a/packages/nx/src/project-graph/build-project-graph.ts b/packages/nx/src/project-graph/build-project-graph.ts index 36fc2a3fb22562..5815a1be361456 100644 --- a/packages/nx/src/project-graph/build-project-graph.ts +++ b/packages/nx/src/project-graph/build-project-graph.ts @@ -4,6 +4,7 @@ import { performance } from 'perf_hooks'; import { assertWorkspaceValidity } from '../utils/assert-workspace-validity'; import { FileData } from './file-utils'; import { + CachedFileData, createProjectFileMapCache, extractCachedFileData, FileMapCache, @@ -155,7 +156,7 @@ async function buildProjectGraphUsingContext( nxJson: NxJsonConfiguration, knownExternalNodes: Record, ctx: CreateDependenciesContext, - cachedFileData: { [project: string]: { [file: string]: FileData } }, + cachedFileData: CachedFileData, projectGraphVersion: string ) { performance.mark('build project graph:start'); diff --git a/packages/nx/src/project-graph/file-map-utils.ts b/packages/nx/src/project-graph/file-map-utils.ts index 5d966eb5d20213..6ef966f336408b 100644 --- a/packages/nx/src/project-graph/file-map-utils.ts +++ b/packages/nx/src/project-graph/file-map-utils.ts @@ -1,6 +1,8 @@ import { FileData, FileMap, + NonProjectFileData, + ProjectFileData, ProjectFileMap, ProjectGraph, } from '../config/project-graph'; @@ -44,7 +46,7 @@ export function createFileMap( createProjectRootMappingsFromProjectConfigurations( projectsConfigurations.projects ); - const nonProjectFiles: FileData[] = []; + const nonProjectFiles: NonProjectFileData[] = []; for (const projectName of Object.keys(projectsConfigurations.projects)) { projectFileMap[projectName] ??= []; @@ -54,10 +56,10 @@ export function createFileMap( if (projectFileMapKey) { const matchingProjectFiles = projectFileMap[projectFileMapKey]; if (matchingProjectFiles) { - matchingProjectFiles.push(f); + matchingProjectFiles.push(f as ProjectFileData); } } else { - nonProjectFiles.push(f); + nonProjectFiles.push(f as NonProjectFileData); } } return { diff --git a/packages/nx/src/project-graph/file-utils.ts b/packages/nx/src/project-graph/file-utils.ts index d95d866fb3d4e5..bc939d08add09d 100644 --- a/packages/nx/src/project-graph/file-utils.ts +++ b/packages/nx/src/project-graph/file-utils.ts @@ -2,7 +2,7 @@ import { execSync } from 'child_process'; import { existsSync, readFileSync } from 'fs'; import { extname, join, relative, sep } from 'path'; import { readNxJson } from '../config/configuration'; -import { FileData } from '../config/project-graph'; +import { BaseFileData, FileData } from '../config/project-graph'; import { ProjectsConfigurations } from '../config/workspace-json-project-json'; import type { NxArgs } from '../utils/command-line-utils'; import { workspaceRoot } from '../utils/workspace-root'; @@ -20,7 +20,7 @@ export interface Change { type: string; } -export interface FileChange extends FileData { +export interface FileChange extends BaseFileData { getChanges: () => T[]; } diff --git a/packages/nx/src/project-graph/nx-deps-cache.ts b/packages/nx/src/project-graph/nx-deps-cache.ts index 2cdc29eb15ebb1..bb01325bedfc6e 100644 --- a/packages/nx/src/project-graph/nx-deps-cache.ts +++ b/packages/nx/src/project-graph/nx-deps-cache.ts @@ -6,6 +6,7 @@ import { NxJsonConfiguration } from '../config/nx-json'; import { FileData, FileMap, + NonProjectFileData, ProjectFileMap, ProjectGraph, } from '../config/project-graph'; @@ -231,8 +232,8 @@ export function shouldRecomputeWholeGraph( return false; } -type CachedFileData = { - nonProjectFiles: Record; +export type CachedFileData = { + nonProjectFiles: Record; projectFileMap: { [project: string]: Record }; }; @@ -284,8 +285,8 @@ export function extractCachedFileData( } function processNonProjectFiles( - cachedFiles: FileData[], - nonProjectFiles: FileData[], + cachedFiles: NonProjectFileData[], + nonProjectFiles: NonProjectFileData[], filesToProcess: FileMap['nonProjectFiles'], cachedFileData: CachedFileData['nonProjectFiles'] ) { diff --git a/packages/nx/src/project-graph/project-graph-builder.ts b/packages/nx/src/project-graph/project-graph-builder.ts index a666a5c9b719df..3febc62b94b485 100644 --- a/packages/nx/src/project-graph/project-graph-builder.ts +++ b/packages/nx/src/project-graph/project-graph-builder.ts @@ -3,8 +3,12 @@ */ import { DependencyType, + FileData, fileDataDepTarget, fileDataDepType, + FileMap, + NonProjectFileData, + ProjectFileData, ProjectFileMap, ProjectGraph, ProjectGraphDependency, @@ -22,19 +26,42 @@ import { getFileMap } from './build-project-graph'; export class ProjectGraphBuilder { // TODO(FrozenPandaz): make this private readonly graph: ProjectGraph; + private readonly projectFileMap: ProjectFileMap; + private readonly nonProjectFiles: NonProjectFileData[]; + private readonly allWorkspaceFiles: FileData[]; + readonly removedEdges: { [source: string]: Set } = {}; - constructor(graph?: ProjectGraph, fileMap?: ProjectFileMap) { + + constructor( + graph?: ProjectGraph, + projectFileMap?: ProjectFileMap, + nonProjectFiles?: FileMap['nonProjectFiles'] + ) { + if (!projectFileMap || !nonProjectFiles) { + const fileMap = getFileMap().fileMap; + projectFileMap ??= fileMap.projectFileMap; + nonProjectFiles ??= fileMap.nonProjectFiles; + } if (graph) { this.graph = graph; - this.projectFileMap = fileMap || getFileMap().fileMap?.projectFileMap; + this.projectFileMap = projectFileMap; + this.nonProjectFiles = nonProjectFiles; } else { this.graph = { nodes: {}, externalNodes: {}, dependencies: {}, }; - this.projectFileMap = fileMap || {}; + this.projectFileMap = projectFileMap || {}; + this.nonProjectFiles = nonProjectFiles || []; + } + + this.allWorkspaceFiles = this.nonProjectFiles; + for (const project in this.projectFileMap) { + this.allWorkspaceFiles = this.allWorkspaceFiles.concat( + this.projectFileMap[project] + ); } } @@ -234,6 +261,13 @@ export class ProjectGraphBuilder { } } } + for (const file of this.nonProjectFiles) { + if (file.deps) { + for (const dep of file.deps) { + this.graph.dependencies[dep.source].push(dep); + } + } + } return this.graph; } @@ -257,8 +291,8 @@ export class ProjectGraphBuilder { { externalNodes: this.graph.externalNodes, fileMap: { - projectFileMap: { ...this.projectFileMap }, - nonProjectFiles: [], + projectFileMap: this.projectFileMap, + nonProjectFiles: this.nonProjectFiles, }, // the validators only really care about the keys on this. projects: this.graph.nodes as any, @@ -280,20 +314,32 @@ export class ProjectGraphBuilder { source, sourceFile, this.graph.nodes, - this.projectFileMap + this.graph.externalNodes, + this.projectFileMap, + this.allWorkspaceFiles ); if (!fileData.deps) { fileData.deps = []; } - if ( - !fileData.deps.find( - (t) => fileDataDepTarget(t) === target && fileDataDepType(t) === type - ) - ) { - const dep: string | [string, string] = - type === 'static' ? target : [target, type]; - fileData.deps.push(dep); + + if (isProjectFileData(source, this.graph.nodes, fileData)) { + if ( + !fileData.deps.find( + (t) => + fileDataDepTarget(t) === target && fileDataDepType(t) === type + ) + ) { + const dep: string | [string, string] = + type === 'static' ? target : [target, type]; + fileData.deps.push(dep); + } + } else { + fileData.deps.push({ + source, + target, + type, + }); } } else if (!isDuplicate) { // only add to dependencies section if the source file is not specified @@ -491,8 +537,19 @@ function validateCommonDependencyRules( throw new Error(`External projects can't depend on internal projects`); } if ('sourceFile' in d && d.sourceFile) { - // Throws if source file is not a valid file within the source project. - getFileData(d.source, d.sourceFile, projects, fileMap.projectFileMap); + if (projects[d.source]) { + // Throws if source file is not a valid file within the source project. + // We can pass empty array for all workspace files here, since its not checked by the impl. + // We need all workspace files in here for the TODO comment though, so lets figure that out. + getFileData( + d.source, + d.sourceFile, + projects, + externalNodes, + fileMap.projectFileMap, + [] + ); + } } } @@ -535,17 +592,38 @@ function getFileData( source: string, sourceFile: string, projects: Record, - fileMap: ProjectFileMap + externalNodes: Record, + fileMap: ProjectFileMap, + allWorkspaceFiles: FileData[] ) { const sourceProject = projects[source]; - if (!sourceProject) { + const matchingExternalNode = externalNodes[source]; + + if (!sourceProject && !matchingExternalNode) { throw new Error(`Source project is not a project node: ${sourceProject}`); } - const fileData = (fileMap[source] || []).find((f) => f.file === sourceFile); - if (!fileData) { - throw new Error( - `Source project ${source} does not have a file: ${sourceFile}` - ); + + if (sourceProject) { + const fileData = (fileMap[source] || []).find((f) => f.file === sourceFile); + if (!fileData) { + throw new Error( + `Source project ${source} does not have a file: ${sourceFile}` + ); + } + return fileData; + } else { + const fileData = allWorkspaceFiles.find((f) => f.file === sourceFile); + if (!fileData) { + throw new Error(`Source file "${sourceFile}" is not in the workspace.`); + } + return fileData; } - return fileData; +} + +function isProjectFileData( + source: string, + projects: Record, + d: FileData +): d is ProjectFileData { + return !!projects[source]; } diff --git a/packages/nx/src/project-graph/utils/retrieve-workspace-files.ts b/packages/nx/src/project-graph/utils/retrieve-workspace-files.ts index e7ebbb8626f536..9ab713def47d8e 100644 --- a/packages/nx/src/project-graph/utils/retrieve-workspace-files.ts +++ b/packages/nx/src/project-graph/utils/retrieve-workspace-files.ts @@ -255,7 +255,7 @@ function buildAllWorkspaceFiles( globalFiles: FileData[] ): FileData[] { performance.mark('get-all-workspace-files:start'); - let fileData = Object.values(projectFileMap).flat(); + let fileData: FileData[] = Object.values(projectFileMap).flat(); fileData = fileData.concat(globalFiles); performance.mark('get-all-workspace-files:end'); diff --git a/packages/workspace/index.ts b/packages/workspace/index.ts index e506584ad01040..dd278a00fd4ebf 100644 --- a/packages/workspace/index.ts +++ b/packages/workspace/index.ts @@ -15,7 +15,6 @@ export { readWorkspaceConfig, readPackageJson, } from 'nx/src/project-graph/file-utils'; -export { ProjectFileMapCache } from 'nx/src/project-graph/nx-deps-cache'; export { getWorkspacePath,