nx 14.3.6 → 14.4.0-beta.2
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/CHANGELOG.md +1 -1
- package/package.json +4 -4
- package/schemas/nx-schema.json +65 -0
- package/schemas/project-schema.json +67 -0
- package/src/adapter/compat.js +7 -2
- package/src/adapter/compat.js.map +1 -1
- package/src/command-line/affected.js +6 -6
- package/src/command-line/affected.js.map +1 -1
- package/src/command-line/format.js +6 -6
- package/src/command-line/format.js.map +1 -1
- package/src/command-line/generate.js +7 -3
- package/src/command-line/generate.js.map +1 -1
- package/src/command-line/print-affected.d.ts +4 -2
- package/src/command-line/print-affected.js.map +1 -1
- package/src/command-line/read-environment.d.ts +3 -0
- package/src/command-line/read-environment.js +3 -0
- package/src/command-line/read-environment.js.map +1 -1
- package/src/command-line/run-many.js +4 -4
- package/src/command-line/run-many.js.map +1 -1
- package/src/command-line/run-one.js +7 -7
- package/src/command-line/run-one.js.map +1 -1
- package/src/command-line/run.d.ts +2 -1
- package/src/command-line/run.js +4 -3
- package/src/command-line/run.js.map +1 -1
- package/src/config/configuration.d.ts +3 -0
- package/src/config/configuration.js +3 -0
- package/src/config/configuration.js.map +1 -1
- package/src/config/nx-json.d.ts +8 -1
- package/src/config/project-graph.d.ts +7 -0
- package/src/config/project-graph.js.map +1 -1
- package/src/config/task-graph.d.ts +3 -3
- package/src/config/workspace-json-project-json.d.ts +14 -0
- package/src/config/workspaces.js +4 -2
- package/src/config/workspaces.js.map +1 -1
- package/src/core/dep-graph/environment.js +1 -0
- package/src/core/dep-graph/favicon.ico +0 -0
- package/src/daemon/client/client.js +1 -1
- package/src/daemon/client/client.js.map +1 -1
- package/src/generators/utils/project-configuration.js +2 -1
- package/src/generators/utils/project-configuration.js.map +1 -1
- package/src/hasher/hasher.d.ts +44 -25
- package/src/hasher/hasher.js +330 -265
- package/src/hasher/hasher.js.map +1 -1
- package/src/project-graph/affected/affected-project-graph-models.d.ts +4 -3
- package/src/project-graph/affected/affected-project-graph.d.ts +2 -2
- package/src/project-graph/affected/affected-project-graph.js +4 -4
- package/src/project-graph/affected/affected-project-graph.js.map +1 -1
- package/src/project-graph/affected/locators/workspace-json-changes.js +3 -3
- package/src/project-graph/affected/locators/workspace-json-changes.js.map +1 -1
- package/src/project-graph/affected/locators/workspace-projects.js +4 -4
- package/src/project-graph/affected/locators/workspace-projects.js.map +1 -1
- package/src/project-graph/build-dependencies/explicit-package-json-dependencies.js +2 -1
- package/src/project-graph/build-dependencies/explicit-package-json-dependencies.js.map +1 -1
- package/src/project-graph/build-project-graph.d.ts +1 -1
- package/src/project-graph/build-project-graph.js +12 -12
- package/src/project-graph/build-project-graph.js.map +1 -1
- package/src/project-graph/file-utils.d.ts +4 -2
- package/src/project-graph/file-utils.js +14 -5
- package/src/project-graph/file-utils.js.map +1 -1
- package/src/project-graph/project-graph.d.ts +4 -1
- package/src/project-graph/project-graph.js +17 -1
- package/src/project-graph/project-graph.js.map +1 -1
- package/src/tasks-runner/batch/run-batch.js +3 -2
- package/src/tasks-runner/batch/run-batch.js.map +1 -1
- package/src/tasks-runner/task-orchestrator.d.ts +1 -0
- package/src/tasks-runner/task-orchestrator.js +5 -3
- package/src/tasks-runner/task-orchestrator.js.map +1 -1
- package/src/tasks-runner/tasks-schedule.d.ts +3 -1
- package/src/tasks-runner/tasks-schedule.js +9 -7
- package/src/tasks-runner/tasks-schedule.js.map +1 -1
- package/src/tasks-runner/utils.d.ts +4 -3
- package/src/tasks-runner/utils.js +7 -8
- package/src/tasks-runner/utils.js.map +1 -1
- package/src/utils/command-line-utils.d.ts +2 -1
- package/src/utils/command-line-utils.js +2 -4
- package/src/utils/command-line-utils.js.map +1 -1
- package/src/utils/package-json.d.ts +1 -0
- package/src/utils/params.js +6 -1
- package/src/utils/params.js.map +1 -1
- package/src/utils/path.d.ts +10 -0
- package/src/utils/path.js +19 -1
- package/src/utils/path.js.map +1 -1
- package/src/utils/project-graph-utils.d.ts +2 -2
- package/src/utils/versions.d.ts +1 -1
- package/src/utils/versions.js +1 -1
package/src/hasher/hasher.js
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Hasher = void 0;
|
|
3
|
+
exports.expandNamedInput = exports.splitInputsIntoSelfAndDependencies = exports.Hasher = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const workspaces_1 = require("../config/workspaces");
|
|
6
5
|
const child_process_1 = require("child_process");
|
|
7
|
-
const fs_1 = require("fs");
|
|
8
6
|
const minimatch = require("minimatch");
|
|
9
|
-
const
|
|
10
|
-
const perf_hooks_1 = require("perf_hooks");
|
|
7
|
+
const fs_1 = require("fs");
|
|
11
8
|
const typescript_1 = require("../utils/typescript");
|
|
12
|
-
const workspace_root_1 = require("../utils/workspace-root");
|
|
13
|
-
const file_utils_1 = require("../project-graph/file-utils");
|
|
14
9
|
const hashing_impl_1 = require("./hashing-impl");
|
|
15
10
|
const fileutils_1 = require("../utils/fileutils");
|
|
11
|
+
const path_1 = require("../utils/path");
|
|
12
|
+
const workspace_root_1 = require("../utils/workspace-root");
|
|
13
|
+
const path_2 = require("path");
|
|
16
14
|
/**
|
|
17
15
|
* The default hasher used by executors.
|
|
18
16
|
*/
|
|
19
17
|
class Hasher {
|
|
20
18
|
constructor(projectGraph, nxJson, options, hashing = undefined) {
|
|
21
|
-
var _a;
|
|
19
|
+
var _a, _b;
|
|
22
20
|
this.projectGraph = projectGraph;
|
|
23
21
|
this.nxJson = nxJson;
|
|
24
22
|
this.options = options;
|
|
@@ -29,34 +27,56 @@ class Hasher {
|
|
|
29
27
|
// this is only used for testing
|
|
30
28
|
this.hashing = hashing;
|
|
31
29
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
const legacyRuntimeInputs = (this.options && this.options.runtimeCacheInputs
|
|
31
|
+
? this.options.runtimeCacheInputs
|
|
32
|
+
: []).map((r) => ({ runtime: r }));
|
|
33
|
+
const legacyFilesetInputs = [
|
|
34
|
+
...Object.keys((_a = this.nxJson.implicitDependencies) !== null && _a !== void 0 ? _a : {}),
|
|
35
|
+
'nx.json',
|
|
36
|
+
//TODO: vsavkin move the special cases into explicit ts support
|
|
37
|
+
'package-lock.json',
|
|
38
|
+
'yarn.lock',
|
|
39
|
+
'pnpm-lock.yaml',
|
|
40
|
+
// ignore files will change the set of inputs to the hasher
|
|
41
|
+
'.gitignore',
|
|
42
|
+
'.nxignore',
|
|
43
|
+
].map((d) => ({ fileset: `{workspaceRoot}/${d}` }));
|
|
44
|
+
this.taskHasher = new TaskHasher(nxJson, legacyRuntimeInputs, legacyFilesetInputs, this.projectGraph, this.readTsConfig(), this.hashing, { selectivelyHashTsConfig: (_b = this.options.selectivelyHashTsConfig) !== null && _b !== void 0 ? _b : false });
|
|
35
45
|
}
|
|
36
|
-
|
|
46
|
+
hashTask(task) {
|
|
37
47
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
const res = yield this.taskHasher.hashTask(task, [task.target.project]);
|
|
38
49
|
const command = this.hashCommand(task);
|
|
39
|
-
const values = (yield Promise.all([
|
|
40
|
-
this.projectHashes.hashProject(task.target.project, [task.target.project], filter),
|
|
41
|
-
this.implicitDepsHash(),
|
|
42
|
-
this.runtimeInputsHash(),
|
|
43
|
-
]));
|
|
44
|
-
const value = this.hashing.hashArray([
|
|
45
|
-
Hasher.version,
|
|
46
|
-
command,
|
|
47
|
-
...values.map((v) => v.value),
|
|
48
|
-
]);
|
|
49
50
|
return {
|
|
50
|
-
value,
|
|
51
|
+
value: this.hashArray([res.value, command]),
|
|
51
52
|
details: {
|
|
52
53
|
command,
|
|
53
|
-
nodes:
|
|
54
|
-
implicitDeps:
|
|
55
|
-
runtime:
|
|
54
|
+
nodes: res.details,
|
|
55
|
+
implicitDeps: {},
|
|
56
|
+
runtime: {},
|
|
56
57
|
},
|
|
57
58
|
};
|
|
58
59
|
});
|
|
59
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* @deprecated use hashTask instead
|
|
63
|
+
*/
|
|
64
|
+
hashTaskWithDepsAndContext(task) {
|
|
65
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
return this.hashTask(task);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* @deprecated hashTask will hash runtime inputs and global files
|
|
71
|
+
*/
|
|
72
|
+
hashContext() {
|
|
73
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
return {
|
|
75
|
+
implicitDeps: '',
|
|
76
|
+
runtime: '',
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
}
|
|
60
80
|
hashCommand(task) {
|
|
61
81
|
var _a, _b, _c;
|
|
62
82
|
const overrides = Object.assign({}, task.overrides);
|
|
@@ -72,21 +92,13 @@ class Hasher {
|
|
|
72
92
|
JSON.stringify(sortedOverrides),
|
|
73
93
|
]);
|
|
74
94
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
this.implicitDepsHash(),
|
|
79
|
-
this.runtimeInputsHash(),
|
|
80
|
-
]));
|
|
81
|
-
return {
|
|
82
|
-
implicitDeps: values[0],
|
|
83
|
-
runtime: values[1],
|
|
84
|
-
};
|
|
85
|
-
});
|
|
86
|
-
}
|
|
95
|
+
/**
|
|
96
|
+
* @deprecated use hashTask
|
|
97
|
+
*/
|
|
87
98
|
hashSource(task) {
|
|
88
99
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
89
|
-
|
|
100
|
+
const hash = yield this.taskHasher.hashTask(task, [task.target.project]);
|
|
101
|
+
return hash.details[`${task.target.project}:$filesets`];
|
|
90
102
|
});
|
|
91
103
|
}
|
|
92
104
|
hashArray(values) {
|
|
@@ -95,277 +107,330 @@ class Hasher {
|
|
|
95
107
|
hashFile(path) {
|
|
96
108
|
return this.hashing.hashFile(path);
|
|
97
109
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return this.runtimeInputs;
|
|
102
|
-
perf_hooks_1.performance.mark('hasher:runtime inputs hash:start');
|
|
103
|
-
this.runtimeInputs = new Promise((res, rej) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
104
|
-
const inputs = this.options && this.options.runtimeCacheInputs
|
|
105
|
-
? this.options.runtimeCacheInputs
|
|
106
|
-
: [];
|
|
107
|
-
if (inputs.length > 0) {
|
|
108
|
-
try {
|
|
109
|
-
const values = (yield Promise.all(inputs.map((input) => new Promise((res, rej) => {
|
|
110
|
-
(0, child_process_1.exec)(input, (err, stdout, stderr) => {
|
|
111
|
-
if (err) {
|
|
112
|
-
rej(err);
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
res({ input, value: `${stdout}${stderr}`.trim() });
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
}))));
|
|
119
|
-
const value = this.hashing.hashArray(values.map((v) => v.value));
|
|
120
|
-
const runtime = values.reduce((m, c) => ((m[c.input] = c.value), m), {});
|
|
121
|
-
perf_hooks_1.performance.mark('hasher:runtime inputs hash:end');
|
|
122
|
-
perf_hooks_1.performance.measure('hasher:runtime inputs hash', 'hasher:runtime inputs hash:start', 'hasher:runtime inputs hash:end');
|
|
123
|
-
res({ value, runtime });
|
|
124
|
-
}
|
|
125
|
-
catch (e) {
|
|
126
|
-
rej(new Error(`Nx failed to execute runtimeCacheInputs defined in nx.json failed:\n${e.message}`));
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
res({ value: '', runtime: {} });
|
|
131
|
-
}
|
|
132
|
-
}));
|
|
133
|
-
return this.runtimeInputs;
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
implicitDepsHash() {
|
|
137
|
-
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
138
|
-
if (this.implicitDependencies)
|
|
139
|
-
return this.implicitDependencies;
|
|
140
|
-
perf_hooks_1.performance.mark('hasher:implicit deps hash:start');
|
|
141
|
-
this.implicitDependencies = new Promise((res) => {
|
|
142
|
-
var _a, _b;
|
|
143
|
-
const implicitDeps = Object.keys((_a = this.nxJson.implicitDependencies) !== null && _a !== void 0 ? _a : {});
|
|
144
|
-
const filesWithoutPatterns = implicitDeps.filter((p) => p.indexOf('*') === -1);
|
|
145
|
-
const patterns = implicitDeps.filter((p) => p.indexOf('*') !== -1);
|
|
146
|
-
const implicitDepsFromPatterns = patterns.length > 0
|
|
147
|
-
? ((_b = this.projectGraph.allWorkspaceFiles) !== null && _b !== void 0 ? _b : [])
|
|
148
|
-
.filter((f) => !!patterns.find((pattern) => minimatch(f.file, pattern)))
|
|
149
|
-
.map((f) => f.file)
|
|
150
|
-
: [];
|
|
151
|
-
const fileNames = [
|
|
152
|
-
...filesWithoutPatterns,
|
|
153
|
-
...implicitDepsFromPatterns,
|
|
154
|
-
//TODO: vsavkin move the special cases into explicit ts support
|
|
155
|
-
'package-lock.json',
|
|
156
|
-
'yarn.lock',
|
|
157
|
-
'pnpm-lock.yaml',
|
|
158
|
-
// ignore files will change the set of inputs to the hasher
|
|
159
|
-
'.gitignore',
|
|
160
|
-
'.nxignore',
|
|
161
|
-
];
|
|
162
|
-
const fileHashes = [
|
|
163
|
-
...fileNames
|
|
164
|
-
.map((maybeRelativePath) => {
|
|
165
|
-
// Normalize the path to always be absolute and starting with workspaceRoot so we can check it exists
|
|
166
|
-
if (!maybeRelativePath.startsWith(workspace_root_1.workspaceRoot)) {
|
|
167
|
-
return (0, path_1.join)(workspace_root_1.workspaceRoot, maybeRelativePath);
|
|
168
|
-
}
|
|
169
|
-
return maybeRelativePath;
|
|
170
|
-
})
|
|
171
|
-
.filter((file) => (0, fs_1.existsSync)(file))
|
|
172
|
-
.map((file) => {
|
|
173
|
-
// we should use default file hasher here
|
|
174
|
-
const hash = this.hashing.hashFile(file);
|
|
175
|
-
return { file, hash };
|
|
176
|
-
}),
|
|
177
|
-
...this.hashNxJson(),
|
|
178
|
-
];
|
|
179
|
-
const combinedHash = this.hashing.hashArray(fileHashes.map((v) => v.hash));
|
|
180
|
-
perf_hooks_1.performance.mark('hasher:implicit deps hash:end');
|
|
181
|
-
perf_hooks_1.performance.measure('hasher:implicit deps hash', 'hasher:implicit deps hash:start', 'hasher:implicit deps hash:end');
|
|
182
|
-
res({
|
|
183
|
-
value: combinedHash,
|
|
184
|
-
files: fileHashes.reduce((m, c) => ((m[c.file] = c.hash), m), {}),
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
return this.implicitDependencies;
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
hashNxJson() {
|
|
191
|
-
const nxJsonPath = (0, path_1.join)(workspace_root_1.workspaceRoot, 'nx.json');
|
|
192
|
-
if (!(0, fs_1.existsSync)(nxJsonPath)) {
|
|
193
|
-
return [];
|
|
194
|
-
}
|
|
195
|
-
let nxJsonContents = '{}';
|
|
110
|
+
readTsConfig() {
|
|
111
|
+
var _a;
|
|
112
|
+
var _b;
|
|
196
113
|
try {
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
114
|
+
const res = (0, fileutils_1.readJsonFile)((0, typescript_1.getRootTsConfigFileName)());
|
|
115
|
+
(_a = (_b = res.compilerOptions).paths) !== null && _a !== void 0 ? _a : (_b.paths = {});
|
|
116
|
+
return res;
|
|
117
|
+
}
|
|
118
|
+
catch (_c) {
|
|
119
|
+
return {
|
|
120
|
+
compilerOptions: { paths: {} },
|
|
121
|
+
};
|
|
200
122
|
}
|
|
201
|
-
catch (_a) { }
|
|
202
|
-
return [
|
|
203
|
-
{
|
|
204
|
-
hash: this.hashing.hashArray([nxJsonContents]),
|
|
205
|
-
file: 'nx.json',
|
|
206
|
-
},
|
|
207
|
-
];
|
|
208
123
|
}
|
|
209
124
|
}
|
|
210
125
|
exports.Hasher = Hasher;
|
|
211
|
-
Hasher.version = '
|
|
212
|
-
|
|
213
|
-
|
|
126
|
+
Hasher.version = '3.0';
|
|
127
|
+
const DEFAULT_INPUTS = [
|
|
128
|
+
{
|
|
129
|
+
projects: 'self',
|
|
130
|
+
fileset: 'default',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
projects: 'dependencies',
|
|
134
|
+
input: 'default',
|
|
135
|
+
},
|
|
136
|
+
];
|
|
137
|
+
class TaskHasher {
|
|
138
|
+
constructor(nxJson, legacyRuntimeInputs, legacyFilesetInputs, projectGraph, tsConfigJson, hashing, options) {
|
|
139
|
+
this.nxJson = nxJson;
|
|
140
|
+
this.legacyRuntimeInputs = legacyRuntimeInputs;
|
|
141
|
+
this.legacyFilesetInputs = legacyFilesetInputs;
|
|
214
142
|
this.projectGraph = projectGraph;
|
|
143
|
+
this.tsConfigJson = tsConfigJson;
|
|
215
144
|
this.hashing = hashing;
|
|
216
145
|
this.options = options;
|
|
217
|
-
this.
|
|
218
|
-
this.
|
|
219
|
-
this.nxJson = this.readNxJsonConfigFile('nx.json');
|
|
220
|
-
this.tsConfigJson = this.readTsConfig();
|
|
146
|
+
this.filesetHashes = {};
|
|
147
|
+
this.runtimeHashes = {};
|
|
221
148
|
}
|
|
222
|
-
|
|
149
|
+
hashTask(task, visited) {
|
|
223
150
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
224
151
|
return Promise.resolve().then(() => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
225
152
|
var _a;
|
|
226
|
-
const
|
|
227
|
-
|
|
153
|
+
const projectNode = this.projectGraph.nodes[task.target.project];
|
|
154
|
+
if (!projectNode) {
|
|
155
|
+
return this.hashExternalDependency(task);
|
|
156
|
+
}
|
|
157
|
+
const projectGraphDeps = (_a = this.projectGraph.dependencies[task.target.project]) !== null && _a !== void 0 ? _a : [];
|
|
158
|
+
const { selfInputs, depsInputs } = this.inputs(task, projectNode);
|
|
159
|
+
const self = yield this.hashSelfInputs(task, selfInputs);
|
|
160
|
+
const deps = yield this.hashDepsTasks(depsInputs, projectGraphDeps, visited);
|
|
161
|
+
let details = {};
|
|
162
|
+
for (const s of self) {
|
|
163
|
+
details = Object.assign(Object.assign({}, details), s.details);
|
|
164
|
+
}
|
|
165
|
+
for (const s of deps) {
|
|
166
|
+
details = Object.assign(Object.assign({}, details), s.details);
|
|
167
|
+
}
|
|
168
|
+
const value = this.hashing.hashArray([
|
|
169
|
+
...self.map((d) => d.value),
|
|
170
|
+
...deps.map((d) => d.value),
|
|
171
|
+
]);
|
|
172
|
+
return { value, details };
|
|
173
|
+
}));
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
hashDepsTasks(inputs, projectGraphDeps, visited) {
|
|
177
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
178
|
+
return (yield Promise.all(inputs.map((input) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
179
|
+
return yield Promise.all(projectGraphDeps.map((d) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
228
180
|
if (visited.indexOf(d.target) > -1) {
|
|
229
181
|
return null;
|
|
230
182
|
}
|
|
231
183
|
else {
|
|
232
184
|
visited.push(d.target);
|
|
233
|
-
return yield this.
|
|
185
|
+
return yield this.hashTask({
|
|
186
|
+
id: `${d.target}:$input:${input.input}`,
|
|
187
|
+
target: {
|
|
188
|
+
project: d.target,
|
|
189
|
+
target: '$input',
|
|
190
|
+
configuration: input.input,
|
|
191
|
+
},
|
|
192
|
+
overrides: {},
|
|
193
|
+
}, visited);
|
|
234
194
|
}
|
|
235
|
-
})))
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
})
|
|
195
|
+
})));
|
|
196
|
+
}))))
|
|
197
|
+
.flat()
|
|
198
|
+
.filter((r) => !!r);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
inputs(task, projectNode) {
|
|
202
|
+
if (task.target.target === '$input') {
|
|
203
|
+
return {
|
|
204
|
+
depsInputs: [{ input: task.target.configuration }],
|
|
205
|
+
selfInputs: expandNamedInput(task.target.configuration, Object.assign(Object.assign({}, this.nxJson.namedInputs), projectNode.data.namedInputs)),
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
const targetData = projectNode.data.targets[task.target.target];
|
|
210
|
+
const targetDefaults = (this.nxJson.targetDefaults || {})[task.target.target];
|
|
211
|
+
// task from TaskGraph can be added here
|
|
212
|
+
return splitInputsIntoSelfAndDependencies(targetData.inputs || (targetDefaults === null || targetDefaults === void 0 ? void 0 : targetDefaults.inputs) || DEFAULT_INPUTS, Object.assign(Object.assign({}, this.nxJson.namedInputs), projectNode.data.namedInputs));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
hashExternalDependency(task) {
|
|
216
|
+
var _a;
|
|
217
|
+
const n = this.projectGraph.externalNodes[task.target.project];
|
|
218
|
+
const version = (_a = n === null || n === void 0 ? void 0 : n.data) === null || _a === void 0 ? void 0 : _a.version;
|
|
219
|
+
let hash;
|
|
220
|
+
if (version) {
|
|
221
|
+
hash = this.hashing.hashArray([version]);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
// unknown dependency
|
|
225
|
+
// this may occur if a file has a dependency to a npm package
|
|
226
|
+
// which is not directly registestered in package.json
|
|
227
|
+
// but only indirectly through dependencies of registered
|
|
228
|
+
// npm packages
|
|
229
|
+
// when it is at a later stage registered in package.json
|
|
230
|
+
// the cache project graph will not know this module but
|
|
231
|
+
// the new project graph will know it
|
|
232
|
+
// The actual checksum added here is of no importance as
|
|
233
|
+
// the version is unknown and may only change when some
|
|
234
|
+
// other change occurs in package.json and/or package-lock.json
|
|
235
|
+
hash = `__${task.target.project}__`;
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
value: hash,
|
|
239
|
+
details: {
|
|
240
|
+
[task.target.project]: version || hash,
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
hashSelfInputs(task, inputs) {
|
|
245
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
246
|
+
const filesets = inputs
|
|
247
|
+
.filter((r) => !!r['fileset'])
|
|
248
|
+
.map((r) => r['fileset']);
|
|
249
|
+
const projectFilesets = filesets.filter((r) => !r.startsWith('{workspaceRoot}'));
|
|
250
|
+
const rootFilesets = filesets.filter((r) => r.startsWith('{workspaceRoot}/'));
|
|
251
|
+
return Promise.all([
|
|
252
|
+
this.hashTaskFileset(task, projectFilesets),
|
|
253
|
+
...[
|
|
254
|
+
...rootFilesets,
|
|
255
|
+
...this.legacyFilesetInputs.map((r) => r.fileset),
|
|
256
|
+
].map((fileset) => this.hashRootFileset(fileset)),
|
|
257
|
+
...[...inputs, ...this.legacyRuntimeInputs]
|
|
258
|
+
.filter((r) => !r['fileset'])
|
|
259
|
+
.map((r) => r['runtime'] ? this.hashRuntime(r['runtime']) : this.hashEnv(r['env'])),
|
|
260
|
+
]);
|
|
251
261
|
});
|
|
252
262
|
}
|
|
253
|
-
|
|
263
|
+
hashRootFileset(fileset) {
|
|
254
264
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
255
|
-
const mapKey =
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
const
|
|
260
|
-
if (
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
// which is not directly registestered in package.json
|
|
271
|
-
// but only indirectly through dependencies of registered
|
|
272
|
-
// npm packages
|
|
273
|
-
// when it is at a later stage registered in package.json
|
|
274
|
-
// the cache project graph will not know this module but
|
|
275
|
-
// the new project graph will know it
|
|
276
|
-
// The actual checksum added here is of no importance as
|
|
277
|
-
// the version is unknown and may only change when some
|
|
278
|
-
// other change occurs in package.json and/or package-lock.json
|
|
279
|
-
hash = `__${projectName}__`;
|
|
265
|
+
const mapKey = fileset;
|
|
266
|
+
const withoutWorkspaceRoot = fileset.substring(16);
|
|
267
|
+
if (!this.filesetHashes[mapKey]) {
|
|
268
|
+
this.filesetHashes[mapKey] = new Promise((res) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
269
|
+
const parts = [];
|
|
270
|
+
if (fileset.indexOf('*') > -1) {
|
|
271
|
+
this.projectGraph.allWorkspaceFiles
|
|
272
|
+
.filter((f) => minimatch(f.file, withoutWorkspaceRoot))
|
|
273
|
+
.forEach((f) => {
|
|
274
|
+
parts.push(this.hashing.hashFile((0, path_2.join)(workspace_root_1.workspaceRoot, f.file)));
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
if ((0, fs_1.existsSync)((0, path_2.join)(workspace_root_1.workspaceRoot, withoutWorkspaceRoot))) {
|
|
279
|
+
parts.push(this.hashing.hashFile((0, path_2.join)(workspace_root_1.workspaceRoot, withoutWorkspaceRoot)));
|
|
280
280
|
}
|
|
281
|
-
res(hash);
|
|
282
|
-
return;
|
|
283
281
|
}
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
282
|
+
const value = this.hashing.hashArray(parts);
|
|
283
|
+
res({
|
|
284
|
+
value,
|
|
285
|
+
details: { [mapKey]: value },
|
|
286
|
+
});
|
|
287
|
+
}));
|
|
288
|
+
}
|
|
289
|
+
return this.filesetHashes[mapKey];
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
hashTaskFileset(task, filesetPatterns) {
|
|
293
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
294
|
+
const mapKey = `${task.target.project}:$filesets`;
|
|
295
|
+
if (!this.filesetHashes[mapKey]) {
|
|
296
|
+
this.filesetHashes[mapKey] = new Promise((res) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
297
|
+
const p = this.projectGraph.nodes[task.target.project];
|
|
298
|
+
const filteredFiles = this.filterFiles(p.data.files, filesetPatterns);
|
|
287
299
|
const fileNames = filteredFiles.map((f) => f.file);
|
|
288
300
|
const values = filteredFiles.map((f) => f.hash);
|
|
289
|
-
const workspaceJson = JSON.stringify((_b = this.workspaceJson.projects[projectName]) !== null && _b !== void 0 ? _b : '');
|
|
290
301
|
let tsConfig;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
tsConfig = JSON.stringify(this.tsConfigJson);
|
|
296
|
-
}
|
|
297
|
-
res(this.hashing.hashArray([
|
|
302
|
+
tsConfig = this.hashTsConfig(p);
|
|
303
|
+
const value = this.hashing.hashArray([
|
|
298
304
|
...fileNames,
|
|
299
305
|
...values,
|
|
300
|
-
|
|
306
|
+
JSON.stringify(Object.assign(Object.assign({}, p.data), { files: undefined })),
|
|
301
307
|
tsConfig,
|
|
302
|
-
])
|
|
308
|
+
]);
|
|
309
|
+
res({
|
|
310
|
+
value,
|
|
311
|
+
details: { [mapKey]: value },
|
|
312
|
+
});
|
|
303
313
|
}));
|
|
304
314
|
}
|
|
305
|
-
return this.
|
|
315
|
+
return this.filesetHashes[mapKey];
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
hashRuntime(runtime) {
|
|
319
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
320
|
+
const mapKey = `runtime:${runtime}`;
|
|
321
|
+
if (!this.runtimeHashes[mapKey]) {
|
|
322
|
+
this.runtimeHashes[mapKey] = new Promise((res, rej) => {
|
|
323
|
+
(0, child_process_1.exec)(runtime, (err, stdout, stderr) => {
|
|
324
|
+
if (err) {
|
|
325
|
+
rej(new Error(`Nx failed to execute {runtime: '${runtime}'}. ${err}.`));
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
const value = `${stdout}${stderr}`.trim();
|
|
329
|
+
res({
|
|
330
|
+
details: { [`runtime:${runtime}`]: value },
|
|
331
|
+
value,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
return this.runtimeHashes[mapKey];
|
|
306
338
|
});
|
|
307
339
|
}
|
|
308
|
-
|
|
309
|
-
return
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
file.endsWith('-spec.ts') ||
|
|
317
|
-
file.endsWith('.spec.js') ||
|
|
318
|
-
file.endsWith('.test.js') ||
|
|
319
|
-
file.endsWith('-test.js') ||
|
|
320
|
-
file.endsWith('-spec.js'));
|
|
340
|
+
hashEnv(envVarName) {
|
|
341
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
342
|
+
const value = this.hashing.hashArray([process.env[envVarName]]);
|
|
343
|
+
return {
|
|
344
|
+
details: { [`runtime:${envVarName}`]: value },
|
|
345
|
+
value,
|
|
346
|
+
};
|
|
347
|
+
});
|
|
321
348
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
349
|
+
filterFiles(files, patterns) {
|
|
350
|
+
patterns = patterns.filter((p) => p !== 'default');
|
|
351
|
+
if (patterns.length === 0)
|
|
352
|
+
return files;
|
|
353
|
+
return files.filter((f) => !!patterns.find((pattern) => minimatch(f.file, pattern)));
|
|
354
|
+
}
|
|
355
|
+
hashTsConfig(p) {
|
|
356
|
+
if (this.options.selectivelyHashTsConfig) {
|
|
357
|
+
return this.removeOtherProjectsPathRecords(p);
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
return JSON.stringify(this.tsConfigJson);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
removeOtherProjectsPathRecords(p) {
|
|
364
|
+
var _a, _b;
|
|
365
|
+
const _c = this.tsConfigJson.compilerOptions, { paths } = _c, compilerOptions = tslib_1.__rest(_c, ["paths"]);
|
|
366
|
+
const rootPath = p.data.root.split('/');
|
|
326
367
|
rootPath.shift();
|
|
327
|
-
const pathAlias =
|
|
368
|
+
const pathAlias = (0, path_1.getImportPath)((_a = this.nxJson) === null || _a === void 0 ? void 0 : _a.npmScope, rootPath.join('/'));
|
|
328
369
|
return JSON.stringify({
|
|
329
370
|
compilerOptions: Object.assign(Object.assign({}, compilerOptions), { paths: {
|
|
330
|
-
[pathAlias]: (
|
|
371
|
+
[pathAlias]: (_b = paths[pathAlias]) !== null && _b !== void 0 ? _b : [],
|
|
331
372
|
} }),
|
|
332
373
|
});
|
|
333
374
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
readWorkspaceConfigFile(path) {
|
|
349
|
-
var _a;
|
|
350
|
-
try {
|
|
351
|
-
const res = (0, fileutils_1.readJsonFile)(path);
|
|
352
|
-
(_a = res.projects) !== null && _a !== void 0 ? _a : (res.projects = {});
|
|
353
|
-
return (0, workspaces_1.resolveNewFormatWithInlineProjects)(res);
|
|
375
|
+
}
|
|
376
|
+
function splitInputsIntoSelfAndDependencies(inputs, namedInputs) {
|
|
377
|
+
const depsInputs = [];
|
|
378
|
+
const selfInputs = [];
|
|
379
|
+
for (const d of inputs) {
|
|
380
|
+
if (typeof d === 'string') {
|
|
381
|
+
if (d.startsWith('^')) {
|
|
382
|
+
depsInputs.push({ input: d.substring(1) });
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
selfInputs.push(d);
|
|
386
|
+
}
|
|
354
387
|
}
|
|
355
|
-
|
|
356
|
-
|
|
388
|
+
else {
|
|
389
|
+
if (d.projects === 'dependencies') {
|
|
390
|
+
depsInputs.push(d);
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
selfInputs.push(d);
|
|
394
|
+
}
|
|
357
395
|
}
|
|
358
396
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
397
|
+
return { depsInputs, selfInputs: expandSelfInputs(selfInputs, namedInputs) };
|
|
398
|
+
}
|
|
399
|
+
exports.splitInputsIntoSelfAndDependencies = splitInputsIntoSelfAndDependencies;
|
|
400
|
+
function expandSelfInputs(inputs, namedInputs) {
|
|
401
|
+
const expanded = [];
|
|
402
|
+
for (const d of inputs) {
|
|
403
|
+
if (typeof d === 'string') {
|
|
404
|
+
if (d.startsWith('^'))
|
|
405
|
+
throw new Error(`namedInputs definitions cannot start with ^`);
|
|
406
|
+
if (namedInputs[d]) {
|
|
407
|
+
expanded.push(...expandNamedInput(d, namedInputs));
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
expanded.push({ fileset: d });
|
|
411
|
+
}
|
|
365
412
|
}
|
|
366
|
-
|
|
367
|
-
|
|
413
|
+
else {
|
|
414
|
+
if (d.projects === 'dependencies') {
|
|
415
|
+
throw new Error(`namedInputs definitions cannot contain any inputs with projects == 'dependencies'`);
|
|
416
|
+
}
|
|
417
|
+
if (d.fileset || d.env || d.runtime) {
|
|
418
|
+
expanded.push(d);
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
expanded.push(...expandNamedInput(d.input, namedInputs));
|
|
422
|
+
}
|
|
368
423
|
}
|
|
369
424
|
}
|
|
425
|
+
return expanded;
|
|
426
|
+
}
|
|
427
|
+
function expandNamedInput(input, namedInputs) {
|
|
428
|
+
if (input === 'default')
|
|
429
|
+
return [{ fileset: 'default' }];
|
|
430
|
+
namedInputs || (namedInputs = {});
|
|
431
|
+
if (!namedInputs[input])
|
|
432
|
+
throw new Error(`Input '${input}' is not defined`);
|
|
433
|
+
return expandSelfInputs(namedInputs[input], namedInputs);
|
|
370
434
|
}
|
|
435
|
+
exports.expandNamedInput = expandNamedInput;
|
|
371
436
|
//# sourceMappingURL=hasher.js.map
|