bumblebee-cli 0.1.0 → 0.1.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/bin/bb.mjs +42 -12
- package/package.json +1 -1
- package/scripts/postinstall.mjs +35 -10
package/bin/bb.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { execFileSync, execSync } from "node:child_process";
|
|
4
|
-
import { existsSync } from "node:fs";
|
|
5
|
-
import { dirname, join } from "node:path";
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { dirname, join, resolve } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
8
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -13,20 +13,45 @@ const args = process.argv.slice(2);
|
|
|
13
13
|
* Thin Node.js wrapper for the Bumblebee Python CLI.
|
|
14
14
|
*
|
|
15
15
|
* Resolution order:
|
|
16
|
-
* 1. `bb` already on PATH (user installed via pip)
|
|
16
|
+
* 1. `bb` already on PATH (user installed via pip — not our own npm wrapper)
|
|
17
17
|
* 2. Local .venv created by postinstall
|
|
18
18
|
* 3. `python -m bb_cli` (fallback)
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
function getNpmGlobalPrefix() {
|
|
22
|
+
try {
|
|
23
|
+
return execSync("npm prefix -g", { encoding: "utf8", stdio: "pipe" }).trim();
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function isOurOwnWrapper(bbPath) {
|
|
30
|
+
// Check if the found bb is inside our npm package or the npm global bin
|
|
31
|
+
const normalized = resolve(bbPath).toLowerCase();
|
|
32
|
+
if (normalized.includes("node_modules") && normalized.includes("bumblebee-cli")) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
// On Windows/Linux, npm global installs create shims in the npm prefix dir
|
|
36
|
+
const npmPrefix = getNpmGlobalPrefix();
|
|
37
|
+
if (npmPrefix && normalized.startsWith(resolve(npmPrefix).toLowerCase())) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
21
43
|
// 1. Check if `bb` is already available on PATH (pip install)
|
|
22
44
|
function trySystemBb() {
|
|
23
45
|
try {
|
|
24
46
|
const which = process.platform === "win32" ? "where" : "which";
|
|
25
47
|
const result = execSync(`${which} bb`, { stdio: "pipe", encoding: "utf8" });
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
48
|
+
// On Windows, `where` may return multiple lines; check each
|
|
49
|
+
const paths = result.trim().split(/\r?\n/);
|
|
50
|
+
for (const bbPath of paths) {
|
|
51
|
+
const p = bbPath.trim();
|
|
52
|
+
if (p && !isOurOwnWrapper(p)) {
|
|
53
|
+
return p;
|
|
54
|
+
}
|
|
30
55
|
}
|
|
31
56
|
} catch {
|
|
32
57
|
// not found
|
|
@@ -48,10 +73,11 @@ function tryLocalVenv() {
|
|
|
48
73
|
|
|
49
74
|
// 3. Fallback to python -m bb_cli
|
|
50
75
|
function tryPythonModule() {
|
|
51
|
-
const pythonCmds =
|
|
76
|
+
const pythonCmds =
|
|
77
|
+
process.platform === "win32" ? ["python", "python3"] : ["python3", "python"];
|
|
52
78
|
for (const py of pythonCmds) {
|
|
53
79
|
try {
|
|
54
|
-
execSync(`${py}
|
|
80
|
+
execSync(`${py} -c "import bb_cli"`, { stdio: "pipe" });
|
|
55
81
|
return { python: py, module: true };
|
|
56
82
|
} catch {
|
|
57
83
|
// try next
|
|
@@ -95,8 +121,12 @@ if (pyFallback) {
|
|
|
95
121
|
}
|
|
96
122
|
|
|
97
123
|
console.error(
|
|
98
|
-
"Error: Could not find
|
|
99
|
-
"
|
|
100
|
-
"
|
|
124
|
+
"Error: Could not find the Bumblebee Python CLI.\n" +
|
|
125
|
+
"\n" +
|
|
126
|
+
"The npm package needs the Python CLI installed. Fix with ONE of:\n" +
|
|
127
|
+
" 1. pip install bumblebee-cli (install globally)\n" +
|
|
128
|
+
" 2. npm rebuild bumblebee-cli (retry postinstall setup)\n" +
|
|
129
|
+
"\n" +
|
|
130
|
+
"Requires Python 3.12+ — https://python.org"
|
|
101
131
|
);
|
|
102
132
|
process.exit(1);
|
package/package.json
CHANGED
package/scripts/postinstall.mjs
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* Postinstall script for bumblebee-cli
|
|
5
5
|
*
|
|
6
6
|
* - Checks for Python 3.12+
|
|
7
|
-
* - Skips if `bb` is already on PATH
|
|
7
|
+
* - Skips if a real (pip-installed) `bb` is already on PATH
|
|
8
8
|
* - Creates a local .venv and installs the Python CLI
|
|
9
9
|
* - NEVER fails npm install — warns instead
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { execSync } from "node:child_process";
|
|
13
13
|
import { existsSync } from "node:fs";
|
|
14
|
-
import { dirname, join } from "node:path";
|
|
14
|
+
import { dirname, join, resolve } from "node:path";
|
|
15
15
|
import { fileURLToPath } from "node:url";
|
|
16
16
|
|
|
17
17
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -26,20 +26,45 @@ function warn(msg) {
|
|
|
26
26
|
console.warn(`[bumblebee-cli] WARNING: ${msg}`);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
// Check if bb is already available
|
|
30
|
-
function
|
|
29
|
+
// Check if a real (non-npm-wrapper) bb is already available
|
|
30
|
+
function isPipBbInstalled() {
|
|
31
31
|
try {
|
|
32
|
+
// Try running bb --help and check if it's the Python CLI (not our wrapper)
|
|
32
33
|
const which = process.platform === "win32" ? "where" : "which";
|
|
33
|
-
execSync(`${which} bb`, { stdio: "pipe" });
|
|
34
|
-
|
|
34
|
+
const result = execSync(`${which} bb`, { encoding: "utf8", stdio: "pipe" });
|
|
35
|
+
const paths = result.trim().split(/\r?\n/);
|
|
36
|
+
|
|
37
|
+
// Get npm global prefix to filter out our own wrapper
|
|
38
|
+
let npmPrefix = null;
|
|
39
|
+
try {
|
|
40
|
+
npmPrefix = execSync("npm prefix -g", { encoding: "utf8", stdio: "pipe" }).trim();
|
|
41
|
+
} catch {}
|
|
42
|
+
|
|
43
|
+
for (const bbPath of paths) {
|
|
44
|
+
const p = bbPath.trim();
|
|
45
|
+
if (!p) continue;
|
|
46
|
+
const normalized = resolve(p).toLowerCase();
|
|
47
|
+
// Skip if it's inside npm global prefix (that's our own wrapper)
|
|
48
|
+
if (npmPrefix && normalized.startsWith(resolve(npmPrefix).toLowerCase())) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
// Skip if it's inside node_modules
|
|
52
|
+
if (normalized.includes("node_modules") && normalized.includes("bumblebee-cli")) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
// Found a real bb (pip-installed)
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
35
58
|
} catch {
|
|
36
|
-
|
|
59
|
+
// not found
|
|
37
60
|
}
|
|
61
|
+
return false;
|
|
38
62
|
}
|
|
39
63
|
|
|
40
64
|
// Find python and check version
|
|
41
65
|
function findPython() {
|
|
42
|
-
const candidates =
|
|
66
|
+
const candidates =
|
|
67
|
+
process.platform === "win32" ? ["python", "python3"] : ["python3", "python"];
|
|
43
68
|
for (const cmd of candidates) {
|
|
44
69
|
try {
|
|
45
70
|
const version = execSync(`${cmd} --version`, {
|
|
@@ -64,8 +89,8 @@ function findPython() {
|
|
|
64
89
|
|
|
65
90
|
function main() {
|
|
66
91
|
// Skip if bb already installed via pip
|
|
67
|
-
if (
|
|
68
|
-
log("'bb' command found on PATH — skipping Python setup.");
|
|
92
|
+
if (isPipBbInstalled()) {
|
|
93
|
+
log("'bb' command found on PATH (pip) — skipping Python setup.");
|
|
69
94
|
return;
|
|
70
95
|
}
|
|
71
96
|
|