nx 22.7.0-beta.11 → 22.7.0-beta.13
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/dist/schemas/nx-schema.json +25 -0
- package/dist/schemas/project-schema.json +25 -0
- package/dist/src/adapter/ngcli-adapter.js +11 -12
- package/dist/src/command-line/daemon/daemon.js +8 -4
- package/dist/src/command-line/graph/graph.js +8 -1
- package/dist/src/command-line/init/implementation/add-nx-to-monorepo.js +19 -9
- package/dist/src/command-line/init/implementation/add-nx-to-nest.js +19 -9
- package/dist/src/command-line/init/implementation/add-nx-to-npm-repo.js +19 -9
- package/dist/src/command-line/init/implementation/angular/index.js +11 -3
- package/dist/src/command-line/init/implementation/angular/legacy-angular-versions.js +11 -5
- package/dist/src/command-line/init/implementation/utils.d.ts +1 -0
- package/dist/src/command-line/init/implementation/utils.js +8 -1
- package/dist/src/command-line/init/init-v2.js +53 -7
- package/dist/src/command-line/migrate/migrate.js +1 -0
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.d.ts +2 -2
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +18 -5
- package/dist/src/command-line/nx-cloud/connect/view-logs.js +1 -1
- package/dist/src/command-line/show/command-object.js +3 -3
- package/dist/src/command-line/show/show-target/index.d.ts +3 -0
- package/dist/src/command-line/show/show-target/index.js +9 -0
- package/dist/src/command-line/show/show-target/info.d.ts +27 -0
- package/dist/src/command-line/show/show-target/info.js +299 -0
- package/dist/src/command-line/show/show-target/inputs.d.ts +2 -0
- package/dist/src/command-line/show/show-target/inputs.js +186 -0
- package/dist/src/command-line/show/show-target/outputs.d.ts +2 -0
- package/dist/src/command-line/show/show-target/outputs.js +195 -0
- package/dist/src/command-line/show/show-target/utils.d.ts +26 -0
- package/dist/src/command-line/show/show-target/utils.js +185 -0
- package/dist/src/command-line/yargs-utils/shared-options.js +5 -1
- package/dist/src/config/nx-json.d.ts +3 -1
- package/dist/src/config/workspace-json-project-json.d.ts +2 -1
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/daemon/client/client.d.ts +11 -4
- package/dist/src/daemon/client/client.js +44 -48
- package/dist/src/daemon/client/daemon-environment.d.ts +4 -0
- package/dist/src/daemon/client/daemon-environment.js +119 -0
- package/dist/src/daemon/client/daemon-socket-messenger.d.ts +2 -5
- package/dist/src/daemon/client/daemon-socket-messenger.js +1 -1
- package/dist/src/daemon/message-types/daemon-message.d.ts +6 -0
- package/dist/src/daemon/message-types/daemon-message.js +6 -0
- package/dist/src/daemon/server/handle-hash-tasks.d.ts +1 -1
- package/dist/src/daemon/server/handle-hash-tasks.js +1 -1
- package/dist/src/daemon/server/handle-outputs-tracking.d.ts +4 -4
- package/dist/src/daemon/server/handle-outputs-tracking.js +11 -11
- package/dist/src/daemon/server/outputs-tracking.d.ts +18 -3
- package/dist/src/daemon/server/outputs-tracking.js +49 -22
- package/dist/src/daemon/server/project-graph-incremental-recomputation.d.ts +2 -1
- package/dist/src/daemon/server/project-graph-incremental-recomputation.js +20 -4
- package/dist/src/daemon/server/server.js +71 -40
- package/dist/src/executors/run-commands/running-tasks.js +2 -3
- package/dist/src/executors/run-script/run-script.impl.js +16 -8
- package/dist/src/hasher/hash-task.d.ts +9 -1
- package/dist/src/hasher/hash-task.js +42 -15
- package/dist/src/hasher/native-task-hasher-impl.d.ts +1 -1
- package/dist/src/hasher/native-task-hasher-impl.js +4 -6
- package/dist/src/hasher/task-hasher.d.ts +20 -9
- package/dist/src/hasher/task-hasher.js +34 -6
- package/dist/src/native/index.d.ts +34 -7
- package/dist/src/native/native-bindings.js +1 -1
- package/dist/src/native/nx.wasi-browser.js +0 -1
- package/dist/src/native/nx.wasi.cjs +0 -1
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/plugins/js/lock-file/npm-parser.js +15 -3
- package/dist/src/plugins/js/lock-file/utils/package-json.d.ts +1 -1
- package/dist/src/plugins/js/lock-file/utils/package-json.js +3 -1
- package/dist/src/plugins/js/utils/register.js +83 -4
- package/dist/src/project-graph/error-types.js +31 -11
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.d.ts +1 -0
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +44 -33
- package/dist/src/project-graph/plugins/isolation/message-types.d.ts +1 -1
- package/dist/src/project-graph/plugins/isolation/messaging.d.ts +9 -0
- package/dist/src/project-graph/plugins/isolation/messaging.js +2 -0
- package/dist/src/project-graph/plugins/isolation/plugin-worker.js +44 -82
- package/dist/src/project-graph/plugins/loaded-nx-plugin.d.ts +6 -0
- package/dist/src/tasks-runner/cache.d.ts +6 -0
- package/dist/src/tasks-runner/cache.js +58 -0
- package/dist/src/tasks-runner/init-tasks-runner.js +13 -7
- package/dist/src/tasks-runner/run-command.js +13 -5
- package/dist/src/tasks-runner/task-env.d.ts +6 -3
- package/dist/src/tasks-runner/task-env.js +23 -6
- package/dist/src/tasks-runner/task-orchestrator.d.ts +79 -7
- package/dist/src/tasks-runner/task-orchestrator.js +327 -120
- package/dist/src/tasks-runner/tasks-schedule.d.ts +5 -2
- package/dist/src/tasks-runner/tasks-schedule.js +31 -17
- package/dist/src/tasks-runner/utils.d.ts +3 -3
- package/dist/src/tasks-runner/utils.js +5 -6
- package/dist/src/utils/ab-testing.d.ts +14 -33
- package/dist/src/utils/ab-testing.js +6 -4
- package/dist/src/utils/dotenv.js +4 -6
- package/dist/src/utils/nx-cloud-utils.d.ts +1 -0
- package/dist/src/utils/nx-cloud-utils.js +5 -1
- package/dist/src/utils/package-json.js +16 -1
- package/dist/src/utils/wait-for-socket-connection.d.ts +15 -0
- package/dist/src/utils/wait-for-socket-connection.js +53 -0
- package/package.json +14 -14
- package/dist/src/command-line/release/utils/test/test-utils.d.ts +0 -20
- package/dist/src/command-line/release/utils/test/test-utils.js +0 -25
- package/dist/src/command-line/release/version/test-utils.d.ts +0 -102
- package/dist/src/command-line/release/version/test-utils.js +0 -417
- package/dist/src/command-line/show/target.d.ts +0 -4
- package/dist/src/command-line/show/target.js +0 -730
- package/dist/src/daemon/client/exec-is-server-available.d.ts +0 -1
- package/dist/src/daemon/client/exec-is-server-available.js +0 -11
- package/dist/src/daemon/client/generate-help-output.d.ts +0 -1
- package/dist/src/daemon/client/generate-help-output.js +0 -26
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.showTargetOutputsHandler = exports.showTargetInputsHandler = exports.showTargetInfoHandler = void 0;
|
|
4
|
+
var info_1 = require("./info");
|
|
5
|
+
Object.defineProperty(exports, "showTargetInfoHandler", { enumerable: true, get: function () { return info_1.showTargetInfoHandler; } });
|
|
6
|
+
var inputs_1 = require("./inputs");
|
|
7
|
+
Object.defineProperty(exports, "showTargetInputsHandler", { enumerable: true, get: function () { return inputs_1.showTargetInputsHandler; } });
|
|
8
|
+
var outputs_1 = require("./outputs");
|
|
9
|
+
Object.defineProperty(exports, "showTargetOutputsHandler", { enumerable: true, get: function () { return outputs_1.showTargetOutputsHandler; } });
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { InputDefinition } from '../../../config/workspace-json-project-json';
|
|
2
|
+
import type { ShowTargetBaseOptions } from '../command-object';
|
|
3
|
+
import { type ResolvedTarget } from './utils';
|
|
4
|
+
export declare function showTargetInfoHandler(args: ShowTargetBaseOptions): Promise<void>;
|
|
5
|
+
export type TargetInfoData = ReturnType<typeof resolveTargetInfoData>;
|
|
6
|
+
declare function resolveTargetInfoData(t: ResolvedTarget): {
|
|
7
|
+
sourceMap?: Record<string, [file: string, plugin: string]>;
|
|
8
|
+
defaultConfiguration?: string;
|
|
9
|
+
configurations?: string[];
|
|
10
|
+
options: any;
|
|
11
|
+
outputs?: string[];
|
|
12
|
+
inputs?: (string | InputDefinition)[];
|
|
13
|
+
_inputSources?: number[];
|
|
14
|
+
parallelism: boolean;
|
|
15
|
+
continuous: boolean;
|
|
16
|
+
cache: boolean;
|
|
17
|
+
dependsOn?: string[];
|
|
18
|
+
_depSources?: number[];
|
|
19
|
+
customHasher?: boolean;
|
|
20
|
+
command?: string;
|
|
21
|
+
_commandSourceKey?: string;
|
|
22
|
+
executor: string;
|
|
23
|
+
configuration?: string;
|
|
24
|
+
project: string;
|
|
25
|
+
target: string;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.showTargetInfoHandler = showTargetInfoHandler;
|
|
4
|
+
const task_hasher_1 = require("../../../hasher/task-hasher");
|
|
5
|
+
const utils_1 = require("../../../tasks-runner/utils");
|
|
6
|
+
const utils_2 = require("./utils");
|
|
7
|
+
// ── Handler ─────────────────────────────────────────────────────────
|
|
8
|
+
async function showTargetInfoHandler(args) {
|
|
9
|
+
const t = await (0, utils_2.resolveTarget)(args, { withSourceMaps: true });
|
|
10
|
+
const data = resolveTargetInfoData(t);
|
|
11
|
+
renderTargetInfo(data, args);
|
|
12
|
+
}
|
|
13
|
+
function resolveTargetInfoData(t) {
|
|
14
|
+
const { projectName, targetName, configuration, node, graph, nxJson, sourceMaps, } = t;
|
|
15
|
+
const targetConfig = node.data.targets[targetName];
|
|
16
|
+
const allTargetNames = new Set();
|
|
17
|
+
for (const n of Object.values(graph.nodes)) {
|
|
18
|
+
for (const name of Object.keys(n.data.targets ?? {})) {
|
|
19
|
+
allTargetNames.add(name);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const extraTargetDeps = Object.fromEntries(Object.entries(nxJson.targetDefaults ?? {})
|
|
23
|
+
.filter(([, config]) => config.dependsOn)
|
|
24
|
+
.map(([name, config]) => [name, config.dependsOn]));
|
|
25
|
+
const depConfigs = (0, utils_1.getDependencyConfigs)({ project: projectName, target: targetName }, extraTargetDeps, graph, [...allTargetNames]);
|
|
26
|
+
// Determine the hoisted command value and which option key it came from
|
|
27
|
+
let command;
|
|
28
|
+
let commandSourceKey;
|
|
29
|
+
if (targetConfig.metadata?.scriptContent) {
|
|
30
|
+
command = targetConfig.metadata.scriptContent;
|
|
31
|
+
commandSourceKey = 'options.script';
|
|
32
|
+
}
|
|
33
|
+
else if (targetConfig.options?.command) {
|
|
34
|
+
command = targetConfig.options.command;
|
|
35
|
+
commandSourceKey = 'options.command';
|
|
36
|
+
}
|
|
37
|
+
else if (targetConfig.options?.commands?.length === 1) {
|
|
38
|
+
command = targetConfig.options.commands[0];
|
|
39
|
+
commandSourceKey = 'options.commands';
|
|
40
|
+
}
|
|
41
|
+
else if (targetConfig.executor === 'nx:run-script' &&
|
|
42
|
+
targetConfig.options?.script) {
|
|
43
|
+
command = targetConfig.options.script;
|
|
44
|
+
commandSourceKey = 'options.script';
|
|
45
|
+
}
|
|
46
|
+
const dependsOn = [];
|
|
47
|
+
const depSourceIndices = [];
|
|
48
|
+
if (depConfigs && depConfigs.length > 0) {
|
|
49
|
+
for (let i = 0; i < depConfigs.length; i++) {
|
|
50
|
+
const dep = depConfigs[i];
|
|
51
|
+
const projects = resolveDependencyProjects(dep, projectName, graph);
|
|
52
|
+
for (const p of projects) {
|
|
53
|
+
dependsOn.push(`${p}:${dep.target}`);
|
|
54
|
+
depSourceIndices.push(i);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const configurations = Object.keys(targetConfig.configurations ?? {});
|
|
59
|
+
const targetSourceMap = extractTargetSourceMap(node.data.root, targetName, sourceMaps);
|
|
60
|
+
const usesCustomHasher = (0, utils_2.hasCustomHasher)(projectName, targetName, graph);
|
|
61
|
+
return {
|
|
62
|
+
project: projectName,
|
|
63
|
+
target: targetName,
|
|
64
|
+
...(configuration ? { configuration } : {}),
|
|
65
|
+
executor: targetConfig.executor,
|
|
66
|
+
...(command ? { command, _commandSourceKey: commandSourceKey } : {}),
|
|
67
|
+
...(usesCustomHasher ? { customHasher: true } : {}),
|
|
68
|
+
...(dependsOn.length > 0
|
|
69
|
+
? { dependsOn, _depSources: depSourceIndices }
|
|
70
|
+
: {}),
|
|
71
|
+
parallelism: targetConfig.parallelism ?? true,
|
|
72
|
+
continuous: targetConfig.continuous ?? false,
|
|
73
|
+
cache: targetConfig.cache ?? false,
|
|
74
|
+
...(targetConfig.inputs
|
|
75
|
+
? (() => {
|
|
76
|
+
const expanded = expandInputsForDisplay(targetConfig.inputs, node, nxJson);
|
|
77
|
+
return {
|
|
78
|
+
inputs: expanded.map((e) => e.value),
|
|
79
|
+
_inputSources: expanded.map((e) => e.originalIndex),
|
|
80
|
+
};
|
|
81
|
+
})()
|
|
82
|
+
: {}),
|
|
83
|
+
...(targetConfig.outputs
|
|
84
|
+
? { outputs: targetConfig.outputs }
|
|
85
|
+
: {}),
|
|
86
|
+
options: {
|
|
87
|
+
...targetConfig.options,
|
|
88
|
+
...(configuration
|
|
89
|
+
? targetConfig.configurations?.[configuration]
|
|
90
|
+
: undefined),
|
|
91
|
+
},
|
|
92
|
+
...(configurations.length > 0 ? { configurations } : {}),
|
|
93
|
+
...(targetConfig.defaultConfiguration
|
|
94
|
+
? { defaultConfiguration: targetConfig.defaultConfiguration }
|
|
95
|
+
: {}),
|
|
96
|
+
...(targetSourceMap ? { sourceMap: targetSourceMap } : {}),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function resolveDependencyProjects(dep, projectName, graph) {
|
|
100
|
+
if (dep.projects && dep.projects.length > 0)
|
|
101
|
+
return dep.projects;
|
|
102
|
+
if (dep.dependencies) {
|
|
103
|
+
const depEdges = graph.dependencies[projectName] ?? [];
|
|
104
|
+
return depEdges
|
|
105
|
+
.filter((edge) => {
|
|
106
|
+
const depNode = graph.nodes[edge.target];
|
|
107
|
+
return depNode && depNode.data.targets?.[dep.target];
|
|
108
|
+
})
|
|
109
|
+
.map((edge) => edge.target);
|
|
110
|
+
}
|
|
111
|
+
return [projectName];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Expands named inputs (e.g. "production") to their definitions while
|
|
115
|
+
* tracking which original input index each expanded item came from.
|
|
116
|
+
* This lets the renderer look up `inputs.${originalIndex}` in the source map.
|
|
117
|
+
*/
|
|
118
|
+
function expandInputsForDisplay(inputs, node, nxJson) {
|
|
119
|
+
const namedInputs = (0, task_hasher_1.getNamedInputs)(nxJson, node);
|
|
120
|
+
const result = [];
|
|
121
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
122
|
+
const input = inputs[i];
|
|
123
|
+
if (typeof input === 'string') {
|
|
124
|
+
if (input.startsWith('^')) {
|
|
125
|
+
result.push({ value: input, originalIndex: i });
|
|
126
|
+
}
|
|
127
|
+
else if (namedInputs[input]) {
|
|
128
|
+
for (const expanded of namedInputs[input]) {
|
|
129
|
+
result.push({ value: expanded, originalIndex: i });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
result.push({ value: input, originalIndex: i });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else if ('input' in input) {
|
|
137
|
+
const name = input.input;
|
|
138
|
+
// Don't expand when the input has additional qualifiers (e.g. projects)
|
|
139
|
+
// since those scopes are meaningful and would be lost by expansion
|
|
140
|
+
const hasQualifiers = Object.keys(input).length > 1;
|
|
141
|
+
if (!hasQualifiers && !name.startsWith('^') && namedInputs[name]) {
|
|
142
|
+
for (const expanded of namedInputs[name]) {
|
|
143
|
+
result.push({ value: expanded, originalIndex: i });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
result.push({ value: input, originalIndex: i });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
result.push({ value: input, originalIndex: i });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
function extractTargetSourceMap(projectRoot, targetName, sourceMaps) {
|
|
157
|
+
if (!sourceMaps)
|
|
158
|
+
return undefined;
|
|
159
|
+
const projectSourceMap = sourceMaps[projectRoot];
|
|
160
|
+
if (!projectSourceMap)
|
|
161
|
+
return undefined;
|
|
162
|
+
const prefix = `targets.${targetName}.`;
|
|
163
|
+
const targetEntry = `targets.${targetName}`;
|
|
164
|
+
const result = {};
|
|
165
|
+
for (const [key, value] of Object.entries(projectSourceMap)) {
|
|
166
|
+
if (key === targetEntry) {
|
|
167
|
+
result['target'] = value;
|
|
168
|
+
}
|
|
169
|
+
else if (key.startsWith(prefix)) {
|
|
170
|
+
result[key.slice(prefix.length)] = value;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return Object.keys(result).length > 0 ? result : undefined;
|
|
174
|
+
}
|
|
175
|
+
// ── Render ──────────────────────────────────────────────────────────
|
|
176
|
+
function renderTargetInfo(data, args) {
|
|
177
|
+
if (args.json) {
|
|
178
|
+
// Strip internal renderer-only fields from JSON output
|
|
179
|
+
const { _inputSources, _depSources, _commandSourceKey, ...jsonData } = data;
|
|
180
|
+
console.log(JSON.stringify(jsonData, null, 2));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const c = (0, utils_2.pc)();
|
|
184
|
+
const sm = data.sourceMap;
|
|
185
|
+
const sourceHint = (key, fallbackKey) => {
|
|
186
|
+
if (!args.verbose)
|
|
187
|
+
return '';
|
|
188
|
+
const entry = sm?.[key] ?? (fallbackKey ? sm?.[fallbackKey] : undefined);
|
|
189
|
+
if (!entry)
|
|
190
|
+
return '';
|
|
191
|
+
const [file, plugin] = entry;
|
|
192
|
+
if (file && plugin)
|
|
193
|
+
return ` ${c.dim(`(from ${file} by ${plugin})`)}`;
|
|
194
|
+
if (file)
|
|
195
|
+
return ` ${c.dim(`(from ${file})`)}`;
|
|
196
|
+
if (plugin)
|
|
197
|
+
return ` ${c.dim(`(by ${plugin})`)}`;
|
|
198
|
+
return '';
|
|
199
|
+
};
|
|
200
|
+
console.log(`${c.bold('Target')}: ${c.cyan(data.project)}:${c.green(data.target)}${sourceHint('target')}`);
|
|
201
|
+
if (data.command) {
|
|
202
|
+
const label = data.executor === 'nx:run-script' ? 'Script' : 'Command';
|
|
203
|
+
const cmdHint = data._commandSourceKey
|
|
204
|
+
? sourceHint(data._commandSourceKey)
|
|
205
|
+
: '';
|
|
206
|
+
console.log(`${c.bold(label)}: ${data.command}${cmdHint}`);
|
|
207
|
+
}
|
|
208
|
+
else if (data.executor) {
|
|
209
|
+
console.log(`${c.bold('Executor')}: ${data.executor}${sourceHint('executor')}`);
|
|
210
|
+
}
|
|
211
|
+
if (data.customHasher) {
|
|
212
|
+
console.log(`${c.bold('Hasher')}: ${c.yellow('custom')} ${c.dim('(inputs do not affect cache hash)')}`);
|
|
213
|
+
}
|
|
214
|
+
if (data.configuration)
|
|
215
|
+
console.log(`${c.bold('Configuration')}: ${data.configuration}`);
|
|
216
|
+
if (data.dependsOn && data.dependsOn.length > 0) {
|
|
217
|
+
console.log(`${c.bold('Depends On')}:`);
|
|
218
|
+
for (let i = 0; i < data.dependsOn.length; i++) {
|
|
219
|
+
const hint = data._depSources?.[i] !== undefined
|
|
220
|
+
? sourceHint(`dependsOn.${data._depSources[i]}`, 'dependsOn')
|
|
221
|
+
: '';
|
|
222
|
+
console.log(` ${data.dependsOn[i]}${hint}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
console.log(`${c.bold('Parallelism')}: ${data.parallelism}${sourceHint('parallelism')}`);
|
|
226
|
+
console.log(`${c.bold('Continuous')}: ${data.continuous}${sourceHint('continuous')}`);
|
|
227
|
+
console.log(`${c.bold('Cache')}: ${data.cache}${sourceHint('cache')}`);
|
|
228
|
+
if (data.inputs && data.inputs.length > 0) {
|
|
229
|
+
console.log(`${c.bold('Inputs')}:`);
|
|
230
|
+
const inputSources = data._inputSources;
|
|
231
|
+
// Build sortable entries with their source index
|
|
232
|
+
const entries = data.inputs.map((input, i) => ({
|
|
233
|
+
value: input,
|
|
234
|
+
sourceIndex: inputSources?.[i],
|
|
235
|
+
}));
|
|
236
|
+
entries.sort((a, b) => {
|
|
237
|
+
const aIsString = typeof a.value === 'string';
|
|
238
|
+
const bIsString = typeof b.value === 'string';
|
|
239
|
+
if (!aIsString && bIsString)
|
|
240
|
+
return 1;
|
|
241
|
+
if (aIsString && !bIsString)
|
|
242
|
+
return -1;
|
|
243
|
+
if (aIsString && bIsString) {
|
|
244
|
+
const aStr = a.value;
|
|
245
|
+
const bStr = b.value;
|
|
246
|
+
const aIsDep = aStr.startsWith('^');
|
|
247
|
+
const bIsDep = bStr.startsWith('^');
|
|
248
|
+
if (aIsDep && !bIsDep)
|
|
249
|
+
return 1;
|
|
250
|
+
if (!aIsDep && bIsDep)
|
|
251
|
+
return -1;
|
|
252
|
+
return aStr < bStr ? -1 : aStr > bStr ? 1 : 0;
|
|
253
|
+
}
|
|
254
|
+
return 0;
|
|
255
|
+
});
|
|
256
|
+
for (const { value, sourceIndex } of entries) {
|
|
257
|
+
const display = typeof value === 'string' ? value : JSON.stringify(value);
|
|
258
|
+
const hint = sourceIndex !== undefined
|
|
259
|
+
? sourceHint(`inputs.${sourceIndex}`, 'inputs')
|
|
260
|
+
: '';
|
|
261
|
+
console.log(` - ${display}${hint}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (data.outputs && data.outputs.length > 0) {
|
|
265
|
+
console.log(`${c.bold('Outputs')}:`);
|
|
266
|
+
for (let i = 0; i < data.outputs.length; i++) {
|
|
267
|
+
const hint = sourceHint(`outputs.${i}`, 'outputs');
|
|
268
|
+
console.log(` - ${data.outputs[i]}${hint}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// When command is hoisted, hide the corresponding option key from display
|
|
272
|
+
const hoistedOptionKey = data._commandSourceKey?.startsWith('options.')
|
|
273
|
+
? data._commandSourceKey.slice('options.'.length)
|
|
274
|
+
: undefined;
|
|
275
|
+
const displayOptions = Object.entries(data.options).filter(([key]) => key !== hoistedOptionKey);
|
|
276
|
+
if (displayOptions.length > 0) {
|
|
277
|
+
console.log(`${c.bold('Options')}:`);
|
|
278
|
+
for (const [key, value] of displayOptions) {
|
|
279
|
+
const hint = sourceHint(`options.${key}`);
|
|
280
|
+
if (typeof value === 'object' && value !== null) {
|
|
281
|
+
console.log(` ${key}:${hint}`);
|
|
282
|
+
const lines = JSON.stringify(value, null, 2).split('\n');
|
|
283
|
+
for (const line of lines) {
|
|
284
|
+
console.log(` ${line}`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
console.log(` ${key}: ${JSON.stringify(value)}${hint}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (data.configurations && data.configurations.length > 0) {
|
|
293
|
+
const configList = data.configurations
|
|
294
|
+
.map((cfg) => cfg === data.defaultConfiguration ? `${cfg} ${c.dim('(default)')}` : cfg)
|
|
295
|
+
.join(', ');
|
|
296
|
+
console.log(`${c.bold('Configurations')}: ${configList}`);
|
|
297
|
+
}
|
|
298
|
+
console.log('');
|
|
299
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.showTargetInputsHandler = showTargetInputsHandler;
|
|
4
|
+
const workspace_root_1 = require("../../../utils/workspace-root");
|
|
5
|
+
const handle_import_1 = require("../../../utils/handle-import");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
// ── Handler ─────────────────────────────────────────────────────────
|
|
8
|
+
async function showTargetInputsHandler(args) {
|
|
9
|
+
const t = await (0, utils_1.resolveTarget)(args);
|
|
10
|
+
const usesCustomHasher = (0, utils_1.hasCustomHasher)(t.projectName, t.targetName, t.graph);
|
|
11
|
+
if (usesCustomHasher) {
|
|
12
|
+
renderCustomHasherWarning(t.projectName, t.targetName, args);
|
|
13
|
+
process.exitCode = 1;
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const hashInputs = await resolveInputFiles(t);
|
|
17
|
+
if (args.check !== undefined) {
|
|
18
|
+
const checkItems = (0, utils_1.deduplicateFolderEntries)(args.check);
|
|
19
|
+
const results = checkItems.map((input) => resolveCheckFromInputs(input, t.projectName, t.targetName, hashInputs));
|
|
20
|
+
if (results.length >= 2) {
|
|
21
|
+
renderBatchCheckInputs(results, t.projectName, t.targetName);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
for (const data of results)
|
|
25
|
+
renderCheckInput(data);
|
|
26
|
+
}
|
|
27
|
+
for (const data of results) {
|
|
28
|
+
process.exitCode ||=
|
|
29
|
+
data.isInput || data.containedInputFiles.length ? 0 : 1;
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
renderInputs({ project: t.projectName, target: t.targetName, ...hashInputs }, t.node.data.targets[t.targetName].inputs, args);
|
|
34
|
+
}
|
|
35
|
+
async function resolveInputFiles(t) {
|
|
36
|
+
const { projectName, targetName, configuration, graph, nxJson } = t;
|
|
37
|
+
const { HashPlanInspector } = (await (0, handle_import_1.handleImport)('../../../hasher/hash-plan-inspector.js', __dirname));
|
|
38
|
+
const inspector = new HashPlanInspector(graph, workspace_root_1.workspaceRoot, nxJson);
|
|
39
|
+
await inspector.init();
|
|
40
|
+
const plan = inspector.inspectTaskInputs({
|
|
41
|
+
project: projectName,
|
|
42
|
+
target: targetName,
|
|
43
|
+
configuration,
|
|
44
|
+
});
|
|
45
|
+
const targetConfig = graph.nodes[projectName]?.data?.targets?.[targetName];
|
|
46
|
+
const effectiveConfig = configuration ?? targetConfig?.defaultConfiguration;
|
|
47
|
+
const taskId = effectiveConfig
|
|
48
|
+
? `${projectName}:${targetName}:${effectiveConfig}`
|
|
49
|
+
: `${projectName}:${targetName}`;
|
|
50
|
+
const result = plan[taskId];
|
|
51
|
+
if (!result) {
|
|
52
|
+
throw new Error(`Could not find hash plan for task "${taskId}". Available tasks: ${Object.keys(plan).join(', ')}`);
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
function resolveCheckFromInputs(rawValue, projectName, targetName, inputs) {
|
|
57
|
+
for (const [category, arr] of [
|
|
58
|
+
['environment', inputs.environment],
|
|
59
|
+
['runtime', inputs.runtime],
|
|
60
|
+
['external', inputs.external],
|
|
61
|
+
['depOutputs', inputs.depOutputs],
|
|
62
|
+
]) {
|
|
63
|
+
if (arr.includes(rawValue)) {
|
|
64
|
+
return {
|
|
65
|
+
value: rawValue,
|
|
66
|
+
file: rawValue,
|
|
67
|
+
project: projectName,
|
|
68
|
+
target: targetName,
|
|
69
|
+
isInput: true,
|
|
70
|
+
matchedCategory: category,
|
|
71
|
+
containedInputFiles: [],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const fileToCheck = (0, utils_1.normalizePath)(rawValue);
|
|
76
|
+
const isFile = inputs.files.includes(fileToCheck);
|
|
77
|
+
let containedInputFiles = [];
|
|
78
|
+
if (!isFile) {
|
|
79
|
+
if (fileToCheck === '') {
|
|
80
|
+
containedInputFiles = inputs.files;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const dirPrefix = fileToCheck.endsWith('/')
|
|
84
|
+
? fileToCheck
|
|
85
|
+
: fileToCheck + '/';
|
|
86
|
+
containedInputFiles = inputs.files.filter((f) => f.startsWith(dirPrefix));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
value: rawValue,
|
|
91
|
+
file: fileToCheck,
|
|
92
|
+
project: projectName,
|
|
93
|
+
target: targetName,
|
|
94
|
+
isInput: isFile,
|
|
95
|
+
matchedCategory: isFile || containedInputFiles.length > 0
|
|
96
|
+
? 'files'
|
|
97
|
+
: null,
|
|
98
|
+
containedInputFiles,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// ── Render ──────────────────────────────────────────────────────────
|
|
102
|
+
function renderInputs(data, configuredInputs, args) {
|
|
103
|
+
if (args.json) {
|
|
104
|
+
const jsonData = data;
|
|
105
|
+
const result = {};
|
|
106
|
+
for (const [k, v] of Object.entries(jsonData)) {
|
|
107
|
+
if (Array.isArray(v) && v.length === 0)
|
|
108
|
+
continue;
|
|
109
|
+
result[k] = v;
|
|
110
|
+
}
|
|
111
|
+
console.log(JSON.stringify(result, null, 2));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const c = (0, utils_1.pc)();
|
|
115
|
+
console.log(`${c.bold('Inputs for')} ${c.cyan(data.project)}:${c.green(data.target)}`);
|
|
116
|
+
if (configuredInputs && configuredInputs.length > 0) {
|
|
117
|
+
(0, utils_1.printList)('Configured inputs', configuredInputs.map((i) => typeof i === 'string' ? i : JSON.stringify(i)));
|
|
118
|
+
}
|
|
119
|
+
(0, utils_1.printList)('External dependencies', [...data.external].sort());
|
|
120
|
+
(0, utils_1.printList)('Runtime inputs', [...data.runtime].sort());
|
|
121
|
+
(0, utils_1.printList)('Environment variables', [...data.environment].sort());
|
|
122
|
+
(0, utils_1.printList)(`Files (${data.files.length})`, [...data.files, ...data.depOutputs].sort());
|
|
123
|
+
}
|
|
124
|
+
function renderCheckInput(data) {
|
|
125
|
+
const c = (0, utils_1.pc)();
|
|
126
|
+
const categoryLabel = data.matchedCategory
|
|
127
|
+
? ` (${data.matchedCategory})`
|
|
128
|
+
: '';
|
|
129
|
+
if (data.isInput) {
|
|
130
|
+
console.log(`${c.green('✓')} ${c.bold(data.value)} is an input for ${c.cyan(data.project)}:${c.green(data.target)}${categoryLabel}`);
|
|
131
|
+
}
|
|
132
|
+
else if (data.containedInputFiles.length > 0) {
|
|
133
|
+
console.log(`${c.yellow('~')} ${c.bold(data.file)} is a directory containing ${c.bold(String(data.containedInputFiles.length))} input file(s) for ${c.cyan(data.project)}:${c.green(data.target)}`);
|
|
134
|
+
for (const f of [...data.containedInputFiles].sort())
|
|
135
|
+
console.log(` ${f}`);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
console.log(`${c.red('✗')} ${c.bold(data.value)} is ${c.red('not')} an input for ${c.cyan(data.project)}:${c.green(data.target)}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function renderBatchCheckInputs(results, projectName, targetName) {
|
|
142
|
+
const c = (0, utils_1.pc)();
|
|
143
|
+
const label = `${c.cyan(projectName)}:${c.green(targetName)}`;
|
|
144
|
+
const matched = [];
|
|
145
|
+
const directories = [];
|
|
146
|
+
const unmatched = [];
|
|
147
|
+
for (const r of results) {
|
|
148
|
+
if (r.isInput) {
|
|
149
|
+
matched.push(r.value);
|
|
150
|
+
}
|
|
151
|
+
else if (r.containedInputFiles.length > 0) {
|
|
152
|
+
directories.push({ value: r.file, count: r.containedInputFiles.length });
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
unmatched.push(r.value);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (matched.length > 0 || directories.length > 0) {
|
|
159
|
+
console.log(`\n${c.green('✓')} These arguments were inputs for ${label}:`);
|
|
160
|
+
for (const v of matched)
|
|
161
|
+
console.log(` ${v}`);
|
|
162
|
+
for (const d of directories) {
|
|
163
|
+
console.log(` ${d.value} (directory containing ${d.count} input files)`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (unmatched.length > 0) {
|
|
167
|
+
console.log(`\n${c.red('✗')} These arguments were ${c.red('not')} inputs for ${label}:`);
|
|
168
|
+
for (const v of unmatched)
|
|
169
|
+
console.log(` ${v}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function renderCustomHasherWarning(projectName, targetName, args) {
|
|
173
|
+
const c = (0, utils_1.pc)();
|
|
174
|
+
const label = `${c.cyan(projectName)}:${c.green(targetName)}`;
|
|
175
|
+
if (args.json) {
|
|
176
|
+
console.log(JSON.stringify({
|
|
177
|
+
project: projectName,
|
|
178
|
+
target: targetName,
|
|
179
|
+
warning: 'This target uses a custom hasher. Configured inputs do not affect the cache hash.',
|
|
180
|
+
}, null, 2));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
console.log(`\n${c.yellow('⚠')} ${label} uses a ${c.yellow('custom hasher')}.`);
|
|
184
|
+
console.log(` Configured inputs do not affect the cache hash for this target.`);
|
|
185
|
+
console.log(` The executor's hasher determines what is included in the hash.`);
|
|
186
|
+
}
|