@nx/devkit 19.0.0-canary.20240423-b37bfdb → 19.0.0-canary.20240425-cec57c4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/generators/plugin-migrations/executor-to-plugin-migrator.d.ts +9 -0
- package/src/generators/plugin-migrations/executor-to-plugin-migrator.js +197 -0
- package/src/generators/plugin-migrations/plugin-migration-utils.d.ts +54 -0
- package/src/generators/plugin-migrations/plugin-migration-utils.js +78 -0
- package/src/utils/add-plugin.js +3 -1
- package/src/utils/convert-nx-executor.js +17 -2
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@nx/devkit",
|
3
|
-
"version": "19.0.0-canary.
|
3
|
+
"version": "19.0.0-canary.20240425-cec57c4",
|
4
4
|
"private": false,
|
5
5
|
"description": "The Nx Devkit is used to customize Nx for different technologies and use cases. It contains many utility functions for reading and writing files, updating configuration, working with Abstract Syntax Trees(ASTs), and more. Learn more about [extending Nx by leveraging the Nx Devkit](https://nx.dev/extending-nx/intro/getting-started) on our docs.",
|
6
6
|
"repository": {
|
@@ -35,7 +35,8 @@
|
|
35
35
|
"tslib": "^2.3.0",
|
36
36
|
"semver": "^7.5.3",
|
37
37
|
"yargs-parser": "21.1.1",
|
38
|
-
"
|
38
|
+
"minimatch": "9.0.3",
|
39
|
+
"@nrwl/devkit": "19.0.0-canary.20240425-cec57c4"
|
39
40
|
},
|
40
41
|
"peerDependencies": {
|
41
42
|
"nx": ">= 16 <= 19"
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import type { TargetConfiguration } from 'nx/src/config/workspace-json-project-json';
|
2
|
+
import type { Tree } from 'nx/src/generators/tree';
|
3
|
+
import type { CreateNodes } from 'nx/src/project-graph/plugins';
|
4
|
+
import type { ProjectGraph } from 'nx/src/config/project-graph';
|
5
|
+
type PluginOptionsBuilder<T> = (targetName: string) => T;
|
6
|
+
type PostTargetTransformer = (targetConfiguration: TargetConfiguration) => TargetConfiguration;
|
7
|
+
type SkipTargetFilter = (targetConfiguration: TargetConfiguration) => [boolean, string];
|
8
|
+
export declare function migrateExecutorToPlugin<T>(tree: Tree, projectGraph: ProjectGraph, executor: string, pluginPath: string, pluginOptionsBuilder: PluginOptionsBuilder<T>, postTargetTransformer: PostTargetTransformer, createNodes: CreateNodes<T>, specificProjectToMigrate?: string, skipTargetFilter?: SkipTargetFilter): Promise<void>;
|
9
|
+
export {};
|
@@ -0,0 +1,197 @@
|
|
1
|
+
"use strict";
|
2
|
+
var _ExecutorToPluginMigrator_instances, _ExecutorToPluginMigrator_projectGraph, _ExecutorToPluginMigrator_executor, _ExecutorToPluginMigrator_pluginPath, _ExecutorToPluginMigrator_pluginOptionsBuilder, _ExecutorToPluginMigrator_postTargetTransformer, _ExecutorToPluginMigrator_skipTargetFilter, _ExecutorToPluginMigrator_specificProjectToMigrate, _ExecutorToPluginMigrator_nxJson, _ExecutorToPluginMigrator_targetDefaultsForExecutor, _ExecutorToPluginMigrator_targetAndProjectsToMigrate, _ExecutorToPluginMigrator_pluginToAddForTarget, _ExecutorToPluginMigrator_createNodes, _ExecutorToPluginMigrator_configFiles, _ExecutorToPluginMigrator_createNodesResultsForTargets, _ExecutorToPluginMigrator_init, _ExecutorToPluginMigrator_migrateTarget, _ExecutorToPluginMigrator_migrateProject, _ExecutorToPluginMigrator_addPlugins, _ExecutorToPluginMigrator_getTargetAndProjectsToMigrate, _ExecutorToPluginMigrator_getTargetDefaultsForExecutor, _ExecutorToPluginMigrator_getCreatedTargetForProjectRoot, _ExecutorToPluginMigrator_getCreateNodesResults;
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
4
|
+
exports.migrateExecutorToPlugin = void 0;
|
5
|
+
const tslib_1 = require("tslib");
|
6
|
+
const minimatch_1 = require("minimatch");
|
7
|
+
const executor_options_utils_1 = require("../executor-options-utils");
|
8
|
+
const plugin_migration_utils_1 = require("./plugin-migration-utils");
|
9
|
+
const nx_1 = require("../../../nx");
|
10
|
+
const { glob, readNxJson, updateNxJson, mergeTargetConfigurations, updateProjectConfiguration, readProjectConfiguration, retrieveProjectConfigurations, LoadedNxPlugin, ProjectConfigurationsError, } = (0, nx_1.requireNx)();
|
11
|
+
class ExecutorToPluginMigrator {
|
12
|
+
constructor(tree, projectGraph, executor, pluginPath, pluginOptionsBuilder, postTargetTransformer, createNodes, specificProjectToMigrate, skipTargetFilter) {
|
13
|
+
_ExecutorToPluginMigrator_instances.add(this);
|
14
|
+
_ExecutorToPluginMigrator_projectGraph.set(this, void 0);
|
15
|
+
_ExecutorToPluginMigrator_executor.set(this, void 0);
|
16
|
+
_ExecutorToPluginMigrator_pluginPath.set(this, void 0);
|
17
|
+
_ExecutorToPluginMigrator_pluginOptionsBuilder.set(this, void 0);
|
18
|
+
_ExecutorToPluginMigrator_postTargetTransformer.set(this, void 0);
|
19
|
+
_ExecutorToPluginMigrator_skipTargetFilter.set(this, void 0);
|
20
|
+
_ExecutorToPluginMigrator_specificProjectToMigrate.set(this, void 0);
|
21
|
+
_ExecutorToPluginMigrator_nxJson.set(this, void 0);
|
22
|
+
_ExecutorToPluginMigrator_targetDefaultsForExecutor.set(this, void 0);
|
23
|
+
_ExecutorToPluginMigrator_targetAndProjectsToMigrate.set(this, void 0);
|
24
|
+
_ExecutorToPluginMigrator_pluginToAddForTarget.set(this, void 0);
|
25
|
+
_ExecutorToPluginMigrator_createNodes.set(this, void 0);
|
26
|
+
_ExecutorToPluginMigrator_configFiles.set(this, void 0);
|
27
|
+
_ExecutorToPluginMigrator_createNodesResultsForTargets.set(this, void 0);
|
28
|
+
this.tree = tree;
|
29
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_projectGraph, projectGraph, "f");
|
30
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_executor, executor, "f");
|
31
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_pluginPath, pluginPath, "f");
|
32
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_pluginOptionsBuilder, pluginOptionsBuilder, "f");
|
33
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_postTargetTransformer, postTargetTransformer, "f");
|
34
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_createNodes, createNodes, "f");
|
35
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_specificProjectToMigrate, specificProjectToMigrate, "f");
|
36
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_skipTargetFilter, skipTargetFilter ?? ((...args) => [false, '']), "f");
|
37
|
+
}
|
38
|
+
async run() {
|
39
|
+
await tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_instances, "m", _ExecutorToPluginMigrator_init).call(this);
|
40
|
+
for (const targetName of tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_targetAndProjectsToMigrate, "f").keys()) {
|
41
|
+
tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_instances, "m", _ExecutorToPluginMigrator_migrateTarget).call(this, targetName);
|
42
|
+
}
|
43
|
+
tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_instances, "m", _ExecutorToPluginMigrator_addPlugins).call(this);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
_ExecutorToPluginMigrator_projectGraph = new WeakMap(), _ExecutorToPluginMigrator_executor = new WeakMap(), _ExecutorToPluginMigrator_pluginPath = new WeakMap(), _ExecutorToPluginMigrator_pluginOptionsBuilder = new WeakMap(), _ExecutorToPluginMigrator_postTargetTransformer = new WeakMap(), _ExecutorToPluginMigrator_skipTargetFilter = new WeakMap(), _ExecutorToPluginMigrator_specificProjectToMigrate = new WeakMap(), _ExecutorToPluginMigrator_nxJson = new WeakMap(), _ExecutorToPluginMigrator_targetDefaultsForExecutor = new WeakMap(), _ExecutorToPluginMigrator_targetAndProjectsToMigrate = new WeakMap(), _ExecutorToPluginMigrator_pluginToAddForTarget = new WeakMap(), _ExecutorToPluginMigrator_createNodes = new WeakMap(), _ExecutorToPluginMigrator_configFiles = new WeakMap(), _ExecutorToPluginMigrator_createNodesResultsForTargets = new WeakMap(), _ExecutorToPluginMigrator_instances = new WeakSet(), _ExecutorToPluginMigrator_init = async function _ExecutorToPluginMigrator_init() {
|
47
|
+
const nxJson = readNxJson(this.tree);
|
48
|
+
nxJson.plugins ??= [];
|
49
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_nxJson, nxJson, "f");
|
50
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_targetAndProjectsToMigrate, new Map(), "f");
|
51
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_pluginToAddForTarget, new Map(), "f");
|
52
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_createNodesResultsForTargets, new Map(), "f");
|
53
|
+
tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_instances, "m", _ExecutorToPluginMigrator_getTargetDefaultsForExecutor).call(this);
|
54
|
+
tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_instances, "m", _ExecutorToPluginMigrator_getTargetAndProjectsToMigrate).call(this);
|
55
|
+
await tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_instances, "m", _ExecutorToPluginMigrator_getCreateNodesResults).call(this);
|
56
|
+
}, _ExecutorToPluginMigrator_migrateTarget = function _ExecutorToPluginMigrator_migrateTarget(targetName) {
|
57
|
+
const include = [];
|
58
|
+
for (const projectName of tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_targetAndProjectsToMigrate, "f").get(targetName)) {
|
59
|
+
include.push(tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_instances, "m", _ExecutorToPluginMigrator_migrateProject).call(this, projectName, targetName));
|
60
|
+
}
|
61
|
+
tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_pluginToAddForTarget, "f").set(targetName, {
|
62
|
+
plugin: tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_pluginPath, "f"),
|
63
|
+
options: tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_pluginOptionsBuilder, "f").call(this, targetName),
|
64
|
+
include,
|
65
|
+
});
|
66
|
+
}, _ExecutorToPluginMigrator_migrateProject = function _ExecutorToPluginMigrator_migrateProject(projectName, targetName) {
|
67
|
+
const projectFromGraph = tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_projectGraph, "f").nodes[projectName];
|
68
|
+
const projectConfig = readProjectConfiguration(this.tree, projectName);
|
69
|
+
const createdTarget = tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_instances, "m", _ExecutorToPluginMigrator_getCreatedTargetForProjectRoot).call(this, targetName, projectFromGraph.data.root);
|
70
|
+
let projectTarget = projectConfig.targets[targetName];
|
71
|
+
projectTarget = mergeTargetConfigurations(projectTarget, tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_targetDefaultsForExecutor, "f"));
|
72
|
+
delete projectTarget.executor;
|
73
|
+
(0, plugin_migration_utils_1.deleteMatchingProperties)(projectTarget, createdTarget);
|
74
|
+
projectTarget = tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_postTargetTransformer, "f").call(this, projectTarget);
|
75
|
+
if (projectTarget.options &&
|
76
|
+
Object.keys(projectTarget.options).length === 0) {
|
77
|
+
delete projectTarget.options;
|
78
|
+
}
|
79
|
+
if (Object.keys(projectTarget).length > 0) {
|
80
|
+
projectConfig.targets[targetName] = projectTarget;
|
81
|
+
}
|
82
|
+
else {
|
83
|
+
delete projectConfig.targets[targetName];
|
84
|
+
}
|
85
|
+
updateProjectConfiguration(this.tree, projectName, projectConfig);
|
86
|
+
return `${projectFromGraph.data.root}/**/*`;
|
87
|
+
}, _ExecutorToPluginMigrator_addPlugins = function _ExecutorToPluginMigrator_addPlugins() {
|
88
|
+
for (const [targetName, plugin] of tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_pluginToAddForTarget, "f").entries()) {
|
89
|
+
const pluginOptions = tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_pluginOptionsBuilder, "f").call(this, targetName);
|
90
|
+
const existingPlugin = tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_nxJson, "f").plugins.find((plugin) => {
|
91
|
+
if (typeof plugin === 'string' ||
|
92
|
+
plugin.plugin !== tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_pluginPath, "f")) {
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
for (const key in plugin.options) {
|
96
|
+
if (plugin.options[key] !== pluginOptions[key]) {
|
97
|
+
return false;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
return true;
|
101
|
+
});
|
102
|
+
if (existingPlugin?.include) {
|
103
|
+
for (const pluginIncludes of existingPlugin.include) {
|
104
|
+
for (const projectPath of plugin.include) {
|
105
|
+
if (!(0, minimatch_1.minimatch)(projectPath, pluginIncludes, { dot: true })) {
|
106
|
+
existingPlugin.include.push(projectPath);
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
const allConfigFilesAreIncluded = tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_configFiles, "f").every((configFile) => {
|
111
|
+
for (const includePattern of existingPlugin.include) {
|
112
|
+
if ((0, minimatch_1.minimatch)(configFile, includePattern, { dot: true })) {
|
113
|
+
return true;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
return false;
|
117
|
+
});
|
118
|
+
if (allConfigFilesAreIncluded) {
|
119
|
+
existingPlugin.include = undefined;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
if (!existingPlugin) {
|
123
|
+
tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_nxJson, "f").plugins.push(plugin);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
updateNxJson(this.tree, tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_nxJson, "f"));
|
127
|
+
}, _ExecutorToPluginMigrator_getTargetAndProjectsToMigrate = function _ExecutorToPluginMigrator_getTargetAndProjectsToMigrate() {
|
128
|
+
(0, executor_options_utils_1.forEachExecutorOptions)(this.tree, tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_executor, "f"), (targetConfiguration, projectName, targetName, configurationName) => {
|
129
|
+
if (configurationName) {
|
130
|
+
return;
|
131
|
+
}
|
132
|
+
if (tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_specificProjectToMigrate, "f") &&
|
133
|
+
projectName !== tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_specificProjectToMigrate, "f")) {
|
134
|
+
return;
|
135
|
+
}
|
136
|
+
const [skipTarget, reasonTargetWasSkipped] = tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_skipTargetFilter, "f").call(this, targetConfiguration);
|
137
|
+
if (skipTarget) {
|
138
|
+
const errorMsg = `${targetName} target on project "${projectName}" cannot be migrated. ${reasonTargetWasSkipped}`;
|
139
|
+
if (tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_specificProjectToMigrate, "f")) {
|
140
|
+
throw new Error(errorMsg);
|
141
|
+
}
|
142
|
+
else {
|
143
|
+
console.warn(errorMsg);
|
144
|
+
}
|
145
|
+
return;
|
146
|
+
}
|
147
|
+
if (tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_targetAndProjectsToMigrate, "f").has(targetName)) {
|
148
|
+
tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_targetAndProjectsToMigrate, "f").get(targetName).add(projectName);
|
149
|
+
}
|
150
|
+
else {
|
151
|
+
tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_targetAndProjectsToMigrate, "f").set(targetName, new Set([projectName]));
|
152
|
+
}
|
153
|
+
});
|
154
|
+
if (tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_targetAndProjectsToMigrate, "f").size === 0) {
|
155
|
+
const errorMsg = tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_specificProjectToMigrate, "f")
|
156
|
+
? `Project "${tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_specificProjectToMigrate, "f")}" does not contain any targets using the "${tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_executor, "f")}" executor. Please select a project that does.`
|
157
|
+
: `Could not find any targets using the "${tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_executor, "f")}" executor.`;
|
158
|
+
throw new Error(errorMsg);
|
159
|
+
}
|
160
|
+
}, _ExecutorToPluginMigrator_getTargetDefaultsForExecutor = function _ExecutorToPluginMigrator_getTargetDefaultsForExecutor() {
|
161
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_targetDefaultsForExecutor, tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_nxJson, "f").targetDefaults?.[tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_executor, "f")], "f");
|
162
|
+
}, _ExecutorToPluginMigrator_getCreatedTargetForProjectRoot = function _ExecutorToPluginMigrator_getCreatedTargetForProjectRoot(targetName, projectRoot) {
|
163
|
+
const createdProject = Object.entries(tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_createNodesResultsForTargets, "f").get(targetName)?.projects ?? {}).find(([root]) => root === projectRoot)[1];
|
164
|
+
const createdTarget = createdProject.targets[targetName];
|
165
|
+
delete createdTarget.command;
|
166
|
+
delete createdTarget.options?.cwd;
|
167
|
+
return createdTarget;
|
168
|
+
}, _ExecutorToPluginMigrator_getCreateNodesResults = async function _ExecutorToPluginMigrator_getCreateNodesResults() {
|
169
|
+
for (const targetName of tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_targetAndProjectsToMigrate, "f").keys()) {
|
170
|
+
const loadedPlugin = new LoadedNxPlugin({
|
171
|
+
createNodes: tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_createNodes, "f"),
|
172
|
+
name: tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_pluginPath, "f"),
|
173
|
+
}, {
|
174
|
+
plugin: tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_pluginPath, "f"),
|
175
|
+
options: tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_pluginOptionsBuilder, "f").call(this, targetName),
|
176
|
+
});
|
177
|
+
let projectConfigs;
|
178
|
+
try {
|
179
|
+
projectConfigs = await retrieveProjectConfigurations([loadedPlugin], this.tree.root, tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_nxJson, "f"));
|
180
|
+
}
|
181
|
+
catch (e) {
|
182
|
+
if (e instanceof ProjectConfigurationsError) {
|
183
|
+
projectConfigs = e.partialProjectConfigurationsResult;
|
184
|
+
}
|
185
|
+
else {
|
186
|
+
throw e;
|
187
|
+
}
|
188
|
+
}
|
189
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_configFiles, Array.from(projectConfigs.matchingProjectFiles), "f");
|
190
|
+
tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_createNodesResultsForTargets, "f").set(targetName, projectConfigs);
|
191
|
+
}
|
192
|
+
};
|
193
|
+
async function migrateExecutorToPlugin(tree, projectGraph, executor, pluginPath, pluginOptionsBuilder, postTargetTransformer, createNodes, specificProjectToMigrate, skipTargetFilter) {
|
194
|
+
const migrator = new ExecutorToPluginMigrator(tree, projectGraph, executor, pluginPath, pluginOptionsBuilder, postTargetTransformer, createNodes, specificProjectToMigrate, skipTargetFilter);
|
195
|
+
await migrator.run();
|
196
|
+
}
|
197
|
+
exports.migrateExecutorToPlugin = migrateExecutorToPlugin;
|
@@ -0,0 +1,54 @@
|
|
1
|
+
/**
|
2
|
+
* Iterate through the current target in the project.json and its options comparing it to the target created by the Plugin itself
|
3
|
+
* Delete matching properties from current target.
|
4
|
+
*
|
5
|
+
* _Note: Deletes by reference_
|
6
|
+
*
|
7
|
+
* @example
|
8
|
+
* // Run the plugin to get all the projects
|
9
|
+
* const { projects } = await createNodes[1](
|
10
|
+
* playwrightConfigPath,
|
11
|
+
* { targetName, ciTargetName: 'e2e-ci' },
|
12
|
+
* { workspaceRoot: tree.root, nxJsonConfiguration, configFiles }
|
13
|
+
* );
|
14
|
+
*
|
15
|
+
* // Find the project that matches the one that is being migrated
|
16
|
+
* const createdProject = Object.entries(projects ?? {}).find(
|
17
|
+
* ([root]) => root === projectFromGraph.data.root
|
18
|
+
* )[1];
|
19
|
+
*
|
20
|
+
* // Get the created TargetConfiguration for the target being migrated
|
21
|
+
* const createdTarget: TargetConfiguration<RunCommandsOptions> =
|
22
|
+
* createdProject.targets[targetName];
|
23
|
+
*
|
24
|
+
* // Delete specific run-commands options
|
25
|
+
* delete createdTarget.command;
|
26
|
+
* delete createdTarget.options?.cwd;
|
27
|
+
*
|
28
|
+
* // Get the TargetConfiguration for the target being migrated from project.json
|
29
|
+
* const projectConfig = readProjectConfiguration(tree, projectName);
|
30
|
+
* let targetToMigrate = projectConfig.targets[targetName];
|
31
|
+
*
|
32
|
+
* // Merge the target defaults for the executor to the target being migrated
|
33
|
+
* target = mergeTargetConfigurations(targetToMigrate, targetDefaultsForExecutor);
|
34
|
+
*
|
35
|
+
* // Delete executor and any additional options that are no longer necessary
|
36
|
+
* delete target.executor;
|
37
|
+
* delete target.options?.config;
|
38
|
+
*
|
39
|
+
* // Run deleteMatchingProperties to delete further options that match what the plugin creates
|
40
|
+
* deleteMatchingProperties(target, createdTarget);
|
41
|
+
*
|
42
|
+
* // Delete the target if it is now empty, otherwise, set it to the updated TargetConfiguration
|
43
|
+
* if (Object.keys(target).length > 0) {
|
44
|
+
* projectConfig.targets[targetName] = target;
|
45
|
+
* } else {
|
46
|
+
* delete projectConfig.targets[targetName];
|
47
|
+
* }
|
48
|
+
*
|
49
|
+
* updateProjectConfiguration(tree, projectName, projectConfig);
|
50
|
+
*
|
51
|
+
* @param targetToMigrate The target from project.json
|
52
|
+
* @param createdTarget The target created by the Plugin
|
53
|
+
*/
|
54
|
+
export declare function deleteMatchingProperties(targetToMigrate: object, createdTarget: object): void;
|
@@ -0,0 +1,78 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.deleteMatchingProperties = void 0;
|
4
|
+
/**
|
5
|
+
* Iterate through the current target in the project.json and its options comparing it to the target created by the Plugin itself
|
6
|
+
* Delete matching properties from current target.
|
7
|
+
*
|
8
|
+
* _Note: Deletes by reference_
|
9
|
+
*
|
10
|
+
* @example
|
11
|
+
* // Run the plugin to get all the projects
|
12
|
+
* const { projects } = await createNodes[1](
|
13
|
+
* playwrightConfigPath,
|
14
|
+
* { targetName, ciTargetName: 'e2e-ci' },
|
15
|
+
* { workspaceRoot: tree.root, nxJsonConfiguration, configFiles }
|
16
|
+
* );
|
17
|
+
*
|
18
|
+
* // Find the project that matches the one that is being migrated
|
19
|
+
* const createdProject = Object.entries(projects ?? {}).find(
|
20
|
+
* ([root]) => root === projectFromGraph.data.root
|
21
|
+
* )[1];
|
22
|
+
*
|
23
|
+
* // Get the created TargetConfiguration for the target being migrated
|
24
|
+
* const createdTarget: TargetConfiguration<RunCommandsOptions> =
|
25
|
+
* createdProject.targets[targetName];
|
26
|
+
*
|
27
|
+
* // Delete specific run-commands options
|
28
|
+
* delete createdTarget.command;
|
29
|
+
* delete createdTarget.options?.cwd;
|
30
|
+
*
|
31
|
+
* // Get the TargetConfiguration for the target being migrated from project.json
|
32
|
+
* const projectConfig = readProjectConfiguration(tree, projectName);
|
33
|
+
* let targetToMigrate = projectConfig.targets[targetName];
|
34
|
+
*
|
35
|
+
* // Merge the target defaults for the executor to the target being migrated
|
36
|
+
* target = mergeTargetConfigurations(targetToMigrate, targetDefaultsForExecutor);
|
37
|
+
*
|
38
|
+
* // Delete executor and any additional options that are no longer necessary
|
39
|
+
* delete target.executor;
|
40
|
+
* delete target.options?.config;
|
41
|
+
*
|
42
|
+
* // Run deleteMatchingProperties to delete further options that match what the plugin creates
|
43
|
+
* deleteMatchingProperties(target, createdTarget);
|
44
|
+
*
|
45
|
+
* // Delete the target if it is now empty, otherwise, set it to the updated TargetConfiguration
|
46
|
+
* if (Object.keys(target).length > 0) {
|
47
|
+
* projectConfig.targets[targetName] = target;
|
48
|
+
* } else {
|
49
|
+
* delete projectConfig.targets[targetName];
|
50
|
+
* }
|
51
|
+
*
|
52
|
+
* updateProjectConfiguration(tree, projectName, projectConfig);
|
53
|
+
*
|
54
|
+
* @param targetToMigrate The target from project.json
|
55
|
+
* @param createdTarget The target created by the Plugin
|
56
|
+
*/
|
57
|
+
function deleteMatchingProperties(targetToMigrate, createdTarget) {
|
58
|
+
for (const key in targetToMigrate) {
|
59
|
+
if (Array.isArray(targetToMigrate[key])) {
|
60
|
+
if (targetToMigrate[key].every((v) => createdTarget[key]?.includes(v)) &&
|
61
|
+
targetToMigrate[key].length === createdTarget[key]?.length) {
|
62
|
+
delete targetToMigrate[key];
|
63
|
+
}
|
64
|
+
}
|
65
|
+
else if (typeof targetToMigrate[key] === 'object' &&
|
66
|
+
typeof createdTarget[key] === 'object') {
|
67
|
+
deleteMatchingProperties(targetToMigrate[key], createdTarget[key]);
|
68
|
+
}
|
69
|
+
else if (targetToMigrate[key] === createdTarget[key]) {
|
70
|
+
delete targetToMigrate[key];
|
71
|
+
}
|
72
|
+
if (typeof targetToMigrate[key] === 'object' &&
|
73
|
+
Object.keys(targetToMigrate[key]).length === 0) {
|
74
|
+
delete targetToMigrate[key];
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
exports.deleteMatchingProperties = deleteMatchingProperties;
|
package/src/utils/add-plugin.js
CHANGED
@@ -17,7 +17,9 @@ async function addPlugin(tree, graph, pluginName, createNodesTuple, options, sho
|
|
17
17
|
optionsLoop: for (const _pluginOptions of combinations) {
|
18
18
|
pluginOptions = _pluginOptions;
|
19
19
|
nxJson.plugins ??= [];
|
20
|
-
if (nxJson.plugins.some((p) => typeof p === 'string'
|
20
|
+
if (nxJson.plugins.some((p) => typeof p === 'string'
|
21
|
+
? p === pluginName
|
22
|
+
: p.plugin === pluginName && !p.include)) {
|
21
23
|
// Plugin has already been added
|
22
24
|
return;
|
23
25
|
}
|
@@ -2,7 +2,9 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.convertNxExecutor = void 0;
|
4
4
|
const nx_1 = require("../../nx");
|
5
|
-
const
|
5
|
+
const package_json_1 = require("./package-json");
|
6
|
+
const semver_1 = require("semver");
|
7
|
+
const { Workspaces, readNxJsonFromDisk, retrieveProjectConfigurationsWithAngularProjects, readProjectConfigurationsFromRootMap, } = (0, nx_1.requireNx)();
|
6
8
|
/**
|
7
9
|
* Convert an Nx Executor into an Angular Devkit Builder
|
8
10
|
*
|
@@ -20,7 +22,20 @@ function convertNxExecutor(executor) {
|
|
20
22
|
const projectsConfigurations = retrieveProjectConfigurationsWithAngularProjects
|
21
23
|
? {
|
22
24
|
version: 2,
|
23
|
-
projects: await retrieveProjectConfigurationsWithAngularProjects(builderContext.workspaceRoot, nxJsonConfiguration).then((p) =>
|
25
|
+
projects: await retrieveProjectConfigurationsWithAngularProjects(builderContext.workspaceRoot, nxJsonConfiguration).then((p) => {
|
26
|
+
if (p.projectNodes) {
|
27
|
+
return p.projectNodes;
|
28
|
+
}
|
29
|
+
// v18.3.4 changed projects to be keyed by root
|
30
|
+
// rather than project name
|
31
|
+
if ((0, semver_1.lt)(package_json_1.NX_VERSION, '18.3.4')) {
|
32
|
+
return p.projects;
|
33
|
+
}
|
34
|
+
if (readProjectConfigurationsFromRootMap) {
|
35
|
+
return readProjectConfigurationsFromRootMap(p.projects);
|
36
|
+
}
|
37
|
+
throw new Error('Unable to successfully map Nx executor -> Angular Builder');
|
38
|
+
}),
|
24
39
|
}
|
25
40
|
: // TODO(v19): remove retrieveProjectConfigurations. This is to be backwards compatible with Nx 16.5 and below.
|
26
41
|
workspaces.readProjectsConfigurations({
|