@akiojin/gwt 9.5.2 → 9.6.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/bin/gwt.cjs +26 -57
- package/package.json +2 -2
- package/scripts/postinstall.cjs +57 -0
- package/scripts/release-assets.cjs +189 -0
- package/scripts/test_release_assets.cjs +97 -0
- package/wix/main.wxs +31 -0
- package/scripts/postinstall.js +0 -115
package/bin/gwt.cjs
CHANGED
|
@@ -8,79 +8,40 @@
|
|
|
8
8
|
const { spawn } = require("child_process");
|
|
9
9
|
const path = require("path");
|
|
10
10
|
const fs = require("fs");
|
|
11
|
-
|
|
12
|
-
const
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
binaryNameForPlatform,
|
|
14
|
+
installReleaseBinary,
|
|
15
|
+
releaseAssetUrl,
|
|
16
|
+
} = require("../scripts/release-assets.cjs");
|
|
13
17
|
|
|
14
18
|
const REPO = "akiojin/gwt";
|
|
15
19
|
const BIN_DIR = __dirname;
|
|
16
|
-
const BIN_NAME = process.platform
|
|
20
|
+
const BIN_NAME = binaryNameForPlatform(process.platform);
|
|
17
21
|
const BIN_PATH = path.join(BIN_DIR, BIN_NAME);
|
|
18
22
|
|
|
19
|
-
function releaseAssetName() {
|
|
20
|
-
const platform = os.platform();
|
|
21
|
-
const arch = os.arch();
|
|
22
|
-
|
|
23
|
-
if (platform === "darwin" && arch === "arm64") return "gwt-macos-aarch64";
|
|
24
|
-
if (platform === "darwin" && arch === "x64") return "gwt-macos-x86_64";
|
|
25
|
-
if (platform === "linux" && arch === "x64") return "gwt-linux-x86_64";
|
|
26
|
-
if (platform === "linux" && arch === "arm64") return "gwt-linux-aarch64";
|
|
27
|
-
if (platform === "win32" && arch === "x64") return "gwt-windows-x86_64.exe";
|
|
28
|
-
|
|
29
|
-
console.error(`Unsupported platform: ${platform}-${arch}`);
|
|
30
|
-
process.exit(1);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
23
|
function readVersion() {
|
|
34
24
|
const pkg = path.join(__dirname, "..", "package.json");
|
|
35
25
|
return JSON.parse(fs.readFileSync(pkg, "utf8")).version;
|
|
36
26
|
}
|
|
37
27
|
|
|
38
|
-
function download(url, dest) {
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
const file = fs.createWriteStream(dest);
|
|
41
|
-
const request = (u) => {
|
|
42
|
-
https
|
|
43
|
-
.get(u, { headers: { "User-Agent": "gwt-postinstall" } }, (res) => {
|
|
44
|
-
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
45
|
-
request(res.headers.location);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
if (res.statusCode !== 200) {
|
|
49
|
-
file.close();
|
|
50
|
-
fs.unlink(dest, () => {});
|
|
51
|
-
reject(new Error(`HTTP ${res.statusCode} for ${u}`));
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
res.pipe(file);
|
|
55
|
-
file.on("finish", () => file.close(resolve));
|
|
56
|
-
})
|
|
57
|
-
.on("error", (err) => {
|
|
58
|
-
file.close();
|
|
59
|
-
fs.unlink(dest, () => {});
|
|
60
|
-
reject(err);
|
|
61
|
-
});
|
|
62
|
-
};
|
|
63
|
-
request(url);
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
28
|
async function ensureBinary() {
|
|
68
29
|
if (fs.existsSync(BIN_PATH)) return;
|
|
69
30
|
|
|
70
31
|
const version = readVersion();
|
|
71
|
-
const
|
|
72
|
-
const tag = `v${version}`;
|
|
73
|
-
const url = `https://github.com/${REPO}/releases/download/${tag}/${asset}`;
|
|
32
|
+
const { url } = releaseAssetUrl(REPO, version, process.platform, process.arch);
|
|
74
33
|
|
|
75
|
-
console.log(`Downloading gwt binary for ${
|
|
34
|
+
console.log(`Downloading gwt binary for ${process.platform}-${process.arch}...`);
|
|
76
35
|
console.log(`Downloading from: ${url}`);
|
|
77
36
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
37
|
+
await installReleaseBinary({
|
|
38
|
+
repo: REPO,
|
|
39
|
+
version,
|
|
40
|
+
binDir: BIN_DIR,
|
|
41
|
+
binaryName: BIN_NAME,
|
|
42
|
+
platform: process.platform,
|
|
43
|
+
arch: process.arch,
|
|
44
|
+
});
|
|
84
45
|
|
|
85
46
|
console.log("gwt binary installed successfully!");
|
|
86
47
|
}
|
|
@@ -113,4 +74,12 @@ async function main() {
|
|
|
113
74
|
});
|
|
114
75
|
}
|
|
115
76
|
|
|
116
|
-
main
|
|
77
|
+
if (require.main === module) {
|
|
78
|
+
main();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = {
|
|
82
|
+
ensureBinary,
|
|
83
|
+
main,
|
|
84
|
+
readVersion,
|
|
85
|
+
};
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akiojin/gwt",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.6.0",
|
|
4
4
|
"description": "Desktop GUI for Git worktree management and coding agent launch",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"gwt": "bin/gwt.cjs"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"postinstall": "node scripts/postinstall.
|
|
10
|
+
"postinstall": "node scripts/postinstall.cjs",
|
|
11
11
|
"dev": "cargo run -p gwt",
|
|
12
12
|
"build": "cargo build --release -p gwt",
|
|
13
13
|
"test": "cargo test -p gwt-core -p gwt --all-features",
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
binaryNameForPlatform,
|
|
9
|
+
installReleaseBinary,
|
|
10
|
+
releaseAssetUrl,
|
|
11
|
+
} = require("./release-assets.cjs");
|
|
12
|
+
|
|
13
|
+
const REPO = "akiojin/gwt";
|
|
14
|
+
const BIN_DIR = path.join(__dirname, "..", "bin");
|
|
15
|
+
const BINARY_NAME = binaryNameForPlatform();
|
|
16
|
+
|
|
17
|
+
function readVersion() {
|
|
18
|
+
const pkg = path.join(__dirname, "..", "package.json");
|
|
19
|
+
const data = JSON.parse(fs.readFileSync(pkg, "utf8"));
|
|
20
|
+
return data.version;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function main() {
|
|
24
|
+
if (process.env.CI) {
|
|
25
|
+
console.log("gwt: skipping binary download in CI");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const version = readVersion();
|
|
30
|
+
const { url } = releaseAssetUrl(REPO, version);
|
|
31
|
+
|
|
32
|
+
console.log(`Downloading gwt binary for ${process.platform}-${process.arch}...`);
|
|
33
|
+
console.log(`Downloading from: ${url}`);
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
await installReleaseBinary({
|
|
37
|
+
repo: REPO,
|
|
38
|
+
version,
|
|
39
|
+
binDir: BIN_DIR,
|
|
40
|
+
binaryName: BINARY_NAME,
|
|
41
|
+
});
|
|
42
|
+
console.log("gwt binary installed successfully!");
|
|
43
|
+
} catch (err) {
|
|
44
|
+
console.error(`gwt: failed to download binary - ${err.message}`);
|
|
45
|
+
console.error("gwt: you can build from source with: cargo build --release -p gwt");
|
|
46
|
+
process.exitCode = 0;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (require.main === module) {
|
|
51
|
+
main();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = {
|
|
55
|
+
main,
|
|
56
|
+
readVersion,
|
|
57
|
+
};
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const https = require("https");
|
|
3
|
+
const os = require("os");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const { execFileSync } = require("child_process");
|
|
6
|
+
|
|
7
|
+
function binaryNameForPlatform(platform = os.platform()) {
|
|
8
|
+
return platform === "win32" ? "gwt.exe" : "gwt";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function releaseAssetName(platform = os.platform(), arch = os.arch()) {
|
|
12
|
+
if (platform === "darwin" && arch === "arm64") {
|
|
13
|
+
return "gwt-macos-arm64.tar.gz";
|
|
14
|
+
}
|
|
15
|
+
if (platform === "darwin" && arch === "x64") {
|
|
16
|
+
return "gwt-macos-x86_64.tar.gz";
|
|
17
|
+
}
|
|
18
|
+
if (platform === "linux" && arch === "x64") {
|
|
19
|
+
return "gwt-linux-x86_64.tar.gz";
|
|
20
|
+
}
|
|
21
|
+
if (platform === "linux" && arch === "arm64") {
|
|
22
|
+
return "gwt-linux-aarch64.tar.gz";
|
|
23
|
+
}
|
|
24
|
+
if (platform === "win32" && arch === "x64") {
|
|
25
|
+
return "gwt-windows-x86_64.zip";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
throw new Error(`Unsupported platform: ${platform}-${arch}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function releaseAssetUrl(repo, version, platform = os.platform(), arch = os.arch()) {
|
|
32
|
+
const asset = releaseAssetName(platform, arch);
|
|
33
|
+
const tag = `v${version}`;
|
|
34
|
+
return {
|
|
35
|
+
asset,
|
|
36
|
+
tag,
|
|
37
|
+
url: `https://github.com/${repo}/releases/download/${tag}/${asset}`,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function download(url, dest) {
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
const file = fs.createWriteStream(dest);
|
|
44
|
+
const request = (nextUrl) => {
|
|
45
|
+
https
|
|
46
|
+
.get(nextUrl, { headers: { "User-Agent": "gwt-postinstall" } }, (res) => {
|
|
47
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
48
|
+
request(res.headers.location);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (res.statusCode !== 200) {
|
|
52
|
+
file.close();
|
|
53
|
+
fs.rmSync(dest, { force: true });
|
|
54
|
+
reject(new Error(`Download failed: HTTP ${res.statusCode} for ${nextUrl}`));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
res.pipe(file);
|
|
58
|
+
file.on("finish", () => {
|
|
59
|
+
file.close(resolve);
|
|
60
|
+
});
|
|
61
|
+
})
|
|
62
|
+
.on("error", (err) => {
|
|
63
|
+
file.close();
|
|
64
|
+
fs.rmSync(dest, { force: true });
|
|
65
|
+
reject(err);
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
request(url);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function findFileRecursive(root, fileName) {
|
|
73
|
+
const entries = fs.readdirSync(root, { withFileTypes: true });
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
const fullPath = path.join(root, entry.name);
|
|
76
|
+
if (entry.isFile() && entry.name === fileName) {
|
|
77
|
+
return fullPath;
|
|
78
|
+
}
|
|
79
|
+
if (entry.isDirectory()) {
|
|
80
|
+
const nested = findFileRecursive(fullPath, fileName);
|
|
81
|
+
if (nested) {
|
|
82
|
+
return nested;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function extractArchive(archivePath, extractDir, asset) {
|
|
90
|
+
if (asset.endsWith(".zip")) {
|
|
91
|
+
execFileSync(
|
|
92
|
+
"powershell.exe",
|
|
93
|
+
[
|
|
94
|
+
"-NoProfile",
|
|
95
|
+
"-NonInteractive",
|
|
96
|
+
"-Command",
|
|
97
|
+
`Expand-Archive -LiteralPath '${archivePath.replace(/'/g, "''")}' -DestinationPath '${extractDir.replace(/'/g, "''")}' -Force`,
|
|
98
|
+
]
|
|
99
|
+
);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (asset.endsWith(".tar.gz")) {
|
|
104
|
+
execFileSync("tar", ["-xzf", archivePath, "-C", extractDir]);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
throw new Error(`Unsupported archive type: ${asset}`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function cleanupTempDir(tempRoot) {
|
|
112
|
+
if (os.platform() === "win32") {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
118
|
+
} catch {
|
|
119
|
+
// Best-effort cleanup only.
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function installBinaryFromArchive({
|
|
124
|
+
archivePath,
|
|
125
|
+
asset,
|
|
126
|
+
binDir,
|
|
127
|
+
binaryName = binaryNameForPlatform(),
|
|
128
|
+
platform = os.platform(),
|
|
129
|
+
}) {
|
|
130
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "gwt-extract-"));
|
|
131
|
+
const extractDir = path.join(tempRoot, "extract");
|
|
132
|
+
const dest = path.join(binDir, binaryName);
|
|
133
|
+
|
|
134
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
135
|
+
fs.mkdirSync(extractDir, { recursive: true });
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
extractArchive(archivePath, extractDir, asset);
|
|
139
|
+
|
|
140
|
+
const extractedBinary = findFileRecursive(extractDir, binaryName);
|
|
141
|
+
if (!extractedBinary) {
|
|
142
|
+
throw new Error(`Extracted archive does not contain ${binaryName}`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
fs.copyFileSync(extractedBinary, dest);
|
|
146
|
+
if (platform !== "win32") {
|
|
147
|
+
fs.chmodSync(dest, 0o755);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return { asset, dest };
|
|
151
|
+
} finally {
|
|
152
|
+
cleanupTempDir(tempRoot);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async function installReleaseBinary({
|
|
157
|
+
repo,
|
|
158
|
+
version,
|
|
159
|
+
binDir,
|
|
160
|
+
binaryName = binaryNameForPlatform(),
|
|
161
|
+
platform = os.platform(),
|
|
162
|
+
arch = os.arch(),
|
|
163
|
+
}) {
|
|
164
|
+
const { asset, url } = releaseAssetUrl(repo, version, platform, arch);
|
|
165
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "gwt-release-"));
|
|
166
|
+
const archivePath = path.join(tempRoot, asset);
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
await download(url, archivePath);
|
|
170
|
+
return installBinaryFromArchive({
|
|
171
|
+
archivePath,
|
|
172
|
+
asset,
|
|
173
|
+
binDir,
|
|
174
|
+
binaryName,
|
|
175
|
+
platform,
|
|
176
|
+
});
|
|
177
|
+
} finally {
|
|
178
|
+
cleanupTempDir(tempRoot);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
module.exports = {
|
|
183
|
+
binaryNameForPlatform,
|
|
184
|
+
download,
|
|
185
|
+
installBinaryFromArchive,
|
|
186
|
+
installReleaseBinary,
|
|
187
|
+
releaseAssetName,
|
|
188
|
+
releaseAssetUrl,
|
|
189
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const assert = require("node:assert/strict");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const os = require("os");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const { execFileSync } = require("child_process");
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
binaryNameForPlatform,
|
|
9
|
+
installBinaryFromArchive,
|
|
10
|
+
releaseAssetName,
|
|
11
|
+
} = require("./release-assets.cjs");
|
|
12
|
+
const postinstall = require("./postinstall.cjs");
|
|
13
|
+
const launcher = require("../bin/gwt.cjs");
|
|
14
|
+
|
|
15
|
+
let failed = false;
|
|
16
|
+
|
|
17
|
+
function run(name, fn) {
|
|
18
|
+
try {
|
|
19
|
+
fn();
|
|
20
|
+
console.log(`ok - ${name}`);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
failed = true;
|
|
23
|
+
console.error(`not ok - ${name}`);
|
|
24
|
+
console.error(error && error.stack ? error.stack : error);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
run("release asset names match the public portable contract", () => {
|
|
29
|
+
assert.equal(releaseAssetName("darwin", "arm64"), "gwt-macos-arm64.tar.gz");
|
|
30
|
+
assert.equal(releaseAssetName("darwin", "x64"), "gwt-macos-x86_64.tar.gz");
|
|
31
|
+
assert.equal(releaseAssetName("linux", "arm64"), "gwt-linux-aarch64.tar.gz");
|
|
32
|
+
assert.equal(releaseAssetName("linux", "x64"), "gwt-linux-x86_64.tar.gz");
|
|
33
|
+
assert.equal(releaseAssetName("win32", "x64"), "gwt-windows-x86_64.zip");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
run("release helper keeps platform binary names stable", () => {
|
|
37
|
+
assert.equal(binaryNameForPlatform("win32"), "gwt.exe");
|
|
38
|
+
assert.equal(binaryNameForPlatform("linux"), "gwt");
|
|
39
|
+
assert.equal(binaryNameForPlatform("darwin"), "gwt");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
run("installer entrypoints are loadable under package type module", () => {
|
|
43
|
+
assert.equal(typeof postinstall.main, "function");
|
|
44
|
+
assert.equal(typeof launcher.main, "function");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
run("portable tarball extraction installs the unix binary", () => {
|
|
48
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "gwt-release-test-"));
|
|
49
|
+
const sourceDir = path.join(root, "source");
|
|
50
|
+
const binDir = path.join(root, "bin");
|
|
51
|
+
const archivePath = path.join(root, "gwt-linux-x86_64.tar.gz");
|
|
52
|
+
fs.mkdirSync(sourceDir, { recursive: true });
|
|
53
|
+
fs.writeFileSync(path.join(sourceDir, "gwt"), "unix-binary");
|
|
54
|
+
|
|
55
|
+
execFileSync("tar", ["-czf", archivePath, "-C", sourceDir, "gwt"]);
|
|
56
|
+
|
|
57
|
+
installBinaryFromArchive({
|
|
58
|
+
archivePath,
|
|
59
|
+
asset: path.basename(archivePath),
|
|
60
|
+
binDir,
|
|
61
|
+
binaryName: "gwt",
|
|
62
|
+
platform: "linux",
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
assert.equal(fs.readFileSync(path.join(binDir, "gwt"), "utf8"), "unix-binary");
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
run("portable zip extraction installs the windows binary", () => {
|
|
69
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "gwt-release-test-"));
|
|
70
|
+
const sourceDir = path.join(root, "source");
|
|
71
|
+
const binDir = path.join(root, "bin");
|
|
72
|
+
const archivePath = path.join(root, "gwt-windows-x86_64.zip");
|
|
73
|
+
const sourceBinary = path.join(sourceDir, "gwt.exe");
|
|
74
|
+
fs.mkdirSync(sourceDir, { recursive: true });
|
|
75
|
+
fs.writeFileSync(sourceBinary, "windows-binary");
|
|
76
|
+
|
|
77
|
+
execFileSync("powershell.exe", [
|
|
78
|
+
"-NoProfile",
|
|
79
|
+
"-NonInteractive",
|
|
80
|
+
"-Command",
|
|
81
|
+
`Compress-Archive -LiteralPath '${sourceBinary.replace(/'/g, "''")}' -DestinationPath '${archivePath.replace(/'/g, "''")}' -Force`,
|
|
82
|
+
]);
|
|
83
|
+
|
|
84
|
+
installBinaryFromArchive({
|
|
85
|
+
archivePath,
|
|
86
|
+
asset: path.basename(archivePath),
|
|
87
|
+
binDir,
|
|
88
|
+
binaryName: "gwt.exe",
|
|
89
|
+
platform: "win32",
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
assert.equal(fs.readFileSync(path.join(binDir, "gwt.exe"), "utf8"), "windows-binary");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (failed) {
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
package/wix/main.wxs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
|
|
3
|
+
<Package
|
|
4
|
+
Name="GWT"
|
|
5
|
+
Language="1033"
|
|
6
|
+
Version="$(Version)"
|
|
7
|
+
Manufacturer="GWT Contributors"
|
|
8
|
+
UpgradeCode="55555555-5555-5555-5555-555555555555"
|
|
9
|
+
InstallerVersion="500"
|
|
10
|
+
Scope="perMachine">
|
|
11
|
+
<SummaryInformation Description="Canvas-based floating terminal GUI for Git Worktree Manager" />
|
|
12
|
+
<MajorUpgrade DowngradeErrorMessage="A newer version of GWT is already installed." />
|
|
13
|
+
<MediaTemplate EmbedCab="yes" />
|
|
14
|
+
|
|
15
|
+
<StandardDirectory Id="ProgramFiles6432Folder">
|
|
16
|
+
<Directory Id="INSTALLFOLDER" Name="GWT" />
|
|
17
|
+
</StandardDirectory>
|
|
18
|
+
|
|
19
|
+
<Feature Id="MainFeature" Title="GWT" Level="1">
|
|
20
|
+
<ComponentGroupRef Id="ProductComponents" />
|
|
21
|
+
</Feature>
|
|
22
|
+
</Package>
|
|
23
|
+
|
|
24
|
+
<Fragment>
|
|
25
|
+
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
|
|
26
|
+
<Component>
|
|
27
|
+
<File Id="GwtExecutable" Source="!(bindpath.gwt)gwt.exe" KeyPath="yes" />
|
|
28
|
+
</Component>
|
|
29
|
+
</ComponentGroup>
|
|
30
|
+
</Fragment>
|
|
31
|
+
</Wix>
|
package/scripts/postinstall.js
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
const os = require("os");
|
|
5
|
-
const fs = require("fs");
|
|
6
|
-
const path = require("path");
|
|
7
|
-
const https = require("https");
|
|
8
|
-
|
|
9
|
-
const REPO = "akiojin/gwt";
|
|
10
|
-
const BIN_DIR = path.join(__dirname, "..", "bin");
|
|
11
|
-
const BINARY_NAME = os.platform() === "win32" ? "gwt.exe" : "gwt";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Detect the GitHub Release asset name for the current platform/arch.
|
|
15
|
-
* Matches the naming convention: gwt-{os}-{arch}[.exe]
|
|
16
|
-
*/
|
|
17
|
-
function releaseAssetName() {
|
|
18
|
-
const platform = os.platform();
|
|
19
|
-
const arch = os.arch();
|
|
20
|
-
|
|
21
|
-
if (platform === "darwin" && arch === "arm64") {
|
|
22
|
-
return "gwt-macos-aarch64";
|
|
23
|
-
}
|
|
24
|
-
if (platform === "darwin" && arch === "x64") {
|
|
25
|
-
return "gwt-macos-x86_64";
|
|
26
|
-
}
|
|
27
|
-
if (platform === "linux" && arch === "x64") {
|
|
28
|
-
return "gwt-linux-x86_64";
|
|
29
|
-
}
|
|
30
|
-
if (platform === "linux" && arch === "arm64") {
|
|
31
|
-
return "gwt-linux-aarch64";
|
|
32
|
-
}
|
|
33
|
-
if (platform === "win32" && arch === "x64") {
|
|
34
|
-
return "gwt-windows-x86_64.exe";
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
throw new Error(`Unsupported platform: ${platform}-${arch}`);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Read the target version from package.json.
|
|
42
|
-
*/
|
|
43
|
-
function readVersion() {
|
|
44
|
-
const pkg = path.join(__dirname, "..", "package.json");
|
|
45
|
-
const data = JSON.parse(fs.readFileSync(pkg, "utf8"));
|
|
46
|
-
return data.version;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Follow redirects and download a URL to a local path.
|
|
51
|
-
*/
|
|
52
|
-
function download(url, dest) {
|
|
53
|
-
return new Promise((resolve, reject) => {
|
|
54
|
-
const file = fs.createWriteStream(dest);
|
|
55
|
-
const request = (u) => {
|
|
56
|
-
https
|
|
57
|
-
.get(u, { headers: { "User-Agent": "gwt-postinstall" } }, (res) => {
|
|
58
|
-
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
59
|
-
request(res.headers.location);
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
if (res.statusCode !== 200) {
|
|
63
|
-
file.close();
|
|
64
|
-
fs.unlink(dest, () => {});
|
|
65
|
-
reject(new Error(`Download failed: HTTP ${res.statusCode} for ${u}`));
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
res.pipe(file);
|
|
69
|
-
file.on("finish", () => {
|
|
70
|
-
file.close(resolve);
|
|
71
|
-
});
|
|
72
|
-
})
|
|
73
|
-
.on("error", (err) => {
|
|
74
|
-
file.close();
|
|
75
|
-
fs.unlink(dest, () => {});
|
|
76
|
-
reject(err);
|
|
77
|
-
});
|
|
78
|
-
};
|
|
79
|
-
request(url);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async function main() {
|
|
84
|
-
// Skip in CI or when running from source
|
|
85
|
-
if (process.env.CI) {
|
|
86
|
-
console.log("gwt: skipping binary download in CI");
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const version = readVersion();
|
|
91
|
-
const asset = releaseAssetName();
|
|
92
|
-
const tag = `v${version}`;
|
|
93
|
-
const binaryUrl = `https://github.com/${REPO}/releases/download/${tag}/${asset}`;
|
|
94
|
-
|
|
95
|
-
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
96
|
-
|
|
97
|
-
const dest = path.join(BIN_DIR, BINARY_NAME);
|
|
98
|
-
|
|
99
|
-
console.log(`Downloading gwt binary for ${os.platform()}-${os.arch()}...`);
|
|
100
|
-
console.log(`Downloading from: ${binaryUrl}`);
|
|
101
|
-
|
|
102
|
-
try {
|
|
103
|
-
await download(binaryUrl, dest);
|
|
104
|
-
if (os.platform() !== "win32") {
|
|
105
|
-
fs.chmodSync(dest, 0o755);
|
|
106
|
-
}
|
|
107
|
-
console.log(`gwt binary installed successfully!`);
|
|
108
|
-
} catch (err) {
|
|
109
|
-
console.error(`gwt: failed to download binary - ${err.message}`);
|
|
110
|
-
console.error("gwt: you can build from source with: cargo build --release -p gwt");
|
|
111
|
-
process.exitCode = 0; // non-fatal so npm install does not fail
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
main();
|