cleanup(core): adjust create dependencies context (#19070)
Co-authored-by: FrozenPandaz <jasonjean1993@gmail.com>
This commit is contained in:
parent
50b62524f5
commit
f2e20c81b6
@ -1,10 +1,10 @@
|
||||
# Type alias: CreateDependencies
|
||||
|
||||
Ƭ **CreateDependencies**: (`context`: [`CreateDependenciesContext`](../../devkit/documents/CreateDependenciesContext)) => [`ProjectGraphDependencyWithFile`](../../devkit/documents/ProjectGraphDependencyWithFile)[] \| `Promise`<[`ProjectGraphDependencyWithFile`](../../devkit/documents/ProjectGraphDependencyWithFile)[]\>
|
||||
Ƭ **CreateDependencies**: (`context`: [`CreateDependenciesContext`](../../devkit/documents/CreateDependenciesContext)) => [`RawProjectGraphDependency`](../../devkit/documents/RawProjectGraphDependency)[] \| `Promise`<[`RawProjectGraphDependency`](../../devkit/documents/RawProjectGraphDependency)[]\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (`context`): [`ProjectGraphDependencyWithFile`](../../devkit/documents/ProjectGraphDependencyWithFile)[] \| `Promise`<[`ProjectGraphDependencyWithFile`](../../devkit/documents/ProjectGraphDependencyWithFile)[]\>
|
||||
▸ (`context`): [`RawProjectGraphDependency`](../../devkit/documents/RawProjectGraphDependency)[] \| `Promise`<[`RawProjectGraphDependency`](../../devkit/documents/RawProjectGraphDependency)[]\>
|
||||
|
||||
A function which parses files in the workspace to create dependencies in the [ProjectGraph](../../devkit/documents/ProjectGraph)
|
||||
Use [validateDependency](../../devkit/documents/validateDependency) to validate dependencies
|
||||
@ -17,4 +17,4 @@ Use [validateDependency](../../devkit/documents/validateDependency) to validate
|
||||
|
||||
##### Returns
|
||||
|
||||
[`ProjectGraphDependencyWithFile`](../../devkit/documents/ProjectGraphDependencyWithFile)[] \| `Promise`<[`ProjectGraphDependencyWithFile`](../../devkit/documents/ProjectGraphDependencyWithFile)[]\>
|
||||
[`RawProjectGraphDependency`](../../devkit/documents/RawProjectGraphDependency)[] \| `Promise`<[`RawProjectGraphDependency`](../../devkit/documents/RawProjectGraphDependency)[]\>
|
||||
|
||||
@ -6,14 +6,23 @@ Context for [CreateDependencies](../../devkit/documents/CreateDependencies)
|
||||
|
||||
### Properties
|
||||
|
||||
- [externalNodes](../../devkit/documents/CreateDependenciesContext#externalnodes): Record<string, ProjectGraphExternalNode>
|
||||
- [fileMap](../../devkit/documents/CreateDependenciesContext#filemap): ProjectFileMap
|
||||
- [filesToProcess](../../devkit/documents/CreateDependenciesContext#filestoprocess): ProjectFileMap
|
||||
- [graph](../../devkit/documents/CreateDependenciesContext#graph): ProjectGraph
|
||||
- [nxJsonConfiguration](../../devkit/documents/CreateDependenciesContext#nxjsonconfiguration): NxJsonConfiguration<string[] | "\*">
|
||||
- [projectsConfigurations](../../devkit/documents/CreateDependenciesContext#projectsconfigurations): ProjectsConfigurations
|
||||
- [projects](../../devkit/documents/CreateDependenciesContext#projects): Record<string, ProjectConfiguration>
|
||||
- [workspaceRoot](../../devkit/documents/CreateDependenciesContext#workspaceroot): string
|
||||
|
||||
## Properties
|
||||
|
||||
### externalNodes
|
||||
|
||||
• `Readonly` **externalNodes**: `Record`<`string`, [`ProjectGraphExternalNode`](../../devkit/documents/ProjectGraphExternalNode)\>
|
||||
|
||||
The external nodes that have been added to the graph.
|
||||
|
||||
---
|
||||
|
||||
### fileMap
|
||||
|
||||
• `Readonly` **fileMap**: [`ProjectFileMap`](../../devkit/documents/ProjectFileMap)
|
||||
@ -30,14 +39,6 @@ Files changes since last invocation
|
||||
|
||||
---
|
||||
|
||||
### graph
|
||||
|
||||
• `Readonly` **graph**: [`ProjectGraph`](../../devkit/documents/ProjectGraph)
|
||||
|
||||
The current project graph,
|
||||
|
||||
---
|
||||
|
||||
### nxJsonConfiguration
|
||||
|
||||
• `Readonly` **nxJsonConfiguration**: [`NxJsonConfiguration`](../../devkit/documents/NxJsonConfiguration)<`string`[] \| `"*"`\>
|
||||
@ -46,8 +47,14 @@ The `nx.json` configuration from the workspace
|
||||
|
||||
---
|
||||
|
||||
### projectsConfigurations
|
||||
### projects
|
||||
|
||||
• `Readonly` **projectsConfigurations**: [`ProjectsConfigurations`](../../devkit/documents/ProjectsConfigurations)
|
||||
• `Readonly` **projects**: `Record`<`string`, [`ProjectConfiguration`](../../devkit/documents/ProjectConfiguration)\>
|
||||
|
||||
The configuration of each project in the workspace
|
||||
The configuration of each project in the workspace.
|
||||
|
||||
---
|
||||
|
||||
### workspaceRoot
|
||||
|
||||
• `Readonly` **workspaceRoot**: `string`
|
||||
|
||||
16
docs/generated/devkit/DynamicDependency.md
Normal file
16
docs/generated/devkit/DynamicDependency.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Type alias: DynamicDependency
|
||||
|
||||
Ƭ **DynamicDependency**: `Object`
|
||||
|
||||
A dynamic [ProjectGraph](../../devkit/documents/ProjectGraph) dependency between 2 projects
|
||||
|
||||
This type of dependency indicates the source project MAY OR MAY NOT load the target project.
|
||||
|
||||
#### Type declaration
|
||||
|
||||
| Name | Type | Description |
|
||||
| :----------- | :---------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `source` | `string` | The name of a [ProjectGraphProjectNode](../../devkit/documents/ProjectGraphProjectNode) depending on the target project |
|
||||
| `sourceFile` | `string` | The path of a file (relative from the workspace root) where the dependency is made |
|
||||
| `target` | `string` | The name of a [ProjectGraphProjectNode](../../devkit/documents/ProjectGraphProjectNode) that the source project depends on |
|
||||
| `type` | typeof [`dynamic`](../../devkit/documents/DependencyType#dynamic) | - |
|
||||
15
docs/generated/devkit/ImplicitDependency.md
Normal file
15
docs/generated/devkit/ImplicitDependency.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Type alias: ImplicitDependency
|
||||
|
||||
Ƭ **ImplicitDependency**: `Object`
|
||||
|
||||
An implicit [ProjectGraph](../../devkit/documents/ProjectGraph) dependency between 2 projects
|
||||
|
||||
This type of dependency indicates a connection without an explicit reference in code
|
||||
|
||||
#### Type declaration
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------- | :------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `source` | `string` | The name of a [ProjectGraphProjectNode](../../devkit/documents/ProjectGraphProjectNode) depending on the target project |
|
||||
| `target` | `string` | The name of a [ProjectGraphProjectNode](../../devkit/documents/ProjectGraphProjectNode) that the source project depends on |
|
||||
| `type` | typeof [`implicit`](../../devkit/documents/DependencyType#implicit) | - |
|
||||
@ -1,45 +0,0 @@
|
||||
# Interface: ProjectGraphDependencyWithFile
|
||||
|
||||
A [ProjectGraph](../../devkit/documents/ProjectGraph) dependency between 2 projects
|
||||
Optional: Specifies a file from where the dependency is made
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [dependencyType](../../devkit/documents/ProjectGraphDependencyWithFile#dependencytype): DependencyType
|
||||
- [source](../../devkit/documents/ProjectGraphDependencyWithFile#source): string
|
||||
- [sourceFile](../../devkit/documents/ProjectGraphDependencyWithFile#sourcefile): string
|
||||
- [target](../../devkit/documents/ProjectGraphDependencyWithFile#target): string
|
||||
|
||||
## Properties
|
||||
|
||||
### dependencyType
|
||||
|
||||
• **dependencyType**: [`DependencyType`](../../devkit/documents/DependencyType)
|
||||
|
||||
The type of dependency
|
||||
|
||||
---
|
||||
|
||||
### source
|
||||
|
||||
• **source**: `string`
|
||||
|
||||
The name of a [ProjectGraphProjectNode](../../devkit/documents/ProjectGraphProjectNode) or [ProjectGraphExternalNode](../../devkit/documents/ProjectGraphExternalNode) depending on the target project
|
||||
|
||||
---
|
||||
|
||||
### sourceFile
|
||||
|
||||
• `Optional` **sourceFile**: `string`
|
||||
|
||||
The path of a file (relative from the workspace root) where the dependency is made
|
||||
|
||||
---
|
||||
|
||||
### target
|
||||
|
||||
• **target**: `string`
|
||||
|
||||
The name of a [ProjectGraphProjectNode](../../devkit/documents/ProjectGraphProjectNode) or [ProjectGraphExternalNode](../../devkit/documents/ProjectGraphExternalNode) that the source project depends on
|
||||
@ -43,7 +43,6 @@ It only uses language primitives and immutable objects
|
||||
- [ProjectFileMap](../../devkit/documents/ProjectFileMap)
|
||||
- [ProjectGraph](../../devkit/documents/ProjectGraph)
|
||||
- [ProjectGraphDependency](../../devkit/documents/ProjectGraphDependency)
|
||||
- [ProjectGraphDependencyWithFile](../../devkit/documents/ProjectGraphDependencyWithFile)
|
||||
- [ProjectGraphExternalNode](../../devkit/documents/ProjectGraphExternalNode)
|
||||
- [ProjectGraphProcessorContext](../../devkit/documents/ProjectGraphProcessorContext)
|
||||
- [ProjectGraphProjectNode](../../devkit/documents/ProjectGraphProjectNode)
|
||||
@ -66,10 +65,12 @@ It only uses language primitives and immutable objects
|
||||
- [CreateNodes](../../devkit/documents/CreateNodes)
|
||||
- [CreateNodesFunction](../../devkit/documents/CreateNodesFunction)
|
||||
- [CustomHasher](../../devkit/documents/CustomHasher)
|
||||
- [DynamicDependency](../../devkit/documents/DynamicDependency)
|
||||
- [Executor](../../devkit/documents/Executor)
|
||||
- [Generator](../../devkit/documents/Generator)
|
||||
- [GeneratorCallback](../../devkit/documents/GeneratorCallback)
|
||||
- [Hasher](../../devkit/documents/Hasher)
|
||||
- [ImplicitDependency](../../devkit/documents/ImplicitDependency)
|
||||
- [ImplicitDependencyEntry](../../devkit/documents/ImplicitDependencyEntry)
|
||||
- [NxPlugin](../../devkit/documents/NxPlugin)
|
||||
- [NxPluginV1](../../devkit/documents/NxPluginV1)
|
||||
@ -78,6 +79,8 @@ It only uses language primitives and immutable objects
|
||||
- [ProjectGraphNode](../../devkit/documents/ProjectGraphNode)
|
||||
- [ProjectTargetConfigurator](../../devkit/documents/ProjectTargetConfigurator)
|
||||
- [ProjectType](../../devkit/documents/ProjectType)
|
||||
- [RawProjectGraphDependency](../../devkit/documents/RawProjectGraphDependency)
|
||||
- [StaticDependency](../../devkit/documents/StaticDependency)
|
||||
- [StringChange](../../devkit/documents/StringChange)
|
||||
- [TaskGraphExecutor](../../devkit/documents/TaskGraphExecutor)
|
||||
- [WorkspaceConfiguration](../../devkit/documents/WorkspaceConfiguration)
|
||||
|
||||
7
docs/generated/devkit/RawProjectGraphDependency.md
Normal file
7
docs/generated/devkit/RawProjectGraphDependency.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Type alias: RawProjectGraphDependency
|
||||
|
||||
Ƭ **RawProjectGraphDependency**: [`ImplicitDependency`](../../devkit/documents/ImplicitDependency) \| [`StaticDependency`](../../devkit/documents/StaticDependency) \| [`DynamicDependency`](../../devkit/documents/DynamicDependency)
|
||||
|
||||
A [ProjectGraph](../../devkit/documents/ProjectGraph) dependency between 2 projects
|
||||
|
||||
See [DynamicDependency](../../devkit/documents/DynamicDependency), [ImplicitDependency](../../devkit/documents/ImplicitDependency), or [StaticDependency](../../devkit/documents/StaticDependency)
|
||||
18
docs/generated/devkit/StaticDependency.md
Normal file
18
docs/generated/devkit/StaticDependency.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Type alias: StaticDependency
|
||||
|
||||
Ƭ **StaticDependency**: `Object`
|
||||
|
||||
A static [ProjectGraph](../../devkit/documents/ProjectGraph) dependency between 2 projects
|
||||
|
||||
This type of dependency indicates the source project ALWAYS load the target project.
|
||||
|
||||
NOTE: StaticDependency#sourceFile MUST be present unless the source is the name of a [ProjectGraphExternalNode](../../devkit/documents/ProjectGraphExternalNode)
|
||||
|
||||
#### Type declaration
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------------ | :-------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `source` | `string` | The name of a [ProjectGraphProjectNode](../../devkit/documents/ProjectGraphProjectNode) or [ProjectGraphExternalNode](../../devkit/documents/ProjectGraphExternalNode) depending on the target project |
|
||||
| `sourceFile?` | `string` | The path of a file (relative from the workspace root) where the dependency is made |
|
||||
| `target` | `string` | The name of a [ProjectGraphProjectNode](../../devkit/documents/ProjectGraphProjectNode) or [ProjectGraphExternalNode](../../devkit/documents/ProjectGraphExternalNode) that the source project depends on |
|
||||
| `type` | typeof [`static`](../../devkit/documents/DependencyType#static) | - |
|
||||
@ -1,6 +1,6 @@
|
||||
# Function: validateDependency
|
||||
|
||||
▸ **validateDependency**(`graph`, `dependency`): `void`
|
||||
▸ **validateDependency**(`dependency`, `ctx`): `void`
|
||||
|
||||
A function to validate dependencies in a [CreateDependencies](../../devkit/documents/CreateDependencies) function
|
||||
|
||||
@ -11,9 +11,9 @@ If the dependency is invalid.
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :----------- | :---------------------------------------------------------------------------------------- |
|
||||
| `graph` | [`ProjectGraph`](../../devkit/documents/ProjectGraph) |
|
||||
| `dependency` | [`ProjectGraphDependencyWithFile`](../../devkit/documents/ProjectGraphDependencyWithFile) |
|
||||
| :----------- | :------------------------------------------------------------------------------ |
|
||||
| `dependency` | [`RawProjectGraphDependency`](../../devkit/documents/RawProjectGraphDependency) |
|
||||
| `ctx` | [`CreateDependenciesContext`](../../devkit/documents/CreateDependenciesContext) |
|
||||
|
||||
#### Returns
|
||||
|
||||
|
||||
@ -43,7 +43,6 @@ It only uses language primitives and immutable objects
|
||||
- [ProjectFileMap](../../devkit/documents/ProjectFileMap)
|
||||
- [ProjectGraph](../../devkit/documents/ProjectGraph)
|
||||
- [ProjectGraphDependency](../../devkit/documents/ProjectGraphDependency)
|
||||
- [ProjectGraphDependencyWithFile](../../devkit/documents/ProjectGraphDependencyWithFile)
|
||||
- [ProjectGraphExternalNode](../../devkit/documents/ProjectGraphExternalNode)
|
||||
- [ProjectGraphProcessorContext](../../devkit/documents/ProjectGraphProcessorContext)
|
||||
- [ProjectGraphProjectNode](../../devkit/documents/ProjectGraphProjectNode)
|
||||
@ -66,10 +65,12 @@ It only uses language primitives and immutable objects
|
||||
- [CreateNodes](../../devkit/documents/CreateNodes)
|
||||
- [CreateNodesFunction](../../devkit/documents/CreateNodesFunction)
|
||||
- [CustomHasher](../../devkit/documents/CustomHasher)
|
||||
- [DynamicDependency](../../devkit/documents/DynamicDependency)
|
||||
- [Executor](../../devkit/documents/Executor)
|
||||
- [Generator](../../devkit/documents/Generator)
|
||||
- [GeneratorCallback](../../devkit/documents/GeneratorCallback)
|
||||
- [Hasher](../../devkit/documents/Hasher)
|
||||
- [ImplicitDependency](../../devkit/documents/ImplicitDependency)
|
||||
- [ImplicitDependencyEntry](../../devkit/documents/ImplicitDependencyEntry)
|
||||
- [NxPlugin](../../devkit/documents/NxPlugin)
|
||||
- [NxPluginV1](../../devkit/documents/NxPluginV1)
|
||||
@ -78,6 +79,8 @@ It only uses language primitives and immutable objects
|
||||
- [ProjectGraphNode](../../devkit/documents/ProjectGraphNode)
|
||||
- [ProjectTargetConfigurator](../../devkit/documents/ProjectTargetConfigurator)
|
||||
- [ProjectType](../../devkit/documents/ProjectType)
|
||||
- [RawProjectGraphDependency](../../devkit/documents/RawProjectGraphDependency)
|
||||
- [StaticDependency](../../devkit/documents/StaticDependency)
|
||||
- [StringChange](../../devkit/documents/StringChange)
|
||||
- [TaskGraphExecutor](../../devkit/documents/TaskGraphExecutor)
|
||||
- [WorkspaceConfiguration](../../devkit/documents/WorkspaceConfiguration)
|
||||
|
||||
@ -90,16 +90,14 @@ The shape of the [`createDependencies`](/packages/devkit/documents/CreateDepende
|
||||
```typescript
|
||||
export type CreateDependencies = (
|
||||
context: CreateDependenciesContext
|
||||
) =>
|
||||
| ProjectGraphDependencyWithFile[]
|
||||
| Promise<ProjectGraphDependencyWithFile[]>;
|
||||
) => CandidateDependency[] | Promise<CandidateDependency[]>;
|
||||
```
|
||||
|
||||
In the `createDependencies` function, you can analyze the files in the workspace and return a list of dependencies. It's up to the plugin to determine how to analyze the files. This should also be exported from the plugin's entry point, as listed in `nx.json`.
|
||||
|
||||
Within the `CreateDependenciesContext`, you have access to the current project graph, the configuration of each project in the workspace, the `nx.json` configuration from the workspace, all files in the workspace, and files that have changed since the last invocation. It's important to utilize the `filesToProcess` parameter, as this will allow Nx to only reanalyze files that have changed since the last invocation, and reuse the information from the previous invocation for files that haven't changed.
|
||||
Within the `CreateDependenciesContext`, you have access to the graph's external nodes, the configuration of each project in the workspace, the `nx.json` configuration from the workspace, all files in the workspace, and files that have changed since the last invocation. It's important to utilize the `filesToProcess` parameter, as this will allow Nx to only reanalyze files that have changed since the last invocation, and reuse the information from the previous invocation for files that haven't changed.
|
||||
|
||||
`@nx/devkit` exports a function called `validateDependency` which can be used to validate a dependency. This function takes in a `ProjectGraphDependencyWithFile` and a `ProjectGraph` and throws an error if the dependency is invalid. This function is called when the returned dependencies are merged with the existing project graph, but may be useful to call within your plugin to validate dependencies before returning them when debugging.
|
||||
`@nx/devkit` exports a function called `validateDependency` which can be used to validate a dependency. This function takes in a `CandidateDependency` and the `CreateDependenciesContext` and throws an error if the dependency is invalid. This function is called when the returned dependencies are merged with the existing project graph, but may be useful to call within your plugin to validate dependencies before returning them when debugging.
|
||||
|
||||
The dependencies can be of three types:
|
||||
|
||||
@ -184,7 +182,7 @@ export const createNodes: CreateNodes = (ctx) => {
|
||||
dependencyType: DependencyType.static,
|
||||
};
|
||||
}
|
||||
validateDependency(ctx.graph, newDependency);
|
||||
validateDependency(newDependency, ctx);
|
||||
results.push(newDependency);
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,7 +156,10 @@ export { DependencyType } from './config/project-graph';
|
||||
*/
|
||||
export {
|
||||
ProjectGraphBuilder,
|
||||
ProjectGraphDependencyWithFile,
|
||||
RawProjectGraphDependency,
|
||||
DynamicDependency,
|
||||
ImplicitDependency,
|
||||
StaticDependency,
|
||||
validateDependency,
|
||||
} from './project-graph/project-graph-builder';
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ import {
|
||||
} from './lock-file/lock-file';
|
||||
import { buildExplicitDependencies } from './project-graph/build-dependencies/build-dependencies';
|
||||
import { jsPluginConfig } from './utils/config';
|
||||
import { ProjectGraphDependencyWithFile } from '../../project-graph/project-graph-builder';
|
||||
import { RawProjectGraphDependency } from '../../project-graph/project-graph-builder';
|
||||
import { hashArray } from '../../hasher/file-hasher';
|
||||
import { detectPackageManager } from '../../utils/package-manager';
|
||||
import { workspaceRoot } from '../../utils/workspace-root';
|
||||
@ -29,7 +29,7 @@ export const name = 'nx-js-graph-plugin';
|
||||
|
||||
interface ParsedLockFile {
|
||||
externalNodes?: ProjectGraph['externalNodes'];
|
||||
dependencies?: ProjectGraphDependencyWithFile[];
|
||||
dependencies?: RawProjectGraphDependency[];
|
||||
}
|
||||
let parsedLockFile: ParsedLockFile = {};
|
||||
|
||||
@ -80,7 +80,7 @@ export const createDependencies: CreateDependencies = (
|
||||
|
||||
const packageManager = detectPackageManager(workspaceRoot);
|
||||
|
||||
let lockfileDependencies: ProjectGraphDependencyWithFile[] = [];
|
||||
let lockfileDependencies: RawProjectGraphDependency[] = [];
|
||||
// lockfile may not exist yet
|
||||
if (
|
||||
pluginConfig.analyzeLockfile &&
|
||||
@ -98,7 +98,7 @@ export const createDependencies: CreateDependencies = (
|
||||
packageManager,
|
||||
lockFileContents,
|
||||
lockFileHash,
|
||||
ctx.graph
|
||||
ctx
|
||||
);
|
||||
|
||||
parsedLockFile.dependencies = lockfileDependencies;
|
||||
|
||||
@ -15,10 +15,7 @@ import {
|
||||
ProjectGraph,
|
||||
ProjectGraphExternalNode,
|
||||
} from '../../../config/project-graph';
|
||||
import {
|
||||
ProjectGraphBuilder,
|
||||
ProjectGraphDependencyWithFile,
|
||||
} from '../../../project-graph/project-graph-builder';
|
||||
import { RawProjectGraphDependency } from '../../../project-graph/project-graph-builder';
|
||||
import { PackageJson } from '../../../utils/package-json';
|
||||
import { output } from '../../../utils/output';
|
||||
|
||||
@ -40,6 +37,7 @@ import {
|
||||
import { pruneProjectGraph } from './project-graph-pruning';
|
||||
import { normalizePackageJson } from './utils/package-json';
|
||||
import { readJsonFile } from '../../../utils/fileutils';
|
||||
import { CreateDependenciesContext } from '../../../utils/nx-plugin';
|
||||
|
||||
const YARN_LOCK_FILE = 'yarn.lock';
|
||||
const NPM_LOCK_FILE = 'package-lock.json';
|
||||
@ -88,17 +86,17 @@ export function getLockFileDependencies(
|
||||
packageManager: PackageManager,
|
||||
contents: string,
|
||||
lockFileHash: string,
|
||||
projectGraph: ProjectGraph
|
||||
): ProjectGraphDependencyWithFile[] {
|
||||
context: CreateDependenciesContext
|
||||
): RawProjectGraphDependency[] {
|
||||
try {
|
||||
if (packageManager === 'yarn') {
|
||||
return getYarnLockfileDependencies(contents, lockFileHash, projectGraph);
|
||||
return getYarnLockfileDependencies(contents, lockFileHash, context);
|
||||
}
|
||||
if (packageManager === 'pnpm') {
|
||||
return getPnpmLockfileDependencies(contents, lockFileHash, projectGraph);
|
||||
return getPnpmLockfileDependencies(contents, lockFileHash, context);
|
||||
}
|
||||
if (packageManager === 'npm') {
|
||||
return getNpmLockfileDependencies(contents, lockFileHash, projectGraph);
|
||||
return getNpmLockfileDependencies(contents, lockFileHash, context);
|
||||
}
|
||||
} catch (e) {
|
||||
if (!isPostInstallProcess()) {
|
||||
|
||||
@ -8,6 +8,7 @@ import { pruneProjectGraph } from './project-graph-pruning';
|
||||
import { vol } from 'memfs';
|
||||
import { ProjectGraph } from '../../../config/project-graph';
|
||||
import { ProjectGraphBuilder } from '../../../project-graph/project-graph-builder';
|
||||
import { CreateDependenciesContext } from '../../../utils/nx-plugin';
|
||||
|
||||
jest.mock('fs', () => {
|
||||
const memFs = require('memfs').fs;
|
||||
@ -36,15 +37,23 @@ describe('NPM lock file utility', () => {
|
||||
JSON.stringify(rootLockFile),
|
||||
hash
|
||||
);
|
||||
const pg = {
|
||||
nodes: {},
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const pg: ProjectGraph = {
|
||||
dependencies: {},
|
||||
nodes: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getNpmLockfileDependencies(
|
||||
JSON.stringify(rootLockFile),
|
||||
hash,
|
||||
pg
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
@ -52,8 +61,8 @@ describe('NPM lock file utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
graph = builder.getUpdatedProjectGraph();
|
||||
@ -84,10 +93,18 @@ describe('NPM lock file utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getNpmLockfileDependencies(
|
||||
JSON.stringify(appLockFile),
|
||||
hash,
|
||||
pg
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
@ -95,8 +112,8 @@ describe('NPM lock file utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const appGraph = builder.getUpdatedProjectGraph();
|
||||
@ -155,10 +172,18 @@ describe('NPM lock file utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getNpmLockfileDependencies(
|
||||
JSON.stringify(rootLockFile),
|
||||
hash,
|
||||
pg
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
@ -166,8 +191,8 @@ describe('NPM lock file utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -237,10 +262,18 @@ describe('NPM lock file utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getNpmLockfileDependencies(
|
||||
JSON.stringify(rootV2LockFile),
|
||||
hash,
|
||||
pg
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
@ -248,8 +281,8 @@ describe('NPM lock file utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -359,10 +392,18 @@ describe('NPM lock file utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getNpmLockfileDependencies(
|
||||
JSON.stringify(rootV2LockFile),
|
||||
hash,
|
||||
pg
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
@ -370,8 +411,8 @@ describe('NPM lock file utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -470,10 +511,18 @@ describe('NPM lock file utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getNpmLockfileDependencies(
|
||||
JSON.stringify(rootLockFile),
|
||||
hash,
|
||||
pg
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
@ -481,8 +530,8 @@ describe('NPM lock file utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -505,10 +554,18 @@ describe('NPM lock file utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getNpmLockfileDependencies(
|
||||
JSON.stringify(rootLockFile),
|
||||
hash,
|
||||
pg
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
@ -516,8 +573,8 @@ describe('NPM lock file utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -544,10 +601,18 @@ describe('NPM lock file utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getNpmLockfileDependencies(
|
||||
JSON.stringify(lockFile),
|
||||
hash,
|
||||
pg
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
@ -555,8 +620,8 @@ describe('NPM lock file utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -594,10 +659,18 @@ describe('NPM lock file utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getNpmLockfileDependencies(
|
||||
JSON.stringify(rootLockFile),
|
||||
hash,
|
||||
pg
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
@ -605,8 +678,8 @@ describe('NPM lock file utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -646,10 +719,18 @@ describe('NPM lock file utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getNpmLockfileDependencies(
|
||||
JSON.stringify(rootLockFile),
|
||||
hash,
|
||||
pg
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
@ -657,8 +738,8 @@ describe('NPM lock file utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
|
||||
@ -4,7 +4,7 @@ import { workspaceRoot } from '../../../utils/workspace-root';
|
||||
import { reverse } from '../../../project-graph/operators';
|
||||
import { NormalizedPackageJson } from './utils/package-json';
|
||||
import {
|
||||
ProjectGraphDependencyWithFile,
|
||||
RawProjectGraphDependency,
|
||||
validateDependency,
|
||||
} from '../../../project-graph/project-graph-builder';
|
||||
import {
|
||||
@ -13,6 +13,7 @@ import {
|
||||
ProjectGraphExternalNode,
|
||||
} from '../../../config/project-graph';
|
||||
import { hashArray } from '../../../hasher/file-hasher';
|
||||
import { CreateDependenciesContext } from '../../../utils/nx-plugin';
|
||||
|
||||
/**
|
||||
* NPM
|
||||
@ -87,14 +88,14 @@ export function getNpmLockfileNodes(
|
||||
export function getNpmLockfileDependencies(
|
||||
lockFileContent: string,
|
||||
lockFileHash: string,
|
||||
projectGraph: ProjectGraph
|
||||
ctx: CreateDependenciesContext
|
||||
) {
|
||||
const data = parsePackageLockFile(
|
||||
lockFileContent,
|
||||
lockFileHash
|
||||
) as NpmLockFile;
|
||||
|
||||
return getDependencies(data, keyMap, projectGraph);
|
||||
return getDependencies(data, keyMap, ctx);
|
||||
}
|
||||
|
||||
function getNodes(
|
||||
@ -246,9 +247,9 @@ function findV3Version(snapshot: NpmDependencyV3, packageName: string): string {
|
||||
function getDependencies(
|
||||
data: NpmLockFile,
|
||||
keyMap: Map<string, ProjectGraphExternalNode>,
|
||||
projectGraph: ProjectGraph
|
||||
): ProjectGraphDependencyWithFile[] {
|
||||
const dependencies: ProjectGraphDependencyWithFile[] = [];
|
||||
ctx: CreateDependenciesContext
|
||||
): RawProjectGraphDependency[] {
|
||||
const dependencies: RawProjectGraphDependency[] = [];
|
||||
if (data.lockfileVersion > 1) {
|
||||
Object.entries(data.packages).forEach(([path, snapshot]) => {
|
||||
// we are skipping workspaces packages
|
||||
@ -265,12 +266,12 @@ function getDependencies(
|
||||
Object.entries(section).forEach(([name, versionRange]) => {
|
||||
const target = findTarget(path, keyMap, name, versionRange);
|
||||
if (target) {
|
||||
const dep = {
|
||||
const dep: RawProjectGraphDependency = {
|
||||
source: sourceName,
|
||||
target: target.name,
|
||||
dependencyType: DependencyType.static,
|
||||
type: DependencyType.static,
|
||||
};
|
||||
validateDependency(projectGraph, dep);
|
||||
validateDependency(dep, ctx);
|
||||
dependencies.push(dep);
|
||||
}
|
||||
});
|
||||
@ -284,7 +285,7 @@ function getDependencies(
|
||||
snapshot,
|
||||
dependencies,
|
||||
keyMap,
|
||||
projectGraph
|
||||
ctx
|
||||
);
|
||||
});
|
||||
}
|
||||
@ -326,21 +327,21 @@ function findTarget(
|
||||
function addV1NodeDependencies(
|
||||
path: string,
|
||||
snapshot: NpmDependencyV1,
|
||||
dependencies: ProjectGraphDependencyWithFile[],
|
||||
dependencies: RawProjectGraphDependency[],
|
||||
keyMap: Map<string, ProjectGraphExternalNode>,
|
||||
projectGraph: ProjectGraph
|
||||
ctx: CreateDependenciesContext
|
||||
) {
|
||||
if (keyMap.has(path) && snapshot.requires) {
|
||||
const source = keyMap.get(path).name;
|
||||
Object.entries(snapshot.requires).forEach(([name, versionRange]) => {
|
||||
const target = findTarget(path, keyMap, name, versionRange);
|
||||
if (target) {
|
||||
const dep = {
|
||||
const dep: RawProjectGraphDependency = {
|
||||
source: source,
|
||||
target: target.name,
|
||||
dependencyType: DependencyType.static,
|
||||
type: DependencyType.static,
|
||||
};
|
||||
validateDependency(projectGraph, dep);
|
||||
validateDependency(dep, ctx);
|
||||
dependencies.push(dep);
|
||||
}
|
||||
});
|
||||
@ -353,7 +354,7 @@ function addV1NodeDependencies(
|
||||
depSnapshot,
|
||||
dependencies,
|
||||
keyMap,
|
||||
projectGraph
|
||||
ctx
|
||||
);
|
||||
});
|
||||
}
|
||||
@ -363,12 +364,12 @@ function addV1NodeDependencies(
|
||||
Object.entries(peerDependencies).forEach(([depName, depSpec]) => {
|
||||
const target = findTarget(path, keyMap, depName, depSpec);
|
||||
if (target) {
|
||||
const dep = {
|
||||
const dep: RawProjectGraphDependency = {
|
||||
source: node.name,
|
||||
target: target.name,
|
||||
dependencyType: DependencyType.static,
|
||||
type: DependencyType.static,
|
||||
};
|
||||
validateDependency(projectGraph, dep);
|
||||
validateDependency(dep, ctx);
|
||||
dependencies.push(dep);
|
||||
}
|
||||
});
|
||||
|
||||
@ -9,8 +9,9 @@ import { vol } from 'memfs';
|
||||
import { pruneProjectGraph } from './project-graph-pruning';
|
||||
import {
|
||||
ProjectGraphBuilder,
|
||||
ProjectGraphDependencyWithFile,
|
||||
RawProjectGraphDependency,
|
||||
} from '../../../project-graph/project-graph-builder';
|
||||
import { CreateDependenciesContext } from '../../../utils/nx-plugin';
|
||||
|
||||
jest.mock('fs', () => {
|
||||
const memFs = require('memfs').fs;
|
||||
@ -127,7 +128,7 @@ describe('pnpm LockFile utility', () => {
|
||||
});
|
||||
|
||||
let externalNodes: ProjectGraph['externalNodes'];
|
||||
let dependencies: ProjectGraphDependencyWithFile[];
|
||||
let dependencies: RawProjectGraphDependency[];
|
||||
let graph: ProjectGraph;
|
||||
|
||||
let lockFile: string;
|
||||
@ -147,19 +148,23 @@ describe('pnpm LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
dependencies = getPnpmLockfileDependencies(
|
||||
lockFile,
|
||||
lockFileHash,
|
||||
graph
|
||||
);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
dependencies = getPnpmLockfileDependencies(lockFile, lockFileHash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(graph);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
graph = builder.getUpdatedProjectGraph();
|
||||
@ -204,19 +209,23 @@ describe('pnpm LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
dependencies = getPnpmLockfileDependencies(
|
||||
lockFile,
|
||||
lockFileHash,
|
||||
graph
|
||||
);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
dependencies = getPnpmLockfileDependencies(lockFile, lockFileHash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(graph);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
graph = builder.getUpdatedProjectGraph();
|
||||
@ -247,10 +256,18 @@ describe('pnpm LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const appCtx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getPnpmLockfileDependencies(
|
||||
appLockFile,
|
||||
appLockFileHash,
|
||||
appGraph
|
||||
appCtx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(appGraph);
|
||||
@ -258,8 +275,8 @@ describe('pnpm LockFile utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
appGraph = builder.getUpdatedProjectGraph();
|
||||
@ -317,10 +334,18 @@ describe('pnpm LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getPnpmLockfileDependencies(
|
||||
lockFile,
|
||||
lockFileHash,
|
||||
graph
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(graph);
|
||||
@ -328,8 +353,8 @@ describe('pnpm LockFile utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
graph = builder.getUpdatedProjectGraph();
|
||||
@ -420,11 +445,18 @@ describe('pnpm LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getPnpmLockfileDependencies(
|
||||
lockFile,
|
||||
lockFileHash,
|
||||
graph
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(graph);
|
||||
@ -432,8 +464,8 @@ describe('pnpm LockFile utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
graph = builder.getUpdatedProjectGraph();
|
||||
@ -481,10 +513,18 @@ describe('pnpm LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getPnpmLockfileDependencies(
|
||||
lockFile,
|
||||
lockFileHash,
|
||||
graph
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(graph);
|
||||
@ -492,8 +532,8 @@ describe('pnpm LockFile utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
graph = builder.getUpdatedProjectGraph();
|
||||
@ -528,10 +568,18 @@ describe('pnpm LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getPnpmLockfileDependencies(
|
||||
lockFile,
|
||||
lockFileHash,
|
||||
graph
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(graph);
|
||||
@ -539,8 +587,8 @@ describe('pnpm LockFile utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
graph = builder.getUpdatedProjectGraph();
|
||||
@ -588,10 +636,18 @@ describe('pnpm LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getPnpmLockfileDependencies(
|
||||
lockFile,
|
||||
lockFileHash,
|
||||
graph
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(graph);
|
||||
@ -599,8 +655,8 @@ describe('pnpm LockFile utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
graph = builder.getUpdatedProjectGraph();
|
||||
@ -659,10 +715,18 @@ describe('pnpm LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getPnpmLockfileDependencies(
|
||||
lockFile,
|
||||
lockFileHash,
|
||||
graph
|
||||
ctx
|
||||
);
|
||||
|
||||
const builder = new ProjectGraphBuilder(graph);
|
||||
@ -670,8 +734,8 @@ describe('pnpm LockFile utility', () => {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
graph = builder.getUpdatedProjectGraph();
|
||||
|
||||
@ -16,7 +16,7 @@ import {
|
||||
} from './utils/package-json';
|
||||
import { sortObjectByKeys } from '../../../utils/object-sort';
|
||||
import {
|
||||
ProjectGraphDependencyWithFile,
|
||||
RawProjectGraphDependency,
|
||||
validateDependency,
|
||||
} from '../../../project-graph/project-graph-builder';
|
||||
import {
|
||||
@ -25,6 +25,7 @@ import {
|
||||
ProjectGraphExternalNode,
|
||||
} from '../../../config/project-graph';
|
||||
import { hashArray } from '../../../hasher/file-hasher';
|
||||
import { CreateDependenciesContext } from '../../../utils/nx-plugin';
|
||||
|
||||
// we use key => node map to avoid duplicate work when parsing keys
|
||||
let keyMap = new Map<string, ProjectGraphExternalNode>();
|
||||
@ -56,12 +57,12 @@ export function getPnpmLockfileNodes(
|
||||
export function getPnpmLockfileDependencies(
|
||||
lockFileContent: string,
|
||||
lockFileHash: string,
|
||||
projectGraph: ProjectGraph
|
||||
ctx: CreateDependenciesContext
|
||||
) {
|
||||
const data = parsePnpmLockFile(lockFileContent, lockFileHash);
|
||||
const isV6 = isV6Lockfile(data);
|
||||
|
||||
return getDependencies(data, keyMap, isV6, projectGraph);
|
||||
return getDependencies(data, keyMap, isV6, ctx);
|
||||
}
|
||||
|
||||
function getNodes(
|
||||
@ -157,9 +158,9 @@ function getDependencies(
|
||||
data: Lockfile,
|
||||
keyMap: Map<string, ProjectGraphExternalNode>,
|
||||
isV6: boolean,
|
||||
projectGraph: ProjectGraph
|
||||
): ProjectGraphDependencyWithFile[] {
|
||||
const results: ProjectGraphDependencyWithFile[] = [];
|
||||
ctx: CreateDependenciesContext
|
||||
): RawProjectGraphDependency[] {
|
||||
const results: RawProjectGraphDependency[] = [];
|
||||
Object.entries(data.packages).forEach(([key, snapshot]) => {
|
||||
const node = keyMap.get(key);
|
||||
[snapshot.dependencies, snapshot.optionalDependencies].forEach(
|
||||
@ -171,15 +172,15 @@ function getDependencies(
|
||||
isV6
|
||||
);
|
||||
const target =
|
||||
projectGraph.externalNodes[`npm:${name}@${version}`] ||
|
||||
projectGraph.externalNodes[`npm:${name}`];
|
||||
ctx.externalNodes[`npm:${name}@${version}`] ||
|
||||
ctx.externalNodes[`npm:${name}`];
|
||||
if (target) {
|
||||
const dep = {
|
||||
const dep: RawProjectGraphDependency = {
|
||||
source: node.name,
|
||||
target: target.name,
|
||||
dependencyType: DependencyType.static,
|
||||
type: DependencyType.static,
|
||||
};
|
||||
validateDependency(projectGraph, dep);
|
||||
validateDependency(dep, ctx);
|
||||
results.push(dep);
|
||||
}
|
||||
});
|
||||
|
||||
@ -9,6 +9,7 @@ import { vol } from 'memfs';
|
||||
import { ProjectGraph } from '../../../config/project-graph';
|
||||
import { PackageJson } from '../../../utils/package-json';
|
||||
import { ProjectGraphBuilder } from '../../../project-graph/project-graph-builder';
|
||||
import { CreateDependenciesContext } from '../../../utils/nx-plugin';
|
||||
|
||||
jest.mock('fs', () => {
|
||||
const memFs = require('memfs').fs;
|
||||
@ -188,15 +189,23 @@ describe('yarn LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
graph = builder.getUpdatedProjectGraph();
|
||||
@ -498,15 +507,23 @@ describe('yarn LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -557,15 +574,23 @@ describe('yarn LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -688,15 +713,23 @@ describe('yarn LockFile utility', () => {
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -757,15 +790,23 @@ __metadata:
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -1223,15 +1264,23 @@ nx-cloud@latest:
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -1424,15 +1473,23 @@ nx-cloud@latest:
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -1473,15 +1530,23 @@ nx-cloud@latest:
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -1608,15 +1673,23 @@ type-fest@^0.20.2:
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -1713,15 +1786,23 @@ __metadata:
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -1828,15 +1909,23 @@ __metadata:
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -2057,15 +2146,23 @@ __metadata:
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
@ -2436,15 +2533,23 @@ __metadata:
|
||||
dependencies: {},
|
||||
externalNodes,
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, pg);
|
||||
const ctx: CreateDependenciesContext = {
|
||||
projects: {},
|
||||
externalNodes,
|
||||
fileMap: {},
|
||||
filesToProcess: {},
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: '/virtual',
|
||||
};
|
||||
const dependencies = getYarnLockfileDependencies(lockFile, hash, ctx);
|
||||
|
||||
const builder = new ProjectGraphBuilder(pg);
|
||||
for (const dep of dependencies) {
|
||||
builder.addDependency(
|
||||
dep.source,
|
||||
dep.target,
|
||||
dep.dependencyType,
|
||||
dep.sourceFile
|
||||
dep.type,
|
||||
'sourceFile' in dep ? dep.sourceFile : null
|
||||
);
|
||||
}
|
||||
const graph = builder.getUpdatedProjectGraph();
|
||||
|
||||
@ -3,7 +3,7 @@ import {
|
||||
NormalizedPackageJson,
|
||||
} from './utils/package-json';
|
||||
import {
|
||||
ProjectGraphDependencyWithFile,
|
||||
RawProjectGraphDependency,
|
||||
validateDependency,
|
||||
} from '../../../project-graph/project-graph-builder';
|
||||
import { gt, Range, satisfies } from 'semver';
|
||||
@ -14,6 +14,7 @@ import {
|
||||
} from '../../../config/project-graph';
|
||||
import { hashArray } from '../../../hasher/file-hasher';
|
||||
import { sortObjectByKeys } from '../../../utils/object-sort';
|
||||
import { CreateDependenciesContext } from '../../../utils/nx-plugin';
|
||||
|
||||
/**
|
||||
* Yarn
|
||||
@ -79,7 +80,7 @@ export function getYarnLockfileNodes(
|
||||
export function getYarnLockfileDependencies(
|
||||
lockFileContent: string,
|
||||
lockFileHash: string,
|
||||
projectGraph: ProjectGraph
|
||||
ctx: CreateDependenciesContext
|
||||
) {
|
||||
const { __metadata, ...dependencies } = parseLockFile(
|
||||
lockFileContent,
|
||||
@ -91,7 +92,7 @@ export function getYarnLockfileDependencies(
|
||||
// yarn classic splits keys when parsing so we need to stich them back together
|
||||
const groupedDependencies = groupDependencies(dependencies, isBerry);
|
||||
|
||||
return getDependencies(groupedDependencies, keyMap, projectGraph);
|
||||
return getDependencies(groupedDependencies, keyMap, ctx);
|
||||
}
|
||||
|
||||
function getPackageNameKeyPairs(keys: string): Map<string, Set<string>> {
|
||||
@ -289,9 +290,9 @@ function getHoistedVersion(packageName: string): string {
|
||||
function getDependencies(
|
||||
dependencies: Record<string, YarnDependency>,
|
||||
keyMap: Map<string, ProjectGraphExternalNode>,
|
||||
projectGraph: ProjectGraph
|
||||
ctx: CreateDependenciesContext
|
||||
) {
|
||||
const projectGraphDependencies: ProjectGraphDependencyWithFile[] = [];
|
||||
const projectGraphDependencies: RawProjectGraphDependency[] = [];
|
||||
Object.keys(dependencies).forEach((keys) => {
|
||||
const snapshot = dependencies[keys];
|
||||
keys.split(', ').forEach((key) => {
|
||||
@ -305,12 +306,12 @@ function getDependencies(
|
||||
keyMap.get(`${name}@npm:${versionRange}`) ||
|
||||
keyMap.get(`${name}@${versionRange}`);
|
||||
if (target) {
|
||||
const dep = {
|
||||
const dep: RawProjectGraphDependency = {
|
||||
source: node.name,
|
||||
target: target.name,
|
||||
dependencyType: DependencyType.static,
|
||||
type: DependencyType.static,
|
||||
};
|
||||
validateDependency(projectGraph, dep);
|
||||
validateDependency(dep, ctx);
|
||||
projectGraphDependencies.push(dep);
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { buildExplicitTypeScriptDependencies } from './explicit-project-dependencies';
|
||||
import { buildExplicitPackageJsonDependencies } from './explicit-package-json-dependencies';
|
||||
import { CreateDependenciesContext } from '../../../../utils/nx-plugin';
|
||||
import { ProjectGraphDependencyWithFile } from '../../../../project-graph/project-graph-builder';
|
||||
import { RawProjectGraphDependency } from '../../../../project-graph/project-graph-builder';
|
||||
|
||||
export function buildExplicitDependencies(
|
||||
jsPluginConfig: {
|
||||
@ -9,10 +9,10 @@ export function buildExplicitDependencies(
|
||||
analyzePackageJson?: boolean;
|
||||
},
|
||||
ctx: CreateDependenciesContext
|
||||
): ProjectGraphDependencyWithFile[] {
|
||||
): RawProjectGraphDependency[] {
|
||||
if (totalNumberOfFilesToProcess(ctx) === 0) return [];
|
||||
|
||||
let dependencies: ProjectGraphDependencyWithFile[] = [];
|
||||
let dependencies: RawProjectGraphDependency[] = [];
|
||||
|
||||
if (
|
||||
jsPluginConfig.analyzeSourceFiles === undefined ||
|
||||
|
||||
@ -93,10 +93,11 @@ describe('explicit package json dependencies', () => {
|
||||
|
||||
ctx = {
|
||||
fileMap: projectFileMap,
|
||||
graph: builder.getUpdatedProjectGraph(),
|
||||
projectsConfigurations: projectsConfigurations as any,
|
||||
externalNodes: builder.getUpdatedProjectGraph().externalNodes,
|
||||
projects: projectsConfigurations.projects,
|
||||
nxJsonConfiguration,
|
||||
filesToProcess: projectFileMap,
|
||||
workspaceRoot: tempFs.tempDir,
|
||||
};
|
||||
});
|
||||
|
||||
@ -112,19 +113,19 @@ describe('explicit package json dependencies', () => {
|
||||
source: 'proj',
|
||||
target: 'proj2',
|
||||
sourceFile: 'libs/proj/package.json',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
sourceFile: 'libs/proj/package.json',
|
||||
source: 'proj',
|
||||
target: 'npm:external',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
source: 'proj',
|
||||
target: 'proj3',
|
||||
sourceFile: 'libs/proj/package.json',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@ -1,38 +1,34 @@
|
||||
import { defaultFileRead } from '../../../../project-graph/file-utils';
|
||||
import { join } from 'path';
|
||||
import {
|
||||
DependencyType,
|
||||
ProjectGraph,
|
||||
ProjectGraphProjectNode,
|
||||
} from '../../../../config/project-graph';
|
||||
import { DependencyType } from '../../../../config/project-graph';
|
||||
import { parseJson } from '../../../../utils/json';
|
||||
import { joinPathFragments } from '../../../../utils/path';
|
||||
import { ProjectsConfigurations } from '../../../../config/workspace-json-project-json';
|
||||
import {
|
||||
ProjectConfiguration,
|
||||
ProjectsConfigurations,
|
||||
} from '../../../../config/workspace-json-project-json';
|
||||
import { NxJsonConfiguration } from '../../../../config/nx-json';
|
||||
import { PackageJson } from '../../../../utils/package-json';
|
||||
import { CreateDependenciesContext } from '../../../../utils/nx-plugin';
|
||||
import {
|
||||
ProjectGraphDependencyWithFile,
|
||||
RawProjectGraphDependency,
|
||||
validateDependency,
|
||||
} from '../../../../project-graph/project-graph-builder';
|
||||
|
||||
export function buildExplicitPackageJsonDependencies({
|
||||
nxJsonConfiguration,
|
||||
projectsConfigurations,
|
||||
graph,
|
||||
filesToProcess,
|
||||
}: CreateDependenciesContext): ProjectGraphDependencyWithFile[] {
|
||||
const res: ProjectGraphDependencyWithFile[] = [];
|
||||
export function buildExplicitPackageJsonDependencies(
|
||||
ctx: CreateDependenciesContext
|
||||
): RawProjectGraphDependency[] {
|
||||
const res: RawProjectGraphDependency[] = [];
|
||||
let packageNameMap = undefined;
|
||||
const nodes = Object.values(graph.nodes);
|
||||
Object.keys(filesToProcess).forEach((source) => {
|
||||
Object.values(filesToProcess[source]).forEach((f) => {
|
||||
const nodes = Object.values(ctx.projects);
|
||||
Object.keys(ctx.filesToProcess).forEach((source) => {
|
||||
Object.values(ctx.filesToProcess[source]).forEach((f) => {
|
||||
if (isPackageJsonAtProjectRoot(nodes, f.file)) {
|
||||
// we only create the package name map once and only if a package.json file changes
|
||||
packageNameMap =
|
||||
packageNameMap ||
|
||||
createPackageNameMap(nxJsonConfiguration, projectsConfigurations);
|
||||
processPackageJson(source, f.file, graph, res, packageNameMap);
|
||||
createPackageNameMap(ctx.nxJsonConfiguration, ctx.projects);
|
||||
processPackageJson(source, f.file, ctx, res, packageNameMap);
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -41,18 +37,13 @@ export function buildExplicitPackageJsonDependencies({
|
||||
|
||||
function createPackageNameMap(
|
||||
nxJsonConfiguration: NxJsonConfiguration,
|
||||
projectsConfigurations: ProjectsConfigurations
|
||||
projects: ProjectsConfigurations['projects']
|
||||
) {
|
||||
const res = {};
|
||||
for (let projectName of Object.keys(projectsConfigurations.projects)) {
|
||||
for (let projectName of Object.keys(projects)) {
|
||||
try {
|
||||
const packageJson = parseJson(
|
||||
defaultFileRead(
|
||||
join(
|
||||
projectsConfigurations.projects[projectName].root,
|
||||
'package.json'
|
||||
)
|
||||
)
|
||||
defaultFileRead(join(projects[projectName].root, 'package.json'))
|
||||
);
|
||||
// TODO(v17): Stop reading nx.json for the npmScope
|
||||
const npmScope = nxJsonConfiguration.npmScope;
|
||||
@ -68,15 +59,14 @@ function createPackageNameMap(
|
||||
}
|
||||
|
||||
function isPackageJsonAtProjectRoot(
|
||||
nodes: ProjectGraphProjectNode[],
|
||||
nodes: ProjectConfiguration[],
|
||||
fileName: string
|
||||
) {
|
||||
return (
|
||||
fileName.endsWith('package.json') &&
|
||||
nodes.find(
|
||||
(projectNode) =>
|
||||
(projectNode.type === 'lib' || projectNode.type === 'app') &&
|
||||
joinPathFragments(projectNode.data.root, 'package.json') === fileName
|
||||
joinPathFragments(projectNode.root, 'package.json') === fileName
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -84,8 +74,8 @@ function isPackageJsonAtProjectRoot(
|
||||
function processPackageJson(
|
||||
sourceProject: string,
|
||||
fileName: string,
|
||||
graph: ProjectGraph,
|
||||
collectedDeps: ProjectGraphDependencyWithFile[],
|
||||
ctx: CreateDependenciesContext,
|
||||
collectedDeps: RawProjectGraphDependency[],
|
||||
packageNameMap: { [packageName: string]: string }
|
||||
) {
|
||||
try {
|
||||
@ -94,22 +84,22 @@ function processPackageJson(
|
||||
deps.forEach((d) => {
|
||||
// package.json refers to another project in the monorepo
|
||||
if (packageNameMap[d]) {
|
||||
const dependency = {
|
||||
const dependency: RawProjectGraphDependency = {
|
||||
source: sourceProject,
|
||||
target: packageNameMap[d],
|
||||
sourceFile: fileName,
|
||||
dependencyType: DependencyType.static,
|
||||
type: DependencyType.static,
|
||||
};
|
||||
validateDependency(graph, dependency);
|
||||
validateDependency(dependency, ctx);
|
||||
collectedDeps.push(dependency);
|
||||
} else if (graph.externalNodes[`npm:${d}`]) {
|
||||
const dependency = {
|
||||
} else if (ctx.externalNodes[`npm:${d}`]) {
|
||||
const dependency: RawProjectGraphDependency = {
|
||||
source: sourceProject,
|
||||
target: `npm:${d}`,
|
||||
sourceFile: fileName,
|
||||
dependencyType: DependencyType.static,
|
||||
type: DependencyType.static,
|
||||
};
|
||||
validateDependency(graph, dependency);
|
||||
validateDependency(dependency, ctx);
|
||||
collectedDeps.push(dependency);
|
||||
}
|
||||
});
|
||||
|
||||
@ -43,25 +43,25 @@ describe('explicit project dependencies', () => {
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.ts',
|
||||
target: 'proj2',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.ts',
|
||||
target: 'proj4ab',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.ts',
|
||||
target: 'npm:npm-package',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.ts',
|
||||
target: 'proj3a',
|
||||
dependencyType: 'dynamic',
|
||||
type: 'dynamic',
|
||||
},
|
||||
]);
|
||||
});
|
||||
@ -89,19 +89,19 @@ describe('explicit project dependencies', () => {
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.ts',
|
||||
target: 'proj2',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.ts',
|
||||
target: 'proj3a',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.ts',
|
||||
target: 'proj4ab',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
]);
|
||||
});
|
||||
@ -128,19 +128,19 @@ describe('explicit project dependencies', () => {
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.mts',
|
||||
target: 'proj2',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.mts',
|
||||
target: 'proj3a',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.mts',
|
||||
target: 'proj4ab',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
]);
|
||||
});
|
||||
@ -168,19 +168,19 @@ describe('explicit project dependencies', () => {
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.ts',
|
||||
target: 'proj2',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.ts',
|
||||
target: 'proj3a',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/index.ts',
|
||||
target: 'proj4ab',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
]);
|
||||
});
|
||||
@ -229,19 +229,19 @@ describe('explicit project dependencies', () => {
|
||||
source,
|
||||
sourceFile: 'libs/proj/component.tsx',
|
||||
target: 'proj2',
|
||||
dependencyType: 'dynamic',
|
||||
type: 'dynamic',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/nested-dynamic-import.ts',
|
||||
target: 'proj3a',
|
||||
dependencyType: 'dynamic',
|
||||
type: 'dynamic',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/nested-require.ts',
|
||||
target: 'proj4ab',
|
||||
dependencyType: 'static',
|
||||
type: 'static',
|
||||
},
|
||||
]);
|
||||
});
|
||||
@ -273,13 +273,13 @@ describe('explicit project dependencies', () => {
|
||||
source,
|
||||
sourceFile: 'libs/proj/absolute-path.ts',
|
||||
target: 'proj3a',
|
||||
dependencyType: 'dynamic',
|
||||
type: 'dynamic',
|
||||
},
|
||||
{
|
||||
source,
|
||||
sourceFile: 'libs/proj/relative-path.ts',
|
||||
target: 'proj4ab',
|
||||
dependencyType: 'dynamic',
|
||||
type: 'dynamic',
|
||||
},
|
||||
]);
|
||||
});
|
||||
@ -563,10 +563,11 @@ async function createContext(
|
||||
await retrieveWorkspaceFiles(tempFs.tempDir, nxJson);
|
||||
|
||||
return {
|
||||
graph: builder.getUpdatedProjectGraph(),
|
||||
projectsConfigurations: projectConfigurations,
|
||||
externalNodes: builder.getUpdatedProjectGraph().externalNodes,
|
||||
projects: projectConfigurations.projects,
|
||||
nxJsonConfiguration: nxJson,
|
||||
filesToProcess: projectFileMap,
|
||||
fileMap: projectFileMap,
|
||||
workspaceRoot: tempFs.tempDir,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,25 +1,32 @@
|
||||
import { TargetProjectLocator } from './target-project-locator';
|
||||
import { DependencyType, ProjectGraph } from '../../../../config/project-graph';
|
||||
import {
|
||||
DependencyType,
|
||||
ProjectGraphProjectNode,
|
||||
} from '../../../../config/project-graph';
|
||||
import { join, relative } from 'path';
|
||||
import { workspaceRoot } from '../../../../utils/workspace-root';
|
||||
import { normalizePath } from '../../../../utils/path';
|
||||
import { CreateDependenciesContext } from '../../../../utils/nx-plugin';
|
||||
import {
|
||||
ProjectGraphDependencyWithFile,
|
||||
RawProjectGraphDependency,
|
||||
validateDependency,
|
||||
} from '../../../../project-graph/project-graph-builder';
|
||||
import { ProjectConfiguration } from '../../../../config/workspace-json-project-json';
|
||||
|
||||
function isRoot(graph: ProjectGraph, projectName: string): boolean {
|
||||
return graph.nodes[projectName]?.data?.root === '.';
|
||||
function isRoot(
|
||||
projects: Record<string, ProjectConfiguration>,
|
||||
projectName: string
|
||||
): boolean {
|
||||
return projects[projectName]?.root === '.';
|
||||
}
|
||||
|
||||
function convertImportToDependency(
|
||||
importExpr: string,
|
||||
sourceFile: string,
|
||||
source: string,
|
||||
dependencyType: ProjectGraphDependencyWithFile['dependencyType'],
|
||||
type: RawProjectGraphDependency['type'],
|
||||
targetProjectLocator: TargetProjectLocator
|
||||
): ProjectGraphDependencyWithFile {
|
||||
): RawProjectGraphDependency {
|
||||
const target =
|
||||
targetProjectLocator.findProjectWithImport(importExpr, sourceFile) ??
|
||||
`npm:${importExpr}`;
|
||||
@ -28,19 +35,31 @@ function convertImportToDependency(
|
||||
source,
|
||||
target,
|
||||
sourceFile,
|
||||
dependencyType,
|
||||
type,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildExplicitTypeScriptDependencies({
|
||||
fileMap,
|
||||
graph,
|
||||
}: CreateDependenciesContext): ProjectGraphDependencyWithFile[] {
|
||||
const targetProjectLocator = new TargetProjectLocator(
|
||||
graph.nodes as any,
|
||||
graph.externalNodes
|
||||
export function buildExplicitTypeScriptDependencies(
|
||||
ctx: CreateDependenciesContext
|
||||
): RawProjectGraphDependency[] {
|
||||
// TODO: TargetProjectLocator is a public API, so we can't change the shape of it
|
||||
// We should eventually let it accept Record<string, ProjectConfiguration> s.t. we
|
||||
// don't have to reshape the CreateDependenciesContext here.
|
||||
const nodes: Record<string, ProjectGraphProjectNode> = Object.fromEntries(
|
||||
Object.entries(ctx.projects).map(([key, config]) => [
|
||||
key,
|
||||
{
|
||||
name: key,
|
||||
type: null,
|
||||
data: config,
|
||||
},
|
||||
])
|
||||
);
|
||||
const res: ProjectGraphDependencyWithFile[] = [];
|
||||
const targetProjectLocator = new TargetProjectLocator(
|
||||
nodes,
|
||||
ctx.externalNodes
|
||||
);
|
||||
const res: RawProjectGraphDependency[] = [];
|
||||
|
||||
const filesToProcess: Record<string, string[]> = {};
|
||||
|
||||
@ -51,7 +70,7 @@ export function buildExplicitTypeScriptDependencies({
|
||||
moduleExtensions.push('.vue');
|
||||
}
|
||||
|
||||
for (const [project, fileData] of Object.entries(fileMap)) {
|
||||
for (const [project, fileData] of Object.entries(ctx.fileMap)) {
|
||||
filesToProcess[project] ??= [];
|
||||
for (const { file } of fileData) {
|
||||
if (moduleExtensions.some((ext) => file.endsWith(ext))) {
|
||||
@ -81,8 +100,8 @@ export function buildExplicitTypeScriptDependencies({
|
||||
);
|
||||
// TODO: These edges technically should be allowed but we need to figure out how to separate config files out from root
|
||||
if (
|
||||
isRoot(graph, dependency.source) ||
|
||||
!isRoot(graph, dependency.target)
|
||||
isRoot(ctx.projects, dependency.source) ||
|
||||
!isRoot(ctx.projects, dependency.target)
|
||||
) {
|
||||
res.push(dependency);
|
||||
}
|
||||
@ -97,10 +116,10 @@ export function buildExplicitTypeScriptDependencies({
|
||||
);
|
||||
// TODO: These edges technically should be allowed but we need to figure out how to separate config files out from root
|
||||
if (
|
||||
isRoot(graph, dependency.source) ||
|
||||
!isRoot(graph, dependency.target)
|
||||
isRoot(ctx.projects, dependency.source) ||
|
||||
!isRoot(ctx.projects, dependency.target)
|
||||
) {
|
||||
validateDependency(graph, dependency);
|
||||
validateDependency(dependency, ctx);
|
||||
res.push(dependency);
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,15 +245,21 @@ async function updateProjectGraphWithPlugins(
|
||||
if (isNxPluginV2(plugin) && plugin.createDependencies) {
|
||||
const builder = new ProjectGraphBuilder(graph, context.fileMap);
|
||||
const newDependencies = await plugin.createDependencies({
|
||||
...context,
|
||||
graph,
|
||||
externalNodes: graph.externalNodes,
|
||||
fileMap: context.fileMap,
|
||||
filesToProcess: context.filesToProcess,
|
||||
nxJsonConfiguration: context.nxJsonConfiguration,
|
||||
projects: context.projectsConfigurations.projects,
|
||||
workspaceRoot: workspaceRoot,
|
||||
});
|
||||
for (const targetProjectDependency of newDependencies) {
|
||||
builder.addDependency(
|
||||
targetProjectDependency.source,
|
||||
targetProjectDependency.target,
|
||||
targetProjectDependency.dependencyType,
|
||||
targetProjectDependency.sourceFile
|
||||
targetProjectDependency.type,
|
||||
'sourceFile' in targetProjectDependency
|
||||
? targetProjectDependency.sourceFile
|
||||
: null
|
||||
);
|
||||
}
|
||||
graph = builder.getUpdatedProjectGraph();
|
||||
|
||||
@ -11,6 +11,8 @@ import {
|
||||
ProjectGraphExternalNode,
|
||||
ProjectGraphProjectNode,
|
||||
} from '../config/project-graph';
|
||||
import { ProjectConfiguration } from '../config/workspace-json-project-json';
|
||||
import { CreateDependenciesContext } from '../utils/nx-plugin';
|
||||
import { getProjectFileMap } from './build-project-graph';
|
||||
|
||||
/**
|
||||
@ -245,12 +247,23 @@ export class ProjectGraphBuilder {
|
||||
return;
|
||||
}
|
||||
|
||||
validateDependency(this.graph, {
|
||||
validateDependency(
|
||||
{
|
||||
source,
|
||||
target,
|
||||
dependencyType: type,
|
||||
type,
|
||||
sourceFile,
|
||||
});
|
||||
},
|
||||
{
|
||||
externalNodes: this.graph.externalNodes,
|
||||
fileMap: this.fileMap,
|
||||
// the validators only really care about the keys on this.
|
||||
projects: this.graph.nodes as any,
|
||||
filesToProcess: null,
|
||||
nxJsonConfiguration: null,
|
||||
workspaceRoot: null,
|
||||
}
|
||||
);
|
||||
|
||||
if (!this.graph.dependencies[source]) {
|
||||
this.graph.dependencies[source] = [];
|
||||
@ -260,20 +273,12 @@ export class ProjectGraphBuilder {
|
||||
);
|
||||
|
||||
if (sourceFile) {
|
||||
const sourceProject = this.graph.nodes[source];
|
||||
if (!sourceProject) {
|
||||
throw new Error(
|
||||
`Source project is not a project node: ${sourceProject}`
|
||||
const fileData = getFileData(
|
||||
source,
|
||||
sourceFile,
|
||||
this.graph.nodes,
|
||||
this.fileMap
|
||||
);
|
||||
}
|
||||
const fileData = (this.fileMap[source] || []).find(
|
||||
(f) => f.file === sourceFile
|
||||
);
|
||||
if (!fileData) {
|
||||
throw new Error(
|
||||
`Source project ${source} does not have a file: ${sourceFile}`
|
||||
);
|
||||
}
|
||||
|
||||
if (!fileData.deps) {
|
||||
fileData.deps = [];
|
||||
@ -369,80 +374,139 @@ export class ProjectGraphBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link ProjectGraph} dependency between 2 projects
|
||||
* Optional: Specifies a file from where the dependency is made
|
||||
* A static {@link ProjectGraph} dependency between 2 projects
|
||||
*
|
||||
* This type of dependency indicates the source project ALWAYS load the target project.
|
||||
*
|
||||
* NOTE: {@link StaticDependency#sourceFile} MUST be present unless the source is the name of a {@link ProjectGraphExternalNode}
|
||||
*/
|
||||
export interface ProjectGraphDependencyWithFile {
|
||||
export type StaticDependency = {
|
||||
/**
|
||||
* The name of a {@link ProjectGraphProjectNode} or {@link ProjectGraphExternalNode} depending on the target project
|
||||
*/
|
||||
source: string;
|
||||
|
||||
/**
|
||||
* The name of a {@link ProjectGraphProjectNode} or {@link ProjectGraphExternalNode} that the source project depends on
|
||||
*/
|
||||
target: string;
|
||||
|
||||
/**
|
||||
* The path of a file (relative from the workspace root) where the dependency is made
|
||||
*/
|
||||
sourceFile?: string;
|
||||
|
||||
type: typeof DependencyType.static;
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of dependency
|
||||
* A dynamic {@link ProjectGraph} dependency between 2 projects
|
||||
*
|
||||
* This type of dependency indicates the source project MAY OR MAY NOT load the target project.
|
||||
*/
|
||||
dependencyType: DependencyType;
|
||||
}
|
||||
export type DynamicDependency = {
|
||||
/**
|
||||
* The name of a {@link ProjectGraphProjectNode} depending on the target project
|
||||
*/
|
||||
source: string;
|
||||
|
||||
/**
|
||||
* The name of a {@link ProjectGraphProjectNode} that the source project depends on
|
||||
*/
|
||||
target: string;
|
||||
|
||||
/**
|
||||
* The path of a file (relative from the workspace root) where the dependency is made
|
||||
*/
|
||||
sourceFile: string;
|
||||
|
||||
type: typeof DependencyType.dynamic;
|
||||
};
|
||||
|
||||
/**
|
||||
* An implicit {@link ProjectGraph} dependency between 2 projects
|
||||
*
|
||||
* This type of dependency indicates a connection without an explicit reference in code
|
||||
*/
|
||||
export type ImplicitDependency = {
|
||||
/**
|
||||
* The name of a {@link ProjectGraphProjectNode} depending on the target project
|
||||
*/
|
||||
source: string;
|
||||
/**
|
||||
* The name of a {@link ProjectGraphProjectNode} that the source project depends on
|
||||
*/
|
||||
target: string;
|
||||
|
||||
type: typeof DependencyType.implicit;
|
||||
};
|
||||
|
||||
/**
|
||||
* A {@link ProjectGraph} dependency between 2 projects
|
||||
*
|
||||
* See {@link DynamicDependency}, {@link ImplicitDependency}, or {@link StaticDependency}
|
||||
*/
|
||||
export type RawProjectGraphDependency =
|
||||
| ImplicitDependency
|
||||
| StaticDependency
|
||||
| DynamicDependency;
|
||||
|
||||
/**
|
||||
* A function to validate dependencies in a {@link CreateDependencies} function
|
||||
* @throws If the dependency is invalid.
|
||||
*/
|
||||
export function validateDependency(
|
||||
graph: ProjectGraph,
|
||||
dependency: ProjectGraphDependencyWithFile
|
||||
dependency: RawProjectGraphDependency,
|
||||
ctx: CreateDependenciesContext
|
||||
): void {
|
||||
if (dependency.dependencyType === DependencyType.implicit) {
|
||||
validateImplicitDependency(graph, dependency);
|
||||
} else if (dependency.dependencyType === DependencyType.dynamic) {
|
||||
validateDynamicDependency(graph, dependency);
|
||||
} else if (dependency.dependencyType === DependencyType.static) {
|
||||
validateStaticDependency(graph, dependency);
|
||||
if (dependency.type === DependencyType.implicit) {
|
||||
validateImplicitDependency(dependency, ctx);
|
||||
} else if (dependency.type === DependencyType.dynamic) {
|
||||
validateDynamicDependency(dependency, ctx);
|
||||
} else if (dependency.type === DependencyType.static) {
|
||||
validateStaticDependency(dependency, ctx);
|
||||
}
|
||||
|
||||
validateCommonDependencyRules(graph, dependency);
|
||||
validateCommonDependencyRules(dependency, ctx);
|
||||
}
|
||||
|
||||
function validateCommonDependencyRules(
|
||||
graph: ProjectGraph,
|
||||
d: ProjectGraphDependencyWithFile
|
||||
d: RawProjectGraphDependency,
|
||||
{ externalNodes, projects, fileMap }: CreateDependenciesContext
|
||||
) {
|
||||
if (!graph.nodes[d.source] && !graph.externalNodes[d.source]) {
|
||||
if (!projects[d.source] && !externalNodes[d.source]) {
|
||||
throw new Error(`Source project does not exist: ${d.source}`);
|
||||
}
|
||||
if (
|
||||
!graph.nodes[d.target] &&
|
||||
!graph.externalNodes[d.target] &&
|
||||
!d.sourceFile
|
||||
!projects[d.target] &&
|
||||
!externalNodes[d.target] &&
|
||||
!('sourceFile' in d && d.sourceFile)
|
||||
) {
|
||||
throw new Error(`Target project does not exist: ${d.target}`);
|
||||
}
|
||||
if (graph.externalNodes[d.source] && graph.nodes[d.target]) {
|
||||
if (externalNodes[d.source] && projects[d.target]) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
function validateImplicitDependency(
|
||||
graph: ProjectGraph,
|
||||
d: ProjectGraphDependencyWithFile
|
||||
d: ImplicitDependency,
|
||||
{ externalNodes }: CreateDependenciesContext
|
||||
) {
|
||||
if (graph.externalNodes[d.source]) {
|
||||
if (externalNodes[d.source]) {
|
||||
throw new Error(`External projects can't have "implicit" dependencies`);
|
||||
}
|
||||
}
|
||||
|
||||
function validateDynamicDependency(
|
||||
graph: ProjectGraph,
|
||||
d: ProjectGraphDependencyWithFile
|
||||
d: DynamicDependency,
|
||||
{ externalNodes }: CreateDependenciesContext
|
||||
) {
|
||||
if (graph.externalNodes[d.source]) {
|
||||
if (externalNodes[d.source]) {
|
||||
throw new Error(`External projects can't have "dynamic" dependencies`);
|
||||
}
|
||||
// dynamic dependency is always bound to a file
|
||||
@ -454,12 +518,31 @@ function validateDynamicDependency(
|
||||
}
|
||||
|
||||
function validateStaticDependency(
|
||||
graph: ProjectGraph,
|
||||
d: ProjectGraphDependencyWithFile
|
||||
d: StaticDependency,
|
||||
{ projects }: CreateDependenciesContext
|
||||
) {
|
||||
// internal nodes must provide sourceProjectFile when creating static dependency
|
||||
// externalNodes do not have sourceProjectFile
|
||||
if (graph.nodes[d.source] && !d.sourceFile) {
|
||||
if (projects[d.source] && !d.sourceFile) {
|
||||
throw new Error(`Source project file is required`);
|
||||
}
|
||||
}
|
||||
|
||||
function getFileData(
|
||||
source: string,
|
||||
sourceFile: string,
|
||||
projects: Record<string, ProjectGraphProjectNode | ProjectConfiguration>,
|
||||
fileMap: ProjectFileMap
|
||||
) {
|
||||
const sourceProject = projects[source];
|
||||
if (!sourceProject) {
|
||||
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}`
|
||||
);
|
||||
}
|
||||
return fileData;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { existsSync } from 'fs';
|
||||
import * as path from 'path';
|
||||
import {
|
||||
FileData,
|
||||
ProjectFileMap,
|
||||
ProjectGraph,
|
||||
ProjectGraphExternalNode,
|
||||
@ -35,7 +36,7 @@ import { NxJsonConfiguration } from '../config/nx-json';
|
||||
import type * as ts from 'typescript';
|
||||
import { retrieveProjectConfigurationsWithoutPluginInference } from '../project-graph/utils/retrieve-workspace-files';
|
||||
import { NxPluginV1 } from './nx-plugin.deprecated';
|
||||
import { ProjectGraphDependencyWithFile } from '../project-graph/project-graph-builder';
|
||||
import { RawProjectGraphDependency } from '../project-graph/project-graph-builder';
|
||||
import { combineGlobPatterns } from './globs';
|
||||
import {
|
||||
NxAngularJsonPlugin,
|
||||
@ -77,14 +78,14 @@ export type CreateNodes = readonly [
|
||||
*/
|
||||
export interface CreateDependenciesContext {
|
||||
/**
|
||||
* The current project graph,
|
||||
* The external nodes that have been added to the graph.
|
||||
*/
|
||||
readonly graph: ProjectGraph;
|
||||
readonly externalNodes: ProjectGraph['externalNodes'];
|
||||
|
||||
/**
|
||||
* The configuration of each project in the workspace
|
||||
* The configuration of each project in the workspace.
|
||||
*/
|
||||
readonly projectsConfigurations: ProjectsConfigurations;
|
||||
readonly projects: Record<string, ProjectConfiguration>;
|
||||
|
||||
/**
|
||||
* The `nx.json` configuration from the workspace
|
||||
@ -100,6 +101,8 @@ export interface CreateDependenciesContext {
|
||||
* Files changes since last invocation
|
||||
*/
|
||||
readonly filesToProcess: ProjectFileMap;
|
||||
|
||||
readonly workspaceRoot: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,9 +111,7 @@ export interface CreateDependenciesContext {
|
||||
*/
|
||||
export type CreateDependencies = (
|
||||
context: CreateDependenciesContext
|
||||
) =>
|
||||
| ProjectGraphDependencyWithFile[]
|
||||
| Promise<ProjectGraphDependencyWithFile[]>;
|
||||
) => RawProjectGraphDependency[] | Promise<RawProjectGraphDependency[]>;
|
||||
|
||||
/**
|
||||
* A plugin for Nx which creates nodes and dependencies for the {@link ProjectGraph}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user