@package-pal/cli 0.0.6 → 0.0.8
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@package-pal/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "CLI tool exposing core PackagePal functionality.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"package",
|
|
@@ -12,13 +12,15 @@
|
|
|
12
12
|
],
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"type": "module",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"tar": "^7.4.3"
|
|
17
|
+
},
|
|
15
18
|
"devDependencies": {
|
|
16
19
|
"@clack/prompts": "^0.11.0",
|
|
17
20
|
"@package-pal/core": "^0.0.2",
|
|
18
21
|
"@package-pal/util": "^0.0.4",
|
|
19
22
|
"@stricli/core": "^1.2.0",
|
|
20
23
|
"@types/bun": "^1.2.19",
|
|
21
|
-
"tar": "^7.4.3",
|
|
22
24
|
"typescript": "^5.8.3",
|
|
23
25
|
"yoctocolors": "^2.1.1"
|
|
24
26
|
},
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
dirname, join, resolve,
|
|
3
3
|
} from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
|
-
import packageJson from '../../../../package.json' with { type: 'json' }
|
|
5
|
+
import packageJson from '../../../../package.json' with { type: 'json' };
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @param {Bun.Platform} platform
|
|
@@ -19,11 +19,10 @@ export const getPlatformInfo = () => {
|
|
|
19
19
|
case 'linux':
|
|
20
20
|
let isMusl = false;
|
|
21
21
|
try {
|
|
22
|
-
// Determine if the OS is using musl libc.
|
|
23
22
|
// The report will not have a glibcVersionRuntime property if musl is being used.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
isMusl = !
|
|
23
|
+
/** @type {{ header?: { glibcVersionRuntime?: unknown } }} */
|
|
24
|
+
const report = process.report.getReport();
|
|
25
|
+
isMusl = !report.header?.glibcVersionRuntime;
|
|
27
26
|
} catch {
|
|
28
27
|
isMusl = true;
|
|
29
28
|
}
|
|
@@ -39,7 +38,7 @@ export const getPlatformInfo = () => {
|
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
if (!targetPackage) {
|
|
42
|
-
throw new Error(`Unsupported
|
|
41
|
+
throw new Error(`Unsupported target: ${usePlatform} ${useArch}.`);
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
return {
|
|
@@ -3,52 +3,72 @@ import { pipeline } from 'stream/promises';
|
|
|
3
3
|
import { x } from 'tar';
|
|
4
4
|
import packageJson from '../../../../package.json' with { type: 'json' };
|
|
5
5
|
|
|
6
|
+
const maxRetries = 3;
|
|
7
|
+
const initialBackoffMs = 500;
|
|
8
|
+
|
|
6
9
|
/**
|
|
7
10
|
* @param {string} tarballUrl
|
|
8
11
|
* @param {string} binName
|
|
9
12
|
* @param {string} outputBinDir
|
|
10
13
|
*/
|
|
11
|
-
const
|
|
14
|
+
const tryDownloadAndExtract = (
|
|
12
15
|
tarballUrl, binName, outputBinDir,
|
|
13
16
|
) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
19
|
-
if (!res.headers.location) {
|
|
20
|
-
reject(new Error(`Failed to download binary: Redirect location missing.`));
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
get(tarballUrl, (res) => {
|
|
19
|
+
const isRedirect = res.statusCode === 301 || res.statusCode === 302;
|
|
20
|
+
const isSuccess = res.statusCode === 200;
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
if (isRedirect) {
|
|
23
|
+
if (!res.headers.location) {
|
|
24
|
+
reject(new Error(`Failed to download binary: Redirect location missing.`));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
downloadAndExtract(
|
|
28
|
+
res.headers.location, binName, outputBinDir,
|
|
29
|
+
)
|
|
30
|
+
.then(resolve)
|
|
31
|
+
.catch(reject);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
});
|
|
35
|
+
if (!isSuccess) {
|
|
36
|
+
reject(new Error(`Failed to download binary: ${res.statusCode?.toString() ?? 'Unknown'}`));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
const extractStream = x({
|
|
41
|
+
cwd: outputBinDir,
|
|
42
|
+
strip: 1,
|
|
43
|
+
filter: path => path === `package/bin/${binName}`,
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
+
pipeline(res, extractStream).then(resolve)
|
|
47
|
+
.catch(reject);
|
|
48
|
+
}).on('error', reject);
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {string} tarballUrl
|
|
54
|
+
* @param {string} binName
|
|
55
|
+
* @param {string} outputBinDir
|
|
56
|
+
*/
|
|
57
|
+
const downloadAndExtract = async (
|
|
58
|
+
tarballUrl, binName, outputBinDir,
|
|
59
|
+
) => {
|
|
60
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
61
|
+
try {
|
|
62
|
+
await tryDownloadAndExtract(
|
|
63
|
+
tarballUrl, binName, outputBinDir,
|
|
64
|
+
);
|
|
46
65
|
return;
|
|
47
|
-
} catch (
|
|
48
|
-
if (
|
|
49
|
-
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (attempt < maxRetries) {
|
|
68
|
+
const delay = initialBackoffMs * 2 ** (attempt - 1);
|
|
69
|
+
console.warn(`Download failed (attempt ${attempt.toString()}), retrying in ${delay.toString()}ms...`);
|
|
50
70
|
} else {
|
|
51
|
-
throw
|
|
71
|
+
throw error;
|
|
52
72
|
}
|
|
53
73
|
}
|
|
54
74
|
}
|
|
@@ -63,15 +83,16 @@ export const loadMissingBinary = async (
|
|
|
63
83
|
binName, targetPackage, outputBinDir,
|
|
64
84
|
) => {
|
|
65
85
|
const fullTargetPackageName = `@package-pal/${targetPackage}`;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const targetPackageVersion =
|
|
86
|
+
/** @type {Record<string, string>} */
|
|
87
|
+
const optionalDeps = packageJson.optionalDependencies;
|
|
88
|
+
const targetPackageVersion = optionalDeps[fullTargetPackageName];
|
|
89
|
+
|
|
69
90
|
if (!targetPackageVersion) {
|
|
70
91
|
throw new Error(`No version found for target package '${fullTargetPackageName}'.`);
|
|
71
92
|
}
|
|
72
93
|
|
|
73
|
-
const tarballUrl = `https://registry.npmjs.org/${fullTargetPackageName}/-/${
|
|
74
|
-
console.log(`Downloading '${fullTargetPackageName}' from ${tarballUrl}...`);
|
|
94
|
+
const tarballUrl = `https://registry.npmjs.org/${fullTargetPackageName}/-/${targetPackage}-${targetPackageVersion}.tgz`;
|
|
95
|
+
console.log(`Downloading '${fullTargetPackageName}' into '${outputBinDir}' from ${tarballUrl}...`);
|
|
75
96
|
|
|
76
97
|
await downloadAndExtract(
|
|
77
98
|
tarballUrl, binName, outputBinDir,
|