@jujulego/jill 3.0.0-alpha.1 → 3.0.0-alpha.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 (104) hide show
  1. package/README.md +1 -2
  2. package/bin/jill.js +1 -0
  3. package/dist/TaskName.js +33 -0
  4. package/dist/TaskName.js.map +1 -0
  5. package/dist/inked.js +66 -0
  6. package/dist/inked.js.map +1 -0
  7. package/dist/instrument.js +8 -0
  8. package/dist/instrument.js.map +1 -0
  9. package/dist/list.ink.js +50 -0
  10. package/dist/list.ink.js.map +1 -0
  11. package/dist/main.js +44 -35
  12. package/dist/main.js.map +1 -1
  13. package/dist/parser.js +2104 -0
  14. package/dist/parser.js.map +1 -0
  15. package/dist/planner.service.js +58 -0
  16. package/dist/planner.service.js.map +1 -0
  17. package/dist/task-exec.ink.js +539 -0
  18. package/dist/task-exec.ink.js.map +1 -0
  19. package/dist/task-plan.ink.js +114 -0
  20. package/dist/task-plan.ink.js.map +1 -0
  21. package/dist/tree.ink.js +185 -0
  22. package/dist/tree.ink.js.map +1 -0
  23. package/dist/tsconfig.build.tsbuildinfo +1 -1
  24. package/package.json +46 -45
  25. package/dist/ajv.config.d.ts +0 -3
  26. package/dist/commands/each.d.ts +0 -25
  27. package/dist/commands/exec.d.ts +0 -26
  28. package/dist/commands/group.d.ts +0 -16
  29. package/dist/commands/list.d.ts +0 -30
  30. package/dist/commands/run.d.ts +0 -24
  31. package/dist/commands/tree.d.ts +0 -6
  32. package/dist/commons/context.service.d.ts +0 -23
  33. package/dist/commons/git.service.d.ts +0 -62
  34. package/dist/commons/logger/log.gateway.d.ts +0 -18
  35. package/dist/commons/logger/parameters.d.ts +0 -2
  36. package/dist/commons/logger/thread.gateway.d.ts +0 -12
  37. package/dist/commons/logger/types.d.ts +0 -2
  38. package/dist/commons/logger.service.d.ts +0 -1
  39. package/dist/config/config-loader.d.ts +0 -4
  40. package/dist/config/config-options.d.ts +0 -5
  41. package/dist/config/types.d.ts +0 -8
  42. package/dist/config/utils.d.ts +0 -5
  43. package/dist/constants.d.ts +0 -1
  44. package/dist/core.plugin-CxgfxFUI.js +0 -642
  45. package/dist/core.plugin-CxgfxFUI.js.map +0 -1
  46. package/dist/core.plugin.d.ts +0 -2
  47. package/dist/filters/affected.filter.d.ts +0 -12
  48. package/dist/filters/pipeline.d.ts +0 -11
  49. package/dist/filters/private.filter.d.ts +0 -7
  50. package/dist/filters/scripts.filter.d.ts +0 -8
  51. package/dist/index.d.ts +0 -45
  52. package/dist/index.js +0 -35
  53. package/dist/index.js.map +0 -1
  54. package/dist/ink-command-CsbkuRbm.js +0 -2071
  55. package/dist/ink-command-CsbkuRbm.js.map +0 -1
  56. package/dist/ink.config.d.ts +0 -3
  57. package/dist/inversify.config.d.ts +0 -4
  58. package/dist/jill.application-DNJpmnCF.js +0 -637
  59. package/dist/jill.application-DNJpmnCF.js.map +0 -1
  60. package/dist/jill.application.d.ts +0 -19
  61. package/dist/main.d.ts +0 -1
  62. package/dist/middlewares/load-project.d.ts +0 -21
  63. package/dist/middlewares/load-workspace.d.ts +0 -20
  64. package/dist/modules/command.d.ts +0 -20
  65. package/dist/modules/ink-command.d.ts +0 -11
  66. package/dist/modules/middleware.d.ts +0 -8
  67. package/dist/modules/module.d.ts +0 -7
  68. package/dist/modules/plugin-loader.service.d.ts +0 -10
  69. package/dist/modules/plugin.d.ts +0 -14
  70. package/dist/modules/service.d.ts +0 -8
  71. package/dist/modules/task-command.d.ts +0 -14
  72. package/dist/project/project.d.ts +0 -27
  73. package/dist/project/project.repository.d.ts +0 -15
  74. package/dist/project/types.d.ts +0 -1
  75. package/dist/project/workspace.d.ts +0 -41
  76. package/dist/tasks/command-task.d.ts +0 -15
  77. package/dist/tasks/errors.d.ts +0 -4
  78. package/dist/tasks/script-task.d.ts +0 -27
  79. package/dist/tasks/task-expression.service.d.ts +0 -25
  80. package/dist/tasks/task-manager.config.d.ts +0 -3
  81. package/dist/types.d.ts +0 -11
  82. package/dist/ui/hooks/useFlatTaskTree.d.ts +0 -14
  83. package/dist/ui/hooks/useIsVerbose.d.ts +0 -1
  84. package/dist/ui/hooks/useStdoutDimensions.d.ts +0 -4
  85. package/dist/ui/layout.d.ts +0 -5
  86. package/dist/ui/list.d.ts +0 -5
  87. package/dist/ui/static-logs.d.ts +0 -1
  88. package/dist/ui/task-name.d.ts +0 -5
  89. package/dist/ui/task-spinner.d.ts +0 -5
  90. package/dist/ui/task-tree-completed.d.ts +0 -5
  91. package/dist/ui/task-tree-full-spinner.d.ts +0 -5
  92. package/dist/ui/task-tree-scrollable-spinner.d.ts +0 -5
  93. package/dist/ui/task-tree-spinner.d.ts +0 -5
  94. package/dist/ui/task-tree-stats.d.ts +0 -5
  95. package/dist/ui/workspace-tree.d.ts +0 -8
  96. package/dist/utils/events.d.ts +0 -3
  97. package/dist/utils/exit.d.ts +0 -4
  98. package/dist/utils/import.d.ts +0 -4
  99. package/dist/utils/json.d.ts +0 -1
  100. package/dist/utils/streams.d.ts +0 -3
  101. package/dist/utils/string.d.ts +0 -2
  102. package/dist/utils/worker-cache.d.ts +0 -3
  103. package/dist/workspace-tree-VWKE0B6b.js +0 -1120
  104. package/dist/workspace-tree-VWKE0B6b.js.map +0 -1
@@ -0,0 +1,58 @@
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]="aa0e01d6-ce3c-4ec7-bca3-fd07f2113565",e._sentryDebugIdIdentifier="sentry-dbid-aa0e01d6-ce3c-4ec7-bca3-fd07f2113565");})();}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.3"};}catch(e){}}();import { _ } from '@swc/helpers/_/_apply_decs_2203_r';
2
+ import { inject$, asyncScope$ } from '@kyrielle/injector';
3
+ import { withLabel } from '@kyrielle/logger';
4
+ import { var$ } from 'kyrielle';
5
+ import { L as LOGGER, d as CWD, f as ConfigService, p as planParser, g as instrument } from './parser.js';
6
+ import '@jujulego/tasks';
7
+ import '@sentry/node';
8
+ import 'node:path';
9
+ import 'node:child_process';
10
+ import 'node:process';
11
+ import 'chalk';
12
+ import 'semver';
13
+ import 'slugify';
14
+ import 'yargs';
15
+ import 'node:fs';
16
+ import 'path-scurry';
17
+ import 'glob';
18
+ import 'normalize-package-data';
19
+ import 'moo';
20
+ import '@jujulego/quick-tag';
21
+ import 'ajv';
22
+ import 'node:os';
23
+ import 'cosmiconfig';
24
+ import 'chalk-template';
25
+
26
+ var _dec, _initProto;
27
+ _dec = instrument('PlannerService.plan');
28
+ class PlannerService {
29
+ static{
30
+ ({ e: [_initProto] } = _(this, [
31
+ [
32
+ _dec,
33
+ 2,
34
+ "plan"
35
+ ]
36
+ ], []));
37
+ }
38
+ // Attributes
39
+ _logger = (_initProto(this), inject$(LOGGER).child(withLabel('planner')));
40
+ // Methods
41
+ /**
42
+ * Returns a task set if any task should be run by given command.
43
+ * Tasks that do not execute tasks will return `null`
44
+ */ async plan(args, cwd) {
45
+ this._logger.debug(`interpreting jill ${args.join(' ')}`);
46
+ const argv = args.map((arg)=>arg.replace(/^["'](.+)["']$/, '$1'));
47
+ const tasks = var$();
48
+ await asyncScope$(async ()=>{
49
+ asyncScope$().set(CWD, cwd);
50
+ asyncScope$().set(ConfigService, new ConfigService()); // <= injects an empty ConfigService, forcing config discovery
51
+ await planParser(tasks).parseAsync(argv);
52
+ });
53
+ return tasks.defer() ?? null;
54
+ }
55
+ }
56
+
57
+ export { PlannerService };
58
+ //# sourceMappingURL=planner.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.service.js","sources":["../src/cli/services/planner.service.ts"],"sourcesContent":["import type { TaskSet } from '@jujulego/tasks';\nimport { asyncScope$, inject$ } from '@kyrielle/injector';\nimport { withLabel } from '@kyrielle/logger';\nimport { var$ } from 'kyrielle';\nimport { ConfigService } from '../../config/config.service.js';\nimport { CWD, LOGGER } from '../../tokens.js';\nimport { instrument } from '../../utils/sentry.js';\nimport { planParser } from '../parser.js';\n\nexport class PlannerService {\n // Attributes\n private readonly _logger = inject$(LOGGER).child(withLabel('planner'));\n\n // Methods\n /**\n * Returns a task set if any task should be run by given command.\n * Tasks that do not execute tasks will return `null`\n */\n @instrument('PlannerService.plan')\n async plan(args: string[], cwd: string): Promise<TaskSet | null> {\n this._logger.debug(`interpreting jill ${args.join(' ')}`);\n\n const argv = args.map(arg => arg.replace(/^[\"'](.+)[\"']$/, '$1'));\n const tasks = var$<TaskSet>();\n\n await asyncScope$(async () => {\n asyncScope$().set(CWD, cwd);\n asyncScope$().set(ConfigService, new ConfigService()); // <= injects an empty ConfigService, forcing config discovery\n\n await planParser(tasks).parseAsync(argv);\n });\n\n return tasks.defer() ?? null;\n }\n}\n"],"names":["instrument","PlannerService","plan","_logger","inject$","LOGGER","child","withLabel","args","cwd","debug","join","argv","map","arg","replace","tasks","var$","asyncScope$","set","CWD","ConfigService","planParser","parseAsync","defer"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;OAkBGA,UAAAA,CAAW,CAAA,cAAA,CAAA,IAAA,CAAA,CAAA,CAAA;AATP,KAAA,CAAMC,cAAAA,CAAAA,CAAAA;;;;;;AAULC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,IAAAA,CAAAA;;;;;AARWC,CAAAA,CAAAA,CAAAA,CAAAA,OAAAA,CAAAA,CAAAA,CAAAA,CAAAA,UAAAA,CAAAA,IAAAA,CAAAA,EAAUC,MAAAA,CAAAA,CAAQC,MAAAA,CAAAA,CAAQC,KAAK,CAACC,UAAU,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;AAG3D,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;;AAGC,CAAA,CAAA,CAAA,CAAA,CAAA,CACD,MACML,IAAAA,CAAKM,IAAc,CAAA,CAAEC,GAAW,CAAA,CAA2B,CAAA;QAC/D,IAAI,CAACN,OAAO,CAACO,KAAK,CAAC,CAAC,YAAA,CAAA,IAAA,CAAkB,CAAA,CAAEF,IAAAA,CAAKG,IAAI,CAAC,GAAA,CAAA,CAAA,CAAM,CAAA,CAAA;QAExD,MAAMC,IAAAA,CAAAA,CAAAA,CAAOJ,KAAKK,GAAG,CAACC,CAAAA,GAAAA,CAAAA,CAAAA,CAAOA,GAAAA,CAAIC,OAAO,CAAC,gBAAA,CAAA,CAAkB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AAC3D,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAMC,KAAAA,CAAAA,CAAAA,CAAQC,GAAAA,CAAAA,CAAAA,CAAAA,CAAAA;AAEd,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAMC,UAAAA,CAAAA,CAAY,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;YAChBA,UAAAA,CAAAA,EAAAA,CAAcC,GAAG,CAACC,GAAAA,CAAAA,CAAKX,GAAAA,CAAAA,CAAAA;AACvBS,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,UAAAA,CAAAA,CAAAA,CAAAA,CAAcC,GAAG,CAACE,aAAAA,CAAAA,CAAe,GAAA,CAAIA;YAErC,KAAA,CAAMC,UAAAA,CAAWN,KAAAA,CAAAA,CAAOO,UAAU,CAACX,IAAAA,CAAAA,CAAAA;AACrC,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;QAEA,OAAOI,KAAAA,CAAMQ,KAAK,CAAA,CAAA,IAAM,IAAA,CAAA;AAC1B,CAAA,CAAA,CAAA,CAAA,CAAA;AACF,CAAA;;"}
@@ -0,0 +1,539 @@
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]="3cae857b-4b2e-4897-afac-f28b5f72c47c",e._sentryDebugIdIdentifier="sentry-dbid-3cae857b-4b2e-4897-afac-f28b5f72c47c");})();}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.3"};}catch(e){}}();import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { inject$ } from '@kyrielle/injector';
3
+ import { waitFor$ } from 'kyrielle';
4
+ import process from 'node:process';
5
+ import { i as isCommandCtx, S as ScriptTask, b as CommandTask, a as isScriptCtx, T as TASK_MANAGER } from './parser.js';
6
+ import { Box, Text, Static, useStdout, useInput, useStdin } from 'ink';
7
+ import { useState, useLayoutEffect, useMemo, useEffect } from 'react';
8
+ import { GroupTask } from '@jujulego/tasks';
9
+ import Spinner from 'ink-spinner';
10
+ import ms from 'pretty-ms';
11
+ import isUnicodeSupported from 'is-unicode-supported';
12
+ import { T as TaskName } from './TaskName.js';
13
+ import { i as inked } from './inked.js';
14
+ import '@kyrielle/logger';
15
+ import '@sentry/node';
16
+ import 'node:path';
17
+ import 'node:child_process';
18
+ import 'chalk';
19
+ import 'semver';
20
+ import 'slugify';
21
+ import 'yargs';
22
+ import 'node:fs';
23
+ import 'path-scurry';
24
+ import '@swc/helpers/_/_apply_decs_2203_r';
25
+ import 'glob';
26
+ import 'normalize-package-data';
27
+ import 'moo';
28
+ import '@jujulego/quick-tag';
29
+ import 'ajv';
30
+ import 'node:os';
31
+ import 'cosmiconfig';
32
+ import 'chalk-template';
33
+
34
+ // Utils
35
+ /**
36
+ * Sorts tasks according to workspace and script, keeping command at the end
37
+ */ function taskComparator(a, b) {
38
+ // 1 - compare kind
39
+ const kindA = a instanceof CommandTask ? 0 : 1;
40
+ const kindB = b instanceof CommandTask ? 0 : 1;
41
+ if (kindA !== kindB) {
42
+ return kindB - kindA;
43
+ }
44
+ // 2 - compare workspaces
45
+ const wksA = 'workspace' in a.context ? a.context.workspace.name : '\uffff';
46
+ const wksB = 'workspace' in b.context ? b.context.workspace.name : '\uffff';
47
+ const wksDiff = wksA.localeCompare(wksB);
48
+ if (wksDiff !== 0) {
49
+ return wksDiff;
50
+ }
51
+ // 1 - compare scripts
52
+ const scriptA = 'script' in a.context ? a.context.script : '\uffff';
53
+ const scriptB = 'script' in b.context ? b.context.script : '\uffff';
54
+ return scriptA.localeCompare(scriptB);
55
+ }
56
+ /**
57
+ * Extract tasks to be printed, with their level in the tree
58
+ */ function* flatTasks(tasks, isVerbose, groupId, level = 0) {
59
+ for (const task of tasks){
60
+ if (task.group?.id !== groupId) {
61
+ continue;
62
+ }
63
+ yield {
64
+ task,
65
+ level
66
+ };
67
+ if (task instanceof GroupTask) {
68
+ const isCommandGroup = task.tasks.some((t)=>!isCommandCtx(t.context));
69
+ const hasFailed = task.tasks.some((t)=>t.status === 'failed');
70
+ const isStarted = task.status === 'running';
71
+ if (isVerbose || isCommandGroup || hasFailed || isStarted) {
72
+ let tasks = task.tasks;
73
+ if (task instanceof ScriptTask) {
74
+ tasks = [
75
+ ...tasks
76
+ ].sort(taskComparator);
77
+ }
78
+ yield* flatTasks(tasks, isVerbose, task.id, level + 1);
79
+ }
80
+ }
81
+ }
82
+ }
83
+ // Hook
84
+ function useFlatTaskTree(manager, isVerbose = false) {
85
+ const [tasks, setTasks] = useState([
86
+ ...manager.tasks
87
+ ].sort(taskComparator));
88
+ const [version, setVersion] = useState(0);
89
+ useLayoutEffect(()=>{
90
+ let dirty = false;
91
+ return manager.events$.on('added', ()=>{
92
+ if (!dirty) {
93
+ dirty = true;
94
+ queueMicrotask(()=>{
95
+ setTasks([
96
+ ...manager.tasks
97
+ ].sort(taskComparator));
98
+ dirty = false;
99
+ });
100
+ }
101
+ }).unsubscribe;
102
+ }, [
103
+ manager
104
+ ]);
105
+ useLayoutEffect(()=>{
106
+ let dirty = false;
107
+ return manager.events$.on('started', ()=>{
108
+ if (!dirty) {
109
+ dirty = true;
110
+ setTimeout(()=>{
111
+ setVersion((old)=>++old);
112
+ dirty = false;
113
+ });
114
+ }
115
+ }).unsubscribe;
116
+ }, [
117
+ manager
118
+ ]);
119
+ useLayoutEffect(()=>{
120
+ let dirty = false;
121
+ return manager.events$.on('completed', ()=>{
122
+ if (!dirty) {
123
+ dirty = true;
124
+ setTimeout(()=>{
125
+ setVersion((old)=>++old);
126
+ dirty = false;
127
+ });
128
+ }
129
+ }).unsubscribe;
130
+ }, [
131
+ manager
132
+ ]);
133
+ return useMemo(()=>{
134
+ return Array.from(flatTasks(tasks, isVerbose));
135
+ }, [
136
+ tasks,
137
+ isVerbose,
138
+ version
139
+ ]); // eslint-disable-line react-hooks/exhaustive-deps
140
+ }
141
+
142
+ const isSupported = !isUnicodeSupported();
143
+ const success = isSupported ? '✔' : '√';
144
+ const error = isSupported ? '✖' : '×';
145
+
146
+ // Components
147
+ function TaskSpinner({ task }) {
148
+ // State
149
+ const [status, setStatus] = useState(task.status);
150
+ const [time, setTime] = useState(task.duration);
151
+ // Effects
152
+ useLayoutEffect(()=>{
153
+ return task.events$.on('status', (event)=>{
154
+ setStatus(event.status);
155
+ }).unsubscribe;
156
+ }, [
157
+ task
158
+ ]);
159
+ useLayoutEffect(()=>{
160
+ return task.events$.on('completed', ({ duration })=>{
161
+ setTime(duration);
162
+ }).unsubscribe;
163
+ }, [
164
+ task
165
+ ]);
166
+ // Render
167
+ const isScriptChild = (isCommandCtx(task.context) && task.group && isScriptCtx(task.group.context)) ?? false;
168
+ switch(status){
169
+ case 'blocked':
170
+ case 'ready':
171
+ case 'starting':
172
+ return /*#__PURE__*/ jsxs(Box, {
173
+ children: [
174
+ /*#__PURE__*/ jsx(Text, {
175
+ color: "grey",
176
+ children: '\u00B7'
177
+ }),
178
+ /*#__PURE__*/ jsx(Box, {
179
+ paddingLeft: 1,
180
+ children: /*#__PURE__*/ jsx(Text, {
181
+ color: "grey",
182
+ wrap: "truncate",
183
+ children: /*#__PURE__*/ jsx(TaskName, {
184
+ task: task,
185
+ withWorkspace: true
186
+ })
187
+ })
188
+ })
189
+ ]
190
+ });
191
+ case 'running':
192
+ return /*#__PURE__*/ jsxs(Box, {
193
+ children: [
194
+ /*#__PURE__*/ jsx(Text, {
195
+ dimColor: isScriptChild,
196
+ children: /*#__PURE__*/ jsx(Spinner, {})
197
+ }),
198
+ /*#__PURE__*/ jsx(Box, {
199
+ paddingLeft: 1,
200
+ children: /*#__PURE__*/ jsx(Text, {
201
+ dimColor: isScriptChild,
202
+ wrap: "truncate",
203
+ children: /*#__PURE__*/ jsx(TaskName, {
204
+ task: task,
205
+ withWorkspace: true
206
+ })
207
+ })
208
+ })
209
+ ]
210
+ });
211
+ case 'done':
212
+ return /*#__PURE__*/ jsxs(Box, {
213
+ children: [
214
+ /*#__PURE__*/ jsx(Text, {
215
+ color: "green",
216
+ children: success
217
+ }),
218
+ /*#__PURE__*/ jsx(Box, {
219
+ paddingLeft: 1,
220
+ children: /*#__PURE__*/ jsx(Text, {
221
+ dimColor: isScriptChild,
222
+ wrap: "truncate",
223
+ children: /*#__PURE__*/ jsx(TaskName, {
224
+ task: task,
225
+ withWorkspace: true
226
+ })
227
+ })
228
+ }),
229
+ /*#__PURE__*/ jsx(Box, {
230
+ paddingLeft: 1,
231
+ flexShrink: 0,
232
+ children: /*#__PURE__*/ jsxs(Text, {
233
+ color: isScriptChild ? 'grey' : 'dim',
234
+ children: [
235
+ "(took ",
236
+ ms(time),
237
+ ")"
238
+ ]
239
+ })
240
+ })
241
+ ]
242
+ });
243
+ case 'failed':
244
+ return /*#__PURE__*/ jsxs(Box, {
245
+ children: [
246
+ /*#__PURE__*/ jsx(Text, {
247
+ color: "red",
248
+ children: error
249
+ }),
250
+ /*#__PURE__*/ jsx(Box, {
251
+ paddingLeft: 1,
252
+ children: /*#__PURE__*/ jsx(Text, {
253
+ dimColor: isScriptChild,
254
+ wrap: "truncate",
255
+ children: /*#__PURE__*/ jsx(TaskName, {
256
+ task: task,
257
+ withWorkspace: true
258
+ })
259
+ })
260
+ }),
261
+ /*#__PURE__*/ jsx(Box, {
262
+ paddingLeft: 1,
263
+ flexShrink: 0,
264
+ children: /*#__PURE__*/ jsxs(Text, {
265
+ color: isScriptChild ? 'grey' : 'dim',
266
+ children: [
267
+ "(took ",
268
+ ms(time),
269
+ ")"
270
+ ]
271
+ })
272
+ })
273
+ ]
274
+ });
275
+ }
276
+ }
277
+
278
+ // Component
279
+ function TaskTreeStats({ manager }) {
280
+ // Follow stats
281
+ const [stats, setStats] = useState(()=>{
282
+ const base = {
283
+ running: 0,
284
+ done: 0,
285
+ failed: 0
286
+ };
287
+ for (const task of manager.tasks){
288
+ switch(task.status){
289
+ case 'starting':
290
+ case 'running':
291
+ base.running += task.weight;
292
+ break;
293
+ case 'done':
294
+ base.done += task.weight;
295
+ break;
296
+ case 'failed':
297
+ base.failed += task.weight;
298
+ break;
299
+ }
300
+ }
301
+ return base;
302
+ });
303
+ useLayoutEffect(()=>{
304
+ return manager.events$.on('started', (task)=>{
305
+ setStats((old)=>({
306
+ ...old,
307
+ running: old.running + task.weight
308
+ }));
309
+ }).unsubscribe;
310
+ }, [
311
+ manager
312
+ ]);
313
+ useLayoutEffect(()=>{
314
+ return manager.events$.on('completed', (task)=>{
315
+ setStats((old)=>({
316
+ running: old.running - task.weight,
317
+ done: task.status === 'done' ? old.done + task.weight : old.done,
318
+ failed: task.status === 'failed' ? old.failed + task.weight : old.failed
319
+ }));
320
+ }).unsubscribe;
321
+ }, [
322
+ manager
323
+ ]);
324
+ // Render
325
+ return /*#__PURE__*/ jsxs(Text, {
326
+ children: [
327
+ stats.running !== 0 && /*#__PURE__*/ jsxs(Fragment, {
328
+ children: [
329
+ /*#__PURE__*/ jsx(Spinner, {
330
+ type: "sand"
331
+ }),
332
+ " ",
333
+ /*#__PURE__*/ jsx(Text, {
334
+ bold: true,
335
+ children: stats.running
336
+ }),
337
+ " running"
338
+ ]
339
+ }),
340
+ stats.running !== 0 && stats.done !== 0 && /*#__PURE__*/ jsx(Fragment, {
341
+ children: ", "
342
+ }),
343
+ stats.done !== 0 && /*#__PURE__*/ jsxs(Text, {
344
+ color: "green",
345
+ children: [
346
+ success,
347
+ " ",
348
+ stats.done,
349
+ " done"
350
+ ]
351
+ }),
352
+ stats.running + stats.done !== 0 && stats.failed !== 0 && /*#__PURE__*/ jsx(Fragment, {
353
+ children: ", "
354
+ }),
355
+ stats.failed !== 0 && /*#__PURE__*/ jsxs(Text, {
356
+ color: "red",
357
+ children: [
358
+ error,
359
+ " ",
360
+ stats.failed,
361
+ " failed"
362
+ ]
363
+ })
364
+ ]
365
+ });
366
+ }
367
+
368
+ // Component
369
+ function TaskTreeCompleted({ manager, verbose }) {
370
+ // Extract all tasks
371
+ const flat = useMemo(()=>{
372
+ return Array.from(flatTasks([
373
+ ...manager.tasks
374
+ ].sort(taskComparator), verbose ?? false));
375
+ }, [
376
+ manager,
377
+ verbose
378
+ ]);
379
+ // Render
380
+ return /*#__PURE__*/ jsxs(Fragment, {
381
+ children: [
382
+ /*#__PURE__*/ jsx(Static, {
383
+ items: flat,
384
+ children: ({ task, level })=>/*#__PURE__*/ jsx(Box, {
385
+ marginLeft: level * 2,
386
+ flexShrink: 0,
387
+ children: /*#__PURE__*/ jsx(TaskSpinner, {
388
+ task: task
389
+ })
390
+ }, task.id)
391
+ }),
392
+ /*#__PURE__*/ jsx(TaskTreeStats, {
393
+ manager: manager
394
+ })
395
+ ]
396
+ });
397
+ }
398
+
399
+ // Component
400
+ function TaskTreeFullSpinner({ manager, verbose }) {
401
+ const flat = useFlatTaskTree(manager, verbose);
402
+ // Render
403
+ return /*#__PURE__*/ jsxs(Fragment, {
404
+ children: [
405
+ /*#__PURE__*/ jsx(Box, {
406
+ flexDirection: "column",
407
+ children: flat.map(({ task, level })=>/*#__PURE__*/ jsx(Box, {
408
+ marginLeft: level * 2,
409
+ flexShrink: 0,
410
+ children: /*#__PURE__*/ jsx(TaskSpinner, {
411
+ task: task
412
+ })
413
+ }, task.id))
414
+ }),
415
+ /*#__PURE__*/ jsx(Text, {
416
+ children: /*#__PURE__*/ jsx(TaskTreeStats, {
417
+ manager: manager
418
+ })
419
+ })
420
+ ]
421
+ });
422
+ }
423
+
424
+ function useStdoutDimensions() {
425
+ const { stdout } = useStdout();
426
+ const [dimensions, setDimensions] = useState({
427
+ columns: stdout.columns ?? Infinity,
428
+ rows: stdout.rows ?? Infinity
429
+ });
430
+ useEffect(()=>{
431
+ const handler = ()=>setDimensions({
432
+ columns: stdout.columns ?? Infinity,
433
+ rows: stdout.rows ?? Infinity
434
+ });
435
+ stdout.on('resize', handler);
436
+ return ()=>{
437
+ stdout.off('resize', handler);
438
+ };
439
+ }, [
440
+ stdout
441
+ ]);
442
+ return dimensions;
443
+ }
444
+
445
+ // Component
446
+ function TaskTreeScrollableSpinner({ manager, verbose }) {
447
+ const { rows: termHeight } = useStdoutDimensions();
448
+ // Extract all tasks
449
+ const flat = useFlatTaskTree(manager, verbose);
450
+ const maxHeight = useMemo(()=>Math.min(termHeight - 4, flat.length), [
451
+ termHeight,
452
+ flat
453
+ ]);
454
+ // Manage scroll
455
+ const [start, setStart] = useState(0);
456
+ const slice = useMemo(()=>flat.slice(start, start + maxHeight), [
457
+ flat,
458
+ start,
459
+ maxHeight
460
+ ]);
461
+ useEffect(()=>{
462
+ if (start + maxHeight > flat.length) {
463
+ setStart(Math.max(flat.length - maxHeight, 0));
464
+ }
465
+ }, [
466
+ start,
467
+ flat,
468
+ maxHeight
469
+ ]);
470
+ useInput((_, key)=>{
471
+ if (key.upArrow) {
472
+ setStart((old)=>Math.max(0, old - 1));
473
+ } else if (key.downArrow) {
474
+ setStart((old)=>Math.min(flat.length - maxHeight, old + 1));
475
+ }
476
+ });
477
+ // Render
478
+ return /*#__PURE__*/ jsxs(Fragment, {
479
+ children: [
480
+ /*#__PURE__*/ jsx(Box, {
481
+ flexDirection: "column",
482
+ children: slice.map(({ task, level })=>/*#__PURE__*/ jsx(Box, {
483
+ marginLeft: level * 2,
484
+ flexShrink: 0,
485
+ children: /*#__PURE__*/ jsx(TaskSpinner, {
486
+ task: task
487
+ })
488
+ }, task.id))
489
+ }),
490
+ /*#__PURE__*/ jsxs(Text, {
491
+ children: [
492
+ /*#__PURE__*/ jsx(TaskTreeStats, {
493
+ manager: manager
494
+ }),
495
+ maxHeight < flat.length && /*#__PURE__*/ jsx(Text, {
496
+ color: "grey",
497
+ children: " - use keyboard arrows to scroll"
498
+ })
499
+ ]
500
+ })
501
+ ]
502
+ });
503
+ }
504
+
505
+ // Component
506
+ function TaskTreeSpinner({ manager, verbose }) {
507
+ const stdin = useStdin();
508
+ if (stdin.isRawModeSupported) {
509
+ return /*#__PURE__*/ jsx(TaskTreeScrollableSpinner, {
510
+ manager: manager,
511
+ verbose: verbose
512
+ });
513
+ } else {
514
+ return /*#__PURE__*/ jsx(TaskTreeFullSpinner, {
515
+ manager: manager,
516
+ verbose: verbose
517
+ });
518
+ }
519
+ }
520
+
521
+ const TaskExecInk = inked(async function*({ tasks, verbose }) {
522
+ const manager = await inject$(TASK_MANAGER);
523
+ yield /*#__PURE__*/ jsx(TaskTreeSpinner, {
524
+ manager: manager,
525
+ verbose: verbose
526
+ });
527
+ tasks.start(manager);
528
+ const results = await waitFor$(tasks.events$, 'finished');
529
+ yield /*#__PURE__*/ jsx(TaskTreeCompleted, {
530
+ manager: manager,
531
+ verbose: verbose
532
+ });
533
+ if (results.failed > 0) {
534
+ process.exitCode = 1;
535
+ }
536
+ });
537
+
538
+ export { TaskExecInk as default };
539
+ //# sourceMappingURL=task-exec.ink.js.map