codebuff-cli 1.0.11 → 1.0.12
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/cli/scripts/download-binary.cjs +47 -19
- package/package.json +1 -1
|
@@ -7,6 +7,9 @@ const os = require('os');
|
|
|
7
7
|
|
|
8
8
|
const REPO = 'Marcus-Mok-GH/codebuff-cli';
|
|
9
9
|
const BINARY_NAME = 'codebuff';
|
|
10
|
+
const MAX_RETRIES = 3;
|
|
11
|
+
const REQUEST_TIMEOUT_MS = 120000;
|
|
12
|
+
const MAX_REDIRECTS = 10;
|
|
10
13
|
|
|
11
14
|
function getVersion() {
|
|
12
15
|
const candidates = [
|
|
@@ -28,8 +31,23 @@ function getBinaryPath() {
|
|
|
28
31
|
return path.join(binDir, name);
|
|
29
32
|
}
|
|
30
33
|
|
|
31
|
-
function
|
|
34
|
+
function cleanup(dest) {
|
|
35
|
+
try {
|
|
36
|
+
if (fs.existsSync(dest)) {
|
|
37
|
+
fs.unlinkSync(dest);
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
// ignore cleanup errors
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function download(url, dest, redirectCount = 0) {
|
|
32
45
|
return new Promise((resolve, reject) => {
|
|
46
|
+
if (redirectCount > MAX_REDIRECTS) {
|
|
47
|
+
reject(new Error(`Too many redirects (max ${MAX_REDIRECTS}) while downloading from ${url}`));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
33
51
|
const client = url.startsWith('https:') ? https : http;
|
|
34
52
|
const file = fs.createWriteStream(dest);
|
|
35
53
|
|
|
@@ -37,10 +55,10 @@ function download(url, dest) {
|
|
|
37
55
|
url,
|
|
38
56
|
{ headers: { 'User-Agent': 'codebuff-cli-installer' } },
|
|
39
57
|
(res) => {
|
|
40
|
-
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
58
|
+
if (res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 307 || res.statusCode === 308) {
|
|
41
59
|
file.close();
|
|
42
|
-
|
|
43
|
-
download(new URL(res.headers.location, url).href, dest)
|
|
60
|
+
cleanup(dest);
|
|
61
|
+
download(new URL(res.headers.location, url).href, dest, redirectCount + 1)
|
|
44
62
|
.then(resolve)
|
|
45
63
|
.catch(reject);
|
|
46
64
|
return;
|
|
@@ -48,8 +66,8 @@ function download(url, dest) {
|
|
|
48
66
|
|
|
49
67
|
if (res.statusCode !== 200) {
|
|
50
68
|
file.close();
|
|
51
|
-
|
|
52
|
-
reject(new Error(`HTTP ${res.statusCode}`));
|
|
69
|
+
cleanup(dest);
|
|
70
|
+
reject(new Error(`Failed to download from ${url}: HTTP ${res.statusCode}`));
|
|
53
71
|
return;
|
|
54
72
|
}
|
|
55
73
|
|
|
@@ -63,26 +81,36 @@ function download(url, dest) {
|
|
|
63
81
|
|
|
64
82
|
req.on('error', (err) => {
|
|
65
83
|
file.close();
|
|
66
|
-
|
|
67
|
-
reject(err);
|
|
84
|
+
cleanup(dest);
|
|
85
|
+
reject(new Error(`Request failed for ${url}: ${err.message}`));
|
|
68
86
|
});
|
|
69
87
|
|
|
70
|
-
req.setTimeout(
|
|
88
|
+
req.setTimeout(REQUEST_TIMEOUT_MS, () => {
|
|
71
89
|
req.destroy();
|
|
72
90
|
file.close();
|
|
73
|
-
|
|
74
|
-
reject(new Error(
|
|
91
|
+
cleanup(dest);
|
|
92
|
+
reject(new Error(`Request timeout after ${REQUEST_TIMEOUT_MS}ms for ${url}`));
|
|
75
93
|
});
|
|
76
94
|
});
|
|
77
95
|
}
|
|
78
96
|
|
|
79
|
-
async function
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
97
|
+
async function downloadWithRetry(url, dest, retries = MAX_RETRIES) {
|
|
98
|
+
let lastError;
|
|
99
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
100
|
+
try {
|
|
101
|
+
await download(url, dest);
|
|
102
|
+
return true;
|
|
103
|
+
} catch (err) {
|
|
104
|
+
lastError = err;
|
|
105
|
+
if (attempt < retries) {
|
|
106
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
107
|
+
console.warn(`Download attempt ${attempt + 1} failed for ${url}, retrying in ${delay}ms...`);
|
|
108
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
85
111
|
}
|
|
112
|
+
console.error(`Download failed after ${retries + 1} attempts for ${url}: ${lastError.message}`);
|
|
113
|
+
return false;
|
|
86
114
|
}
|
|
87
115
|
|
|
88
116
|
async function main() {
|
|
@@ -105,9 +133,9 @@ async function main() {
|
|
|
105
133
|
|
|
106
134
|
fs.mkdirSync(path.dirname(binaryPath), { recursive: true });
|
|
107
135
|
|
|
108
|
-
if (await
|
|
136
|
+
if (await downloadWithRetry(platformUrl, binaryPath)) {
|
|
109
137
|
console.log(`Downloaded platform-specific binary: ${platformName}`);
|
|
110
|
-
} else if (await
|
|
138
|
+
} else if (await downloadWithRetry(genericUrl, binaryPath)) {
|
|
111
139
|
console.log(`Downloaded generic binary: ${BINARY_NAME}`);
|
|
112
140
|
} else {
|
|
113
141
|
console.error(
|