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