bunosh 0.3.2 → 0.4.1
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 +225 -328
- package/bunosh.js +173 -48
- package/index.js +3 -3
- package/package.json +1 -1
- package/src/init.js +2 -2
- package/src/io.js +90 -21
- package/src/printer.js +14 -2
- package/src/program.js +321 -21
- package/src/task.js +41 -43
- package/src/tasks/exec.js +14 -2
- package/src/tasks/fetch.js +4 -3
- package/src/tasks/shell.js +37 -5
- package/src/open-editor.js +0 -95
package/src/tasks/shell.js
CHANGED
|
@@ -4,13 +4,45 @@ import Printer from "../printer.js";
|
|
|
4
4
|
const isBun = typeof Bun !== 'undefined' && typeof Bun.spawn === 'function';
|
|
5
5
|
|
|
6
6
|
export default function shell(strings, ...values) {
|
|
7
|
+
let envs = null;
|
|
8
|
+
let cwd = null;
|
|
9
|
+
|
|
10
|
+
// Check if called as regular function instead of template literal
|
|
11
|
+
if (!Array.isArray(strings)) {
|
|
12
|
+
// If first argument is a string, treat it as the command
|
|
13
|
+
if (typeof strings === 'string') {
|
|
14
|
+
// For Bun shell, we need to create a template literal-like call
|
|
15
|
+
// But since we can't, fall back to exec
|
|
16
|
+
console.log('Note: shell() with string argument falls back to exec()');
|
|
17
|
+
const cmdPromise = (async () => {
|
|
18
|
+
const { default: exec } = await import("./exec.js");
|
|
19
|
+
let execPromise = exec(strings);
|
|
20
|
+
if (envs) execPromise = execPromise.env(envs);
|
|
21
|
+
if (cwd) execPromise = execPromise.cwd(cwd);
|
|
22
|
+
return execPromise;
|
|
23
|
+
})();
|
|
24
|
+
|
|
25
|
+
// Add .env and .cwd methods
|
|
26
|
+
cmdPromise.env = (newEnvs) => {
|
|
27
|
+
envs = newEnvs;
|
|
28
|
+
return cmdPromise;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
cmdPromise.cwd = (newCwd) => {
|
|
32
|
+
cwd = newCwd;
|
|
33
|
+
return cmdPromise;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return cmdPromise;
|
|
37
|
+
} else {
|
|
38
|
+
throw new Error('shell() must be called as a template literal: shell`command`');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
7
42
|
const cmd = strings.reduce((accumulator, str, i) => {
|
|
8
43
|
return accumulator + str + (values[i] || "");
|
|
9
44
|
}, "");
|
|
10
45
|
|
|
11
|
-
let envs = null;
|
|
12
|
-
let cwd = null;
|
|
13
|
-
|
|
14
46
|
const cmdPromise = new Promise(async (resolve, reject) => {
|
|
15
47
|
const extraInfo = {};
|
|
16
48
|
if (cwd) extraInfo.cwd = cwd;
|
|
@@ -18,7 +50,7 @@ export default function shell(strings, ...values) {
|
|
|
18
50
|
|
|
19
51
|
if (!isBun) {
|
|
20
52
|
const { default: exec } = await import("./exec.js");
|
|
21
|
-
let execPromise = exec(
|
|
53
|
+
let execPromise = exec([cmd]);
|
|
22
54
|
if (envs) execPromise = execPromise.env(envs);
|
|
23
55
|
if (cwd) execPromise = execPromise.cwd(cwd);
|
|
24
56
|
const result = await execPromise;
|
|
@@ -64,7 +96,7 @@ export default function shell(strings, ...values) {
|
|
|
64
96
|
finishTaskInfo(taskInfo, true, null, "fallback to exec");
|
|
65
97
|
|
|
66
98
|
const { default: exec } = await import("./exec.js");
|
|
67
|
-
let execPromise = exec
|
|
99
|
+
let execPromise = exec([cmd]);
|
|
68
100
|
if (envs) execPromise = execPromise.env(envs);
|
|
69
101
|
if (cwd) execPromise = execPromise.cwd(cwd);
|
|
70
102
|
const result = await execPromise;
|
package/src/open-editor.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'child_process';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
|
|
4
|
-
export default function openEditor(files, options = {}) {
|
|
5
|
-
if (!Array.isArray(files) || files.length === 0) {
|
|
6
|
-
throw new Error('Files array is required and cannot be empty');
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const editor = options.editor || getDefaultEditor();
|
|
10
|
-
const fileArgs = buildEditorArgs(editor, files);
|
|
11
|
-
|
|
12
|
-
return new Promise((resolve, reject) => {
|
|
13
|
-
const child = spawn(editor, fileArgs, {
|
|
14
|
-
stdio: 'inherit',
|
|
15
|
-
detached: true
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
child.on('error', (err) => {
|
|
19
|
-
reject(new Error(`Failed to open editor '${editor}': ${err.message}`));
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
child.on('spawn', () => {
|
|
23
|
-
resolve();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
if (child.pid) {
|
|
27
|
-
child.unref();
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function getDefaultEditor() {
|
|
33
|
-
if (process.env.EDITOR) {
|
|
34
|
-
return process.env.EDITOR;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const editors = ['code', 'subl', 'atom', 'vim', 'nvim', 'nano', 'gedit'];
|
|
38
|
-
|
|
39
|
-
for (const editor of editors) {
|
|
40
|
-
if (isCommandAvailable(editor)) {
|
|
41
|
-
return editor;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return process.platform === 'win32' ? 'notepad' : 'vi';
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function isCommandAvailable(command) {
|
|
49
|
-
try {
|
|
50
|
-
const { execSync } = require('child_process');
|
|
51
|
-
execSync(`which ${command}`, { stdio: 'ignore' });
|
|
52
|
-
return true;
|
|
53
|
-
} catch {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function buildEditorArgs(editor, files) {
|
|
59
|
-
const editorName = path.basename(editor);
|
|
60
|
-
const args = [];
|
|
61
|
-
|
|
62
|
-
for (const fileInfo of files) {
|
|
63
|
-
const filePath = typeof fileInfo === 'string' ? fileInfo : fileInfo.file;
|
|
64
|
-
|
|
65
|
-
if (!filePath) {
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (fileInfo.line && typeof fileInfo === 'object') {
|
|
70
|
-
switch (editorName) {
|
|
71
|
-
case 'code':
|
|
72
|
-
case 'code-insiders':
|
|
73
|
-
args.push('--goto', `${filePath}:${fileInfo.line}:${fileInfo.column || 1}`);
|
|
74
|
-
break;
|
|
75
|
-
case 'subl':
|
|
76
|
-
case 'sublime_text':
|
|
77
|
-
args.push(`${filePath}:${fileInfo.line}:${fileInfo.column || 1}`);
|
|
78
|
-
break;
|
|
79
|
-
case 'vim':
|
|
80
|
-
case 'nvim':
|
|
81
|
-
args.push(`+${fileInfo.line}`, filePath);
|
|
82
|
-
break;
|
|
83
|
-
case 'nano':
|
|
84
|
-
args.push(`+${fileInfo.line}`, filePath);
|
|
85
|
-
break;
|
|
86
|
-
default:
|
|
87
|
-
args.push(filePath);
|
|
88
|
-
}
|
|
89
|
-
} else {
|
|
90
|
-
args.push(filePath);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return args;
|
|
95
|
-
}
|