turnout-cli 0.2.2 → 0.3.0
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 +3 -1
- package/download.js +88 -0
- package/install.js +4 -79
- package/package.json +5 -4
- package/run.js +14 -8
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<p align="center"><img src="https://raw.githubusercontent.com/lacodda/turnout/main/assets/banner.svg" alt="turnout - a developer's switchyard" width="720"></p>
|
|
2
|
+
|
|
1
3
|
# turnout-cli
|
|
2
4
|
|
|
3
5
|
npm distribution of [turnout](https://github.com/lacodda/turnout) - a developer's switchyard: point local apps at any backend stand, keep servers and secrets at hand, build and deploy from any directory.
|
|
@@ -7,6 +9,6 @@ npm i -g turnout-cli
|
|
|
7
9
|
turnout setup
|
|
8
10
|
```
|
|
9
11
|
|
|
10
|
-
The package downloads the prebuilt binary for your platform (Windows x86_64, Linux x86_64, macOS arm64) from GitHub Releases on install. On other platforms use `cargo install turnout`.
|
|
12
|
+
The package downloads the prebuilt binary for your platform (Windows x86_64, Linux x86_64, macOS arm64) from GitHub Releases - on install, or on first run when npm skips install scripts. On other platforms use `cargo install turnout`.
|
|
11
13
|
|
|
12
14
|
Documentation: https://lacodda.github.io/turnout/
|
package/download.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Downloads the turnout binary matching this package version from GitHub Releases.
|
|
2
|
+
// Shared by install.js (postinstall, where lifecycle scripts are allowed) and
|
|
3
|
+
// run.js (first-run fallback: npm v12 skips install scripts by default).
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const https = require("https");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const { spawnSync } = require("child_process");
|
|
8
|
+
|
|
9
|
+
const pkg = require("./package.json");
|
|
10
|
+
const REPO = "lacodda/turnout";
|
|
11
|
+
// The wrapper can be patched independently of the Rust binary: an explicit
|
|
12
|
+
// turnout.binary field pins the release tag, otherwise it follows the version.
|
|
13
|
+
const TAG = (pkg.turnout && pkg.turnout.binary) || `v${pkg.version}`;
|
|
14
|
+
|
|
15
|
+
const TARGETS = {
|
|
16
|
+
"win32-x64": ["x86_64-pc-windows-msvc", "zip"],
|
|
17
|
+
"linux-x64": ["x86_64-unknown-linux-gnu", "tar.gz"],
|
|
18
|
+
"darwin-arm64": ["aarch64-apple-darwin", "tar.gz"],
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const exe = process.platform === "win32" ? "turnout.exe" : "turnout";
|
|
22
|
+
const exePath = path.join(__dirname, exe);
|
|
23
|
+
|
|
24
|
+
function download(url, file, redirects, done) {
|
|
25
|
+
if (redirects > 5) return done(new Error("too many redirects"));
|
|
26
|
+
https
|
|
27
|
+
.get(url, { headers: { "user-agent": "turnout-cli" } }, (res) => {
|
|
28
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
29
|
+
res.resume();
|
|
30
|
+
return download(res.headers.location, file, redirects + 1, done);
|
|
31
|
+
}
|
|
32
|
+
if (res.statusCode !== 200) {
|
|
33
|
+
res.resume();
|
|
34
|
+
return done(new Error(`HTTP ${res.statusCode} for ${url}`));
|
|
35
|
+
}
|
|
36
|
+
const out = fs.createWriteStream(file);
|
|
37
|
+
res.pipe(out);
|
|
38
|
+
out.on("finish", () => out.close(done));
|
|
39
|
+
out.on("error", done);
|
|
40
|
+
})
|
|
41
|
+
.on("error", done);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function install(done) {
|
|
45
|
+
const key = `${process.platform}-${process.arch}`;
|
|
46
|
+
const entry = TARGETS[key];
|
|
47
|
+
if (!entry) {
|
|
48
|
+
console.error(`turnout-cli: no prebuilt binary for ${key}; install with: cargo install turnout`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const [target, ext] = entry;
|
|
52
|
+
const name = `turnout-${TAG}-${target}`;
|
|
53
|
+
const url = `https://github.com/${REPO}/releases/download/${TAG}/${name}.${ext}`;
|
|
54
|
+
const archive = path.join(__dirname, `archive.${ext}`);
|
|
55
|
+
|
|
56
|
+
console.log(`turnout-cli: downloading ${url}`);
|
|
57
|
+
download(url, archive, 0, (err) => {
|
|
58
|
+
if (err) {
|
|
59
|
+
console.error(`turnout-cli: download failed: ${err.message}`);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
// Extraction must not depend on which tar happens to be first in PATH
|
|
63
|
+
// (Git Bash ships a GNU tar that cannot read zip): zip goes through
|
|
64
|
+
// PowerShell's Expand-Archive, tar.gz through tar on Unix systems.
|
|
65
|
+
const result =
|
|
66
|
+
ext === "zip"
|
|
67
|
+
? spawnSync(
|
|
68
|
+
"powershell.exe",
|
|
69
|
+
["-NoProfile", "-NonInteractive", "-Command", "Expand-Archive -LiteralPath 'archive.zip' -DestinationPath . -Force"],
|
|
70
|
+
{ cwd: __dirname, stdio: "inherit" },
|
|
71
|
+
)
|
|
72
|
+
: spawnSync("tar", ["-xzf", `archive.${ext}`], { cwd: __dirname, stdio: "inherit" });
|
|
73
|
+
if (result.status !== 0) {
|
|
74
|
+
console.error("turnout-cli: cannot extract the archive");
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
fs.renameSync(path.join(__dirname, name, exe), exePath);
|
|
78
|
+
fs.rmSync(path.join(__dirname, name), { recursive: true, force: true });
|
|
79
|
+
fs.rmSync(archive, { force: true });
|
|
80
|
+
if (process.platform !== "win32") {
|
|
81
|
+
fs.chmodSync(exePath, 0o755);
|
|
82
|
+
}
|
|
83
|
+
console.log(`turnout-cli: installed turnout ${TAG}`);
|
|
84
|
+
done();
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = { install, exePath };
|
package/install.js
CHANGED
|
@@ -1,79 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const { spawnSync } = require("child_process");
|
|
6
|
-
|
|
7
|
-
const pkg = require("./package.json");
|
|
8
|
-
const REPO = "lacodda/turnout";
|
|
9
|
-
// The wrapper can be patched independently of the Rust binary: an explicit
|
|
10
|
-
// turnout.binary field pins the release tag, otherwise it follows the version.
|
|
11
|
-
const TAG = (pkg.turnout && pkg.turnout.binary) || `v${pkg.version}`;
|
|
12
|
-
|
|
13
|
-
const TARGETS = {
|
|
14
|
-
"win32-x64": ["x86_64-pc-windows-msvc", "zip"],
|
|
15
|
-
"linux-x64": ["x86_64-unknown-linux-gnu", "tar.gz"],
|
|
16
|
-
"darwin-arm64": ["aarch64-apple-darwin", "tar.gz"],
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const key = `${process.platform}-${process.arch}`;
|
|
20
|
-
const entry = TARGETS[key];
|
|
21
|
-
if (!entry) {
|
|
22
|
-
console.error(`turnout-cli: no prebuilt binary for ${key}; install with: cargo install turnout`);
|
|
23
|
-
process.exit(1);
|
|
24
|
-
}
|
|
25
|
-
const [target, ext] = entry;
|
|
26
|
-
const name = `turnout-${TAG}-${target}`;
|
|
27
|
-
const url = `https://github.com/${REPO}/releases/download/${TAG}/${name}.${ext}`;
|
|
28
|
-
const exe = process.platform === "win32" ? "turnout.exe" : "turnout";
|
|
29
|
-
const archive = path.join(__dirname, `archive.${ext}`);
|
|
30
|
-
|
|
31
|
-
function download(url, file, redirects, done) {
|
|
32
|
-
if (redirects > 5) return done(new Error("too many redirects"));
|
|
33
|
-
https
|
|
34
|
-
.get(url, { headers: { "user-agent": "turnout-cli" } }, (res) => {
|
|
35
|
-
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
36
|
-
res.resume();
|
|
37
|
-
return download(res.headers.location, file, redirects + 1, done);
|
|
38
|
-
}
|
|
39
|
-
if (res.statusCode !== 200) {
|
|
40
|
-
res.resume();
|
|
41
|
-
return done(new Error(`HTTP ${res.statusCode} for ${url}`));
|
|
42
|
-
}
|
|
43
|
-
const out = fs.createWriteStream(file);
|
|
44
|
-
res.pipe(out);
|
|
45
|
-
out.on("finish", () => out.close(done));
|
|
46
|
-
out.on("error", done);
|
|
47
|
-
})
|
|
48
|
-
.on("error", done);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
console.log(`turnout-cli: downloading ${url}`);
|
|
52
|
-
download(url, archive, 0, (err) => {
|
|
53
|
-
if (err) {
|
|
54
|
-
console.error(`turnout-cli: download failed: ${err.message}`);
|
|
55
|
-
process.exit(1);
|
|
56
|
-
}
|
|
57
|
-
// Extraction must not depend on which tar happens to be first in PATH
|
|
58
|
-
// (Git Bash ships a GNU tar that cannot read zip): zip goes through
|
|
59
|
-
// PowerShell's Expand-Archive, tar.gz through tar on Unix systems.
|
|
60
|
-
const result =
|
|
61
|
-
ext === "zip"
|
|
62
|
-
? spawnSync(
|
|
63
|
-
"powershell.exe",
|
|
64
|
-
["-NoProfile", "-NonInteractive", "-Command", "Expand-Archive -LiteralPath 'archive.zip' -DestinationPath . -Force"],
|
|
65
|
-
{ cwd: __dirname, stdio: "inherit" },
|
|
66
|
-
)
|
|
67
|
-
: spawnSync("tar", ["-xzf", `archive.${ext}`], { cwd: __dirname, stdio: "inherit" });
|
|
68
|
-
if (result.status !== 0) {
|
|
69
|
-
console.error("turnout-cli: cannot extract the archive");
|
|
70
|
-
process.exit(1);
|
|
71
|
-
}
|
|
72
|
-
fs.renameSync(path.join(__dirname, name, exe), path.join(__dirname, exe));
|
|
73
|
-
fs.rmSync(path.join(__dirname, name), { recursive: true, force: true });
|
|
74
|
-
fs.rmSync(archive, { force: true });
|
|
75
|
-
if (process.platform !== "win32") {
|
|
76
|
-
fs.chmodSync(path.join(__dirname, exe), 0o755);
|
|
77
|
-
}
|
|
78
|
-
console.log(`turnout-cli: installed turnout ${TAG}`);
|
|
79
|
-
});
|
|
1
|
+
// Postinstall entry: pre-downloads the binary where lifecycle scripts are
|
|
2
|
+
// allowed. On npm v12+ this script is skipped by default and run.js downloads
|
|
3
|
+
// the binary on first launch instead.
|
|
4
|
+
require("./download").install(() => {});
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "turnout-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"turnout": {
|
|
5
|
-
"binary": "v0.
|
|
5
|
+
"binary": "v0.3.0"
|
|
6
6
|
},
|
|
7
7
|
"description": "A developer's switchyard: point local apps at any backend stand, keep servers and secrets at hand, build and deploy from any directory",
|
|
8
8
|
"license": "MIT",
|
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
},
|
|
15
15
|
"keywords": ["cli", "proxy", "gateway", "deploy", "dev-environment", "stands"],
|
|
16
16
|
"bin": {
|
|
17
|
-
"turnout": "run.js"
|
|
17
|
+
"turnout": "run.js",
|
|
18
|
+
"tn": "run.js"
|
|
18
19
|
},
|
|
19
|
-
"files": ["install.js", "run.js"],
|
|
20
|
+
"files": ["download.js", "install.js", "run.js"],
|
|
20
21
|
"scripts": {
|
|
21
22
|
"postinstall": "node install.js"
|
|
22
23
|
},
|
package/run.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Thin launcher: forwards everything to the
|
|
3
|
-
|
|
2
|
+
// Thin launcher: forwards everything to the turnout binary, downloading it on
|
|
3
|
+
// first run when the postinstall script was skipped (npm v12 default).
|
|
4
|
+
const fs = require("fs");
|
|
4
5
|
const { spawnSync } = require("child_process");
|
|
6
|
+
const { install, exePath } = require("./download");
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
function exec() {
|
|
9
|
+
const result = spawnSync(exePath, process.argv.slice(2), { stdio: "inherit" });
|
|
10
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (fs.existsSync(exePath)) {
|
|
14
|
+
exec();
|
|
15
|
+
} else {
|
|
16
|
+
console.error("turnout-cli: binary not present yet - downloading it now");
|
|
17
|
+
install(exec);
|
|
10
18
|
}
|
|
11
|
-
const result = spawnSync(exe, process.argv.slice(2), { stdio: "inherit" });
|
|
12
|
-
process.exit(result.status === null ? 1 : result.status);
|