@tomasko/mb 0.0.0-stage → 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/README.md +52 -2
- package/bin/mb.js +27 -0
- package/install.js +117 -0
- package/package.json +40 -4
package/README.md
CHANGED
|
@@ -1,3 +1,53 @@
|
|
|
1
|
-
#
|
|
1
|
+
# mb (npm)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
npm wrapper for [`mb`](../../README.md) — a MoonBit-native, uv-style toolchain
|
|
4
|
+
and package manager.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
pnpm install -g @tomasko/mb
|
|
8
|
+
mb --help
|
|
9
|
+
mb moon install 0.10.14
|
|
10
|
+
mb tool install bobzhang/zip
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## How it works
|
|
14
|
+
|
|
15
|
+
The package itself contains only a small launcher. On install,
|
|
16
|
+
`install.js` downloads the prebuilt `mb` binary for the current platform from
|
|
17
|
+
GitHub Releases and writes it to `bin/mb`. The published `bin` entry
|
|
18
|
+
(`bin/mb.js`) then spawns it, forwarding arguments and standard IO.
|
|
19
|
+
|
|
20
|
+
Supported targets:
|
|
21
|
+
|
|
22
|
+
| Node `platform-arch` | Release asset |
|
|
23
|
+
| -------------------- | ------------------- |
|
|
24
|
+
| `linux-x64` | `mb-linux-x86_64` |
|
|
25
|
+
| `linux-arm64` | `mb-linux-aarch64` |
|
|
26
|
+
| `darwin-arm64` | `mb-darwin-aarch64` |
|
|
27
|
+
|
|
28
|
+
Intel macOS (`darwin-x64`) is not supported: the MoonBit toolchain no longer
|
|
29
|
+
ships a `darwin-x86_64` target, so no such build can be produced.
|
|
30
|
+
|
|
31
|
+
Assets are produced by `.github/workflows/release.yml` when a `v*` tag is
|
|
32
|
+
pushed.
|
|
33
|
+
|
|
34
|
+
## Overrides
|
|
35
|
+
|
|
36
|
+
| Variable | Purpose |
|
|
37
|
+
| -------------------- | ------------------------------------------------ |
|
|
38
|
+
| `MB_REPO` | `owner/repo` to download from |
|
|
39
|
+
| `MB_VERSION` | release version to download |
|
|
40
|
+
| `MB_DOWNLOAD_BASE` | full base URL (mirror), e.g. `https://host/assets` |
|
|
41
|
+
| `MB_FORCE_DOWNLOAD` | re-download even if the binary is present |
|
|
42
|
+
| `MB_SKIP_DOWNLOAD` | skip the download entirely |
|
|
43
|
+
|
|
44
|
+
## Publishing
|
|
45
|
+
|
|
46
|
+
From this directory:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm publish --access public
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Change `name`, `repository` and `homepage` in `package.json` first if you
|
|
53
|
+
publish under a different scope or repository.
|
package/bin/mb.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Thin launcher for the downloaded native `mb` binary.
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { spawnSync } = require("child_process");
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
|
|
9
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
10
|
+
const binary = path.join(__dirname, "mb" + ext);
|
|
11
|
+
|
|
12
|
+
if (!fs.existsSync(binary)) {
|
|
13
|
+
console.error(
|
|
14
|
+
`mb: native binary not found at ${binary}\n` +
|
|
15
|
+
"mb: reinstall it with `npm rebuild mb` (or `npm install -g mb --force`)."
|
|
16
|
+
);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const result = spawnSync(binary, process.argv.slice(2), { stdio: "inherit" });
|
|
21
|
+
|
|
22
|
+
if (result.error) {
|
|
23
|
+
console.error(`mb: failed to launch ${binary}: ${result.error.message}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
process.exit(typeof result.status === "number" ? result.status : 1);
|
package/install.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Downloads the prebuilt `mb` binary for the current platform from GitHub
|
|
3
|
+
// Releases and drops it next to this package's launcher (`bin/mb.js`).
|
|
4
|
+
//
|
|
5
|
+
// Overridable for forks / private mirrors:
|
|
6
|
+
// MB_REPO owner/repo (default: parsed from package.json)
|
|
7
|
+
// MB_VERSION release version (default: package.json version)
|
|
8
|
+
// MB_DOWNLOAD_BASE full base URL (overrides MB_REPO/MB_VERSION)
|
|
9
|
+
// MB_SKIP_DOWNLOAD set to skip fetching
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
const fs = require("fs");
|
|
13
|
+
const path = require("path");
|
|
14
|
+
const https = require("https");
|
|
15
|
+
const http = require("http");
|
|
16
|
+
|
|
17
|
+
const pkg = require("./package.json");
|
|
18
|
+
|
|
19
|
+
const TARGETS = {
|
|
20
|
+
"linux-x64": "linux-x86_64",
|
|
21
|
+
"linux-arm64": "linux-aarch64",
|
|
22
|
+
"darwin-arm64": "darwin-aarch64",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function repoSlug(repo) {
|
|
26
|
+
if (!repo) return null;
|
|
27
|
+
const url = typeof repo === "string" ? repo : repo.url || "";
|
|
28
|
+
const m = url.match(/github\.com[/:]([^/]+)\/([^/.]+)/);
|
|
29
|
+
return m ? `${m[1]}/${m[2]}` : null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function target() {
|
|
33
|
+
return TARGETS[`${process.platform}-${process.arch}`];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function downloadUrl(targetName) {
|
|
37
|
+
if (process.env.MB_DOWNLOAD_BASE) {
|
|
38
|
+
return `${process.env.MB_DOWNLOAD_BASE.replace(/\/$/, "")}/mb-${targetName}`;
|
|
39
|
+
}
|
|
40
|
+
const repo = process.env.MB_REPO || repoSlug(pkg.repository) || "tomasky/mb";
|
|
41
|
+
const version = process.env.MB_VERSION || pkg.version;
|
|
42
|
+
return `https://github.com/${repo}/releases/download/v${version}/mb-${targetName}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function fetch(url, redirects) {
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
if (redirects > 10) return reject(new Error("too many redirects"));
|
|
48
|
+
const client = url.startsWith("http:") ? http : https;
|
|
49
|
+
const req = client.get(
|
|
50
|
+
url,
|
|
51
|
+
{ headers: { "user-agent": `mb-npm/${pkg.version}` } },
|
|
52
|
+
(res) => {
|
|
53
|
+
const { statusCode, headers } = res;
|
|
54
|
+
if (statusCode >= 300 && statusCode < 400 && headers.location) {
|
|
55
|
+
res.resume();
|
|
56
|
+
const next = new URL(headers.location, url).toString();
|
|
57
|
+
resolve(fetch(next, (redirects || 0) + 1));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (statusCode !== 200) {
|
|
61
|
+
res.resume();
|
|
62
|
+
reject(new Error(`GET ${url} -> HTTP ${statusCode}`));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
resolve(res);
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
req.on("error", reject);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function main() {
|
|
73
|
+
if (process.env.MB_SKIP_DOWNLOAD) {
|
|
74
|
+
console.log("mb: MB_SKIP_DOWNLOAD set, skipping binary download");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const targetName = target();
|
|
79
|
+
if (!targetName) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`unsupported platform ${process.platform}-${process.arch}; mb ` +
|
|
82
|
+
`supports linux-x64, linux-arm64 and darwin-arm64 (the MoonBit ` +
|
|
83
|
+
`toolchain no longer ships a darwin-x64 target)`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
88
|
+
const dest = path.join(__dirname, "bin", "mb" + ext);
|
|
89
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
90
|
+
|
|
91
|
+
if (fs.existsSync(dest) && !process.env.MB_FORCE_DOWNLOAD) {
|
|
92
|
+
console.log(`mb: ${dest} already present, skipping download`);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const url = downloadUrl(targetName);
|
|
97
|
+
console.log(`mb: downloading ${url}`);
|
|
98
|
+
const res = await fetch(url, 0);
|
|
99
|
+
await new Promise((resolve, reject) => {
|
|
100
|
+
const out = fs.createWriteStream(dest);
|
|
101
|
+
res.pipe(out);
|
|
102
|
+
out.on("finish", () => out.close(resolve));
|
|
103
|
+
out.on("error", reject);
|
|
104
|
+
res.on("error", reject);
|
|
105
|
+
});
|
|
106
|
+
fs.chmodSync(dest, 0o755);
|
|
107
|
+
console.log(`mb: installed ${dest}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
main().catch((err) => {
|
|
111
|
+
console.error(`mb: failed to install the native binary: ${err.message}`);
|
|
112
|
+
console.error(
|
|
113
|
+
"mb: set MB_DOWNLOAD_BASE (or MB_REPO/MB_VERSION) to point at a mirror, " +
|
|
114
|
+
"or set MB_SKIP_DOWNLOAD=1 to skip."
|
|
115
|
+
);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomasko/mb",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "A MoonBit-native, uv-style toolchain and package manager: manage MoonBit toolchains and install tools from mooncakes.io.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"bin": {
|
|
7
|
+
"mb": "bin/mb.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"postinstall": "node install.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"bin/mb.js",
|
|
14
|
+
"install.js",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=20"
|
|
19
|
+
},
|
|
20
|
+
"os": [
|
|
21
|
+
"darwin",
|
|
22
|
+
"linux"
|
|
23
|
+
],
|
|
24
|
+
"cpu": [
|
|
25
|
+
"x64",
|
|
26
|
+
"arm64"
|
|
27
|
+
],
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/tomasky/mb.git"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/tomasky/mb",
|
|
33
|
+
"bugs": "https://github.com/tomasky/mb/issues",
|
|
34
|
+
"keywords": [
|
|
35
|
+
"moonbit",
|
|
36
|
+
"mooncakes",
|
|
37
|
+
"toolchain",
|
|
38
|
+
"package-manager",
|
|
39
|
+
"uv"
|
|
40
|
+
],
|
|
41
|
+
"preferGlobal": true
|
|
42
|
+
}
|