@blzsky/variant 0.2.0
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/LICENSE +20 -0
- package/README.md +177 -0
- package/dist/build-2LO7GD2S.js +63 -0
- package/dist/check-ZTKGGF4M.js +44 -0
- package/dist/chunk-3E5LBU3O.js +180 -0
- package/dist/chunk-4LLK2S4R.js +630 -0
- package/dist/chunk-6J4XDG44.js +14 -0
- package/dist/chunk-CXNXZLDG.js +13 -0
- package/dist/chunk-DRMASVYN.js +25 -0
- package/dist/chunk-GDSZFIHM.js +29 -0
- package/dist/chunk-ISRF5F3Q.js +68 -0
- package/dist/chunk-KSHWC2XN.js +78 -0
- package/dist/chunk-LJDDS4RR.js +91 -0
- package/dist/chunk-LXKLCLL6.js +91 -0
- package/dist/chunk-MZZOE7L4.js +26 -0
- package/dist/chunk-NSNZOH5P.js +31 -0
- package/dist/chunk-O4LZKXNZ.js +301 -0
- package/dist/chunk-RGD422OM.js +108 -0
- package/dist/chunk-RVXUCJYA.js +81 -0
- package/dist/chunk-SWPVR2DF.js +468 -0
- package/dist/chunk-V22IPJ7A.js +64 -0
- package/dist/chunk-V5CTGXMM.js +256 -0
- package/dist/chunk-VTJ67TT5.js +238 -0
- package/dist/chunk-XTYVVUWW.js +279 -0
- package/dist/chunk-XUBWCTJZ.js +100 -0
- package/dist/chunk-YYGCSKIQ.js +29 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +225 -0
- package/dist/diff-GFI6RAEA.js +60 -0
- package/dist/doctor-GH4RZVEH.js +127 -0
- package/dist/env-QORDD6FQ.js +24 -0
- package/dist/impact-AF453PLK.js +702 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.js +7 -0
- package/dist/init-KJIUNGAN.js +158 -0
- package/dist/insight-DZ5NQY6D.js +29 -0
- package/dist/pr-UFZRZX6S.js +152 -0
- package/dist/run-6PNH4QRA.js +40 -0
- package/dist/symbol-graph-YYUEMZGR.js +22 -0
- package/dist/tsconfig-paths-E3UEDGXZ.js +10 -0
- package/dist/workspace-X5FUBTY3.js +186 -0
- package/package.json +86 -0
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
import {
|
|
2
|
+
detectProject,
|
|
3
|
+
genericAdapter,
|
|
4
|
+
nextAdapter,
|
|
5
|
+
nextPlugin,
|
|
6
|
+
viteAdapter
|
|
7
|
+
} from "./chunk-V5CTGXMM.js";
|
|
8
|
+
import {
|
|
9
|
+
loadConfig
|
|
10
|
+
} from "./chunk-RGD422OM.js";
|
|
11
|
+
import {
|
|
12
|
+
getColors
|
|
13
|
+
} from "./chunk-YYGCSKIQ.js";
|
|
14
|
+
import {
|
|
15
|
+
changedFilesToPackages,
|
|
16
|
+
getChangedFiles
|
|
17
|
+
} from "./chunk-MZZOE7L4.js";
|
|
18
|
+
import {
|
|
19
|
+
computeAffectedPackages,
|
|
20
|
+
loadPackageGraph,
|
|
21
|
+
tasksFromPackageGraph
|
|
22
|
+
} from "./chunk-3E5LBU3O.js";
|
|
23
|
+
import {
|
|
24
|
+
ConfigError,
|
|
25
|
+
CycleError
|
|
26
|
+
} from "./chunk-RVXUCJYA.js";
|
|
27
|
+
import {
|
|
28
|
+
errorLines
|
|
29
|
+
} from "./chunk-6J4XDG44.js";
|
|
30
|
+
import {
|
|
31
|
+
getPrinter
|
|
32
|
+
} from "./chunk-V22IPJ7A.js";
|
|
33
|
+
|
|
34
|
+
// src/adapters/frameworks/plugin.ts
|
|
35
|
+
var wrapFrameworkAsPlugin = (a) => ({
|
|
36
|
+
name: `framework:${a.name}`,
|
|
37
|
+
hooks: {
|
|
38
|
+
onDetect: async (ctx) => {
|
|
39
|
+
if (!await Promise.resolve(a.detect(ctx.cwd))) return;
|
|
40
|
+
ctx.framework = ctx.framework ?? a.name;
|
|
41
|
+
if (!ctx.tasks["dev"]?.command) {
|
|
42
|
+
ctx.tasks["dev"] = { ...ctx.tasks["dev"], command: a.devCommand() };
|
|
43
|
+
}
|
|
44
|
+
if (!ctx.tasks["build"]?.command) {
|
|
45
|
+
ctx.tasks["build"] = {
|
|
46
|
+
...ctx.tasks["build"],
|
|
47
|
+
command: a.buildCommand()
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// src/core/execution/scheduler.ts
|
|
55
|
+
async function runScheduled(target, graph, runner, options) {
|
|
56
|
+
const levels = graph.toLevels(target);
|
|
57
|
+
const allTasks = levels.flat();
|
|
58
|
+
const remainingDeps = /* @__PURE__ */ new Map();
|
|
59
|
+
const dependents = /* @__PURE__ */ new Map();
|
|
60
|
+
for (const t of allTasks) {
|
|
61
|
+
remainingDeps.set(t, 0);
|
|
62
|
+
dependents.set(t, /* @__PURE__ */ new Set());
|
|
63
|
+
}
|
|
64
|
+
for (const t of allTasks) {
|
|
65
|
+
for (const dep of graph.getDependencies(t)) {
|
|
66
|
+
if (remainingDeps.has(dep)) {
|
|
67
|
+
remainingDeps.set(t, (remainingDeps.get(t) ?? 0) + 1);
|
|
68
|
+
dependents.get(dep)?.add(t);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const priorityOf = options.priorityOf ?? (() => 0);
|
|
73
|
+
const ready = [];
|
|
74
|
+
for (const [t, n] of remainingDeps) {
|
|
75
|
+
if (n === 0) ready.push(t);
|
|
76
|
+
}
|
|
77
|
+
ready.sort((a, b) => priorityOf(a) - priorityOf(b));
|
|
78
|
+
let inFlight = 0;
|
|
79
|
+
let firstError = null;
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
const tryDrain = () => {
|
|
82
|
+
if (firstError !== null && inFlight === 0) {
|
|
83
|
+
reject(firstError);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
while (firstError === null && inFlight < options.concurrency && ready.length > 0) {
|
|
87
|
+
const next = ready.shift();
|
|
88
|
+
if (next === void 0) continue;
|
|
89
|
+
inFlight++;
|
|
90
|
+
runner(next).then(() => {
|
|
91
|
+
for (const dep of dependents.get(next) ?? []) {
|
|
92
|
+
const left = (remainingDeps.get(dep) ?? 0) - 1;
|
|
93
|
+
remainingDeps.set(dep, left);
|
|
94
|
+
if (left === 0) {
|
|
95
|
+
insertSorted(ready, dep, priorityOf);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}).catch((err) => {
|
|
99
|
+
if (firstError === null) firstError = err;
|
|
100
|
+
}).finally(() => {
|
|
101
|
+
inFlight--;
|
|
102
|
+
if (ready.length === 0 && inFlight === 0 && [...remainingDeps.values()].every((n) => n <= 0)) {
|
|
103
|
+
firstError === null ? resolve() : reject(firstError);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
tryDrain();
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
tryDrain();
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function priorityFromConfig(config, tasks) {
|
|
114
|
+
const policy = config.scheduler?.policy;
|
|
115
|
+
if (policy === "light-first") {
|
|
116
|
+
return (task) => tasks[task]?.cpuHeavy ? 1 : 0;
|
|
117
|
+
}
|
|
118
|
+
if (policy === "pack-heavy") {
|
|
119
|
+
return (task) => tasks[task]?.cpuHeavy ? 0 : 1;
|
|
120
|
+
}
|
|
121
|
+
return void 0;
|
|
122
|
+
}
|
|
123
|
+
function insertSorted(arr, item, priorityOf) {
|
|
124
|
+
const p = priorityOf(item);
|
|
125
|
+
let lo = 0;
|
|
126
|
+
let hi = arr.length;
|
|
127
|
+
while (lo < hi) {
|
|
128
|
+
const mid = lo + hi >>> 1;
|
|
129
|
+
const midTask = arr[mid];
|
|
130
|
+
if (midTask === void 0 || priorityOf(midTask) <= p) lo = mid + 1;
|
|
131
|
+
else hi = mid;
|
|
132
|
+
}
|
|
133
|
+
arr.splice(lo, 0, item);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/core/graph/dag.ts
|
|
137
|
+
var TaskGraph = class {
|
|
138
|
+
tasks = /* @__PURE__ */ new Set();
|
|
139
|
+
deps = /* @__PURE__ */ new Map();
|
|
140
|
+
// task -> set of tasks it depends on
|
|
141
|
+
levelCache = /* @__PURE__ */ new Map();
|
|
142
|
+
addTask(name) {
|
|
143
|
+
if (!this.tasks.has(name)) {
|
|
144
|
+
this.tasks.add(name);
|
|
145
|
+
this.deps.set(name, /* @__PURE__ */ new Set());
|
|
146
|
+
this.levelCache.clear();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
addDependency(task, dependsOn) {
|
|
150
|
+
this.addTask(task);
|
|
151
|
+
this.addTask(dependsOn);
|
|
152
|
+
const taskDeps = this.deps.get(task);
|
|
153
|
+
taskDeps?.add(dependsOn);
|
|
154
|
+
this.levelCache.clear();
|
|
155
|
+
}
|
|
156
|
+
getDependencies(task) {
|
|
157
|
+
return this.deps.get(task) ?? /* @__PURE__ */ new Set();
|
|
158
|
+
}
|
|
159
|
+
toLevels(target) {
|
|
160
|
+
const cached = this.levelCache.get(target);
|
|
161
|
+
if (cached !== void 0) {
|
|
162
|
+
return cached.map((level) => [...level]);
|
|
163
|
+
}
|
|
164
|
+
if (!this.tasks.has(target)) {
|
|
165
|
+
throw new ConfigError(`Task "${target}" not found in graph`);
|
|
166
|
+
}
|
|
167
|
+
const subgraph = /* @__PURE__ */ new Set();
|
|
168
|
+
const stack = [target];
|
|
169
|
+
while (stack.length) {
|
|
170
|
+
const node = stack.pop();
|
|
171
|
+
if (node === void 0) continue;
|
|
172
|
+
if (subgraph.has(node)) continue;
|
|
173
|
+
subgraph.add(node);
|
|
174
|
+
for (const dep of this.deps.get(node) ?? []) {
|
|
175
|
+
stack.push(dep);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
179
|
+
for (const node of subgraph) inDegree.set(node, 0);
|
|
180
|
+
for (const node of subgraph) {
|
|
181
|
+
for (const dep of this.deps.get(node) ?? []) {
|
|
182
|
+
if (subgraph.has(dep)) {
|
|
183
|
+
inDegree.set(dep, (inDegree.get(dep) ?? 0) + 1);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const levels = [];
|
|
188
|
+
let queue = [...subgraph].filter((n) => inDegree.get(n) === 0);
|
|
189
|
+
let processed = 0;
|
|
190
|
+
while (queue.length) {
|
|
191
|
+
levels.push([...queue].sort());
|
|
192
|
+
processed += queue.length;
|
|
193
|
+
const next = [];
|
|
194
|
+
for (const node of queue) {
|
|
195
|
+
for (const dep of this.deps.get(node) ?? []) {
|
|
196
|
+
if (subgraph.has(dep)) {
|
|
197
|
+
const newDeg = (inDegree.get(dep) ?? 0) - 1;
|
|
198
|
+
inDegree.set(dep, newDeg);
|
|
199
|
+
if (newDeg === 0) next.push(dep);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
queue = next;
|
|
204
|
+
}
|
|
205
|
+
if (processed < subgraph.size) {
|
|
206
|
+
const remaining = [...subgraph].filter((n) => (inDegree.get(n) ?? 0) > 0);
|
|
207
|
+
throw new CycleError(remaining);
|
|
208
|
+
}
|
|
209
|
+
const result = levels.reverse();
|
|
210
|
+
this.levelCache.set(
|
|
211
|
+
target,
|
|
212
|
+
result.map((level) => [...level])
|
|
213
|
+
);
|
|
214
|
+
return result;
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// src/core/graph/planner.ts
|
|
219
|
+
function buildGraph(config) {
|
|
220
|
+
const graph = new TaskGraph();
|
|
221
|
+
for (const [name, task] of Object.entries(config.tasks)) {
|
|
222
|
+
graph.addTask(name);
|
|
223
|
+
task.dependsOn?.forEach((dep) => {
|
|
224
|
+
graph.addDependency(name, dep);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
return graph;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// src/core/plugins/registry.ts
|
|
231
|
+
var swallowErrors = () => {
|
|
232
|
+
};
|
|
233
|
+
var PluginRegistry = class {
|
|
234
|
+
plugins = [];
|
|
235
|
+
onError;
|
|
236
|
+
constructor(onError = swallowErrors) {
|
|
237
|
+
this.onError = onError;
|
|
238
|
+
}
|
|
239
|
+
register(plugin) {
|
|
240
|
+
this.plugins.push(plugin);
|
|
241
|
+
}
|
|
242
|
+
list() {
|
|
243
|
+
return this.plugins;
|
|
244
|
+
}
|
|
245
|
+
async runOnDetect(ctx) {
|
|
246
|
+
for (const p of this.plugins) {
|
|
247
|
+
const hook = p.hooks?.onDetect;
|
|
248
|
+
if (!hook) continue;
|
|
249
|
+
try {
|
|
250
|
+
await hook(ctx);
|
|
251
|
+
} catch (err) {
|
|
252
|
+
this.onError(err, p.name, "onDetect");
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Extra hash inputs from every plugin, deduped and sorted so the cache key
|
|
258
|
+
* does not depend on plugin registration order.
|
|
259
|
+
*/
|
|
260
|
+
async runOnHash(task, files) {
|
|
261
|
+
const acc = /* @__PURE__ */ new Set();
|
|
262
|
+
for (const p of this.plugins) {
|
|
263
|
+
const hook = p.hooks?.onHash;
|
|
264
|
+
if (!hook) continue;
|
|
265
|
+
try {
|
|
266
|
+
const out = await hook(task, Array.from(files));
|
|
267
|
+
if (Array.isArray(out)) for (const v of out) acc.add(v);
|
|
268
|
+
} catch (err) {
|
|
269
|
+
this.onError(err, p.name, "onHash", task);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return [...acc].sort();
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* True when the task should be skipped. One plugin vetoing is enough — a
|
|
276
|
+
* plugin that knows the work is unnecessary is not outvoted by plugins
|
|
277
|
+
* that merely have no opinion.
|
|
278
|
+
*/
|
|
279
|
+
async runOnBeforeExecute(task) {
|
|
280
|
+
let skip = false;
|
|
281
|
+
for (const p of this.plugins) {
|
|
282
|
+
const hook = p.hooks?.onBeforeExecute;
|
|
283
|
+
if (!hook) continue;
|
|
284
|
+
try {
|
|
285
|
+
const out = await hook(task);
|
|
286
|
+
if (out === false) skip = true;
|
|
287
|
+
} catch (err) {
|
|
288
|
+
this.onError(err, p.name, "onBeforeExecute", task);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return skip;
|
|
292
|
+
}
|
|
293
|
+
async runOnAfterExecute(task, result) {
|
|
294
|
+
for (const p of this.plugins) {
|
|
295
|
+
const hook = p.hooks?.onAfterExecute;
|
|
296
|
+
if (!hook) continue;
|
|
297
|
+
try {
|
|
298
|
+
await hook(task, result);
|
|
299
|
+
} catch (err) {
|
|
300
|
+
this.onError(err, p.name, "onAfterExecute", task);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
// src/core/provenance/capture.ts
|
|
307
|
+
function packageOfTask(taskId) {
|
|
308
|
+
const separator = taskId.lastIndexOf(":");
|
|
309
|
+
return separator === -1 ? void 0 : taskId.slice(0, separator);
|
|
310
|
+
}
|
|
311
|
+
function isAlwaysRun(strategy, task) {
|
|
312
|
+
return strategy === "strict" || (task.inputs?.length ?? 0) === 0;
|
|
313
|
+
}
|
|
314
|
+
function isDirty(taskId, affected) {
|
|
315
|
+
if (affected === void 0) return true;
|
|
316
|
+
const owner = packageOfTask(taskId);
|
|
317
|
+
return owner === void 0 || affected.has(owner);
|
|
318
|
+
}
|
|
319
|
+
function reverseAdjacency(tasks, graph) {
|
|
320
|
+
const dependents = /* @__PURE__ */ new Map();
|
|
321
|
+
for (const taskId of Object.keys(tasks)) {
|
|
322
|
+
for (const upstream of graph.getDependencies(taskId)) {
|
|
323
|
+
const existing = dependents.get(upstream);
|
|
324
|
+
if (existing === void 0) dependents.set(upstream, [taskId]);
|
|
325
|
+
else existing.push(taskId);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return dependents;
|
|
329
|
+
}
|
|
330
|
+
function seedReason(taskId, input) {
|
|
331
|
+
const task = input.tasks[taskId] ?? {};
|
|
332
|
+
if (isAlwaysRun(input.strategy, task)) return { kind: "always" };
|
|
333
|
+
return { kind: "affected-by", changedFiles: [...input.changedFiles ?? []] };
|
|
334
|
+
}
|
|
335
|
+
function buildProvenance(input) {
|
|
336
|
+
const dependents = reverseAdjacency(input.tasks, input.graph);
|
|
337
|
+
const provenance = /* @__PURE__ */ new Map();
|
|
338
|
+
for (const taskId of Object.keys(input.tasks)) {
|
|
339
|
+
provenance.set(taskId, {
|
|
340
|
+
taskId,
|
|
341
|
+
reason: seedReason(taskId, input),
|
|
342
|
+
// Sorted so a reason block never reorders between identical runs.
|
|
343
|
+
dirtyDependents: (dependents.get(taskId) ?? []).filter((dependent) => isDirty(dependent, input.affectedPackages)).sort(),
|
|
344
|
+
upstreamTasks: [...input.graph.getDependencies(taskId)].sort()
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
return provenance;
|
|
348
|
+
}
|
|
349
|
+
function recordCacheMiss(provenance, taskId, expectedHash, actualHash) {
|
|
350
|
+
const existing = provenance?.get(taskId);
|
|
351
|
+
if (existing === void 0) return;
|
|
352
|
+
existing.reason = { kind: "cache-miss", expectedHash, actualHash };
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// src/cli/render/plugin-errors.ts
|
|
356
|
+
var reportPluginError = (err, pluginName, hook, task) => {
|
|
357
|
+
const colors = getColors();
|
|
358
|
+
const where = task ? `${pluginName}.${hook} (${task})` : `${pluginName}.${hook}`;
|
|
359
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
360
|
+
errorLines(
|
|
361
|
+
getPrinter(),
|
|
362
|
+
`${colors.yellow("[variant plugin]")} ${where} threw: ${detail}`
|
|
363
|
+
);
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
// src/cli/context.ts
|
|
367
|
+
var EMPTY_PACKAGE_GRAPH = {
|
|
368
|
+
packages: [],
|
|
369
|
+
edges: /* @__PURE__ */ new Map()
|
|
370
|
+
};
|
|
371
|
+
async function createContext(cwd = process.cwd(), options = {}) {
|
|
372
|
+
const [rawConfig, { pm, runtime, framework }] = await Promise.all([
|
|
373
|
+
loadConfig(cwd),
|
|
374
|
+
detectProject(cwd)
|
|
375
|
+
]);
|
|
376
|
+
const workspaceEnabled = rawConfig.workspace?.enabled === true;
|
|
377
|
+
const scopeEnabled = options.scope !== false && rawConfig.git?.enabled !== false;
|
|
378
|
+
const packageGraphPromise = workspaceEnabled ? loadPackageGraph(cwd) : scopeEnabled ? loadPackageGraph(cwd).catch(() => EMPTY_PACKAGE_GRAPH) : void 0;
|
|
379
|
+
const changedFilesPromise = scopeEnabled ? getChangedFiles(
|
|
380
|
+
rawConfig.git?.baseRef === void 0 ? { cwd } : { cwd, baseRef: rawConfig.git.baseRef }
|
|
381
|
+
) : void 0;
|
|
382
|
+
const [pkgGraph, gitFiles] = await Promise.all([
|
|
383
|
+
packageGraphPromise,
|
|
384
|
+
changedFilesPromise
|
|
385
|
+
]);
|
|
386
|
+
let config = rawConfig;
|
|
387
|
+
if (workspaceEnabled && pkgGraph !== void 0) {
|
|
388
|
+
config = {
|
|
389
|
+
...config,
|
|
390
|
+
tasks: tasksFromPackageGraph(
|
|
391
|
+
pkgGraph,
|
|
392
|
+
config.tasks,
|
|
393
|
+
config.workspace?.scripts,
|
|
394
|
+
pm.name
|
|
395
|
+
)
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
let packageScopes;
|
|
399
|
+
let affectedPackages;
|
|
400
|
+
let changedFiles;
|
|
401
|
+
if (gitFiles != null) {
|
|
402
|
+
changedFiles = gitFiles;
|
|
403
|
+
const graph2 = pkgGraph ?? EMPTY_PACKAGE_GRAPH;
|
|
404
|
+
const changed = changedFilesToPackages(gitFiles, graph2, cwd);
|
|
405
|
+
if (changed.size > 0) {
|
|
406
|
+
const affected = computeAffectedPackages(changed, graph2);
|
|
407
|
+
packageScopes = graph2.packages.filter((p) => affected.has(p.name)).map((p) => p.dir);
|
|
408
|
+
affectedPackages = affected;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
const cacheDir = config.cache.directory;
|
|
412
|
+
const plugins = new PluginRegistry(reportPluginError);
|
|
413
|
+
plugins.register(wrapFrameworkAsPlugin(nextAdapter));
|
|
414
|
+
plugins.register(wrapFrameworkAsPlugin(viteAdapter));
|
|
415
|
+
plugins.register(wrapFrameworkAsPlugin(genericAdapter));
|
|
416
|
+
plugins.register(nextPlugin);
|
|
417
|
+
await plugins.runOnDetect({
|
|
418
|
+
cwd,
|
|
419
|
+
pm: pm.name,
|
|
420
|
+
framework: framework?.name ?? null,
|
|
421
|
+
tasks: config.tasks
|
|
422
|
+
});
|
|
423
|
+
const graph = buildGraph(config);
|
|
424
|
+
const provenance = buildProvenance({
|
|
425
|
+
tasks: config.tasks,
|
|
426
|
+
graph,
|
|
427
|
+
strategy: config.strategy,
|
|
428
|
+
...changedFiles !== void 0 ? { changedFiles } : {},
|
|
429
|
+
...affectedPackages !== void 0 ? { affectedPackages } : {}
|
|
430
|
+
});
|
|
431
|
+
return {
|
|
432
|
+
cwd,
|
|
433
|
+
config,
|
|
434
|
+
pm: pm.name,
|
|
435
|
+
runtime: { primary: runtime.name, fallback: "node" },
|
|
436
|
+
framework: framework?.name ?? null,
|
|
437
|
+
graph,
|
|
438
|
+
cacheDir,
|
|
439
|
+
plugins,
|
|
440
|
+
provenance,
|
|
441
|
+
...packageScopes !== void 0 ? { packageScopes } : {},
|
|
442
|
+
...affectedPackages !== void 0 ? { affectedPackages } : {}
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
function toRunOptions(ctx, overrides = {}) {
|
|
446
|
+
const schedulerEnabled = ctx.config.scheduler?.policy !== void 0;
|
|
447
|
+
const derivedPriorityOf = schedulerEnabled ? priorityFromConfig(ctx.config, ctx.config.tasks) : void 0;
|
|
448
|
+
return {
|
|
449
|
+
cwd: ctx.cwd,
|
|
450
|
+
cacheDir: ctx.cacheDir,
|
|
451
|
+
pm: ctx.pm,
|
|
452
|
+
config: ctx.config,
|
|
453
|
+
tasks: ctx.config.tasks,
|
|
454
|
+
plugins: ctx.plugins,
|
|
455
|
+
provenance: ctx.provenance,
|
|
456
|
+
...ctx.packageScopes !== void 0 ? { packageScopes: ctx.packageScopes } : {},
|
|
457
|
+
...schedulerEnabled ? { useScheduler: true } : {},
|
|
458
|
+
...derivedPriorityOf !== void 0 ? { priorityOf: derivedPriorityOf } : {},
|
|
459
|
+
...overrides.concurrency !== void 0 ? { concurrency: overrides.concurrency } : {}
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
export {
|
|
464
|
+
runScheduled,
|
|
465
|
+
recordCacheMiss,
|
|
466
|
+
createContext,
|
|
467
|
+
toRunOptions
|
|
468
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// src/cli/visuals/printer.ts
|
|
2
|
+
var Printer = class _Printer {
|
|
3
|
+
mode;
|
|
4
|
+
out;
|
|
5
|
+
err;
|
|
6
|
+
constructor(mode, streams = {}) {
|
|
7
|
+
this.mode = mode;
|
|
8
|
+
this.out = streams.stdout ?? process.stdout;
|
|
9
|
+
this.err = streams.stderr ?? process.stderr;
|
|
10
|
+
}
|
|
11
|
+
static fromFlags(flags = {}, streams) {
|
|
12
|
+
const quiet = flags.quiet ?? 0;
|
|
13
|
+
const verbose = flags.verbose ?? 0;
|
|
14
|
+
if (quiet === 1) return new _Printer("quiet", streams);
|
|
15
|
+
if (quiet > 1) return new _Printer("silent", streams);
|
|
16
|
+
if (verbose > 0) return new _Printer("verbose", streams);
|
|
17
|
+
if (flags.noProgress) return new _Printer("no-progress", streams);
|
|
18
|
+
return new _Printer("default", streams);
|
|
19
|
+
}
|
|
20
|
+
get stdoutEnabled() {
|
|
21
|
+
return this.mode !== "silent" && this.mode !== "quiet";
|
|
22
|
+
}
|
|
23
|
+
get stderrEnabled() {
|
|
24
|
+
return this.mode !== "silent" && this.mode !== "quiet";
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether animated progress may draw: only in default mode on a TTY.
|
|
28
|
+
* Verbose hides bars so they don't interleave with debug logs, and
|
|
29
|
+
* `VARIANT_TEST_NO_CLI_PROGRESS` suppresses them because concurrent bar
|
|
30
|
+
* output is non-deterministic and breaks snapshot tests.
|
|
31
|
+
*/
|
|
32
|
+
get progressEnabled() {
|
|
33
|
+
if (this.mode !== "default" || this.err.isTTY !== true) return false;
|
|
34
|
+
const testFlag = process.env["VARIANT_TEST_NO_CLI_PROGRESS"];
|
|
35
|
+
return testFlag === void 0 || testFlag === "";
|
|
36
|
+
}
|
|
37
|
+
/** The raw stderr sink, for renderers that manage their own ANSI drawing. */
|
|
38
|
+
get progressStream() {
|
|
39
|
+
return this.err;
|
|
40
|
+
}
|
|
41
|
+
stdout(text) {
|
|
42
|
+
if (this.stdoutEnabled) this.out.write(text);
|
|
43
|
+
}
|
|
44
|
+
stderr(text) {
|
|
45
|
+
if (this.stderrEnabled) this.err.write(text);
|
|
46
|
+
}
|
|
47
|
+
/** Write a debug line, shown only in verbose mode. */
|
|
48
|
+
debug(text) {
|
|
49
|
+
if (this.mode === "verbose") this.err.write(text);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var globalPrinter = new Printer("default");
|
|
53
|
+
function setGlobalPrinter(printer) {
|
|
54
|
+
globalPrinter = printer;
|
|
55
|
+
}
|
|
56
|
+
function getPrinter() {
|
|
57
|
+
return globalPrinter;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export {
|
|
61
|
+
Printer,
|
|
62
|
+
setGlobalPrinter,
|
|
63
|
+
getPrinter
|
|
64
|
+
};
|