@jujulego/jill 3.0.0-alpha.7 → 3.0.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/jill.js +0 -0
- package/dist/inked.js +1 -1
- package/dist/instrument.js +1 -1
- package/dist/job-exec.ink.js +606 -0
- package/dist/job-exec.ink.js.map +1 -0
- package/dist/list.ink.js +1 -1
- package/dist/main.js +278 -470
- package/dist/main.js.map +1 -1
- package/dist/planner.service.js +5 -5
- package/dist/planner.service.js.map +1 -1
- package/dist/tree.ink.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +20 -15
- package/dist/TaskName.js +0 -33
- package/dist/TaskName.js.map +0 -1
- package/dist/task-exec.ink.js +0 -542
- package/dist/task-exec.ink.js.map +0 -1
- package/dist/task-plan.ink.js +0 -116
- package/dist/task-plan.ink.js.map +0 -1
package/bin/jill.js
CHANGED
|
File without changes
|
package/dist/inked.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
;{try{(function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
;{try{(function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="709d1bbb-5a2d-41fa-b3b6-a52a755c1e53",e._sentryDebugIdIdentifier="sentry-dbid-709d1bbb-5a2d-41fa-b3b6-a52a755c1e53");})();}catch(e){}};!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};e.SENTRY_RELEASE={id:"3.0.0-alpha.8"};}catch(e){}}();import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { startSpan } from '@sentry/node';
|
|
3
3
|
import { useStderr, render } from 'ink';
|
|
4
4
|
import { inject$ } from '@kyrielle/injector';
|
package/dist/instrument.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
;{try{(function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
;{try{(function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c2fd80ca-6b66-4bbf-a184-cbd02d33b725",e._sentryDebugIdIdentifier="sentry-dbid-c2fd80ca-6b66-4bbf-a184-cbd02d33b725");})();}catch(e){}};!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};e.SENTRY_RELEASE={id:"3.0.0-alpha.8"};}catch(e){}}();import { init } from '@sentry/node';
|
|
2
2
|
|
|
3
3
|
init({
|
|
4
4
|
dsn: 'https://53e6d10c16975ebd025175d9836d039b@o4508229080055808.ingest.de.sentry.io/4509876546895952',
|
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
;{try{(function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c565de71-f9f2-474d-8656-f5f60a03995d",e._sentryDebugIdIdentifier="sentry-dbid-c565de71-f9f2-474d-8656-f5f60a03995d");})();}catch(e){}};!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};e.SENTRY_RELEASE={id:"3.0.0-alpha.8"};}catch(e){}}();import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { WorkloadState, isWorkloadEnded } from '@jujulego/tasks';
|
|
3
|
+
import { inject$ } from '@kyrielle/injector';
|
|
4
|
+
import { pipe$, map$, collect$, off$, waitFor$, filter$ } from 'kyrielle';
|
|
5
|
+
import process from 'node:process';
|
|
6
|
+
import { S as SCHEDULER } from './main.js';
|
|
7
|
+
import { Text, Box, Static, useStdout, useInput, useStdin } from 'ink';
|
|
8
|
+
import { createHash } from 'node:crypto';
|
|
9
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
10
|
+
import Spinner from 'ink-spinner';
|
|
11
|
+
import ms from 'pretty-ms';
|
|
12
|
+
import isUnicodeSupported from 'is-unicode-supported';
|
|
13
|
+
import { i as inked } from './inked.js';
|
|
14
|
+
import '@sentry/node';
|
|
15
|
+
import 'yargs/helpers';
|
|
16
|
+
import 'yargs';
|
|
17
|
+
import '@kyrielle/logger';
|
|
18
|
+
import 'node:fs';
|
|
19
|
+
import 'path-scurry';
|
|
20
|
+
import '@swc/helpers/_/_apply_decs_2203_r';
|
|
21
|
+
import 'node:stream/consumers';
|
|
22
|
+
import 'node:path';
|
|
23
|
+
import 'glob';
|
|
24
|
+
import 'normalize-package-data';
|
|
25
|
+
import 'semver';
|
|
26
|
+
import 'moo';
|
|
27
|
+
import 'node:child_process';
|
|
28
|
+
import 'chalk';
|
|
29
|
+
import 'slugify';
|
|
30
|
+
import '@jujulego/quick-tag';
|
|
31
|
+
import 'ajv';
|
|
32
|
+
import 'node:os';
|
|
33
|
+
import 'cosmiconfig';
|
|
34
|
+
import 'chalk-template';
|
|
35
|
+
|
|
36
|
+
// Hook
|
|
37
|
+
function useWorkflowFlatTree(workload, verbose) {
|
|
38
|
+
const [tree, setTree] = useState(()=>buildTree(workload, verbose));
|
|
39
|
+
useEffect(()=>{
|
|
40
|
+
const oldHash = hashTree(tree);
|
|
41
|
+
let dirty = false;
|
|
42
|
+
function update() {
|
|
43
|
+
if (!dirty) return;
|
|
44
|
+
const updated = buildTree(workload, verbose);
|
|
45
|
+
if (hashTree(updated) !== oldHash) {
|
|
46
|
+
setTree(updated);
|
|
47
|
+
}
|
|
48
|
+
dirty = false;
|
|
49
|
+
}
|
|
50
|
+
const off = pipe$(tree, map$(({ workload })=>workload.state$.subscribe(()=>{
|
|
51
|
+
dirty = true;
|
|
52
|
+
queueMicrotask(update);
|
|
53
|
+
})), collect$(off$()));
|
|
54
|
+
return ()=>{
|
|
55
|
+
dirty = false;
|
|
56
|
+
off.unsubscribe();
|
|
57
|
+
};
|
|
58
|
+
}, [
|
|
59
|
+
tree,
|
|
60
|
+
verbose,
|
|
61
|
+
workload
|
|
62
|
+
]);
|
|
63
|
+
return tree;
|
|
64
|
+
}
|
|
65
|
+
// Utils
|
|
66
|
+
function* listRoots(workload) {
|
|
67
|
+
const marks = new Set();
|
|
68
|
+
const queue = [
|
|
69
|
+
workload
|
|
70
|
+
];
|
|
71
|
+
while(queue.length){
|
|
72
|
+
const item = queue.shift();
|
|
73
|
+
// Mark all member of workflows, so they're not added as root
|
|
74
|
+
if (isWorkflow(item)) {
|
|
75
|
+
for (const wkl of item.workloads()){
|
|
76
|
+
marks.add(wkl.id);
|
|
77
|
+
queue.unshift(wkl);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Load job dependencies
|
|
81
|
+
if (isJob(item)) {
|
|
82
|
+
for (const dep of item.dependencies()){
|
|
83
|
+
queue.push(dep);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Ignore marked workloads
|
|
87
|
+
if (marks.has(item.id)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
yield item;
|
|
91
|
+
marks.add(item.id);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function buildTree(workload, verbose = false) {
|
|
95
|
+
const tree = [];
|
|
96
|
+
const stack = pipe$(listRoots(workload), map$((workload)=>({
|
|
97
|
+
workload,
|
|
98
|
+
level: 0
|
|
99
|
+
})), collect$());
|
|
100
|
+
while(stack.length > 0){
|
|
101
|
+
const item = stack.pop();
|
|
102
|
+
const mustShow = [
|
|
103
|
+
WorkloadState.Starting,
|
|
104
|
+
WorkloadState.Running,
|
|
105
|
+
WorkloadState.Failed
|
|
106
|
+
].includes(item.workload.state());
|
|
107
|
+
if (!verbose && !isWorkflow(item.workload) && !mustShow && item.level > 0) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
// Add to tree
|
|
111
|
+
let level = item.level;
|
|
112
|
+
if (item.workload.label !== '[hidden]') {
|
|
113
|
+
tree.push(item);
|
|
114
|
+
level++;
|
|
115
|
+
}
|
|
116
|
+
// Load "member" tasks
|
|
117
|
+
if (isWorkflow(item.workload)) {
|
|
118
|
+
const children = [
|
|
119
|
+
...item.workload.workloads()
|
|
120
|
+
].reverse();
|
|
121
|
+
for (const workload of children){
|
|
122
|
+
stack.push({
|
|
123
|
+
workload,
|
|
124
|
+
level
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return tree;
|
|
130
|
+
}
|
|
131
|
+
function isJob(workload) {
|
|
132
|
+
return 'dependencies' in workload && typeof workload.dependencies === 'function';
|
|
133
|
+
}
|
|
134
|
+
function isWorkflow(workload) {
|
|
135
|
+
return 'workloads' in workload && typeof workload.workloads === 'function';
|
|
136
|
+
}
|
|
137
|
+
function hashTree(tree) {
|
|
138
|
+
const hash = createHash('sha256');
|
|
139
|
+
for (const { workload } of tree){
|
|
140
|
+
hash.update(workload.id);
|
|
141
|
+
}
|
|
142
|
+
return hash.digest('hex');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const isSupported = !isUnicodeSupported();
|
|
146
|
+
const success = isSupported ? '✔' : '√';
|
|
147
|
+
const error = isSupported ? '✖' : '×';
|
|
148
|
+
|
|
149
|
+
function capitalize(str) {
|
|
150
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Component
|
|
154
|
+
function WorkloadName({ workload, withWorkspace, ...rest }) {
|
|
155
|
+
if (isScriptWorkflow(workload)) {
|
|
156
|
+
return /*#__PURE__*/ jsxs(Text, {
|
|
157
|
+
...rest,
|
|
158
|
+
children: [
|
|
159
|
+
"Run ",
|
|
160
|
+
/*#__PURE__*/ jsx(Text, {
|
|
161
|
+
bold: true,
|
|
162
|
+
children: workload.script
|
|
163
|
+
}),
|
|
164
|
+
" script",
|
|
165
|
+
withWorkspace && /*#__PURE__*/ jsxs(Fragment, {
|
|
166
|
+
children: [
|
|
167
|
+
' ',
|
|
168
|
+
"in ",
|
|
169
|
+
workload.workspace.name
|
|
170
|
+
]
|
|
171
|
+
})
|
|
172
|
+
]
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
let name = workload.label;
|
|
176
|
+
if (workload.type !== 'spawn') {
|
|
177
|
+
name = capitalize(name);
|
|
178
|
+
}
|
|
179
|
+
return /*#__PURE__*/ jsx(Text, {
|
|
180
|
+
...rest,
|
|
181
|
+
children: name
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
// Utils
|
|
185
|
+
function isScriptWorkflow(workload) {
|
|
186
|
+
return workload.type === 'script';
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Component
|
|
190
|
+
function WorkloadSpinner({ workload }) {
|
|
191
|
+
// Track task state
|
|
192
|
+
const [state, setState] = useState(workload.state());
|
|
193
|
+
useEffect(()=>{
|
|
194
|
+
const sub = workload.state$.subscribe(setState);
|
|
195
|
+
return sub.unsubscribe;
|
|
196
|
+
}, [
|
|
197
|
+
workload.state$
|
|
198
|
+
]);
|
|
199
|
+
// Render
|
|
200
|
+
const dim = workload.type === 'spawn';
|
|
201
|
+
const time = workload.duration().seconds() * 1000;
|
|
202
|
+
switch(state){
|
|
203
|
+
case WorkloadState.Blocked:
|
|
204
|
+
case WorkloadState.Ready:
|
|
205
|
+
case WorkloadState.Starting:
|
|
206
|
+
return /*#__PURE__*/ jsxs(Box, {
|
|
207
|
+
children: [
|
|
208
|
+
/*#__PURE__*/ jsx(Text, {
|
|
209
|
+
color: "grey",
|
|
210
|
+
children: '\u00B7'
|
|
211
|
+
}),
|
|
212
|
+
/*#__PURE__*/ jsx(Box, {
|
|
213
|
+
paddingLeft: 1,
|
|
214
|
+
children: /*#__PURE__*/ jsx(WorkloadName, {
|
|
215
|
+
color: "grey",
|
|
216
|
+
wrap: "truncate",
|
|
217
|
+
workload: workload,
|
|
218
|
+
withWorkspace: true
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
]
|
|
222
|
+
});
|
|
223
|
+
case WorkloadState.Running:
|
|
224
|
+
return /*#__PURE__*/ jsxs(Box, {
|
|
225
|
+
children: [
|
|
226
|
+
/*#__PURE__*/ jsx(Text, {
|
|
227
|
+
dimColor: dim,
|
|
228
|
+
children: /*#__PURE__*/ jsx(Spinner, {})
|
|
229
|
+
}),
|
|
230
|
+
/*#__PURE__*/ jsx(Box, {
|
|
231
|
+
paddingLeft: 1,
|
|
232
|
+
children: /*#__PURE__*/ jsx(WorkloadName, {
|
|
233
|
+
dimColor: dim,
|
|
234
|
+
wrap: "truncate",
|
|
235
|
+
workload: workload,
|
|
236
|
+
withWorkspace: true
|
|
237
|
+
})
|
|
238
|
+
})
|
|
239
|
+
]
|
|
240
|
+
});
|
|
241
|
+
case WorkloadState.Canceling:
|
|
242
|
+
return /*#__PURE__*/ jsxs(Box, {
|
|
243
|
+
children: [
|
|
244
|
+
/*#__PURE__*/ jsx(Text, {
|
|
245
|
+
dimColor: dim,
|
|
246
|
+
color: "grey",
|
|
247
|
+
children: /*#__PURE__*/ jsx(Spinner, {
|
|
248
|
+
type: "line2"
|
|
249
|
+
})
|
|
250
|
+
}),
|
|
251
|
+
/*#__PURE__*/ jsx(Box, {
|
|
252
|
+
paddingLeft: 1,
|
|
253
|
+
children: /*#__PURE__*/ jsx(WorkloadName, {
|
|
254
|
+
dimColor: dim,
|
|
255
|
+
color: "grey",
|
|
256
|
+
wrap: "truncate",
|
|
257
|
+
workload: workload,
|
|
258
|
+
withWorkspace: true
|
|
259
|
+
})
|
|
260
|
+
})
|
|
261
|
+
]
|
|
262
|
+
});
|
|
263
|
+
case WorkloadState.Succeeded:
|
|
264
|
+
return /*#__PURE__*/ jsxs(Box, {
|
|
265
|
+
children: [
|
|
266
|
+
/*#__PURE__*/ jsx(Text, {
|
|
267
|
+
color: "green",
|
|
268
|
+
children: success
|
|
269
|
+
}),
|
|
270
|
+
/*#__PURE__*/ jsx(Box, {
|
|
271
|
+
paddingLeft: 1,
|
|
272
|
+
children: /*#__PURE__*/ jsx(WorkloadName, {
|
|
273
|
+
dimColor: dim,
|
|
274
|
+
wrap: "truncate",
|
|
275
|
+
workload: workload,
|
|
276
|
+
withWorkspace: true
|
|
277
|
+
})
|
|
278
|
+
}),
|
|
279
|
+
/*#__PURE__*/ jsx(Box, {
|
|
280
|
+
paddingLeft: 1,
|
|
281
|
+
flexShrink: 0,
|
|
282
|
+
children: /*#__PURE__*/ jsxs(Text, {
|
|
283
|
+
color: dim ? 'grey' : 'dim',
|
|
284
|
+
children: [
|
|
285
|
+
"(took ",
|
|
286
|
+
ms(time),
|
|
287
|
+
")"
|
|
288
|
+
]
|
|
289
|
+
})
|
|
290
|
+
})
|
|
291
|
+
]
|
|
292
|
+
});
|
|
293
|
+
case WorkloadState.Failed:
|
|
294
|
+
return /*#__PURE__*/ jsxs(Box, {
|
|
295
|
+
children: [
|
|
296
|
+
/*#__PURE__*/ jsx(Text, {
|
|
297
|
+
color: "red",
|
|
298
|
+
children: error
|
|
299
|
+
}),
|
|
300
|
+
/*#__PURE__*/ jsx(Box, {
|
|
301
|
+
paddingLeft: 1,
|
|
302
|
+
children: /*#__PURE__*/ jsx(WorkloadName, {
|
|
303
|
+
dimColor: dim,
|
|
304
|
+
wrap: "truncate",
|
|
305
|
+
workload: workload,
|
|
306
|
+
withWorkspace: true
|
|
307
|
+
})
|
|
308
|
+
}),
|
|
309
|
+
/*#__PURE__*/ jsx(Box, {
|
|
310
|
+
paddingLeft: 1,
|
|
311
|
+
flexShrink: 0,
|
|
312
|
+
children: /*#__PURE__*/ jsxs(Text, {
|
|
313
|
+
color: dim ? 'grey' : 'dim',
|
|
314
|
+
children: [
|
|
315
|
+
"(took ",
|
|
316
|
+
ms(time),
|
|
317
|
+
")"
|
|
318
|
+
]
|
|
319
|
+
})
|
|
320
|
+
})
|
|
321
|
+
]
|
|
322
|
+
});
|
|
323
|
+
case WorkloadState.Canceled:
|
|
324
|
+
return /*#__PURE__*/ jsxs(Box, {
|
|
325
|
+
children: [
|
|
326
|
+
/*#__PURE__*/ jsx(Text, {
|
|
327
|
+
dimColor: true,
|
|
328
|
+
children: "-"
|
|
329
|
+
}),
|
|
330
|
+
/*#__PURE__*/ jsx(Box, {
|
|
331
|
+
paddingLeft: 1,
|
|
332
|
+
children: /*#__PURE__*/ jsx(WorkloadName, {
|
|
333
|
+
dimColor: true,
|
|
334
|
+
wrap: "truncate",
|
|
335
|
+
workload: workload,
|
|
336
|
+
withWorkspace: true
|
|
337
|
+
})
|
|
338
|
+
}),
|
|
339
|
+
/*#__PURE__*/ jsx(Box, {
|
|
340
|
+
paddingLeft: 1,
|
|
341
|
+
flexShrink: 0,
|
|
342
|
+
children: /*#__PURE__*/ jsxs(Text, {
|
|
343
|
+
color: dim ? 'grey' : 'dim',
|
|
344
|
+
children: [
|
|
345
|
+
"(took ",
|
|
346
|
+
ms(time),
|
|
347
|
+
")"
|
|
348
|
+
]
|
|
349
|
+
})
|
|
350
|
+
})
|
|
351
|
+
]
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Hook
|
|
357
|
+
function useScriptsStats(workloads) {
|
|
358
|
+
const [stats, setStats] = useState(()=>countScripts(workloads));
|
|
359
|
+
useEffect(()=>{
|
|
360
|
+
let dirty = false;
|
|
361
|
+
function recount() {
|
|
362
|
+
if (!dirty) return;
|
|
363
|
+
setStats(countScripts(workloads));
|
|
364
|
+
dirty = false;
|
|
365
|
+
}
|
|
366
|
+
const off = pipe$(workloads, map$((wkl)=>wkl.state$.subscribe(()=>{
|
|
367
|
+
dirty = true;
|
|
368
|
+
queueMicrotask(recount);
|
|
369
|
+
})), collect$(off$()));
|
|
370
|
+
return ()=>{
|
|
371
|
+
dirty = false;
|
|
372
|
+
off.unsubscribe();
|
|
373
|
+
};
|
|
374
|
+
}, [
|
|
375
|
+
workloads
|
|
376
|
+
]);
|
|
377
|
+
return stats;
|
|
378
|
+
}
|
|
379
|
+
// Utils
|
|
380
|
+
function countScripts(workloads) {
|
|
381
|
+
const stats = {
|
|
382
|
+
[WorkloadState.Ready]: 0,
|
|
383
|
+
[WorkloadState.Blocked]: 0,
|
|
384
|
+
[WorkloadState.Starting]: 0,
|
|
385
|
+
[WorkloadState.Running]: 0,
|
|
386
|
+
[WorkloadState.Succeeded]: 0,
|
|
387
|
+
[WorkloadState.Failed]: 0,
|
|
388
|
+
[WorkloadState.Canceling]: 0,
|
|
389
|
+
[WorkloadState.Canceled]: 0
|
|
390
|
+
};
|
|
391
|
+
for (const workload of workloads){
|
|
392
|
+
if (workload.type === 'script') {
|
|
393
|
+
stats[workload.state()] += 1;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return stats;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Component
|
|
400
|
+
function WorkloadTreeStats({ tree, ...rest }) {
|
|
401
|
+
const workloads = useMemo(()=>tree.map((item)=>item.workload), [
|
|
402
|
+
tree
|
|
403
|
+
]);
|
|
404
|
+
const stats = useScriptsStats(workloads);
|
|
405
|
+
// Render
|
|
406
|
+
const running = stats[WorkloadState.Running] + stats[WorkloadState.Starting] + stats[WorkloadState.Canceling];
|
|
407
|
+
const done = stats[WorkloadState.Succeeded];
|
|
408
|
+
const failed = stats[WorkloadState.Failed];
|
|
409
|
+
const canceled = stats[WorkloadState.Canceled];
|
|
410
|
+
return /*#__PURE__*/ jsxs(Text, {
|
|
411
|
+
...rest,
|
|
412
|
+
children: [
|
|
413
|
+
running > 0 && /*#__PURE__*/ jsxs(Fragment, {
|
|
414
|
+
children: [
|
|
415
|
+
/*#__PURE__*/ jsx(Spinner, {
|
|
416
|
+
type: "sand"
|
|
417
|
+
}),
|
|
418
|
+
" ",
|
|
419
|
+
/*#__PURE__*/ jsx(Text, {
|
|
420
|
+
bold: true,
|
|
421
|
+
children: running
|
|
422
|
+
}),
|
|
423
|
+
" running"
|
|
424
|
+
]
|
|
425
|
+
}),
|
|
426
|
+
running > 0 && done > 0 && ', ',
|
|
427
|
+
done > 0 && /*#__PURE__*/ jsxs(Text, {
|
|
428
|
+
color: "green",
|
|
429
|
+
children: [
|
|
430
|
+
success,
|
|
431
|
+
" ",
|
|
432
|
+
done,
|
|
433
|
+
" done"
|
|
434
|
+
]
|
|
435
|
+
}),
|
|
436
|
+
running + done > 0 && failed > 0 && ', ',
|
|
437
|
+
failed > 0 && /*#__PURE__*/ jsxs(Text, {
|
|
438
|
+
color: "red",
|
|
439
|
+
children: [
|
|
440
|
+
error,
|
|
441
|
+
" ",
|
|
442
|
+
failed,
|
|
443
|
+
" failed"
|
|
444
|
+
]
|
|
445
|
+
}),
|
|
446
|
+
running + done + failed > 0 && canceled > 0 && ', ',
|
|
447
|
+
canceled > 0 && /*#__PURE__*/ jsxs(Text, {
|
|
448
|
+
dimColor: true,
|
|
449
|
+
children: [
|
|
450
|
+
"- ",
|
|
451
|
+
canceled,
|
|
452
|
+
" canceled"
|
|
453
|
+
]
|
|
454
|
+
})
|
|
455
|
+
]
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Component
|
|
460
|
+
function WorkloadTreeCompleted({ workload, verbose }) {
|
|
461
|
+
const tree = useWorkflowFlatTree(workload, verbose);
|
|
462
|
+
// Render
|
|
463
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
|
464
|
+
children: [
|
|
465
|
+
/*#__PURE__*/ jsx(Static, {
|
|
466
|
+
items: tree,
|
|
467
|
+
children: ({ workload, level })=>/*#__PURE__*/ jsx(Box, {
|
|
468
|
+
marginLeft: level * 2,
|
|
469
|
+
flexShrink: 0,
|
|
470
|
+
children: /*#__PURE__*/ jsx(WorkloadSpinner, {
|
|
471
|
+
workload: workload
|
|
472
|
+
})
|
|
473
|
+
}, workload.id)
|
|
474
|
+
}),
|
|
475
|
+
/*#__PURE__*/ jsx(WorkloadTreeStats, {
|
|
476
|
+
tree: tree
|
|
477
|
+
})
|
|
478
|
+
]
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Component
|
|
483
|
+
function WorkloadTreeFullSpinner({ workload, verbose }) {
|
|
484
|
+
const tree = useWorkflowFlatTree(workload, verbose);
|
|
485
|
+
// Render
|
|
486
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
|
487
|
+
children: [
|
|
488
|
+
/*#__PURE__*/ jsx(Box, {
|
|
489
|
+
flexDirection: "column",
|
|
490
|
+
children: tree.map(({ workload, level })=>/*#__PURE__*/ jsx(Box, {
|
|
491
|
+
marginLeft: level * 2,
|
|
492
|
+
flexShrink: 0,
|
|
493
|
+
children: /*#__PURE__*/ jsx(WorkloadSpinner, {
|
|
494
|
+
workload: workload
|
|
495
|
+
})
|
|
496
|
+
}, workload.id))
|
|
497
|
+
}),
|
|
498
|
+
/*#__PURE__*/ jsx(WorkloadTreeStats, {
|
|
499
|
+
tree: tree
|
|
500
|
+
})
|
|
501
|
+
]
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function useStdoutDimensions() {
|
|
506
|
+
const { stdout } = useStdout();
|
|
507
|
+
const [dimensions, setDimensions] = useState({
|
|
508
|
+
columns: stdout.columns ?? Infinity,
|
|
509
|
+
rows: stdout.rows ?? Infinity
|
|
510
|
+
});
|
|
511
|
+
useEffect(()=>{
|
|
512
|
+
const handler = ()=>setDimensions({
|
|
513
|
+
columns: stdout.columns ?? Infinity,
|
|
514
|
+
rows: stdout.rows ?? Infinity
|
|
515
|
+
});
|
|
516
|
+
stdout.on('resize', handler);
|
|
517
|
+
return ()=>{
|
|
518
|
+
stdout.off('resize', handler);
|
|
519
|
+
};
|
|
520
|
+
}, [
|
|
521
|
+
stdout
|
|
522
|
+
]);
|
|
523
|
+
return dimensions;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// Component
|
|
527
|
+
function WorkloadTreeScrollableSpinner({ workload, verbose }) {
|
|
528
|
+
const tree = useWorkflowFlatTree(workload, verbose);
|
|
529
|
+
// Manage scroll
|
|
530
|
+
const { rows: termRows } = useStdoutDimensions();
|
|
531
|
+
const [scroll, setScroll] = useState(0);
|
|
532
|
+
const maxRows = Math.min(termRows - 4, tree.length);
|
|
533
|
+
const firstIndex = Math.max(0, tree.length - scroll - maxRows);
|
|
534
|
+
const lastIndex = Math.min(tree.length, firstIndex + maxRows);
|
|
535
|
+
const effectiveScroll = tree.length - lastIndex;
|
|
536
|
+
useInput((_, key)=>{
|
|
537
|
+
if (key.upArrow) {
|
|
538
|
+
setScroll(Math.min(tree.length - maxRows, effectiveScroll + 1));
|
|
539
|
+
} else {
|
|
540
|
+
setScroll(Math.max(0, effectiveScroll - 1));
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
// Render
|
|
544
|
+
const slice = tree.slice(firstIndex, lastIndex);
|
|
545
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
|
546
|
+
children: [
|
|
547
|
+
/*#__PURE__*/ jsx(Box, {
|
|
548
|
+
flexDirection: "column",
|
|
549
|
+
children: slice.map(({ workload, level })=>/*#__PURE__*/ jsx(Box, {
|
|
550
|
+
marginLeft: level * 2,
|
|
551
|
+
flexShrink: 0,
|
|
552
|
+
children: /*#__PURE__*/ jsx(WorkloadSpinner, {
|
|
553
|
+
workload: workload
|
|
554
|
+
})
|
|
555
|
+
}, workload.id))
|
|
556
|
+
}),
|
|
557
|
+
/*#__PURE__*/ jsxs(Text, {
|
|
558
|
+
children: [
|
|
559
|
+
/*#__PURE__*/ jsx(WorkloadTreeStats, {
|
|
560
|
+
tree: tree
|
|
561
|
+
}),
|
|
562
|
+
termRows < tree.length && /*#__PURE__*/ jsx(Text, {
|
|
563
|
+
color: "grey",
|
|
564
|
+
children: " | use keyboard arrows to scroll"
|
|
565
|
+
})
|
|
566
|
+
]
|
|
567
|
+
})
|
|
568
|
+
]
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// Component
|
|
573
|
+
function WorkloadTreeSpinner({ workload, verbose }) {
|
|
574
|
+
const stdin = useStdin();
|
|
575
|
+
if (stdin.isRawModeSupported) {
|
|
576
|
+
return /*#__PURE__*/ jsx(WorkloadTreeScrollableSpinner, {
|
|
577
|
+
workload: workload,
|
|
578
|
+
verbose: verbose
|
|
579
|
+
});
|
|
580
|
+
} else {
|
|
581
|
+
return /*#__PURE__*/ jsx(WorkloadTreeFullSpinner, {
|
|
582
|
+
workload: workload,
|
|
583
|
+
verbose: verbose
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
const JobExecInk = inked(async function*({ job, verbose }) {
|
|
589
|
+
const scheduler = await inject$(SCHEDULER);
|
|
590
|
+
yield /*#__PURE__*/ jsx(WorkloadTreeSpinner, {
|
|
591
|
+
workload: job,
|
|
592
|
+
verbose: verbose
|
|
593
|
+
});
|
|
594
|
+
scheduler.register(job);
|
|
595
|
+
const outcome = await waitFor$(pipe$(job.state$, filter$(isWorkloadEnded)));
|
|
596
|
+
yield /*#__PURE__*/ jsx(WorkloadTreeCompleted, {
|
|
597
|
+
workload: job,
|
|
598
|
+
verbose: verbose
|
|
599
|
+
});
|
|
600
|
+
if (outcome !== WorkloadState.Succeeded) {
|
|
601
|
+
process.exitCode = 1;
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
export { JobExecInk as default };
|
|
606
|
+
//# sourceMappingURL=job-exec.ink.js.map
|