@stacksjs/cli 0.58.58 → 0.58.61
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/dist/index.js +463 -81
- package/package.json +1 -1
- package/src/cli.ts +9 -31
- package/src/console.ts +19 -19
- package/src/exec.ts +25 -8
- package/src/helpers.ts +3 -3
- package/src/index.ts +1 -1
- package/src/parse.ts +95 -17
- package/src/run.ts +7 -7
- package/src/utils.ts +62 -0
- package/src/utilities.ts +0 -2
package/dist/index.js
CHANGED
|
@@ -12,50 +12,34 @@ async function installStack(name, options) {
|
|
|
12
12
|
return await installPkg(`@stacksjs/${name}`, { silent: true });
|
|
13
13
|
}
|
|
14
14
|
// src/cli.ts
|
|
15
|
-
import
|
|
16
|
-
// package.json
|
|
17
|
-
var version = "0.58.58";
|
|
18
|
-
|
|
19
|
-
// src/cli.ts
|
|
15
|
+
import {CAC} from "cac";
|
|
20
16
|
function cli(name, options) {
|
|
21
17
|
if (typeof name === "object") {
|
|
22
18
|
options = name;
|
|
23
19
|
name = options.name;
|
|
24
20
|
}
|
|
25
|
-
|
|
26
|
-
cli2.help();
|
|
27
|
-
cli2.version(options?.version || version);
|
|
28
|
-
return cli2;
|
|
29
|
-
}
|
|
30
|
-
function parseOptions() {
|
|
31
|
-
const options = cli().parse().options;
|
|
32
|
-
for (const key in options) {
|
|
33
|
-
if (options[key] === "true")
|
|
34
|
-
options[key] = true;
|
|
35
|
-
else if (options[key] === "false")
|
|
36
|
-
options[key] = false;
|
|
37
|
-
}
|
|
38
|
-
return options;
|
|
21
|
+
return new CAC(name || "buddy");
|
|
39
22
|
}
|
|
40
23
|
// src/exec.ts
|
|
41
|
-
import
|
|
24
|
+
import process2 from "process";
|
|
42
25
|
import {err, handleError, ok} from "@stacksjs/error-handling";
|
|
43
26
|
import {ExitCode} from "@stacksjs/types";
|
|
44
27
|
async function exec(command, options) {
|
|
45
28
|
const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]+|"[^"]*")+/g);
|
|
46
29
|
if (!cmd)
|
|
47
30
|
return err(handleError(`Failed to parse command: ${cmd}`, options));
|
|
48
|
-
|
|
49
|
-
|
|
31
|
+
log2.debug("exec:", Array.isArray(command) ? command.join(" ") : command);
|
|
32
|
+
log2.debug("cmd:", cmd);
|
|
33
|
+
log2.debug("exec options:", options);
|
|
50
34
|
const proc = Bun.spawn(cmd, {
|
|
51
35
|
...options,
|
|
52
|
-
stdout: options?.silent ? "ignore" : options?.stdin ? options.stdin : options?.stdout || "inherit",
|
|
53
|
-
stderr: options?.silent ? "ignore" : options?.stderr || "inherit",
|
|
36
|
+
stdout: options?.silent || options?.quiet ? "ignore" : options?.stdin ? options.stdin : options?.stdout || "inherit",
|
|
37
|
+
stderr: options?.silent || options?.quiet ? "ignore" : options?.stderr || "inherit",
|
|
54
38
|
detached: options?.background || false,
|
|
55
39
|
cwd: options?.cwd || import.meta.dir,
|
|
56
40
|
onExit(_subprocess, exitCode, _signalCode, _error) {
|
|
57
41
|
if (exitCode && exitCode !== ExitCode.Success)
|
|
58
|
-
|
|
42
|
+
process2.exit(exitCode);
|
|
59
43
|
}
|
|
60
44
|
});
|
|
61
45
|
if (options?.stdin === "pipe" && options.input) {
|
|
@@ -70,26 +54,341 @@ async function exec(command, options) {
|
|
|
70
54
|
return err(handleError(`Failed to execute command: ${cmd.join(" ")}`));
|
|
71
55
|
}
|
|
72
56
|
async function execSync(command, options) {
|
|
73
|
-
|
|
57
|
+
log2.debug("Running execSync:", command);
|
|
58
|
+
log2.debug("execSync Options:", options);
|
|
59
|
+
const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]+|"[^"]*")+/g);
|
|
60
|
+
if (!cmd) {
|
|
61
|
+
log2.error(`Failed to parse command: ${cmd}`, options);
|
|
62
|
+
process2.exit(ExitCode.FatalError);
|
|
63
|
+
}
|
|
74
64
|
const proc = Bun.spawnSync(cmd, {
|
|
75
65
|
...options,
|
|
66
|
+
stdin: options?.stdin ?? "inherit",
|
|
76
67
|
stdout: options?.stdout ?? "pipe",
|
|
77
68
|
stderr: options?.stderr ?? "inherit",
|
|
78
69
|
cwd: options?.cwd ?? import.meta.dir,
|
|
79
70
|
onExit(_subprocess, exitCode, _signalCode, _error) {
|
|
80
71
|
if (exitCode !== ExitCode.Success && exitCode)
|
|
81
|
-
|
|
72
|
+
process2.exit(exitCode);
|
|
82
73
|
}
|
|
83
74
|
});
|
|
84
75
|
return proc.stdout.toString();
|
|
85
76
|
}
|
|
86
77
|
|
|
87
|
-
// src/
|
|
78
|
+
// src/utils.ts
|
|
88
79
|
import * as kolorist from "kolorist";
|
|
89
|
-
|
|
80
|
+
|
|
81
|
+
// /home/runner/work/stacks/stacks/node_modules/consola/dist/utils.mjs
|
|
82
|
+
import * as tty from "tty";
|
|
83
|
+
var replaceClose = function(index, string, close, replace, head = string.slice(0, Math.max(0, index)) + replace, tail = string.slice(Math.max(0, index + close.length)), next = tail.indexOf(close)) {
|
|
84
|
+
return head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
|
|
85
|
+
};
|
|
86
|
+
var clearBleed = function(index, string, open, close, replace) {
|
|
87
|
+
return index < 0 ? open + string + close : open + replaceClose(index, string, close, replace) + close;
|
|
88
|
+
};
|
|
89
|
+
var filterEmpty = function(open, close, replace = open, at = open.length + 1) {
|
|
90
|
+
return (string) => string || !(string === "" || string === undefined) ? clearBleed(("" + string).indexOf(close, at), string, open, close, replace) : "";
|
|
91
|
+
};
|
|
92
|
+
var init = function(open, close, replace) {
|
|
93
|
+
return filterEmpty(`\x1B[${open}m`, `\x1B[${close}m`, replace);
|
|
94
|
+
};
|
|
95
|
+
var createColors = function(useColor = isColorSupported) {
|
|
96
|
+
return useColor ? colorDefs : Object.fromEntries(Object.keys(colorDefs).map((key) => [key, String]));
|
|
97
|
+
};
|
|
98
|
+
var getColor = function(color, fallback = "reset") {
|
|
99
|
+
return colors[color] || colors[fallback];
|
|
100
|
+
};
|
|
101
|
+
var colorize = function(color, text) {
|
|
102
|
+
return getColor(color)(text);
|
|
103
|
+
};
|
|
104
|
+
var stripAnsi = function(text) {
|
|
105
|
+
return text.replace(new RegExp(ansiRegex, "g"), "");
|
|
106
|
+
};
|
|
107
|
+
var centerAlign = function(str, len, space = " ") {
|
|
108
|
+
const free = len - str.length;
|
|
109
|
+
if (free <= 0) {
|
|
110
|
+
return str;
|
|
111
|
+
}
|
|
112
|
+
const freeLeft = Math.floor(free / 2);
|
|
113
|
+
let _str = "";
|
|
114
|
+
for (let i = 0;i < len; i++) {
|
|
115
|
+
_str += i < freeLeft || i >= freeLeft + str.length ? space : str[i - freeLeft];
|
|
116
|
+
}
|
|
117
|
+
return _str;
|
|
118
|
+
};
|
|
119
|
+
var rightAlign = function(str, len, space = " ") {
|
|
120
|
+
const free = len - str.length;
|
|
121
|
+
if (free <= 0) {
|
|
122
|
+
return str;
|
|
123
|
+
}
|
|
124
|
+
let _str = "";
|
|
125
|
+
for (let i = 0;i < len; i++) {
|
|
126
|
+
_str += i < free ? space : str[i - free];
|
|
127
|
+
}
|
|
128
|
+
return _str;
|
|
129
|
+
};
|
|
130
|
+
var leftAlign = function(str, len, space = " ") {
|
|
131
|
+
let _str = "";
|
|
132
|
+
for (let i = 0;i < len; i++) {
|
|
133
|
+
_str += i < str.length ? str[i] : space;
|
|
134
|
+
}
|
|
135
|
+
return _str;
|
|
136
|
+
};
|
|
137
|
+
var align = function(alignment, str, len, space = " ") {
|
|
138
|
+
switch (alignment) {
|
|
139
|
+
case "left": {
|
|
140
|
+
return leftAlign(str, len, space);
|
|
141
|
+
}
|
|
142
|
+
case "right": {
|
|
143
|
+
return rightAlign(str, len, space);
|
|
144
|
+
}
|
|
145
|
+
case "center": {
|
|
146
|
+
return centerAlign(str, len, space);
|
|
147
|
+
}
|
|
148
|
+
default: {
|
|
149
|
+
return str;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
var box = function(text, _opts = {}) {
|
|
154
|
+
const opts = {
|
|
155
|
+
..._opts,
|
|
156
|
+
style: {
|
|
157
|
+
...defaultStyle,
|
|
158
|
+
..._opts.style
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const textLines = text.split("\n");
|
|
162
|
+
const boxLines = [];
|
|
163
|
+
const _color = getColor(opts.style.borderColor);
|
|
164
|
+
const borderStyle = {
|
|
165
|
+
...typeof opts.style.borderStyle === "string" ? boxStylePresets[opts.style.borderStyle] || boxStylePresets.solid : opts.style.borderStyle
|
|
166
|
+
};
|
|
167
|
+
if (_color) {
|
|
168
|
+
for (const key in borderStyle) {
|
|
169
|
+
borderStyle[key] = _color(borderStyle[key]);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const paddingOffset = opts.style.padding % 2 === 0 ? opts.style.padding : opts.style.padding + 1;
|
|
173
|
+
const height = textLines.length + paddingOffset;
|
|
174
|
+
const width = Math.max(...textLines.map((line) => line.length)) + paddingOffset;
|
|
175
|
+
const widthOffset = width + paddingOffset;
|
|
176
|
+
const leftSpace = opts.style.marginLeft > 0 ? " ".repeat(opts.style.marginLeft) : "";
|
|
177
|
+
if (opts.style.marginTop > 0) {
|
|
178
|
+
boxLines.push("".repeat(opts.style.marginTop));
|
|
179
|
+
}
|
|
180
|
+
if (opts.title) {
|
|
181
|
+
const left = borderStyle.h.repeat(Math.floor((width - stripAnsi(opts.title).length) / 2));
|
|
182
|
+
const right = borderStyle.h.repeat(width - stripAnsi(opts.title).length - stripAnsi(left).length + paddingOffset);
|
|
183
|
+
boxLines.push(`${leftSpace}${borderStyle.tl}${left}${opts.title}${right}${borderStyle.tr}`);
|
|
184
|
+
} else {
|
|
185
|
+
boxLines.push(`${leftSpace}${borderStyle.tl}${borderStyle.h.repeat(widthOffset)}${borderStyle.tr}`);
|
|
186
|
+
}
|
|
187
|
+
const valignOffset = opts.style.valign === "center" ? Math.floor((height - textLines.length) / 2) : opts.style.valign === "top" ? height - textLines.length - paddingOffset : height - textLines.length;
|
|
188
|
+
for (let i = 0;i < height; i++) {
|
|
189
|
+
if (i < valignOffset || i >= valignOffset + textLines.length) {
|
|
190
|
+
boxLines.push(`${leftSpace}${borderStyle.v}${" ".repeat(widthOffset)}${borderStyle.v}`);
|
|
191
|
+
} else {
|
|
192
|
+
const line = textLines[i - valignOffset];
|
|
193
|
+
const left = " ".repeat(paddingOffset);
|
|
194
|
+
const right = " ".repeat(width - stripAnsi(line).length);
|
|
195
|
+
boxLines.push(`${leftSpace}${borderStyle.v}${left}${line}${right}${borderStyle.v}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
boxLines.push(`${leftSpace}${borderStyle.bl}${borderStyle.h.repeat(widthOffset)}${borderStyle.br}`);
|
|
199
|
+
if (opts.style.marginBottom > 0) {
|
|
200
|
+
boxLines.push("".repeat(opts.style.marginBottom));
|
|
201
|
+
}
|
|
202
|
+
return boxLines.join("\n");
|
|
203
|
+
};
|
|
204
|
+
var {
|
|
205
|
+
env = {},
|
|
206
|
+
argv = [],
|
|
207
|
+
platform = ""
|
|
208
|
+
} = typeof process === "undefined" ? {} : process;
|
|
209
|
+
var isDisabled = "NO_COLOR" in env || argv.includes("--no-color");
|
|
210
|
+
var isForced = "FORCE_COLOR" in env || argv.includes("--color");
|
|
211
|
+
var isWindows = platform === "win32";
|
|
212
|
+
var isDumbTerminal = env.TERM === "dumb";
|
|
213
|
+
var isCompatibleTerminal = tty && tty.isatty && tty.isatty(1) && env.TERM && !isDumbTerminal;
|
|
214
|
+
var isCI = "CI" in env && (("GITHUB_ACTIONS" in env) || ("GITLAB_CI" in env) || ("CIRCLECI" in env));
|
|
215
|
+
var isColorSupported = !isDisabled && (isForced || isWindows && !isDumbTerminal || isCompatibleTerminal || isCI);
|
|
216
|
+
var colorDefs = {
|
|
217
|
+
reset: init(0, 0),
|
|
218
|
+
bold: init(1, 22, "\x1B[22m\x1B[1m"),
|
|
219
|
+
dim: init(2, 22, "\x1B[22m\x1B[2m"),
|
|
220
|
+
italic: init(3, 23),
|
|
221
|
+
underline: init(4, 24),
|
|
222
|
+
inverse: init(7, 27),
|
|
223
|
+
hidden: init(8, 28),
|
|
224
|
+
strikethrough: init(9, 29),
|
|
225
|
+
black: init(30, 39),
|
|
226
|
+
red: init(31, 39),
|
|
227
|
+
green: init(32, 39),
|
|
228
|
+
yellow: init(33, 39),
|
|
229
|
+
blue: init(34, 39),
|
|
230
|
+
magenta: init(35, 39),
|
|
231
|
+
cyan: init(36, 39),
|
|
232
|
+
white: init(37, 39),
|
|
233
|
+
gray: init(90, 39),
|
|
234
|
+
bgBlack: init(40, 49),
|
|
235
|
+
bgRed: init(41, 49),
|
|
236
|
+
bgGreen: init(42, 49),
|
|
237
|
+
bgYellow: init(43, 49),
|
|
238
|
+
bgBlue: init(44, 49),
|
|
239
|
+
bgMagenta: init(45, 49),
|
|
240
|
+
bgCyan: init(46, 49),
|
|
241
|
+
bgWhite: init(47, 49),
|
|
242
|
+
blackBright: init(90, 39),
|
|
243
|
+
redBright: init(91, 39),
|
|
244
|
+
greenBright: init(92, 39),
|
|
245
|
+
yellowBright: init(93, 39),
|
|
246
|
+
blueBright: init(94, 39),
|
|
247
|
+
magentaBright: init(95, 39),
|
|
248
|
+
cyanBright: init(96, 39),
|
|
249
|
+
whiteBright: init(97, 39),
|
|
250
|
+
bgBlackBright: init(100, 49),
|
|
251
|
+
bgRedBright: init(101, 49),
|
|
252
|
+
bgGreenBright: init(102, 49),
|
|
253
|
+
bgYellowBright: init(103, 49),
|
|
254
|
+
bgBlueBright: init(104, 49),
|
|
255
|
+
bgMagentaBright: init(105, 49),
|
|
256
|
+
bgCyanBright: init(106, 49),
|
|
257
|
+
bgWhiteBright: init(107, 49)
|
|
258
|
+
};
|
|
259
|
+
var colors = createColors();
|
|
260
|
+
var ansiRegex = [
|
|
261
|
+
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
|
|
262
|
+
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"
|
|
263
|
+
].join("|");
|
|
264
|
+
var boxStylePresets = {
|
|
265
|
+
solid: {
|
|
266
|
+
tl: "\u250C",
|
|
267
|
+
tr: "\u2510",
|
|
268
|
+
bl: "\u2514",
|
|
269
|
+
br: "\u2518",
|
|
270
|
+
h: "\u2500",
|
|
271
|
+
v: "\u2502"
|
|
272
|
+
},
|
|
273
|
+
double: {
|
|
274
|
+
tl: "\u2554",
|
|
275
|
+
tr: "\u2557",
|
|
276
|
+
bl: "\u255A",
|
|
277
|
+
br: "\u255D",
|
|
278
|
+
h: "\u2550",
|
|
279
|
+
v: "\u2551"
|
|
280
|
+
},
|
|
281
|
+
doubleSingle: {
|
|
282
|
+
tl: "\u2553",
|
|
283
|
+
tr: "\u2556",
|
|
284
|
+
bl: "\u2559",
|
|
285
|
+
br: "\u255C",
|
|
286
|
+
h: "\u2500",
|
|
287
|
+
v: "\u2551"
|
|
288
|
+
},
|
|
289
|
+
doubleSingleRounded: {
|
|
290
|
+
tl: "\u256D",
|
|
291
|
+
tr: "\u256E",
|
|
292
|
+
bl: "\u2570",
|
|
293
|
+
br: "\u256F",
|
|
294
|
+
h: "\u2500",
|
|
295
|
+
v: "\u2551"
|
|
296
|
+
},
|
|
297
|
+
singleThick: {
|
|
298
|
+
tl: "\u250F",
|
|
299
|
+
tr: "\u2513",
|
|
300
|
+
bl: "\u2517",
|
|
301
|
+
br: "\u251B",
|
|
302
|
+
h: "\u2501",
|
|
303
|
+
v: "\u2503"
|
|
304
|
+
},
|
|
305
|
+
singleDouble: {
|
|
306
|
+
tl: "\u2552",
|
|
307
|
+
tr: "\u2555",
|
|
308
|
+
bl: "\u2558",
|
|
309
|
+
br: "\u255B",
|
|
310
|
+
h: "\u2550",
|
|
311
|
+
v: "\u2502"
|
|
312
|
+
},
|
|
313
|
+
singleDoubleRounded: {
|
|
314
|
+
tl: "\u256D",
|
|
315
|
+
tr: "\u256E",
|
|
316
|
+
bl: "\u2570",
|
|
317
|
+
br: "\u256F",
|
|
318
|
+
h: "\u2550",
|
|
319
|
+
v: "\u2502"
|
|
320
|
+
},
|
|
321
|
+
rounded: {
|
|
322
|
+
tl: "\u256D",
|
|
323
|
+
tr: "\u256E",
|
|
324
|
+
bl: "\u2570",
|
|
325
|
+
br: "\u256F",
|
|
326
|
+
h: "\u2500",
|
|
327
|
+
v: "\u2502"
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
var defaultStyle = {
|
|
331
|
+
borderColor: "white",
|
|
332
|
+
borderStyle: "rounded",
|
|
333
|
+
valign: "center",
|
|
334
|
+
padding: 2,
|
|
335
|
+
marginLeft: 1,
|
|
336
|
+
marginTop: 1,
|
|
337
|
+
marginBottom: 1
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
// src/utils.ts
|
|
341
|
+
import {
|
|
342
|
+
ansi256Bg,
|
|
343
|
+
bgBlack,
|
|
344
|
+
bgBlue,
|
|
345
|
+
bgCyan,
|
|
346
|
+
bgGray,
|
|
347
|
+
bgGreen,
|
|
348
|
+
bgLightBlue,
|
|
349
|
+
bgLightCyan,
|
|
350
|
+
bgLightGray,
|
|
351
|
+
bgLightGreen,
|
|
352
|
+
bgLightMagenta,
|
|
353
|
+
bgLightRed,
|
|
354
|
+
bgLightYellow,
|
|
355
|
+
bgMagenta,
|
|
356
|
+
bgRed,
|
|
357
|
+
bgWhite,
|
|
358
|
+
bgYellow,
|
|
359
|
+
black,
|
|
360
|
+
blue,
|
|
361
|
+
bold,
|
|
362
|
+
cyan,
|
|
363
|
+
dim,
|
|
364
|
+
gray,
|
|
365
|
+
green,
|
|
366
|
+
hidden,
|
|
367
|
+
inverse,
|
|
368
|
+
italic,
|
|
369
|
+
lightBlue,
|
|
370
|
+
lightCyan,
|
|
371
|
+
lightGray,
|
|
372
|
+
lightGreen,
|
|
373
|
+
lightMagenta,
|
|
374
|
+
lightRed,
|
|
375
|
+
lightYellow,
|
|
376
|
+
link,
|
|
377
|
+
magenta,
|
|
378
|
+
red,
|
|
379
|
+
reset,
|
|
380
|
+
strikethrough,
|
|
381
|
+
underline,
|
|
382
|
+
white,
|
|
383
|
+
yellow,
|
|
384
|
+
ansi256,
|
|
385
|
+
trueColor,
|
|
386
|
+
trueColorBg,
|
|
387
|
+
stripColors
|
|
388
|
+
} from "kolorist";
|
|
90
389
|
|
|
91
390
|
// src/console.ts
|
|
92
|
-
import {log} from "@stacksjs/logging";
|
|
391
|
+
import {log as log2, logger} from "@stacksjs/logging";
|
|
93
392
|
import prompts from "prompts";
|
|
94
393
|
|
|
95
394
|
class Prompt {
|
|
@@ -106,61 +405,61 @@ class Prompt {
|
|
|
106
405
|
}
|
|
107
406
|
async select(message, options) {
|
|
108
407
|
if (this.isRequired())
|
|
109
|
-
return
|
|
110
|
-
return
|
|
408
|
+
return logger.prompt(message, { ...options, type: "select", required: true });
|
|
409
|
+
return logger.prompt(message, { ...options, type: "select" });
|
|
111
410
|
}
|
|
112
411
|
async checkbox(message, options) {
|
|
113
412
|
if (this.isRequired())
|
|
114
|
-
return
|
|
115
|
-
return
|
|
413
|
+
return logger.prompt(message, { ...options, type: "multiselect", required: true });
|
|
414
|
+
return logger.prompt(message, { ...options, type: "multiselect" });
|
|
116
415
|
}
|
|
117
416
|
async confirm(message, options) {
|
|
118
417
|
if (this.isRequired())
|
|
119
|
-
return
|
|
120
|
-
return
|
|
418
|
+
return logger.prompt(message, { ...options, type: "confirm", required: true });
|
|
419
|
+
return logger.prompt(message, { ...options, type: "confirm" });
|
|
121
420
|
}
|
|
122
421
|
async input(message, options) {
|
|
123
422
|
if (this.isRequired())
|
|
124
|
-
return
|
|
125
|
-
return
|
|
423
|
+
return logger.prompt(message, { ...options, type: "text", required: true });
|
|
424
|
+
return logger.prompt(message, { ...options, type: "text" });
|
|
126
425
|
}
|
|
127
426
|
async password(message, options) {
|
|
128
427
|
if (this.isRequired())
|
|
129
|
-
return
|
|
130
|
-
return
|
|
428
|
+
return logger.prompt(message, { ...options, type: "password", required: true });
|
|
429
|
+
return logger.prompt(message, { ...options, type: "password" });
|
|
131
430
|
}
|
|
132
431
|
async number(message, options) {
|
|
133
432
|
if (this.isRequired())
|
|
134
|
-
return
|
|
135
|
-
return
|
|
433
|
+
return logger.prompt(message, { ...options, type: "numeral", required: true });
|
|
434
|
+
return logger.prompt(message, { ...options, type: "numeral" });
|
|
136
435
|
}
|
|
137
436
|
async multiselect(message, options) {
|
|
138
437
|
if (this.isRequired())
|
|
139
|
-
return
|
|
140
|
-
return
|
|
438
|
+
return logger.prompt(message, { ...options, type: "multiselect", required: true });
|
|
439
|
+
return logger.prompt(message, { ...options, type: "multiselect" });
|
|
141
440
|
}
|
|
142
441
|
async autocomplete(message, options) {
|
|
143
442
|
if (this.isRequired())
|
|
144
|
-
return
|
|
145
|
-
return
|
|
443
|
+
return logger.prompt(message, { ...options, type: "autocomplete", required: true });
|
|
444
|
+
return logger.prompt(message, { ...options, type: "autocomplete" });
|
|
146
445
|
}
|
|
147
446
|
}
|
|
148
|
-
var prompt = new Prompt;
|
|
447
|
+
var prompt = () => new Prompt;
|
|
149
448
|
|
|
150
449
|
// src/run.ts
|
|
151
450
|
async function runCommand(command, options) {
|
|
152
|
-
|
|
153
|
-
|
|
451
|
+
log2.debug("runCommand:", command);
|
|
452
|
+
log2.debug("options:", options);
|
|
154
453
|
return await exec(command, options);
|
|
155
454
|
}
|
|
156
455
|
async function runProcess(command, options) {
|
|
157
|
-
|
|
158
|
-
|
|
456
|
+
log2.debug("runProcess:", italic(command));
|
|
457
|
+
log2.debug("runProcess Options:", options);
|
|
159
458
|
return await exec(command, options);
|
|
160
459
|
}
|
|
161
460
|
async function runCommandSync(command, options) {
|
|
162
|
-
|
|
163
|
-
|
|
461
|
+
log2.debug("runCommandSync:", italic(command));
|
|
462
|
+
log2.debug("runCommandSync Options:", options);
|
|
164
463
|
const result = await execSync(command, options);
|
|
165
464
|
return result;
|
|
166
465
|
}
|
|
@@ -188,23 +487,35 @@ class Command {
|
|
|
188
487
|
this.onSuccess = onSuccess;
|
|
189
488
|
}
|
|
190
489
|
}
|
|
490
|
+
var command = {
|
|
491
|
+
run: async (command2, options) => {
|
|
492
|
+
return await runCommand(command2, options);
|
|
493
|
+
},
|
|
494
|
+
runSync: async (command2, options) => {
|
|
495
|
+
return await runCommand(command2, options);
|
|
496
|
+
}
|
|
497
|
+
};
|
|
191
498
|
// src/helpers.ts
|
|
192
499
|
import {config as config2} from "@stacksjs/config";
|
|
193
500
|
import {handleError as handleError2} from "@stacksjs/error-handling";
|
|
194
|
-
import {log as
|
|
501
|
+
import {log as log3} from "@stacksjs/logging";
|
|
195
502
|
import {ExitCode as ExitCode2} from "@stacksjs/types";
|
|
196
503
|
import {bgCyan as bgCyan2, bold as bold2, cyan as cyan2, dim as dim2, gray as gray2, green as green2, italic as italic2} from "kolorist";
|
|
197
|
-
|
|
504
|
+
// package.json
|
|
505
|
+
var version = "0.58.61";
|
|
506
|
+
|
|
507
|
+
// src/helpers.ts
|
|
508
|
+
async function intro(command2, options) {
|
|
198
509
|
return new Promise((resolve) => {
|
|
199
510
|
if (options?.quiet === false) {
|
|
200
511
|
console.log();
|
|
201
512
|
console.log(cyan2(bold2("Stacks CLI")) + dim2(` v${version}`));
|
|
202
513
|
console.log();
|
|
203
514
|
}
|
|
204
|
-
let msg = `Running ${bgCyan2(italic2(bold2(` ${
|
|
205
|
-
if (
|
|
206
|
-
msg = `Running ${bgCyan2(italic2(bold2(` ${
|
|
207
|
-
|
|
515
|
+
let msg = `Running ${bgCyan2(italic2(bold2(` ${command2} `)))}`;
|
|
516
|
+
if (command2 === "buddy deploy")
|
|
517
|
+
msg = `Running ${bgCyan2(italic2(bold2(` ${command2} `)))} for ${bold2(`${config2.app.name}`)} ${italic2(`via ${config2.app.url}`)}`;
|
|
518
|
+
log3.info(msg);
|
|
208
519
|
if (options?.showPerformance === false || options?.quiet)
|
|
209
520
|
return resolve(0);
|
|
210
521
|
return resolve(performance.now());
|
|
@@ -229,23 +540,25 @@ function outro(text, options, error) {
|
|
|
229
540
|
if (opts.quiet === true)
|
|
230
541
|
return resolve(ExitCode2.Success);
|
|
231
542
|
if (error)
|
|
232
|
-
|
|
543
|
+
log3.error(`[${time.toFixed(2)}${opts.useSeconds ? "s" : "ms"}] Failed`);
|
|
233
544
|
else if (opts.type === "info")
|
|
234
|
-
|
|
545
|
+
log3.info(`${dim2(gray2(`[${time.toFixed(2)}${opts.useSeconds ? "s" : "ms"}]`))} ${opts.message ?? "Complete"}`);
|
|
235
546
|
else
|
|
236
|
-
|
|
547
|
+
log3.success(`${dim2(gray2(bold2(`[${time.toFixed(2)}${opts.useSeconds ? "s" : "ms"}]`)))} ${bold2(green2(opts.message ?? "Complete"))}`);
|
|
237
548
|
} else {
|
|
238
549
|
if (opts?.type === "info")
|
|
239
|
-
|
|
550
|
+
log3.info(text);
|
|
240
551
|
else if (opts?.type === "success" && opts?.quiet !== true)
|
|
241
|
-
|
|
552
|
+
log3.success(text);
|
|
242
553
|
}
|
|
243
554
|
return resolve(ExitCode2.Success);
|
|
244
555
|
});
|
|
245
556
|
}
|
|
246
557
|
// src/parse.ts
|
|
247
|
-
import
|
|
558
|
+
import process3 from "process";
|
|
248
559
|
var isLongOption = function(arg) {
|
|
560
|
+
if (!arg)
|
|
561
|
+
return false;
|
|
249
562
|
return arg.startsWith("--");
|
|
250
563
|
};
|
|
251
564
|
var isShortOption = function(arg) {
|
|
@@ -261,27 +574,29 @@ var parseValue = function(value) {
|
|
|
261
574
|
return numberValue;
|
|
262
575
|
return value.replace(/"/g, "");
|
|
263
576
|
};
|
|
264
|
-
var parseLongOption = function(arg,
|
|
577
|
+
var parseLongOption = function(arg, argv2, index, options) {
|
|
265
578
|
const [key, value] = arg.slice(2).split("=");
|
|
266
579
|
if (value !== undefined) {
|
|
267
580
|
options[key] = parseValue(value);
|
|
268
|
-
} else if (index + 1 <
|
|
269
|
-
options[key] =
|
|
581
|
+
} else if (index + 1 < argv2.length && !argv2[index + 1].startsWith("-")) {
|
|
582
|
+
options[key] = argv2[index + 1];
|
|
270
583
|
index++;
|
|
271
584
|
} else {
|
|
272
585
|
options[key] = true;
|
|
273
586
|
}
|
|
274
587
|
return index;
|
|
275
588
|
};
|
|
276
|
-
var parseShortOption = function(arg,
|
|
589
|
+
var parseShortOption = function(arg, argv2, index, options) {
|
|
277
590
|
const [key, value] = arg.slice(1).split("=");
|
|
278
|
-
if (
|
|
591
|
+
if (key === undefined)
|
|
592
|
+
return index;
|
|
593
|
+
if (value !== undefined && key !== undefined) {
|
|
279
594
|
for (let j = 0;j < key.length; j++)
|
|
280
595
|
options[key[j]] = parseValue(value);
|
|
281
596
|
} else {
|
|
282
597
|
for (let j = 0;j < key.length; j++) {
|
|
283
|
-
if (index + 1 <
|
|
284
|
-
options[key[j]] = parseValue(
|
|
598
|
+
if (index + 1 < argv2.length && j === key.length - 1 && !argv2[index + 1].startsWith("-")) {
|
|
599
|
+
options[key[j]] = parseValue(argv2[index + 1]);
|
|
285
600
|
index++;
|
|
286
601
|
} else {
|
|
287
602
|
options[key[j]] = true;
|
|
@@ -290,22 +605,75 @@ var parseShortOption = function(arg, argv, index, options) {
|
|
|
290
605
|
}
|
|
291
606
|
return index;
|
|
292
607
|
};
|
|
293
|
-
function parseArgv(
|
|
294
|
-
if (
|
|
295
|
-
|
|
608
|
+
function parseArgv(argv2) {
|
|
609
|
+
if (argv2 === undefined)
|
|
610
|
+
argv2 = process3.argv.slice(2);
|
|
296
611
|
const args = [];
|
|
297
612
|
const options = {};
|
|
298
|
-
for (let i = 0;i <
|
|
299
|
-
const arg =
|
|
613
|
+
for (let i = 0;i < argv2.length; i++) {
|
|
614
|
+
const arg = argv2[i];
|
|
615
|
+
if (!arg)
|
|
616
|
+
continue;
|
|
300
617
|
if (isLongOption(arg))
|
|
301
|
-
i = parseLongOption(arg,
|
|
618
|
+
i = parseLongOption(arg, argv2, i, options);
|
|
302
619
|
else if (isShortOption(arg))
|
|
303
|
-
i = parseShortOption(arg,
|
|
620
|
+
i = parseShortOption(arg, argv2, i, options);
|
|
304
621
|
else
|
|
305
622
|
args.push(arg);
|
|
306
623
|
}
|
|
307
624
|
return { args, options };
|
|
308
625
|
}
|
|
626
|
+
function parseArgs(argv2) {
|
|
627
|
+
if (argv2 === undefined)
|
|
628
|
+
argv2 = process3.argv.slice(2);
|
|
629
|
+
return parseArgv(argv2).args;
|
|
630
|
+
}
|
|
631
|
+
function parseOptions(options) {
|
|
632
|
+
options = options || {};
|
|
633
|
+
const args = process3.argv.slice(2);
|
|
634
|
+
for (let i = 0;i < args.length; i++) {
|
|
635
|
+
const arg = args[i];
|
|
636
|
+
if (arg?.startsWith("--")) {
|
|
637
|
+
const key = arg.substring(2);
|
|
638
|
+
const camelCaseKey = key.replace(/-([a-z])/gi, (g) => g[1] ? g[1].toUpperCase() : "");
|
|
639
|
+
if (i + 1 < args.length) {
|
|
640
|
+
if (args[i + 1] === "true" || args[i + 1] === "false") {
|
|
641
|
+
options[camelCaseKey] = args[i + 1] === "true";
|
|
642
|
+
i++;
|
|
643
|
+
} else {
|
|
644
|
+
options[camelCaseKey] = args[i + 1];
|
|
645
|
+
i++;
|
|
646
|
+
}
|
|
647
|
+
} else {
|
|
648
|
+
options[camelCaseKey] = true;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
if (Object.keys(options).length === 0)
|
|
653
|
+
return { dryRun: false, quiet: false, verbose: false };
|
|
654
|
+
Object.keys(options).forEach((key) => {
|
|
655
|
+
if (!options)
|
|
656
|
+
return { dryRun: false, quiet: false, verbose: false };
|
|
657
|
+
const value = options[key];
|
|
658
|
+
if (value === "true" || value === "false")
|
|
659
|
+
options[key] = value === "true";
|
|
660
|
+
});
|
|
661
|
+
return options;
|
|
662
|
+
}
|
|
663
|
+
function buddyOptions(options) {
|
|
664
|
+
if (!options) {
|
|
665
|
+
options = process3.argv.slice(2);
|
|
666
|
+
options = Array.from(new Set(options));
|
|
667
|
+
if (options[0] && !options[0].startsWith("-"))
|
|
668
|
+
options.shift();
|
|
669
|
+
}
|
|
670
|
+
if (options?.verbose) {
|
|
671
|
+
log.debug("process.argv", process3.argv);
|
|
672
|
+
log.debug("process.argv.slice(2)", process3.argv.slice(2));
|
|
673
|
+
log.debug("options inside buddyOptions", options);
|
|
674
|
+
}
|
|
675
|
+
return options.join(" ");
|
|
676
|
+
}
|
|
309
677
|
// src/spinner.ts
|
|
310
678
|
import ora from "ora";
|
|
311
679
|
var spinner = ora;
|
|
@@ -316,21 +684,25 @@ export {
|
|
|
316
684
|
trueColorBg,
|
|
317
685
|
trueColor,
|
|
318
686
|
stripColors,
|
|
687
|
+
stripAnsi,
|
|
319
688
|
strikethrough,
|
|
320
689
|
spinner,
|
|
321
690
|
runProcess,
|
|
322
691
|
runCommands,
|
|
323
692
|
runCommandSync,
|
|
324
693
|
runCommand,
|
|
694
|
+
rightAlign,
|
|
325
695
|
reset,
|
|
326
696
|
red,
|
|
327
697
|
prompts,
|
|
328
698
|
prompt,
|
|
329
699
|
parseOptions,
|
|
330
700
|
parseArgv,
|
|
701
|
+
parseArgs,
|
|
331
702
|
outro,
|
|
332
703
|
magenta,
|
|
333
|
-
|
|
704
|
+
logger,
|
|
705
|
+
log2 as log,
|
|
334
706
|
link,
|
|
335
707
|
lightYellow,
|
|
336
708
|
lightRed,
|
|
@@ -339,6 +711,7 @@ export {
|
|
|
339
711
|
lightGray,
|
|
340
712
|
lightCyan,
|
|
341
713
|
lightBlue,
|
|
714
|
+
leftAlign,
|
|
342
715
|
kolorist,
|
|
343
716
|
italic,
|
|
344
717
|
inverse,
|
|
@@ -348,11 +721,18 @@ export {
|
|
|
348
721
|
hidden,
|
|
349
722
|
green,
|
|
350
723
|
gray,
|
|
724
|
+
getColor,
|
|
351
725
|
execSync,
|
|
352
726
|
exec,
|
|
353
727
|
dim,
|
|
354
728
|
cyan,
|
|
729
|
+
command,
|
|
730
|
+
colors,
|
|
731
|
+
colorize,
|
|
355
732
|
cli,
|
|
733
|
+
centerAlign,
|
|
734
|
+
buddyOptions,
|
|
735
|
+
box,
|
|
356
736
|
bold,
|
|
357
737
|
blue,
|
|
358
738
|
black,
|
|
@@ -374,6 +754,8 @@ export {
|
|
|
374
754
|
bgBlack,
|
|
375
755
|
ansi256Bg,
|
|
376
756
|
ansi256,
|
|
757
|
+
align,
|
|
377
758
|
Prompt,
|
|
378
|
-
Command
|
|
759
|
+
Command,
|
|
760
|
+
CAC
|
|
379
761
|
};
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// import type { CliOptions } from '@stacksjs/types'
|
|
2
|
-
import
|
|
3
|
-
import { version } from '../package.json'
|
|
2
|
+
import { CAC } from 'cac'
|
|
4
3
|
|
|
5
|
-
interface ParsedArgv {
|
|
4
|
+
export interface ParsedArgv {
|
|
6
5
|
args: ReadonlyArray<string>
|
|
7
6
|
options: {
|
|
8
7
|
[k: string]: any
|
|
@@ -11,8 +10,8 @@ interface ParsedArgv {
|
|
|
11
10
|
|
|
12
11
|
interface CliOptions {
|
|
13
12
|
name?: string
|
|
14
|
-
version: string
|
|
15
|
-
description: string
|
|
13
|
+
// version: string
|
|
14
|
+
// description: string
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
export function cli(name?: string | CliOptions, options?: CliOptions) {
|
|
@@ -21,32 +20,11 @@ export function cli(name?: string | CliOptions, options?: CliOptions) {
|
|
|
21
20
|
name = options.name
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
cli.help()
|
|
27
|
-
cli.version(options?.version || version)
|
|
28
|
-
|
|
29
|
-
return cli
|
|
23
|
+
return new CAC(name || 'buddy')
|
|
30
24
|
}
|
|
31
25
|
|
|
32
|
-
export
|
|
33
|
-
return cli(options).command(name, description)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function parseArgs() {
|
|
37
|
-
return cli().parse().args
|
|
38
|
-
}
|
|
26
|
+
export { CAC }
|
|
39
27
|
|
|
40
|
-
export function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// Iterate over the options and convert "true" and "false" strings to boolean
|
|
44
|
-
for (const key in options) {
|
|
45
|
-
if (options[key] === 'true')
|
|
46
|
-
options[key] = true
|
|
47
|
-
else if (options[key] === 'false')
|
|
48
|
-
options[key] = false
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return options
|
|
52
|
-
}
|
|
28
|
+
// export function command(name: string, description: string, options?: CliOptions) {
|
|
29
|
+
// return cli(options).command(name, description)
|
|
30
|
+
// }
|
package/src/console.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { log } from '@stacksjs/logging'
|
|
1
|
+
import { log, logger } from '@stacksjs/logging'
|
|
2
2
|
import prompts from 'prompts'
|
|
3
3
|
|
|
4
4
|
export class Prompt {
|
|
@@ -19,61 +19,61 @@ export class Prompt {
|
|
|
19
19
|
|
|
20
20
|
async select(message: any, options: any) {
|
|
21
21
|
if (this.isRequired())
|
|
22
|
-
return
|
|
22
|
+
return logger.prompt(message, { ...options, type: 'select', required: true })
|
|
23
23
|
|
|
24
|
-
return
|
|
24
|
+
return logger.prompt(message, { ...options, type: 'select' })
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
async checkbox(message: any, options: any) {
|
|
28
28
|
if (this.isRequired())
|
|
29
|
-
return
|
|
29
|
+
return logger.prompt(message, { ...options, type: 'multiselect', required: true })
|
|
30
30
|
|
|
31
|
-
return
|
|
31
|
+
return logger.prompt(message, { ...options, type: 'multiselect' })
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
async confirm(message: any, options: any) {
|
|
35
35
|
if (this.isRequired())
|
|
36
|
-
return
|
|
36
|
+
return logger.prompt(message, { ...options, type: 'confirm', required: true })
|
|
37
37
|
|
|
38
|
-
return
|
|
38
|
+
return logger.prompt(message, { ...options, type: 'confirm' })
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
async input(message: any, options: any) {
|
|
42
42
|
if (this.isRequired())
|
|
43
|
-
return
|
|
43
|
+
return logger.prompt(message, { ...options, type: 'text', required: true })
|
|
44
44
|
|
|
45
|
-
return
|
|
45
|
+
return logger.prompt(message, { ...options, type: 'text' })
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
async password(message: any, options: any) {
|
|
49
49
|
if (this.isRequired())
|
|
50
|
-
return
|
|
50
|
+
return logger.prompt(message, { ...options, type: 'password', required: true })
|
|
51
51
|
|
|
52
|
-
return
|
|
52
|
+
return logger.prompt(message, { ...options, type: 'password' })
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
async number(message: any, options: any) {
|
|
56
56
|
if (this.isRequired())
|
|
57
|
-
return
|
|
57
|
+
return logger.prompt(message, { ...options, type: 'numeral', required: true })
|
|
58
58
|
|
|
59
|
-
return
|
|
59
|
+
return logger.prompt(message, { ...options, type: 'numeral' })
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
async multiselect(message: any, options: any) {
|
|
63
63
|
if (this.isRequired())
|
|
64
|
-
return
|
|
64
|
+
return logger.prompt(message, { ...options, type: 'multiselect', required: true })
|
|
65
65
|
|
|
66
|
-
return
|
|
66
|
+
return logger.prompt(message, { ...options, type: 'multiselect' })
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
async autocomplete(message: any, options: any) {
|
|
70
70
|
if (this.isRequired())
|
|
71
|
-
return
|
|
71
|
+
return logger.prompt(message, { ...options, type: 'autocomplete', required: true })
|
|
72
72
|
|
|
73
|
-
return
|
|
73
|
+
return logger.prompt(message, { ...options, type: 'autocomplete' })
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
export { prompts, log }
|
|
77
|
+
export { prompts, logger, log }
|
|
78
78
|
|
|
79
|
-
export const prompt = new Prompt()
|
|
79
|
+
export const prompt = () => new Prompt()
|
package/src/exec.ts
CHANGED
|
@@ -2,6 +2,7 @@ import process from 'node:process'
|
|
|
2
2
|
import { type Result, err, handleError, ok } from '@stacksjs/error-handling'
|
|
3
3
|
import type { CliOptions, StacksError, Subprocess } from '@stacksjs/types'
|
|
4
4
|
import { ExitCode } from '@stacksjs/types'
|
|
5
|
+
import { log } from './'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Execute a command.
|
|
@@ -24,19 +25,21 @@ import { ExitCode } from '@stacksjs/types'
|
|
|
24
25
|
* ```
|
|
25
26
|
*/
|
|
26
27
|
export async function exec(command: string | string[], options?: CliOptions): Promise<Result<Subprocess, StacksError>> {
|
|
27
|
-
const cmd = Array.isArray(command)
|
|
28
|
+
const cmd = Array.isArray(command)
|
|
29
|
+
? command
|
|
30
|
+
: command.match(/(?:[^\s"]+|"[^"]*")+/g)
|
|
28
31
|
|
|
29
32
|
if (!cmd)
|
|
30
33
|
return err(handleError(`Failed to parse command: ${cmd}`, options))
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
log.debug('exec:', Array.isArray(command) ? command.join(' ') : command)
|
|
36
|
+
log.debug('cmd:', cmd)
|
|
37
|
+
log.debug('exec options:', options)
|
|
35
38
|
|
|
36
39
|
const proc = Bun.spawn(cmd, {
|
|
37
40
|
...options,
|
|
38
|
-
stdout: options?.silent ? 'ignore' : (options?.stdin ? options.stdin : (options?.stdout || 'inherit')),
|
|
39
|
-
stderr: options?.silent ? 'ignore' : (options?.stderr || 'inherit'),
|
|
41
|
+
stdout: (options?.silent || options?.quiet) ? 'ignore' : (options?.stdin ? options.stdin : (options?.stdout || 'inherit')),
|
|
42
|
+
stderr: (options?.silent || options?.quiet) ? 'ignore' : (options?.stderr || 'inherit'),
|
|
40
43
|
detached: options?.background || false,
|
|
41
44
|
cwd: options?.cwd || import.meta.dir,
|
|
42
45
|
// env: { ...e, ...options?.env },
|
|
@@ -47,9 +50,12 @@ export async function exec(command: string | string[], options?: CliOptions): Pr
|
|
|
47
50
|
})
|
|
48
51
|
|
|
49
52
|
// Check if we need to write to stdin
|
|
53
|
+
// this is currently only used for `buddy aws:configure`
|
|
50
54
|
if (options?.stdin === 'pipe' && options.input) {
|
|
51
55
|
if (proc.stdin) {
|
|
56
|
+
// @ts-expect-error - this works even though there is a type error
|
|
52
57
|
proc.stdin.write(options.input)
|
|
58
|
+
// @ts-expect-error - this works even though there is a type error
|
|
53
59
|
proc.stdin.end()
|
|
54
60
|
}
|
|
55
61
|
}
|
|
@@ -78,10 +84,21 @@ export async function exec(command: string | string[], options?: CliOptions): Pr
|
|
|
78
84
|
* ```
|
|
79
85
|
*/
|
|
80
86
|
export async function execSync(command: string | string[], options?: CliOptions): Promise<string> {
|
|
81
|
-
|
|
87
|
+
log.debug('Running execSync:', command)
|
|
88
|
+
log.debug('execSync Options:', options)
|
|
89
|
+
|
|
90
|
+
const cmd = Array.isArray(command)
|
|
91
|
+
? command
|
|
92
|
+
: command.match(/(?:[^\s"]+|"[^"]*")+/g)
|
|
93
|
+
|
|
94
|
+
if (!cmd) {
|
|
95
|
+
log.error(`Failed to parse command: ${cmd}`, options)
|
|
96
|
+
process.exit(ExitCode.FatalError)
|
|
97
|
+
}
|
|
98
|
+
|
|
82
99
|
const proc = Bun.spawnSync(cmd, {
|
|
83
100
|
...options,
|
|
84
|
-
|
|
101
|
+
stdin: options?.stdin ?? 'inherit',
|
|
85
102
|
stdout: options?.stdout ?? 'pipe',
|
|
86
103
|
stderr: options?.stderr ?? 'inherit',
|
|
87
104
|
cwd: options?.cwd ?? import.meta.dir,
|
package/src/helpers.ts
CHANGED
|
@@ -61,14 +61,14 @@ export function outro(text: string, options?: OutroOptions, error?: Error | stri
|
|
|
61
61
|
if (error)
|
|
62
62
|
log.error(`[${time.toFixed(2)}${opts.useSeconds ? 's' : 'ms'}] Failed`)
|
|
63
63
|
else if (opts.type === 'info')
|
|
64
|
-
|
|
64
|
+
log.info(`${dim(gray(`[${time.toFixed(2)}${opts.useSeconds ? 's' : 'ms'}]`))} ${opts.message ?? 'Complete'}`)
|
|
65
65
|
else
|
|
66
|
-
|
|
66
|
+
log.success(`${dim(gray(bold(`[${time.toFixed(2)}${opts.useSeconds ? 's' : 'ms'}]`)))} ${bold(green(opts.message ?? 'Complete'))}`)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
else {
|
|
70
70
|
if (opts?.type === 'info')
|
|
71
|
-
|
|
71
|
+
log.info(text)
|
|
72
72
|
|
|
73
73
|
// the following condition triggers in the case of "Cleaned up" messages
|
|
74
74
|
else if (opts?.type === 'success' && opts?.quiet !== true)
|
package/src/index.ts
CHANGED
package/src/parse.ts
CHANGED
|
@@ -7,7 +7,10 @@ interface ParsedArgv {
|
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
function isLongOption(arg
|
|
10
|
+
function isLongOption(arg?: string): boolean {
|
|
11
|
+
if (!arg)
|
|
12
|
+
return false
|
|
13
|
+
|
|
11
14
|
return arg.startsWith('--')
|
|
12
15
|
}
|
|
13
16
|
|
|
@@ -32,14 +35,14 @@ function parseValue(value: string): string | boolean | number {
|
|
|
32
35
|
function parseLongOption(arg: string, argv: string[], index: number, options: { [k: string]: string | boolean | number }): number {
|
|
33
36
|
const [key, value] = arg.slice(2).split('=')
|
|
34
37
|
if (value !== undefined) {
|
|
35
|
-
options[key] = parseValue(value)
|
|
38
|
+
options[key as string] = parseValue(value)
|
|
36
39
|
}
|
|
37
|
-
else if (index + 1 < argv.length && !argv[index + 1]
|
|
38
|
-
options[key] = argv[index + 1]
|
|
40
|
+
else if (index + 1 < argv.length && !argv[index + 1]!.startsWith('-')) {
|
|
41
|
+
options[key as string] = argv[index + 1] as string
|
|
39
42
|
index++
|
|
40
43
|
}
|
|
41
44
|
else {
|
|
42
|
-
options[key] = true
|
|
45
|
+
options[key as string] = true
|
|
43
46
|
}
|
|
44
47
|
return index
|
|
45
48
|
}
|
|
@@ -47,18 +50,22 @@ function parseLongOption(arg: string, argv: string[], index: number, options: {
|
|
|
47
50
|
function parseShortOption(arg: string, argv: string[], index: number, options: { [k: string]: string | boolean | number }): number {
|
|
48
51
|
const [key, value] = arg.slice(1).split('=')
|
|
49
52
|
|
|
50
|
-
if
|
|
53
|
+
// Check if key is undefined and handle it
|
|
54
|
+
if (key === undefined)
|
|
55
|
+
return index
|
|
56
|
+
|
|
57
|
+
if (value !== undefined && key !== undefined) {
|
|
51
58
|
for (let j = 0; j < key.length; j++)
|
|
52
|
-
options[key[j]] = parseValue(value)
|
|
59
|
+
options[key[j] as string] = parseValue(value)
|
|
53
60
|
}
|
|
54
61
|
else {
|
|
55
62
|
for (let j = 0; j < key.length; j++) {
|
|
56
|
-
if (index + 1 < argv.length && j === key.length - 1 && !argv[index + 1]
|
|
57
|
-
options[key[j]] = parseValue(argv[index + 1])
|
|
63
|
+
if (index + 1 < argv.length && j === key.length - 1 && !argv[index + 1]!.startsWith('-')) {
|
|
64
|
+
options[key[j] as string] = parseValue(argv[index + 1]!)
|
|
58
65
|
index++
|
|
59
66
|
}
|
|
60
67
|
else {
|
|
61
|
-
options[key[j]] = true
|
|
68
|
+
options[key[j] as string] = true
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
71
|
}
|
|
@@ -75,6 +82,8 @@ export function parseArgv(argv?: string[]): ParsedArgv {
|
|
|
75
82
|
|
|
76
83
|
for (let i = 0; i < argv.length; i++) {
|
|
77
84
|
const arg = argv[i]
|
|
85
|
+
if (!arg)
|
|
86
|
+
continue
|
|
78
87
|
if (isLongOption(arg))
|
|
79
88
|
i = parseLongOption(arg, argv, i, options)
|
|
80
89
|
else if (isShortOption(arg))
|
|
@@ -86,16 +95,85 @@ export function parseArgv(argv?: string[]): ParsedArgv {
|
|
|
86
95
|
return { args, options }
|
|
87
96
|
}
|
|
88
97
|
|
|
89
|
-
// export function parseOptions(argv?: string[]): { [k: string]: string | boolean | number } {
|
|
90
|
-
// if (argv === undefined)
|
|
91
|
-
// argv = process.argv.slice(2)
|
|
92
|
-
|
|
93
|
-
// return parseArgv(argv).options
|
|
94
|
-
// }
|
|
95
|
-
|
|
96
98
|
export function parseArgs(argv?: string[]): string[] {
|
|
97
99
|
if (argv === undefined)
|
|
98
100
|
argv = process.argv.slice(2)
|
|
99
101
|
|
|
100
102
|
return parseArgv(argv).args
|
|
101
103
|
}
|
|
104
|
+
|
|
105
|
+
interface CliOptions {
|
|
106
|
+
dryRun?: boolean
|
|
107
|
+
quiet?: boolean
|
|
108
|
+
verbose?: boolean
|
|
109
|
+
[k: string]: string | boolean | number | undefined
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function parseOptions(options?: CliOptions): CliOptions {
|
|
113
|
+
options = options || {}
|
|
114
|
+
const args = process.argv.slice(2)
|
|
115
|
+
|
|
116
|
+
for (let i = 0; i < args.length; i++) {
|
|
117
|
+
const arg = args[i]
|
|
118
|
+
if (arg?.startsWith('--')) {
|
|
119
|
+
const key = arg.substring(2) // remove the --
|
|
120
|
+
const camelCaseKey = key.replace(
|
|
121
|
+
/-([a-z])/gi,
|
|
122
|
+
g => (g[1] ? g[1].toUpperCase() : ''), // convert kebab-case to camelCase
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
if (i + 1 < args.length) { // if the next arg exists
|
|
126
|
+
if (args[i + 1] === 'true' || args[i + 1] === 'false') { // if the next arg is a boolean
|
|
127
|
+
options[camelCaseKey] = args[i + 1] === 'true' // set the value to the boolean
|
|
128
|
+
i++
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
options[camelCaseKey] = args[i + 1]
|
|
132
|
+
i++
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
options[camelCaseKey] = true
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// if options has no keys, return undefined, e.g. `buddy release`
|
|
142
|
+
if (Object.keys(options).length === 0)
|
|
143
|
+
return { dryRun: false, quiet: false, verbose: false }
|
|
144
|
+
|
|
145
|
+
// convert the string 'true' or 'false' to a boolean
|
|
146
|
+
Object.keys(options).forEach((key) => {
|
|
147
|
+
if (!options)
|
|
148
|
+
return { dryRun: false, quiet: false, verbose: false }
|
|
149
|
+
|
|
150
|
+
const value = options[key]
|
|
151
|
+
|
|
152
|
+
if (value === 'true' || value === 'false')
|
|
153
|
+
options[key] = value === 'true'
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
return options
|
|
157
|
+
}
|
|
158
|
+
// interface BuddyOptions {
|
|
159
|
+
// dryRun?: boolean
|
|
160
|
+
// verbose?: boolean
|
|
161
|
+
// }
|
|
162
|
+
export function buddyOptions(options?: any): string {
|
|
163
|
+
if (!options) {
|
|
164
|
+
options = process.argv.slice(2)
|
|
165
|
+
options = Array.from(new Set(options))
|
|
166
|
+
// delete the 0 element if it does not start with a -
|
|
167
|
+
// e.g. is used when buddy changelog --dry-run is used
|
|
168
|
+
if (options[0] && !options[0].startsWith('-'))
|
|
169
|
+
options.shift()
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (options?.verbose) {
|
|
173
|
+
log.debug('process.argv', process.argv)
|
|
174
|
+
log.debug('process.argv.slice(2)', process.argv.slice(2))
|
|
175
|
+
log.debug('options inside buddyOptions', options)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return options.join(' ')
|
|
179
|
+
}
|
package/src/run.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CliOptions, CommandError, Subprocess } from '@stacksjs/types'
|
|
2
2
|
import type { Result } from '@stacksjs/error-handling'
|
|
3
3
|
import { exec, execSync } from './exec'
|
|
4
|
-
import { italic
|
|
4
|
+
import { italic } from './utils'
|
|
5
5
|
import { log } from './console'
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -30,15 +30,15 @@ import { log } from './console'
|
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
32
|
export async function runCommand(command: string, options?: CliOptions): Promise<Result<Subprocess, CommandError>> {
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
log.debug('runCommand:', command)
|
|
34
|
+
log.debug('options:', options)
|
|
35
35
|
|
|
36
36
|
return await exec(command, options)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export async function runProcess(command: string, options?: CliOptions): Promise<Result<Subprocess, CommandError>> {
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
log.debug('runProcess:', italic(command))
|
|
41
|
+
log.debug('runProcess Options:', options)
|
|
42
42
|
|
|
43
43
|
return await exec(command, options)
|
|
44
44
|
}
|
|
@@ -69,8 +69,8 @@ export async function runProcess(command: string, options?: CliOptions): Promise
|
|
|
69
69
|
* ```
|
|
70
70
|
*/
|
|
71
71
|
export async function runCommandSync(command: string, options?: CliOptions): Promise<string> {
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
log.debug('runCommandSync:', italic(command))
|
|
73
|
+
log.debug('runCommandSync Options:', options)
|
|
74
74
|
|
|
75
75
|
const result = await execSync(command, options)
|
|
76
76
|
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export * as kolorist from 'kolorist'
|
|
2
|
+
|
|
3
|
+
export {
|
|
4
|
+
stripAnsi,
|
|
5
|
+
centerAlign,
|
|
6
|
+
rightAlign,
|
|
7
|
+
leftAlign,
|
|
8
|
+
align,
|
|
9
|
+
box,
|
|
10
|
+
colors,
|
|
11
|
+
getColor,
|
|
12
|
+
colorize,
|
|
13
|
+
} from 'consola/utils'
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
ansi256Bg,
|
|
17
|
+
bgBlack,
|
|
18
|
+
bgBlue,
|
|
19
|
+
bgCyan,
|
|
20
|
+
bgGray,
|
|
21
|
+
bgGreen,
|
|
22
|
+
bgLightBlue,
|
|
23
|
+
bgLightCyan,
|
|
24
|
+
bgLightGray,
|
|
25
|
+
bgLightGreen,
|
|
26
|
+
bgLightMagenta,
|
|
27
|
+
bgLightRed,
|
|
28
|
+
bgLightYellow,
|
|
29
|
+
bgMagenta,
|
|
30
|
+
bgRed,
|
|
31
|
+
bgWhite,
|
|
32
|
+
bgYellow,
|
|
33
|
+
black,
|
|
34
|
+
blue,
|
|
35
|
+
bold,
|
|
36
|
+
cyan,
|
|
37
|
+
dim,
|
|
38
|
+
gray,
|
|
39
|
+
green,
|
|
40
|
+
hidden,
|
|
41
|
+
inverse,
|
|
42
|
+
italic,
|
|
43
|
+
lightBlue,
|
|
44
|
+
lightCyan,
|
|
45
|
+
lightGray,
|
|
46
|
+
lightGreen,
|
|
47
|
+
lightMagenta,
|
|
48
|
+
lightRed,
|
|
49
|
+
lightYellow,
|
|
50
|
+
link,
|
|
51
|
+
magenta,
|
|
52
|
+
red,
|
|
53
|
+
reset,
|
|
54
|
+
strikethrough,
|
|
55
|
+
underline,
|
|
56
|
+
white,
|
|
57
|
+
yellow,
|
|
58
|
+
ansi256,
|
|
59
|
+
trueColor,
|
|
60
|
+
trueColorBg,
|
|
61
|
+
stripColors,
|
|
62
|
+
} from 'kolorist'
|
package/src/utilities.ts
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
export * as kolorist from 'kolorist'
|
|
2
|
-
export { ansi256Bg, bgBlack, bgBlue, bgCyan, bgGray, bgGreen, bgLightBlue, bgLightCyan, bgLightGray, bgLightGreen, bgLightMagenta, bgLightRed, bgLightYellow, bgMagenta, bgRed, bgWhite, bgYellow, black, blue, bold, cyan, dim, gray, green, hidden, inverse, italic, lightBlue, lightCyan, lightGray, lightGreen, lightMagenta, lightRed, lightYellow, link, magenta, red, reset, strikethrough, underline, white, yellow, ansi256, trueColor, trueColorBg, stripColors } from 'kolorist'
|