bunosh 0.1.0 → 0.1.2
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/README.md +116 -6
- package/package.json +10 -2
- package/run.js +3 -2
- package/src/init.js +32 -3
- package/src/program.js +47 -21
- package/src/tasks/exec.jsx +31 -14
- package/templates/banner.js +4 -8
- package/templates/{init.js → init.js.tpl} +6 -7
- package/bunosh +0 -0
- package/bunosh.tasks.js +0 -83
- package/io.jsx +0 -47
- package/test.txt +0 -44
package/README.md
CHANGED
|
@@ -1,15 +1,125 @@
|
|
|
1
|
-
# bunosh
|
|
1
|
+
# 🍲 bunosh
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> *Named after **banosh**, a traditional Ukrainian dish from cornmeal cooked with various ingredients such as mushrooms, cheese, sour cream*
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="assets/logo.jpg" alt="Logo">
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
## What it is?
|
|
10
|
+
|
|
11
|
+
Bunosh is a task runner powered by [Bun](https://bun.sh). Bunosh is aimed to help you to write common scripts in JavaScript with less effort. Combines awesome tools: Bun, Commander.js, Ink, Inquirer in a the most compact way.
|
|
12
|
+
|
|
13
|
+
What can you automate with Bunosh:
|
|
14
|
+
|
|
15
|
+
* shell scripts → use JavaScript to write them (you know it better, anyway!)
|
|
16
|
+
* boilerplate scripts → create new files from templates
|
|
17
|
+
* deploy scripts → combine JS and Shell commands to build and deploy
|
|
18
|
+
* parallel tasks → with native `Promise.all` execute multiple tasks at once
|
|
19
|
+
* ...every other task you have previously written a custom `js` or `shell` script
|
|
20
|
+
|
|
21
|
+
Bunosh will get your scripts cooked into a **single JavaScript file**.
|
|
22
|
+
|
|
23
|
+
Each function of this file:
|
|
24
|
+
```js
|
|
25
|
+
/** Cleans up tmp & logs dir **/
|
|
26
|
+
export async function cleanTmp() {
|
|
27
|
+
await $`rm -rf tmp/*`;
|
|
28
|
+
await $`rm -rf logs/*`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Builds Docker images for project **/
|
|
32
|
+
export async function build(opts = { push: false }) {
|
|
33
|
+
await Promise.all([
|
|
34
|
+
buildFrontend(),
|
|
35
|
+
buildBackend(),
|
|
36
|
+
])
|
|
37
|
+
|
|
38
|
+
if (opts.push) {
|
|
39
|
+
await $`docker push frontend`;
|
|
40
|
+
await $`docker push backend`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Deploys application **/
|
|
45
|
+
export async function deploy(env = 'staging') {
|
|
46
|
+
await build();
|
|
47
|
+
// ...
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Adds value to config **/
|
|
51
|
+
export async function addToConfig(key, value) {}
|
|
52
|
+
|
|
53
|
+
//....
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Is turned into an executable command:
|
|
57
|
+
```
|
|
58
|
+
Commands:
|
|
59
|
+
add:to-config Adds value to config
|
|
60
|
+
bunosh add:to-config [key] [value]
|
|
61
|
+
build Builds Docker images for project
|
|
62
|
+
bunosh build --push
|
|
63
|
+
clean:tmp Cleans up tmp & logs dir
|
|
64
|
+
deploy Deploys application
|
|
65
|
+
bunosh deploy [env=staging]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
Special Commands:
|
|
69
|
+
📝 Edit bunosh file: bunosh edit
|
|
70
|
+
📥 Export scripts to package.json: bunosh export:scripts
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Command Rules:
|
|
75
|
+
|
|
76
|
+
* each exported function is a command:
|
|
77
|
+
* `function addUserModel` → `bunosh add:user-model`
|
|
78
|
+
* each function argument is a command argument:
|
|
79
|
+
* `addUser(name)` → `bunosh add:user <name>`
|
|
80
|
+
* `addUser(name='john')` → `bunosh add:user [name=john]`
|
|
81
|
+
* last argument passed as an object defines options:
|
|
82
|
+
* `clean(opts = {tmp: false, logs: false})` → `bunosh clean --tmp --logs`
|
|
83
|
+
* `addUsers(opts = {num: 1})` → `bunosh add:users --num 1`
|
|
84
|
+
* docblock or first-line comment of a function makes a command description
|
|
85
|
+
* functions can call make fetch requests, exec shell commands or call other functions
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
### Installation
|
|
89
|
+
|
|
90
|
+
Install [Bun](https://bun.sh) (faster NodeJS alternative)
|
|
91
|
+
|
|
92
|
+
Install Bunosh globally:
|
|
4
93
|
|
|
5
94
|
```bash
|
|
6
|
-
bun install
|
|
95
|
+
bun install -g bunosh
|
|
7
96
|
```
|
|
8
97
|
|
|
9
|
-
|
|
98
|
+
Create a new tasks file in a project directory:
|
|
10
99
|
|
|
11
100
|
```bash
|
|
12
|
-
|
|
101
|
+
bunosh init
|
|
13
102
|
```
|
|
14
103
|
|
|
15
|
-
|
|
104
|
+
### API
|
|
105
|
+
|
|
106
|
+
Commands can be written using classical NodeJS API using `fs` or `child_process` modules and print output using `console.log`. However, this doesn't unleash true Bunosh power.
|
|
107
|
+
|
|
108
|
+
Bunosh ships with a built-in functions to simplify writing scripts:
|
|
109
|
+
|
|
110
|
+
### Exec
|
|
111
|
+
|
|
112
|
+
`exec` or `$` is a wrapper around [Bun Shell](https://bun.sh/docs/runtime/shell). It is cross-platform bash-like shell with seamless JavaScript interop.
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
import { exec } from `bunosh`
|
|
116
|
+
|
|
117
|
+
export async function build()
|
|
118
|
+
{
|
|
119
|
+
await exec`docker ps`
|
|
120
|
+
await exec`docker build -t api .`
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Bunosh wraps `$` to make a fancy realtime output with Ink:
|
|
125
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bunosh",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"module": "index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"bunosh": "./run.js"
|
|
@@ -24,10 +24,18 @@
|
|
|
24
24
|
"ink-spinner": "^5.0.0",
|
|
25
25
|
"inquirer": "^9.2.13",
|
|
26
26
|
"open-editor": "^4.1.1",
|
|
27
|
-
"picocolors": "^1.0.0",
|
|
28
27
|
"react": "^18.2.0",
|
|
29
28
|
"timer-node": "^5.0.7"
|
|
30
29
|
},
|
|
30
|
+
"license": "ISC",
|
|
31
|
+
"files": [
|
|
32
|
+
"index.js",
|
|
33
|
+
"run.js",
|
|
34
|
+
"io.js",
|
|
35
|
+
"files.js",
|
|
36
|
+
"src",
|
|
37
|
+
"templates"
|
|
38
|
+
],
|
|
31
39
|
"lint-staged": {
|
|
32
40
|
"*.{js,css,md}": "prettier --write"
|
|
33
41
|
},
|
package/run.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
2
|
import program, { BUNOSHFILE, banner } from "./src/program";
|
|
3
3
|
import { existsSync, readFileSync } from "fs";
|
|
4
4
|
import init from "./src/init";
|
|
5
|
+
import path from "path";
|
|
5
6
|
import { say, yell } from './io';
|
|
6
7
|
|
|
7
|
-
const tasksFile =
|
|
8
|
+
const tasksFile = path.join(process.cwd(), BUNOSHFILE);
|
|
8
9
|
|
|
9
10
|
if (!existsSync(tasksFile)) {
|
|
10
11
|
console.log(banner);
|
package/src/init.js
CHANGED
|
@@ -1,11 +1,40 @@
|
|
|
1
1
|
import { BUNOSHFILE } from "./program";
|
|
2
2
|
import color from "picocolors";
|
|
3
|
-
import fs from
|
|
4
|
-
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
|
|
5
|
+
const template = `
|
|
6
|
+
import { exec, fetch, ignoreFail } from 'bunosh';
|
|
7
|
+
import { say, yell } from 'bunosh/io';
|
|
8
|
+
import { writeToFile } from 'bunosh/files';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 🎉 Hello world command
|
|
12
|
+
*/
|
|
13
|
+
export async function helloWorld() {
|
|
14
|
+
// use say() to print to the console
|
|
15
|
+
// say('Hello World!');
|
|
16
|
+
|
|
17
|
+
// use exec\`\` to execute shell scripts:
|
|
18
|
+
// await exec\`git status\`
|
|
19
|
+
|
|
20
|
+
// use fetch() to make HTTP requests
|
|
21
|
+
// await fetch('https://reqres.in/api/users')
|
|
22
|
+
|
|
23
|
+
// add arguments and options to this function if needed
|
|
24
|
+
// export async function helloWorld(userName, opts = { force: false })
|
|
25
|
+
//
|
|
26
|
+
// bunosh hello:world 'bob' --force
|
|
27
|
+
|
|
28
|
+
// use ignoreFail(true) to prevent the command from stopping on error
|
|
29
|
+
|
|
30
|
+
yell('Heloo Bunosh!');
|
|
31
|
+
say('Edit me with bunosh edit');
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
5
34
|
|
|
6
35
|
export default function init() {
|
|
7
36
|
if (!fs.existsSync(BUNOSHFILE)) {
|
|
8
|
-
|
|
37
|
+
Bun.write(BUNOSHFILE, template);
|
|
9
38
|
console.log(color.bold(`🎉 Bunosh ${BUNOSHFILE} file created`));
|
|
10
39
|
console.log(' Edit it with "bunosh edit" command');
|
|
11
40
|
console.log(' Or open it in your favorite editor');
|
package/src/program.js
CHANGED
|
@@ -16,7 +16,7 @@ export default function bunosh(commands, source) {
|
|
|
16
16
|
const internalCommands = [];
|
|
17
17
|
|
|
18
18
|
program.configureHelp({
|
|
19
|
-
commandDescription: _cmd => `${banner}\n Commands are loaded from ${color.bold(BUNOSHFILE)}
|
|
19
|
+
commandDescription: _cmd => `${banner}\n Commands are loaded from exported functions in ${color.bold(BUNOSHFILE)}`,
|
|
20
20
|
commandUsage: usg => 'bunosh <command> <args> [options]',
|
|
21
21
|
showGlobalOptions: false,
|
|
22
22
|
// visibleArguments: cmd => cmd.registeredArguments,
|
|
@@ -49,30 +49,50 @@ export default function bunosh(commands, source) {
|
|
|
49
49
|
const fnBody = commands[fnName].toString();
|
|
50
50
|
|
|
51
51
|
const ast = fetchFnAst();
|
|
52
|
-
|
|
53
52
|
const args = parseArgs();
|
|
54
53
|
const opts = parseOpts();
|
|
54
|
+
|
|
55
55
|
const comment = comments[fnName];
|
|
56
56
|
|
|
57
|
-
const
|
|
58
|
-
|
|
57
|
+
const commandName = prepareCommandName(fnName);
|
|
58
|
+
|
|
59
|
+
const command = program.command(commandName);
|
|
60
|
+
command.hook('preAction', (_thisCommand) => {
|
|
59
61
|
process.env.BUNOSH_COMMAND_STARTED = true;
|
|
60
62
|
})
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
let argsAndOptsDescription = [];
|
|
65
|
+
|
|
66
|
+
Object.entries(args).forEach(([arg, value]) => {
|
|
67
|
+
if (value === undefined) {
|
|
68
|
+
argsAndOptsDescription.push(`<${arg}>`);
|
|
69
|
+
return command.argument(`<${arg}>`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (value === null) {
|
|
73
|
+
argsAndOptsDescription.push(`[${arg}]`);
|
|
74
|
+
return command.argument(`[${arg}]`, '', null);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
argsAndOptsDescription.push(`[${arg}=${value}]`);
|
|
78
|
+
command.argument(`[${arg}]`, ``, value);
|
|
64
79
|
});
|
|
80
|
+
|
|
65
81
|
Object.entries(opts).forEach(([opt, value]) => {
|
|
66
|
-
if (value === false || value === null)
|
|
82
|
+
if (value === false || value === null) {
|
|
83
|
+
argsAndOptsDescription.push(`--${opt}`);
|
|
84
|
+
return command.option(`--${opt}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
argsAndOptsDescription.push(`--${opt}=${value}`);
|
|
67
88
|
command.option(`--${opt} [${opt}]`, "", value);
|
|
89
|
+
|
|
68
90
|
});
|
|
69
91
|
|
|
70
|
-
let description = comment || '';
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (
|
|
74
|
-
if (Object.keys(opts).length > 0) argsAndOpts += ` ${Object.keys(opts).map(opt => color.blueBright(`--${opt}`)).join(' ')}`
|
|
75
|
-
if (comment && argsAndOpts) description += `\n ${argsAndOpts.trim()}\n`;
|
|
92
|
+
let description = comment?.split('\n')[0] || '';
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
if (comment && argsAndOptsDescription.length) description += `\n ${color.gray(`bunosh ${commandName}`)} ${color.blue(argsAndOptsDescription.join(' ').trim())}`;
|
|
76
96
|
|
|
77
97
|
command.description(description);
|
|
78
98
|
command.action(commands[fnName].bind(commands));
|
|
@@ -97,7 +117,7 @@ export default function bunosh(commands, source) {
|
|
|
97
117
|
|
|
98
118
|
// We parse command args from function args
|
|
99
119
|
function parseArgs() {
|
|
100
|
-
const functionArguments =
|
|
120
|
+
const functionArguments = {};
|
|
101
121
|
|
|
102
122
|
traverse(ast, {
|
|
103
123
|
FunctionDeclaration(path) {
|
|
@@ -107,13 +127,20 @@ export default function bunosh(commands, source) {
|
|
|
107
127
|
.filter((node) => {
|
|
108
128
|
return node?.right?.type !== "ObjectExpression";
|
|
109
129
|
})
|
|
110
|
-
.
|
|
130
|
+
.forEach((param) => {
|
|
131
|
+
if (param.type === "AssignmentPattern") {
|
|
132
|
+
functionArguments[param.left.name] = param.right.value;
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (!param.name) return;
|
|
136
|
+
|
|
137
|
+
return functionArguments[param.name] = null;
|
|
138
|
+
});
|
|
111
139
|
|
|
112
|
-
functionArguments.push(params);
|
|
113
140
|
},
|
|
114
141
|
});
|
|
115
142
|
|
|
116
|
-
return functionArguments
|
|
143
|
+
return functionArguments;
|
|
117
144
|
}
|
|
118
145
|
|
|
119
146
|
// We parse command options from the object of last function args
|
|
@@ -132,7 +159,8 @@ export default function bunosh(commands, source) {
|
|
|
132
159
|
)
|
|
133
160
|
return;
|
|
134
161
|
|
|
135
|
-
|
|
162
|
+
|
|
163
|
+
node?.right?.properties?.forEach((p) => {
|
|
136
164
|
if (
|
|
137
165
|
["NumericLiteral", "StringLiteral", "BooleanLiteral"].includes(
|
|
138
166
|
p.value.type,
|
|
@@ -183,13 +211,10 @@ export default function bunosh(commands, source) {
|
|
|
183
211
|
internalCommands.push(exoprtCmd);
|
|
184
212
|
|
|
185
213
|
program.addHelpText('after', `
|
|
186
|
-
Example call:
|
|
187
|
-
bunosh ${program.commands.find(c => !internalCommands.includes(c)).name()} ${color.gray('<args>')} ${color.gray('[options]')}
|
|
188
214
|
|
|
189
215
|
Special Commands:
|
|
190
216
|
📝 Edit bunosh file: ${color.bold('bunosh edit')}
|
|
191
217
|
📥 Export scripts to package.json: ${color.bold('bunosh export:scripts')}
|
|
192
|
-
|
|
193
218
|
`);
|
|
194
219
|
|
|
195
220
|
|
|
@@ -220,6 +245,7 @@ Special Commands:
|
|
|
220
245
|
if (matches && matches[1]) {
|
|
221
246
|
comments[functionName] = matches[1]
|
|
222
247
|
.replace(/^\s*\*\s*/gm, "") // remove * chars
|
|
248
|
+
.replace(/\s*\*\*\s*$/gm, "") // remove * chars
|
|
223
249
|
.trim()
|
|
224
250
|
.replace(/^@.*$/gm, "") // remove params from description
|
|
225
251
|
.trim();
|
package/src/tasks/exec.jsx
CHANGED
|
@@ -19,32 +19,49 @@ export default function exec(strings, ...values) {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
let envs = null
|
|
22
|
-
cmdPromise.env = (newEnvs) =>
|
|
22
|
+
cmdPromise.env = (newEnvs) => {
|
|
23
|
+
envs = newEnvs;
|
|
24
|
+
return cmdPromise;
|
|
25
|
+
}
|
|
23
26
|
|
|
24
27
|
let cwd = null;
|
|
25
|
-
cmdPromise.cwd = (newCwd) =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (cwd) {
|
|
30
|
-
shell = shell.cwd(cwd);
|
|
31
|
-
}
|
|
32
|
-
if (envs) {
|
|
33
|
-
shell = shell.env(envs);
|
|
34
|
-
}
|
|
28
|
+
cmdPromise.cwd = (newCwd) => {
|
|
29
|
+
cwd = newCwd;
|
|
30
|
+
return cmdPromise;
|
|
31
|
+
}
|
|
35
32
|
|
|
33
|
+
const ExecOutput = () => {
|
|
36
34
|
const stackOutput = [];
|
|
37
|
-
|
|
35
|
+
|
|
38
36
|
const [printedLines, setPrintedLines] = useState([]);
|
|
39
37
|
const [exitCode, setExitCode] = useState(null);
|
|
40
|
-
|
|
38
|
+
|
|
41
39
|
const readNextChunk = async () => {
|
|
40
|
+
let shell = $(strings, ...values);
|
|
41
|
+
|
|
42
|
+
if (cwd) {
|
|
43
|
+
shell = shell.cwd(cwd);
|
|
44
|
+
}
|
|
45
|
+
if (envs) {
|
|
46
|
+
shell = shell.env(envs);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// there should be API to read stderr line by line...
|
|
42
50
|
for await (let line of shell.lines()) {
|
|
43
51
|
debugTask(cmd, line);
|
|
44
52
|
stackOutput.push(line);
|
|
45
53
|
setPrintedLines(stackOutput.slice(-DEFAULT_OUTPUT_SIZE));
|
|
46
54
|
}
|
|
47
|
-
|
|
55
|
+
|
|
56
|
+
const { exitCode, stderr } = await shell;
|
|
57
|
+
|
|
58
|
+
if (stderr) {
|
|
59
|
+
debugTask(cmd, stderr.toString());
|
|
60
|
+
stackOutput.push(stderr.toString())
|
|
61
|
+
setPrintedLines(stackOutput.slice(-DEFAULT_OUTPUT_SIZE));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const code = parseInt(exitCode, 10);
|
|
48
65
|
setExitCode(code);
|
|
49
66
|
if (code == 0) resolve(TaskResult.success(stackOutput.join('\n')));
|
|
50
67
|
if (code !== 0) resolve(TaskResult.fail(stackOutput.join('\n')));
|
package/templates/banner.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import color from "
|
|
1
|
+
import color from "chalk";
|
|
2
|
+
import cfonts from "cfonts";
|
|
2
3
|
|
|
3
4
|
export default `
|
|
4
|
-
|
|
5
|
-
[38;2;0;0;255m─[39m[38;2;0;21;255m║[39m[38;2;0;42;255m╔[39m[38;2;0;63;255m╗[39m[38;2;0;85;255m║[39m[38;2;0;106;255m─[39m[38;2;0;127;255m─[39m[38;2;0;148;255m║[39m[38;2;0;169;255m║[39m[38;2;0;191;255m─[39m[38;2;0;212;255m║[39m[38;2;0;233;255m║[39m[38;2;0;255;255m─[39m[38;2;0;255;233m║[39m[38;2;0;255;212m║[39m[38;2;0;255;191m╚[39m[38;2;0;255;169m╗[39m[38;2;0;255;148m║[39m[38;2;0;255;127m║[39m[38;2;0;255;106m─[39m[38;2;0;255;85m║[39m[38;2;0;255;63m╔[39m[38;2;0;255;42m═[39m[38;2;0;255;21m╗[39m[38;2;0;255;0m║[39m[38;2;21;255;0m─[39m[38;2;42;255;0m║[39m[38;2;63;255;0m╔[39m[38;2;84;255;0m═[39m[38;2;106;255;0m╗[39m[38;2;127;255;0m║[39m[38;2;148;255;0m─[39m[38;2;170;255;0m║[39m[38;2;191;255;0m║[39m[38;2;212;255;0m─[39m[38;2;233;255;0m║[39m[38;2;255;255;0m║[39m
|
|
6
|
-
[38;2;0;0;255m─[39m[38;2;0;21;255m║[39m[38;2;0;42;255m╚[39m[38;2;0;63;255m╝[39m[38;2;0;85;255m╚[39m[38;2;0;106;255m╗[39m[38;2;0;127;255m─[39m[38;2;0;148;255m║[39m[38;2;0;169;255m║[39m[38;2;0;191;255m─[39m[38;2;0;212;255m║[39m[38;2;0;233;255m║[39m[38;2;0;255;255m─[39m[38;2;0;255;233m║[39m[38;2;0;255;212m╔[39m[38;2;0;255;191m╗[39m[38;2;0;255;169m╚[39m[38;2;0;255;148m╝[39m[38;2;0;255;127m║[39m[38;2;0;255;106m─[39m[38;2;0;255;85m║[39m[38;2;0;255;63m║[39m[38;2;0;255;42m─[39m[38;2;0;255;21m║[39m[38;2;0;255;0m║[39m[38;2;21;255;0m─[39m[38;2;42;255;0m║[39m[38;2;63;255;0m╚[39m[38;2;84;255;0m═[39m[38;2;106;255;0m═[39m[38;2;127;255;0m╗[39m[38;2;148;255;0m─[39m[38;2;170;255;0m║[39m[38;2;191;255;0m╚[39m[38;2;212;255;0m═[39m[38;2;233;255;0m╝[39m[38;2;255;255;0m║[39m
|
|
7
|
-
[38;2;0;0;255m─[39m[38;2;0;21;255m║[39m[38;2;0;42;255m╔[39m[38;2;0;63;255m═[39m[38;2;0;85;255m╗[39m[38;2;0;106;255m║[39m[38;2;0;127;255m─[39m[38;2;0;148;255m║[39m[38;2;0;169;255m║[39m[38;2;0;191;255m─[39m[38;2;0;212;255m║[39m[38;2;0;233;255m║[39m[38;2;0;255;255m─[39m[38;2;0;255;233m║[39m[38;2;0;255;212m║[39m[38;2;0;255;191m╚[39m[38;2;0;255;169m╗[39m[38;2;0;255;148m║[39m[38;2;0;255;127m║[39m[38;2;0;255;106m─[39m[38;2;0;255;85m║[39m[38;2;0;255;63m║[39m[38;2;0;255;42m─[39m[38;2;0;255;21m║[39m[38;2;0;255;0m║[39m[38;2;21;255;0m─[39m[38;2;42;255;0m╚[39m[38;2;63;255;0m═[39m[38;2;84;255;0m═[39m[38;2;106;255;0m╗[39m[38;2;127;255;0m║[39m[38;2;148;255;0m─[39m[38;2;170;255;0m║[39m[38;2;191;255;0m╔[39m[38;2;212;255;0m═[39m[38;2;233;255;0m╗[39m[38;2;255;255;0m║[39m
|
|
8
|
-
[38;2;0;0;255m─[39m[38;2;0;21;255m║[39m[38;2;0;42;255m╚[39m[38;2;0;63;255m═[39m[38;2;0;85;255m╝[39m[38;2;0;106;255m║[39m[38;2;0;127;255m─[39m[38;2;0;148;255m║[39m[38;2;0;169;255m╚[39m[38;2;0;191;255m═[39m[38;2;0;212;255m╝[39m[38;2;0;233;255m║[39m[38;2;0;255;255m─[39m[38;2;0;255;233m║[39m[38;2;0;255;212m║[39m[38;2;0;255;191m─[39m[38;2;0;255;169m║[39m[38;2;0;255;148m║[39m[38;2;0;255;127m║[39m[38;2;0;255;106m─[39m[38;2;0;255;85m║[39m[38;2;0;255;63m╚[39m[38;2;0;255;42m═[39m[38;2;0;255;21m╝[39m[38;2;0;255;0m║[39m[38;2;21;255;0m─[39m[38;2;42;255;0m║[39m[38;2;63;255;0m╚[39m[38;2;84;255;0m═[39m[38;2;106;255;0m╝[39m[38;2;127;255;0m║[39m[38;2;148;255;0m─[39m[38;2;170;255;0m║[39m[38;2;191;255;0m║[39m[38;2;212;255;0m─[39m[38;2;233;255;0m║[39m[38;2;255;255;0m║[39m
|
|
9
|
-
[38;2;0;0;255m─[39m[38;2;0;21;255m╚[39m[38;2;0;42;255m═[39m[38;2;0;63;255m═[39m[38;2;0;85;255m═[39m[38;2;0;106;255m╝[39m[38;2;0;127;255m─[39m[38;2;0;148;255m╚[39m[38;2;0;169;255m═[39m[38;2;0;191;255m═[39m[38;2;0;212;255m═[39m[38;2;0;233;255m╝[39m[38;2;0;255;255m─[39m[38;2;0;255;233m╚[39m[38;2;0;255;212m╝[39m[38;2;0;255;191m─[39m[38;2;0;255;169m╚[39m[38;2;0;255;148m═[39m[38;2;0;255;127m╝[39m[38;2;0;255;106m─[39m[38;2;0;255;85m╚[39m[38;2;0;255;63m═[39m[38;2;0;255;42m═[39m[38;2;0;255;21m═[39m[38;2;0;255;0m╝[39m[38;2;21;255;0m─[39m[38;2;42;255;0m╚[39m[38;2;63;255;0m═[39m[38;2;84;255;0m═[39m[38;2;106;255;0m═[39m[38;2;127;255;0m╝[39m[38;2;148;255;0m─[39m[38;2;170;255;0m╚[39m[38;2;191;255;0m╝[39m[38;2;212;255;0m─[39m[38;2;233;255;0m╚[39m[38;2;255;255;0m╝[39m
|
|
5
|
+
${cfonts.render('Bunosh', { font: 'pallet', gradient: ['blue','yellow'], colors: ['system'], space: false}).string}
|
|
10
6
|
|
|
11
|
-
🍲 ${color.bold(color.white('Bunosh'))} - your ${color.bold('exceptional')} task runner powered by Bun
|
|
7
|
+
🍲 ${color.bold(color.dim.white('Bunosh'))} - your ${color.bold('exceptional')} task runner powered by Bun
|
|
12
8
|
`.trim();
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
import { say, yell } from
|
|
4
|
-
import { writeToFile } from
|
|
2
|
+
import { exec, fetch, ignoreFail } from 'bunosh';
|
|
3
|
+
import { say, yell } from 'bunosh/io';
|
|
4
|
+
import { writeToFile } from 'bunosh/files';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* 🎉 Hello world command
|
|
8
8
|
*/
|
|
9
9
|
export async function helloWorld() {
|
|
10
10
|
// use say() to print to the console
|
|
11
|
-
// say(
|
|
11
|
+
// say('Hello World!');
|
|
12
12
|
|
|
13
13
|
// use exec`` to execute shell scripts:
|
|
14
14
|
// await exec\`git status\`
|
|
@@ -23,7 +23,6 @@ export async function helloWorld() {
|
|
|
23
23
|
|
|
24
24
|
// use ignoreFail(true) to prevent the command from stopping on error
|
|
25
25
|
|
|
26
|
-
yell(
|
|
27
|
-
say('Edit me with
|
|
26
|
+
yell('Heloo Bunosh!');
|
|
27
|
+
say('Edit me with bunosh edit');
|
|
28
28
|
}
|
|
29
|
-
`;
|
package/bunosh
DELETED
|
Binary file
|
package/bunosh.tasks.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
import { exec, fetch, task, ignoreFail } from "./index";
|
|
3
|
-
import { ask, say, yell } from "./io";
|
|
4
|
-
import fs from "fs";
|
|
5
|
-
import { writeToFile } from "./files";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Builds binary file for Bunosh
|
|
9
|
-
*/
|
|
10
|
-
export async function buildBinary() {
|
|
11
|
-
await exec`bun build ./run.js --compile --outfile bunosh`;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* 🎉 Hello world
|
|
16
|
-
* @param {*} arg1
|
|
17
|
-
* @param {*} opts
|
|
18
|
-
*/
|
|
19
|
-
export async function helloWorld(
|
|
20
|
-
arg1,
|
|
21
|
-
opts = { user: null, val: "ok", flag: false },
|
|
22
|
-
) {
|
|
23
|
-
// console.log("Hello World!", arg1);
|
|
24
|
-
yell("I need all git status");
|
|
25
|
-
const pack = await task('read file', () => {
|
|
26
|
-
return fs.readFileSync("package.json").toString();
|
|
27
|
-
});
|
|
28
|
-
say(pack);
|
|
29
|
-
writeToFile('test.txt', l => {
|
|
30
|
-
l`lock file`
|
|
31
|
-
l('Hello world');
|
|
32
|
-
l.fromFile('package.json');
|
|
33
|
-
});
|
|
34
|
-
yell('done');
|
|
35
|
-
yell('ok');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Hello other
|
|
40
|
-
*/
|
|
41
|
-
export async function helloOther(opts = {
|
|
42
|
-
user: null,
|
|
43
|
-
val: "ok",
|
|
44
|
-
flag: false
|
|
45
|
-
}) {
|
|
46
|
-
|
|
47
|
-
yell('running everything!')
|
|
48
|
-
|
|
49
|
-
await fetch('https://reqres.in/api/users')
|
|
50
|
-
|
|
51
|
-
await Promise.all([
|
|
52
|
-
fetch('https://reqres.in/api/users/1'),
|
|
53
|
-
exec`ps aux | grep redis`,
|
|
54
|
-
fetch('https://reqres.in/api/users/2')
|
|
55
|
-
])
|
|
56
|
-
|
|
57
|
-
ignoreFail(true);
|
|
58
|
-
|
|
59
|
-
await exec`ps aux | grep node`,
|
|
60
|
-
await exec`git status`.cwd('/home/davert/projects/codeceptjs');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Deploys code to staging
|
|
65
|
-
*/
|
|
66
|
-
export async function updateToProduction() {
|
|
67
|
-
|
|
68
|
-
await Promise.all([
|
|
69
|
-
exec`ps aux | grep redis`,
|
|
70
|
-
exec`ps aux | grep clickhouse`,
|
|
71
|
-
fetch('https://reqres.in/api/users/2'),
|
|
72
|
-
])
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Deploys code to production
|
|
77
|
-
*/
|
|
78
|
-
export async function updateToStaging() {
|
|
79
|
-
// this is not ok
|
|
80
|
-
const env = await ask('Which environment we are in?');
|
|
81
|
-
say(env);
|
|
82
|
-
}
|
|
83
|
-
|
package/io.jsx
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import React, {useState, useEffect} from 'react';
|
|
2
|
-
import { Box, Text } from 'ink';
|
|
3
|
-
import { renderOnce, isStaticOutput} from './src/output';
|
|
4
|
-
import Gradient from 'ink-gradient';
|
|
5
|
-
import BigText from 'ink-big-text';
|
|
6
|
-
import inquirer from 'inquirer';
|
|
7
|
-
|
|
8
|
-
export function say(...args) {
|
|
9
|
-
if (isStaticOutput) {
|
|
10
|
-
console.log(...args);
|
|
11
|
-
return;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const colors = ['yellow', 'magenta', 'cyan', 'blue', 'blueBright', 'magentaBright', 'cyanBright', 'whiteBright'];
|
|
15
|
-
|
|
16
|
-
renderOnce(
|
|
17
|
-
<Box gap={1} height={20} overflow='hidden' >
|
|
18
|
-
<Text color='white'>!</Text>
|
|
19
|
-
{args.map((arg, i) => <Text color={colors[i]} key={i}>{arg}</Text>)}
|
|
20
|
-
</Box>
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export async function ask(question, opts = {}) {
|
|
25
|
-
|
|
26
|
-
const answers = await inquirer.prompt({ name: question, message: question, ...opts })
|
|
27
|
-
|
|
28
|
-
return Object.values(answers)[0];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function yell(text) {
|
|
32
|
-
if (isStaticOutput) {
|
|
33
|
-
console.log();
|
|
34
|
-
console.log(text.toUpperCase());
|
|
35
|
-
console.log();
|
|
36
|
-
return;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
renderOnce(
|
|
40
|
-
<Box gap={1} marginLeft={1}>
|
|
41
|
-
<Gradient name="teen">
|
|
42
|
-
<BigText text={text}/>
|
|
43
|
-
</Gradient>
|
|
44
|
-
|
|
45
|
-
</Box>
|
|
46
|
-
);
|
|
47
|
-
}
|
package/test.txt
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
lock file
|
|
2
|
-
Hello world
|
|
3
|
-
{
|
|
4
|
-
"name": "bunosh",
|
|
5
|
-
"module": "index.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"bunosh": "./run.js"
|
|
8
|
-
},
|
|
9
|
-
"devDependencies": {
|
|
10
|
-
"@types/bun": "latest",
|
|
11
|
-
"prettier": "^3.2.4",
|
|
12
|
-
"lint-staged": "^15.2.0"
|
|
13
|
-
},
|
|
14
|
-
"peerDependencies": {
|
|
15
|
-
"typescript": "^5.0.0"
|
|
16
|
-
},
|
|
17
|
-
"dependencies": {
|
|
18
|
-
"@babel/parser": "^7.23.6",
|
|
19
|
-
"@babel/traverse": "^7.23.7",
|
|
20
|
-
"cfonts": "^3.2.0",
|
|
21
|
-
"chalk": "^5.3.0",
|
|
22
|
-
"commander": "^11.1.0",
|
|
23
|
-
"debug": "^4.3.4",
|
|
24
|
-
"fs-extra": "^11.2.0",
|
|
25
|
-
"ink": "^4.4.1",
|
|
26
|
-
"ink-big-text": "^2.0.0",
|
|
27
|
-
"ink-gradient": "^3.0.0",
|
|
28
|
-
"ink-spinner": "^5.0.0",
|
|
29
|
-
"inquirer": "^9.2.13",
|
|
30
|
-
"open-editor": "^4.1.1",
|
|
31
|
-
"picocolors": "^1.0.0",
|
|
32
|
-
"react": "^18.2.0",
|
|
33
|
-
"timer-node": "^5.0.7"
|
|
34
|
-
},
|
|
35
|
-
"lint-staged": {
|
|
36
|
-
"*.{js,css,md}": "prettier --write"
|
|
37
|
-
},
|
|
38
|
-
"scripts": {
|
|
39
|
-
"hello:other": "bunosh hello:other",
|
|
40
|
-
"hello:world": "bunosh hello:world",
|
|
41
|
-
"update:to-production": "bunosh update:to-production",
|
|
42
|
-
"update:to-staging": "bunosh update:to-staging"
|
|
43
|
-
}
|
|
44
|
-
}
|