nx 14.4.0-beta.0 → 14.4.0-beta.3

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