@nx/devkit 17.3.0-beta.6 → 17.3.0-beta.8
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/devkit",
|
|
3
|
-
"version": "17.3.0-beta.
|
|
3
|
+
"version": "17.3.0-beta.8",
|
|
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": {
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"tmp": "~0.2.1",
|
|
35
35
|
"tslib": "^2.3.0",
|
|
36
36
|
"semver": "7.5.3",
|
|
37
|
-
"
|
|
37
|
+
"yargs-parser": "21.1.1",
|
|
38
|
+
"@nrwl/devkit": "17.3.0-beta.8"
|
|
38
39
|
},
|
|
39
40
|
"peerDependencies": {
|
|
40
41
|
"nx": ">= 16 <= 18"
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updatePackageScripts = void 0;
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const yargs = require("yargs-parser");
|
|
6
|
+
const nx_1 = require("../../nx");
|
|
7
|
+
const { glob, readJson, readNxJson, workspaceRoot, writeJson } = (0, nx_1.requireNx)();
|
|
8
|
+
async function updatePackageScripts(tree, createNodesTuple) {
|
|
9
|
+
const nxJson = readNxJson(tree);
|
|
10
|
+
const [pattern, createNodes] = createNodesTuple;
|
|
11
|
+
const files = glob(tree, [pattern]);
|
|
12
|
+
for (const file of files) {
|
|
13
|
+
const projectRoot = getProjectRootFromConfigFile(file);
|
|
14
|
+
await processProject(tree, projectRoot, file, createNodes, nxJson);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.updatePackageScripts = updatePackageScripts;
|
|
18
|
+
async function processProject(tree, projectRoot, projectConfigurationFile, createNodesFunction, nxJsonConfiguration) {
|
|
19
|
+
const packageJsonPath = `${projectRoot}/package.json`;
|
|
20
|
+
if (!tree.exists(packageJsonPath)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const packageJson = readJson(tree, packageJsonPath);
|
|
24
|
+
if (!packageJson.scripts || !Object.keys(packageJson.scripts).length) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const result = await createNodesFunction(projectConfigurationFile, {}, { nxJsonConfiguration, workspaceRoot });
|
|
28
|
+
const targetCommands = getInferredTargetCommands(result);
|
|
29
|
+
if (!targetCommands.length) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// exclude package.json scripts from nx
|
|
33
|
+
packageJson.nx ??= {};
|
|
34
|
+
packageJson.nx.includedScripts ??= [];
|
|
35
|
+
for (const targetCommand of targetCommands) {
|
|
36
|
+
const { command, target, configuration } = targetCommand;
|
|
37
|
+
const targetCommandRegex = new RegExp(`(?<=^|&)((?: )*(?:[^&\\r\\n\\s]+ )*)(${command})((?: [^&\\r\\n\\s]+)*(?: )*)(?=$|&)`, 'g');
|
|
38
|
+
for (const scriptName of Object.keys(packageJson.scripts)) {
|
|
39
|
+
const script = packageJson.scripts[scriptName];
|
|
40
|
+
// quick check for exact match within the script
|
|
41
|
+
if (targetCommandRegex.test(script)) {
|
|
42
|
+
packageJson.scripts[scriptName] = script.replace(targetCommandRegex, configuration
|
|
43
|
+
? `$1nx ${target} --configuration=${configuration}$3`
|
|
44
|
+
: `$1nx ${target}$3`);
|
|
45
|
+
excludeScriptFromPackageJson(packageJson, scriptName);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
/**
|
|
49
|
+
* Parse script and command to handle the following:
|
|
50
|
+
* - if command doesn't match script => don't replace
|
|
51
|
+
* - if command has more args => don't replace
|
|
52
|
+
* - if command has same args, regardless of order => replace removing args
|
|
53
|
+
* - if command has less args or with different value => replace leaving args
|
|
54
|
+
*/
|
|
55
|
+
const parsedCommand = yargs(command, {
|
|
56
|
+
configuration: { 'strip-dashed': true },
|
|
57
|
+
});
|
|
58
|
+
// this assumes there are no positional args in the command, everything is a command or subcommand
|
|
59
|
+
const commandCommand = parsedCommand._.join(' ');
|
|
60
|
+
const commandRegex = new RegExp(`(?<=^|&)((?: )*(?:[^&\\r\\n\\s]+ )*)(${commandCommand})((?: [^&\\r\\n\\s]+)*( )*)(?=$|&)`, 'g');
|
|
61
|
+
const matches = script.match(commandRegex);
|
|
62
|
+
if (!matches) {
|
|
63
|
+
// the command doesn't match the script, don't replace
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
for (const match of matches) {
|
|
67
|
+
// parse the matched command within the script
|
|
68
|
+
const parsedScript = yargs(match, {
|
|
69
|
+
configuration: { 'strip-dashed': true },
|
|
70
|
+
});
|
|
71
|
+
let hasArgsWithDifferentValues = false;
|
|
72
|
+
let scriptHasExtraArgs = false;
|
|
73
|
+
let commandHasExtraArgs = false;
|
|
74
|
+
for (const [key, value] of Object.entries(parsedCommand)) {
|
|
75
|
+
if (key === '_') {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (parsedScript[key] === undefined) {
|
|
79
|
+
commandHasExtraArgs = true;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
if (parsedScript[key] !== value) {
|
|
83
|
+
hasArgsWithDifferentValues = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (commandHasExtraArgs) {
|
|
87
|
+
// the command has extra args, don't replace
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
for (const key of Object.keys(parsedScript)) {
|
|
91
|
+
if (key === '_') {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (!parsedCommand[key]) {
|
|
95
|
+
scriptHasExtraArgs = true;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (!hasArgsWithDifferentValues && !scriptHasExtraArgs) {
|
|
100
|
+
// they are the same, replace with the command removing the args
|
|
101
|
+
packageJson.scripts[scriptName] = packageJson.scripts[scriptName].replace(match, match.replace(commandRegex, configuration
|
|
102
|
+
? `$1nx ${target} --configuration=${configuration}$4`
|
|
103
|
+
: `$1nx ${target}$4`));
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
// there are different args or the script has extra args, replace with the command leaving the args
|
|
107
|
+
packageJson.scripts[scriptName] = packageJson.scripts[scriptName].replace(match, match.replace(commandRegex, configuration
|
|
108
|
+
? `$1nx ${target} --configuration=${configuration}$3`
|
|
109
|
+
: `$1nx ${target}$3`));
|
|
110
|
+
}
|
|
111
|
+
excludeScriptFromPackageJson(packageJson, scriptName);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
writeJson(tree, packageJsonPath, packageJson);
|
|
117
|
+
}
|
|
118
|
+
function getInferredTargetCommands(result) {
|
|
119
|
+
const targetCommands = [];
|
|
120
|
+
for (const project of Object.values(result.projects ?? {})) {
|
|
121
|
+
for (const [targetName, target] of Object.entries(project.targets ?? {})) {
|
|
122
|
+
if (target.command) {
|
|
123
|
+
targetCommands.push({ command: target.command, target: targetName });
|
|
124
|
+
}
|
|
125
|
+
else if (target.executor === 'nx:run-commands' &&
|
|
126
|
+
target.options?.command) {
|
|
127
|
+
targetCommands.push({
|
|
128
|
+
command: target.options.command,
|
|
129
|
+
target: targetName,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
if (!target.configurations) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
for (const [configurationName, configuration] of Object.entries(target.configurations)) {
|
|
136
|
+
if (configuration.command) {
|
|
137
|
+
targetCommands.push({
|
|
138
|
+
command: configuration.command,
|
|
139
|
+
target: targetName,
|
|
140
|
+
configuration: configurationName,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
else if (target.executor === 'nx:run-commands' &&
|
|
144
|
+
configuration.options?.command) {
|
|
145
|
+
targetCommands.push({
|
|
146
|
+
command: configuration.options.command,
|
|
147
|
+
target: targetName,
|
|
148
|
+
configuration: configurationName,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return targetCommands;
|
|
155
|
+
}
|
|
156
|
+
function excludeScriptFromPackageJson(packageJson, scriptName) {
|
|
157
|
+
packageJson.nx.includedScripts = packageJson.nx.includedScripts.filter((s) => s !== scriptName);
|
|
158
|
+
}
|
|
159
|
+
function getProjectRootFromConfigFile(file) {
|
|
160
|
+
let projectRoot = (0, path_1.dirname)(file);
|
|
161
|
+
if ((0, path_1.basename)(projectRoot) === '.storybook') {
|
|
162
|
+
projectRoot = (0, path_1.dirname)(projectRoot);
|
|
163
|
+
}
|
|
164
|
+
return projectRoot;
|
|
165
|
+
}
|