bunosh 0.1.5 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,125 +1,541 @@
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
4
 
5
5
  <p align="center">
6
- <img src="assets/logo.jpg" alt="Logo">
6
+ <img src="assets/logo.png" alt="Logo" width="150">
7
7
  </p>
8
8
 
9
- ## What it is?
9
+ ## What is Bunosh?
10
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.
11
+ Bunosh is a modern task runner that transforms JavaScript functions into CLI commands. Write your build, deploy, and automation tasks in JavaScript and run them directly from the command line.
12
12
 
13
- What can you automate with Bunosh:
13
+ **Why Bunosh?**
14
+ - ✨ **Zero Configuration**: Write functions, get CLI commands
15
+ - 🚀 **Fast Execution**: Built for speed with beautiful terminal output
16
+ - 🎨 **Rich Output**: Colored formatting with progress indicators
17
+ - 📦 **Built-in Tasks**: Shell execution, HTTP requests, file operations
18
+ - 🔧 **Cross-Platform**: Works on macOS, Linux, and Windows
14
19
 
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
+ ## Installation
20
21
 
21
- Bunosh will get your scripts cooked into a **single JavaScript file**.
22
+ ### Option 1: Single Executable (Recommended)
22
23
 
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/*`;
24
+ Download and install the standalone executable - no Node.js or Bun required. Includes built-in upgrade functionality:
25
+
26
+ **macOS:**
27
+ ```bash
28
+ curl -fsSL https://github.com/davertmik/bunosh/releases/latest/download/bunosh-darwin-arm64.tar.gz | tar -xz
29
+ sudo mv bunosh-darwin-arm64 /usr/local/bin/bunosh
30
+ ```
31
+
32
+ **Linux:**
33
+ ```bash
34
+ curl -fsSL https://github.com/davertmik/bunosh/releases/latest/download/bunosh-linux-x64.tar.gz | tar -xz
35
+ sudo mv bunosh-linux-x64 /usr/local/bin/bunosh
36
+ ```
37
+
38
+ **Windows (PowerShell):**
39
+ ```powershell
40
+ Invoke-WebRequest -Uri "https://github.com/davertmik/bunosh/releases/latest/download/bunosh-windows-x64.exe.zip" -OutFile "bunosh.zip"
41
+ Expand-Archive -Path "bunosh.zip" -DestinationPath .
42
+ Move-Item "bunosh-windows-x64.exe" "bunosh.exe"
43
+ # Add bunosh.exe to your PATH
44
+ ```
45
+
46
+ ### Option 2: Bun Package Manager
47
+
48
+ ```bash
49
+ bun add -g bunosh
50
+ ```
51
+
52
+ ### Option 3: NPM Package
53
+
54
+ ```bash
55
+ npm install -g bunosh
56
+ ```
57
+
58
+
59
+ ```bash
60
+ # Initialize a new Bunoshfile
61
+ bunosh init
62
+
63
+ # This creates Bunoshfile.js with sample tasks
64
+ ```
65
+
66
+ ### Example: Web Development Tasks
67
+
68
+ Create a `Bunoshfile.js`:
69
+
70
+ ```javascript
71
+ // Import Bunosh functions from global object
72
+ const { exec, fetch, writeToFile, say, ask, yell } = global.bunosh;
73
+
74
+ /**
75
+ * Installs project dependencies
76
+ */
77
+ export async function install() {
78
+ await exec`npm install`;
79
+ say('📦 Dependencies installed!');
80
+ }
81
+
82
+ /**
83
+ * Starts development server
84
+ */
85
+ export async function dev() {
86
+ say('🚀 Starting development server...');
87
+ await exec`npm run dev`;
29
88
  }
30
89
 
31
- /** Builds Docker images for project **/
32
- export async function build(opts = { push: false }) {
33
- await Promise.all([
34
- buildFrontend(),
35
- buildBackend(),
36
- ])
90
+ /**
91
+ * Builds project for production
92
+ */
93
+ export async function build(target = 'production') {
94
+ say(`🔨 Building for ${target}...`);
95
+ await exec`npm run build`;
37
96
 
38
- if (opts.push) {
39
- await $`docker push frontend`;
40
- await $`docker push backend`;
97
+ if (target === 'production') {
98
+ await exec`npm run optimize`;
99
+ yell('BUILD COMPLETE!');
41
100
  }
42
101
  }
43
102
 
44
- /** Deploys application **/
45
- export async function deploy(env = 'staging') {
46
- await build();
47
- // ...
103
+ /**
104
+ * Deploys to specified environment
105
+ */
106
+ export async function deploy(env = 'staging', options = { skipTests: false }) {
107
+ if (!options.skipTests) {
108
+ say('🧪 Running tests...');
109
+ await exec`npm test`;
110
+ }
111
+
112
+ say(`🚀 Deploying to ${env}...`);
113
+ await build('production');
114
+ await exec`docker build -t myapp:${env} .`;
115
+ await exec`docker push myapp:${env}`;
116
+
117
+ yell(`DEPLOYED TO ${env.toUpperCase()}!`);
118
+ }
119
+
120
+ /**
121
+ * Cleans up temporary files
122
+ */
123
+ export async function clean() {
124
+ await exec`rm -rf dist node_modules/.cache tmp`;
125
+ say('✨ All clean!');
126
+ }
127
+
128
+ /**
129
+ * Setup new project environment
130
+ */
131
+ export async function setup() {
132
+ const projectName = await ask('What is your project name?');
133
+ const useTypescript = await ask('Use TypeScript? (y/n)') === 'y';
134
+
135
+ say('🏗️ Setting up project...');
136
+
137
+ // Create package.json
138
+ writeToFile('package.json', (line) => {
139
+ line`{`;
140
+ line` "name": "${projectName}",`;
141
+ line` "version": "1.0.0",`;
142
+ line` "type": "module"`;
143
+ if (useTypescript) {
144
+ line`, "devDependencies": {`;
145
+ line` "typescript": "^5.0.0"`;
146
+ line` }`;
147
+ }
148
+ line`}`;
149
+ });
150
+
151
+ if (useTypescript) {
152
+ await exec`npm install typescript --save-dev`;
153
+ }
154
+
155
+ yell('PROJECT READY!');
48
156
  }
157
+ ```
49
158
 
50
- /** Adds value to config **/
51
- export async function addToConfig(key, value) {}
159
+ ### Run Your Tasks
52
160
 
53
- //....
161
+ ```bash
162
+ # List all available commands
163
+ bunosh
164
+
165
+ # Run individual tasks
166
+ bunosh install
167
+ bunosh dev
168
+ bunosh build
169
+ bunosh build staging
170
+ bunosh deploy production --skip-tests
171
+ bunosh clean
172
+ bunosh setup
54
173
  ```
55
174
 
56
- Is turned into an executable command:
175
+ **Bunosh will display your tasks like this:**
176
+
57
177
  ```
178
+ 🍲 Your exceptional task runner
179
+
180
+ Usage: bunosh <command> <args> [options]
181
+
182
+ Commands are loaded from exported functions in Bunoshfile.js
183
+
58
184
  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]
185
+ build Builds project for production
186
+ bunosh build [target]
187
+ clean Cleans up temporary files
188
+ deploy Deploys to specified environment
189
+ bunosh deploy [env] --skip-tests
190
+ dev Starts development server
191
+ install Installs project dependencies
192
+ setup Setup new project environment
193
+ ```
66
194
 
195
+ ## Example: DevOps Tasks
67
196
 
68
- Special Commands:
69
- 📝 Edit bunosh file: bunosh edit
70
- 📥 Export scripts to package.json: bunosh export:scripts
197
+ ```javascript
198
+ const { exec, fetch, writeToFile, say, task } = global.bunosh;
71
199
 
200
+ /**
201
+ * Checks service health across environments
202
+ */
203
+ export async function healthCheck(env = 'production') {
204
+ const services = ['api', 'web', 'database'];
205
+
206
+ for (const service of services) {
207
+ const url = `https://${service}.${env}.example.com/health`;
208
+ await task(`Checking ${service}`, async () => {
209
+ const response = await fetch(url);
210
+ if (!response.ok) throw new Error(`${service} is down!`);
211
+ });
212
+ }
213
+
214
+ say('✅ All services healthy!');
215
+ }
216
+
217
+ /**
218
+ * Backup database with compression
219
+ */
220
+ export async function backup(database = 'main') {
221
+ const timestamp = new Date().toISOString().split('T')[0];
222
+ const filename = `backup-${database}-${timestamp}.sql.gz`;
223
+
224
+ await exec`pg_dump ${database} | gzip > ${filename}`;
225
+ await exec`aws s3 cp ${filename} s3://backups/${filename}`;
226
+ await exec`rm ${filename}`;
227
+
228
+ say(`📦 Backup saved: ${filename}`);
229
+ }
230
+
231
+ /**
232
+ * Updates SSL certificates
233
+ */
234
+ export async function updateCerts() {
235
+ await exec`certbot renew`;
236
+ await exec`nginx -s reload`;
237
+ say('🔒 Certificates updated!');
238
+ }
239
+
240
+ /**
241
+ * Deploys application with health checks
242
+ */
243
+ export async function deployWithChecks(env = 'staging') {
244
+ await exec`kubectl apply -f k8s/${env}/`;
245
+ await exec`kubectl rollout status deployment/myapp`;
246
+ await healthCheck(env);
247
+ say(`🚀 Successfully deployed to ${env}!`);
248
+ }
249
+
250
+ /**
251
+ * Scales application instances
252
+ */
253
+ export async function scale(replicas = 3, service = 'myapp') {
254
+ await exec`kubectl scale deployment/${service} --replicas=${replicas}`;
255
+ say(`⚖️ Scaled ${service} to ${replicas} replicas`);
256
+ }
72
257
  ```
73
258
 
74
- ### Command Rules:
259
+ **Bunosh displays these as:**
75
260
 
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
261
+ ```
262
+ Usage: bunosh <command> <args> [options]
86
263
 
264
+ Commands are loaded from exported functions in Bunoshfile.js
87
265
 
88
- ### Installation
266
+ Commands:
267
+ backup Backup database with compression
268
+ bunosh backup [database]
269
+ deploy:with-checks Deploys application with health checks
270
+ bunosh deploy:with-checks [env]
271
+ health:check Checks service health across environments
272
+ bunosh health:check [env]
273
+ scale Scales application instances
274
+ bunosh scale [replicas] [service]
275
+ update:certs Updates SSL certificates
89
276
 
90
- Install [Bun](https://bun.sh) (faster NodeJS alternative)
277
+ ```
91
278
 
92
- Install Bunosh globally:
279
+ ## Example: Content Management
280
+
281
+ ```javascript
282
+ const { exec, writeToFile, ask, say } = global.bunosh;
283
+
284
+ /**
285
+ * Creates new blog post template
286
+ */
287
+ export async function newPost() {
288
+ const title = await ask('Post title:');
289
+ const slug = title.toLowerCase().replace(/\s+/g, '-');
290
+ const date = new Date().toISOString().split('T')[0];
291
+
292
+ writeToFile(`posts/${date}-${slug}.md`, (line) => {
293
+ line`---`;
294
+ line`title: "${title}"`;
295
+ line`date: ${date}`;
296
+ line`draft: true`;
297
+ line`---`;
298
+ line``;
299
+ line`# ${title}`;
300
+ line``;
301
+ line`Your content here...`;
302
+ });
303
+
304
+ say(`📝 Created: posts/${date}-${slug}.md`);
305
+ }
306
+
307
+ /**
308
+ * Optimizes and compresses images
309
+ */
310
+ export async function optimizeImages() {
311
+ await exec`find ./images -name "*.jpg" -exec jpegoptim --max=80 {} \\;`;
312
+ await exec`find ./images -name "*.png" -exec optipng -o2 {} \\;`;
313
+ say('🖼️ Images optimized!');
314
+ }
315
+
316
+ /**
317
+ * Creates new page template
318
+ */
319
+ export async function newPage(name) {
320
+ const slug = name.toLowerCase().replace(/\s+/g, '-');
321
+
322
+ writeToFile(`content/pages/${slug}.md`, (line) => {
323
+ line`---`;
324
+ line`title: "${name}"`;
325
+ line`type: "page"`;
326
+ line`---`;
327
+ line``;
328
+ line`# ${name}`;
329
+ line``;
330
+ line`Page content here...`;
331
+ });
332
+
333
+ say(`📄 Created: content/pages/${slug}.md`);
334
+ }
335
+
336
+ /**
337
+ * Generates site and deploys
338
+ */
339
+ export async function publish() {
340
+ await exec`hugo --minify`;
341
+ await exec`rsync -avz public/ user@server:/var/www/site/`;
342
+ say('🌐 Site published!');
343
+ }
344
+
345
+ /**
346
+ * Builds and serves development site
347
+ */
348
+ export async function serve(port = 1313) {
349
+ await exec`hugo server --port ${port} --buildDrafts`;
350
+ }
351
+ ```
352
+
353
+ **Bunosh displays these as:**
354
+
355
+ ```
356
+ Usage: bunosh <command> <args> [options]
357
+
358
+ Commands are loaded from exported functions in Bunoshfile.js
359
+
360
+ Commands:
361
+ new:page Creates new page template
362
+ bunosh new:page <name>
363
+ new:post Creates new blog post template
364
+ optimize:images Optimizes and compresses images
365
+ publish Generates site and deploys
366
+ serve Builds and serves development site
367
+ bunosh serve [port]
368
+
369
+ ```
370
+
371
+ ## Built-in Functions
372
+
373
+ All Bunosh functions are available via `global.bunosh`:
374
+
375
+ ```javascript
376
+ const { exec, fetch, writeToFile, copyFile, say, ask, yell, task } = global.bunosh;
377
+ ```
378
+
379
+ ### Shell Execution (`exec`)
380
+ ```javascript
381
+ // Simple commands
382
+ await exec`echo "Hello World"`;
383
+ await exec`npm install`;
384
+
385
+ // With environment variables
386
+ await exec`echo $NODE_ENV`.env({ NODE_ENV: 'production' });
387
+
388
+ // With working directory
389
+ await exec`ls -la`.cwd('/tmp');
390
+
391
+ // Complex shell commands
392
+ await exec`find . -name "*.js" | grep -v node_modules | wc -l`;
393
+ ```
394
+
395
+ ### HTTP Requests (`fetch`)
396
+ ```javascript
397
+ // GET request with progress indicator
398
+ const response = await fetch('https://api.github.com/repos/user/repo');
399
+ const data = await response.json();
400
+ ```
401
+
402
+ ### File Operations
403
+ ```javascript
404
+ // Write file with template builder
405
+ writeToFile('config.json', (line) => {
406
+ line`{`;
407
+ line` "name": "myapp",`;
408
+ line` "version": "1.0.0"`;
409
+ line`}`;
410
+ });
411
+
412
+ // Copy files
413
+ copyFile('template.js', 'output.js');
414
+ ```
93
415
 
416
+ ### User Interaction
417
+ ```javascript
418
+ // Get user input
419
+ const name = await ask('What is your name?');
420
+
421
+ // Output messages
422
+ say('Building project...'); // Normal output
423
+ yell('BUILD COMPLETE!'); // Emphasized output
424
+
425
+ // Wrap long operations
426
+ await task('Installing dependencies', async () => {
427
+ await exec`npm install`;
428
+ });
429
+ ```
430
+
431
+ ## Command Features
432
+
433
+ ### Automatic CLI Generation
434
+ - `functionName` → `bunosh function:name`
435
+ - Function parameters become command arguments
436
+ - Last object parameter becomes CLI options
437
+ - JSDoc comments become help descriptions
438
+
439
+ ### Smart Argument Handling
440
+ ```javascript
441
+ // Function definition
442
+ export function deploy(env = 'staging', options = { force: false, verbose: false }) {
443
+ // ...
444
+ }
445
+
446
+ // CLI usage
447
+ bunosh deploy production --force --verbose
448
+ ```
449
+
450
+ ### Help and Documentation
94
451
  ```bash
95
- bun install -g bunosh
452
+ # List all commands
453
+ bunosh
454
+
455
+ # Get help for specific command
456
+ bunosh deploy --help
96
457
  ```
97
458
 
98
- Create a new tasks file in a project directory:
459
+ ### Shell Auto-Completion
460
+ Enable tab completion for faster command typing:
99
461
 
100
462
  ```bash
101
- bunosh init
463
+ # 🚀 Auto-setup (recommended) - detects your shell and installs completion
464
+ bunosh setup-completion
465
+
466
+ # Manual setup if needed
467
+ bunosh completion bash > ~/.bunosh-completion.bash
468
+ echo "source ~/.bunosh-completion.bash" >> ~/.bashrc
469
+ source ~/.bashrc
470
+
471
+ # Now use tab completion
472
+ bunosh dep<TAB> # Completes to 'deploy'
473
+ bunosh <TAB><TAB> # Shows all available commands
102
474
  ```
103
475
 
104
- ### API
476
+ **Supported shells:** bash, zsh, fish. The `setup-completion` command automatically detects your shell and handles installation. See [COMPLETION.md](COMPLETION.md) for detailed setup.
105
477
 
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.
478
+ ### Staying Up to Date
107
479
 
108
- Bunosh ships with a built-in functions to simplify writing scripts:
480
+ **Single Executable:**
481
+ ```bash
482
+ # Check for updates
483
+ bunosh upgrade --check
484
+
485
+ # Upgrade to latest version
486
+ bunosh upgrade
487
+
488
+ # Force reinstall current version
489
+ bunosh upgrade --force
490
+ ```
109
491
 
110
- ### Exec
492
+ **NPM Installation:**
493
+ ```bash
494
+ npm update -g bunosh
495
+ ```
111
496
 
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.
497
+ ## Advanced Usage
113
498
 
114
- ```js
115
- import { exec } from `bunosh`
499
+ ### Parallel Task Execution
500
+ ```javascript
501
+ const results = await Promise.all([
502
+ task('Task 1', () => exec`sleep 2 && echo "Done 1"`),
503
+ task('Task 2', () => exec`sleep 2 && echo "Done 2"`),
504
+ task('Task 3', () => exec`sleep 2 && echo "Done 3"`)
505
+ ]);
506
+ ```
116
507
 
117
- export async function build()
118
- {
119
- await exec`docker ps`
120
- await exec`docker build -t api .`
508
+ ### Error Handling
509
+ ```javascript
510
+ export async function deployWithRollback(env) {
511
+ try {
512
+ await deploy(env);
513
+ } catch (error) {
514
+ say('❌ Deployment failed, rolling back...');
515
+ await exec`kubectl rollout undo deployment/myapp`;
516
+ throw error;
517
+ }
121
518
  }
122
519
  ```
123
520
 
124
- Bunosh wraps `$` to make a fancy realtime output with Ink:
521
+ ### NPM Scripts Integration
522
+ Bunosh automatically includes your package.json scripts:
523
+ ```bash
524
+ bunosh npm:test # runs npm run test
525
+ bunosh npm:build # runs npm run build
526
+ ```
527
+
528
+ ## Contributing
529
+
530
+ 1. Fork the repository
531
+ 2. Create a feature branch
532
+ 3. Write tests for new functionality
533
+ 4. Submit a pull request
534
+
535
+ ## License
536
+
537
+ MIT License - see LICENSE file for details.
538
+
539
+ ---
125
540
 
541
+ Built with ❤️ for modern JavaScript development