Skip to content

Commit

Permalink
feat(core): support for async createNodes functions
Browse files Browse the repository at this point in the history
  • Loading branch information
AgentEnder committed Nov 9, 2023
1 parent 6d080c8 commit d78c706
Show file tree
Hide file tree
Showing 23 changed files with 504 additions and 314 deletions.
9 changes: 9 additions & 0 deletions docs/generated/devkit/CreateNodesAsync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Type alias: CreateNodesAsync<T\>

Ƭ **CreateNodesAsync**<`T`\>: readonly [projectFilePattern: string, createNodesFunction: CreateNodesFunctionAsync<T\>]

#### Type parameters

| Name | Type |
| :--- | :-------- |
| `T` | `unknown` |
11 changes: 3 additions & 8 deletions docs/generated/devkit/CreateNodesFunction.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Type alias: CreateNodesFunction<T\>

Ƭ **CreateNodesFunction**<`T`\>: (`projectConfigurationFile`: `string`, `options`: `T` \| `undefined`, `context`: [`CreateNodesContext`](../../devkit/documents/CreateNodesContext)) => { `externalNodes?`: `Record`<`string`, [`ProjectGraphExternalNode`](../../devkit/documents/ProjectGraphExternalNode)\> ; `projects?`: `Record`<`string`, `Optional`<[`ProjectConfiguration`](../../devkit/documents/ProjectConfiguration), `"root"`\>\> }
Ƭ **CreateNodesFunction**<`T`\>: (`projectConfigurationFile`: `string`, `options`: `T` \| `undefined`, `context`: [`CreateNodesContext`](../../devkit/documents/CreateNodesContext)) => [`CreateNodesResult`](../../devkit/documents/CreateNodesResult)

#### Type parameters

Expand All @@ -10,7 +10,7 @@

#### Type declaration

▸ (`projectConfigurationFile`, `options`, `context`): `Object`
▸ (`projectConfigurationFile`, `options`, `context`): [`CreateNodesResult`](../../devkit/documents/CreateNodesResult)

A function which parses a configuration file into a set of nodes.
Used for creating nodes for the [ProjectGraph](../../devkit/documents/ProjectGraph)
Expand All @@ -25,9 +25,4 @@ Used for creating nodes for the [ProjectGraph](../../devkit/documents/ProjectGra

##### Returns

`Object`

| Name | Type | Description |
| :--------------- | :---------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------- |
| `externalNodes?` | `Record`<`string`, [`ProjectGraphExternalNode`](../../devkit/documents/ProjectGraphExternalNode)\> | A map of external node name -> external node. External nodes do not have a root, so the key is their name. |
| `projects?` | `Record`<`string`, `Optional`<[`ProjectConfiguration`](../../devkit/documents/ProjectConfiguration), `"root"`\>\> | A map of project root -> project configuration |
[`CreateNodesResult`](../../devkit/documents/CreateNodesResult)
24 changes: 24 additions & 0 deletions docs/generated/devkit/CreateNodesResult.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Interface: CreateNodesResult

## Table of contents

### Properties

- [externalNodes](../../devkit/documents/CreateNodesResult#externalnodes): Record&lt;string, ProjectGraphExternalNode&gt;
- [projects](../../devkit/documents/CreateNodesResult#projects): Record&lt;string, Optional&lt;ProjectConfiguration, &quot;root&quot;&gt;&gt;

## Properties

### externalNodes

`Optional` **externalNodes**: `Record`<`string`, [`ProjectGraphExternalNode`](../../devkit/documents/ProjectGraphExternalNode)\>

A map of external node name -> external node. External nodes do not have a root, so the key is their name.

---

### projects

`Optional` **projects**: `Record`<`string`, `Optional`<[`ProjectConfiguration`](../../devkit/documents/ProjectConfiguration), `"root"`\>\>

A map of project root -> project configuration
21 changes: 11 additions & 10 deletions docs/generated/devkit/NxPluginV2.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
# Type alias: NxPluginV2<T\>
# Type alias: NxPluginV2<TOptions, TCreateNodes\>

Ƭ **NxPluginV2**<`T`\>: `Object`
Ƭ **NxPluginV2**<`TOptions`, `TCreateNodes`\>: `Object`

A plugin for Nx which creates nodes and dependencies for the [ProjectGraph](../../devkit/documents/ProjectGraph)

#### Type parameters

| Name | Type |
| :--- | :-------- |
| `T` | `unknown` |
| Name | Type |
| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `TOptions` | `unknown` |
| `TCreateNodes` | extends [`CreateNodes`](../../devkit/documents/CreateNodes)<`TOptions`\> \| [`CreateNodesAsync`](../../devkit/documents/CreateNodesAsync)<`TOptions`\> = [`CreateNodes`](../../devkit/documents/CreateNodes)<`TOptions`\> \| [`CreateNodesAsync`](../../devkit/documents/CreateNodesAsync)<`TOptions`\> |

#### Type declaration

| Name | Type | Description |
| :-------------------- | :---------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------- |
| `createDependencies?` | [`CreateDependencies`](../../devkit/documents/CreateDependencies)<`T`\> | Provides a function to analyze files to create dependencies for the [ProjectGraph](../../devkit/documents/ProjectGraph) |
| `createNodes?` | [`CreateNodes`](../../devkit/documents/CreateNodes)<`T`\> | Provides a file pattern and function that retrieves configuration info from those files. e.g. { '\*_/_.csproj': buildProjectsFromCsProjFile } |
| `name` | `string` | - |
| Name | Type | Description |
| :-------------------- | :----------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------- |
| `createDependencies?` | [`CreateDependencies`](../../devkit/documents/CreateDependencies)<`TOptions`\> | Provides a function to analyze files to create dependencies for the [ProjectGraph](../../devkit/documents/ProjectGraph) |
| `createNodes?` | `TCreateNodes` | Provides a file pattern and function that retrieves configuration info from those files. e.g. { '\*_/_.csproj': buildProjectsFromCsProjFile } |
| `name` | `string` | - |
2 changes: 2 additions & 0 deletions docs/generated/devkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ It only uses language primitives and immutable objects

- [CreateDependenciesContext](../../devkit/documents/CreateDependenciesContext)
- [CreateNodesContext](../../devkit/documents/CreateNodesContext)
- [CreateNodesResult](../../devkit/documents/CreateNodesResult)
- [DefaultTasksRunnerOptions](../../devkit/documents/DefaultTasksRunnerOptions)
- [ExecutorContext](../../devkit/documents/ExecutorContext)
- [ExecutorsJson](../../devkit/documents/ExecutorsJson)
Expand Down Expand Up @@ -64,6 +65,7 @@ It only uses language primitives and immutable objects

- [CreateDependencies](../../devkit/documents/CreateDependencies)
- [CreateNodes](../../devkit/documents/CreateNodes)
- [CreateNodesAsync](../../devkit/documents/CreateNodesAsync)
- [CreateNodesFunction](../../devkit/documents/CreateNodesFunction)
- [CustomHasher](../../devkit/documents/CustomHasher)
- [DynamicDependency](../../devkit/documents/DynamicDependency)
Expand Down
2 changes: 2 additions & 0 deletions docs/generated/packages/devkit/documents/nx_devkit.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ It only uses language primitives and immutable objects

- [CreateDependenciesContext](../../devkit/documents/CreateDependenciesContext)
- [CreateNodesContext](../../devkit/documents/CreateNodesContext)
- [CreateNodesResult](../../devkit/documents/CreateNodesResult)
- [DefaultTasksRunnerOptions](../../devkit/documents/DefaultTasksRunnerOptions)
- [ExecutorContext](../../devkit/documents/ExecutorContext)
- [ExecutorsJson](../../devkit/documents/ExecutorsJson)
Expand Down Expand Up @@ -64,6 +65,7 @@ It only uses language primitives and immutable objects

- [CreateDependencies](../../devkit/documents/CreateDependencies)
- [CreateNodes](../../devkit/documents/CreateNodes)
- [CreateNodesAsync](../../devkit/documents/CreateNodesAsync)
- [CreateNodesFunction](../../devkit/documents/CreateNodesFunction)
- [CustomHasher](../../devkit/documents/CustomHasher)
- [DynamicDependency](../../devkit/documents/DynamicDependency)
Expand Down
2 changes: 1 addition & 1 deletion packages/nx/src/config/workspaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { dirname } from 'path';
import type { NxJsonConfiguration } from './nx-json';
import { readNxJson } from './nx-json';
import { ProjectsConfigurations } from './workspace-json-project-json';
import { retrieveProjectConfigurationsSync } from '../project-graph/utils/retrieve-workspace-files';
import { retrieveProjectConfigurationsSync } from '../project-graph/utils/retrieve-workspace-files.deprecated';

// TODO(v18): remove this class
/**
Expand Down
2 changes: 2 additions & 0 deletions packages/nx/src/devkit-exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ export type {
NxPluginV2,
ProjectTargetConfigurator,
CreateNodes,
CreateNodesAsync,
CreateNodesFunction,
CreateNodesResult,
CreateNodesContext,
CreateDependencies,
CreateDependenciesContext,
Expand Down
4 changes: 2 additions & 2 deletions packages/nx/src/native/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ export class Watcher {
export class WorkspaceContext {
workspaceRoot: string
constructor(workspaceRoot: string)
getWorkspaceFiles(globs: Array<string>, parseConfigurations: (arg0: Array<string>) => Promise<ConfigurationParserResult>): object | null
getWorkspaceFiles(globs: Array<string>, parseConfigurations: (arg0: Array<string>) => Promise<ConfigurationParserResult>): Promise<NxWorkspaceFiles>
glob(globs: Array<string>): Array<string>
getProjectConfigurations(globs: Array<string>, parseConfigurations: (arg0: Array<string>) => Promise<ConfigurationParserResult>): object
getProjectConfigurations(globs: Array<string>, parseConfigurations: (arg0: Array<string>) => Promise<ConfigurationParserResult>): Promise<ConfigurationParserResult>
incrementalUpdate(updatedFiles: Array<string>, deletedFiles: Array<string>): Record<string, string>
allFileData(): Array<FileData>
}
204 changes: 102 additions & 102 deletions packages/nx/src/native/tests/workspace_files.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,108 +163,108 @@ describe('workspace files', () => {
`);
});

// it('should assign files to the root project if it exists', async () => {
// const fs = new TempFs('workspace-files');
// const nxJson: NxJsonConfiguration = {};
// await fs.createFiles({
// './nx.json': JSON.stringify(nxJson),
// './package.json': JSON.stringify({
// name: 'repo-name',
// version: '0.0.0',
// dependencies: {},
// }),
// './project.json': JSON.stringify({
// name: 'repo-name',
// }),
// './src/index.js': '',
// './jest.config.js': '',
// });
//
// const context = new WorkspaceContext(fs.tempDir);
//
// const globs = ['project.json', '**/project.json', '**/package.json'];
// const { globalFiles, projectFileMap } = context.getWorkspaceFiles(
// globs,
// createParseConfigurationsFunction(fs.tempDir)
// );
//
// expect(globalFiles).toEqual([]);
// expect(projectFileMap['repo-name']).toMatchInlineSnapshot(`
// [
// {
// "file": "jest.config.js",
// "hash": "3244421341483603138",
// },
// {
// "file": "nx.json",
// "hash": "1389868326933519382",
// },
// {
// "file": "package.json",
// "hash": "14409636362330144230",
// },
// {
// "file": "project.json",
// "hash": "4357927788053707201",
// },
// {
// "file": "src/index.js",
// "hash": "3244421341483603138",
// },
// ]
// `);
// });
//
// it('should dedupe configuration files', async () => {
// const fs = new TempFs('workspace-files');
// const nxJson: NxJsonConfiguration = {};
// await fs.createFiles({
// './nx.json': JSON.stringify(nxJson),
// './package.json': JSON.stringify({
// name: 'repo-name',
// version: '0.0.0',
// dependencies: {},
// }),
// './project.json': JSON.stringify({
// name: 'repo-name',
// }),
// './libs/project1/project.json': JSON.stringify({
// name: 'project1',
// }),
// './libs/project1/package.json': JSON.stringify({
// name: 'project1',
// }),
// './libs/project1/index.js': '',
// });
//
// const context = new WorkspaceContext(fs.tempDir);
// let globs = ['project.json', '**/project.json', '**/package.json'];
//
// let nodes = context.getProjectConfigurations(globs, (filenames) => {
// const res = {};
// for (const filename of filenames) {
// const json = readJsonFile(join(fs.tempDir, filename));
// res[json.name] = {
// ...json,
// root: dirname(filename),
// };
// }
// return {
// externalNodes: {},
// projectNodes: res,
// };
// });
// expect(nodes.projectNodes).toEqual({
// project1: {
// name: 'project1',
// root: 'libs/project1',
// },
// 'repo-name': expect.objectContaining({
// name: 'repo-name',
// root: '.',
// }),
// });
// });
it('should assign files to the root project if it exists', async () => {
const fs = new TempFs('workspace-files');
const nxJson: NxJsonConfiguration = {};
await fs.createFiles({
'./nx.json': JSON.stringify(nxJson),
'./package.json': JSON.stringify({
name: 'repo-name',
version: '0.0.0',
dependencies: {},
}),
'./project.json': JSON.stringify({
name: 'repo-name',
}),
'./src/index.js': '',
'./jest.config.js': '',
});

const context = new WorkspaceContext(fs.tempDir);

const globs = ['project.json', '**/project.json', '**/package.json'];
const { globalFiles, projectFileMap } = await context.getWorkspaceFiles(
globs,
createParseConfigurationsFunction(fs.tempDir)
);

expect(globalFiles).toEqual([]);
expect(projectFileMap['repo-name']).toMatchInlineSnapshot(`
[
{
"file": "jest.config.js",
"hash": "3244421341483603138",
},
{
"file": "nx.json",
"hash": "1389868326933519382",
},
{
"file": "package.json",
"hash": "14409636362330144230",
},
{
"file": "project.json",
"hash": "4357927788053707201",
},
{
"file": "src/index.js",
"hash": "3244421341483603138",
},
]
`);
});

it('should dedupe configuration files', async () => {
const fs = new TempFs('workspace-files');
const nxJson: NxJsonConfiguration = {};
await fs.createFiles({
'./nx.json': JSON.stringify(nxJson),
'./package.json': JSON.stringify({
name: 'repo-name',
version: '0.0.0',
dependencies: {},
}),
'./project.json': JSON.stringify({
name: 'repo-name',
}),
'./libs/project1/project.json': JSON.stringify({
name: 'project1',
}),
'./libs/project1/package.json': JSON.stringify({
name: 'project1',
}),
'./libs/project1/index.js': '',
});

const context = new WorkspaceContext(fs.tempDir);
let globs = ['project.json', '**/project.json', '**/package.json'];

let nodes = await context.getProjectConfigurations(globs, async (filenames) => {
const res = {};
for (const filename of filenames) {
const json = readJsonFile(join(fs.tempDir, filename));
res[json.name] = {
...json,
root: dirname(filename),
};
}
return {
externalNodes: {},
projectNodes: res,
};
});
expect(nodes.projectNodes).toEqual({
project1: {
name: 'project1',
root: 'libs/project1',
},
'repo-name': expect.objectContaining({
name: 'repo-name',
root: '.',
}),
});
});

// describe('errors', () => {
// it('it should infer names of configuration files without a name', async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/nx/src/native/workspace/config_files.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::native::utils::glob::build_glob_set;
use crate::native::utils::path::Normalize;
use crate::native::workspace::types::ConfigurationParserResult;
use napi::bindgen_prelude::{Object, Promise};
use napi::bindgen_prelude::Promise;

use crate::native::workspace::errors::{InternalWorkspaceErrors, WorkspaceErrors};
use rayon::prelude::*;
Expand Down
Loading

0 comments on commit d78c706

Please sign in to comment.