@lumi-ai-lab/harness-data 0.0.11 → 0.0.13
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 +1 -1
- package/src/commands/install.js +6 -2
- package/src/commands/update.js +21 -43
- package/src/lib/tool-release.js +47 -0
package/package.json
CHANGED
package/src/commands/install.js
CHANGED
|
@@ -6,6 +6,7 @@ import { ask, askSecret, chooseAgent } from "../lib/prompt.js";
|
|
|
6
6
|
import { resolveWorkspaceDir, writeState } from "../lib/paths.js";
|
|
7
7
|
import { installToolsFromManifest, manifestDigest, readManifest } from "../lib/manifest.js";
|
|
8
8
|
import { binaryName, platformKey } from "../lib/platform.js";
|
|
9
|
+
import { resolveLatestManifest } from "../lib/tool-release.js";
|
|
9
10
|
import { collectDoctor } from "./doctor.js";
|
|
10
11
|
import { packageVersion } from "../lib/package.js";
|
|
11
12
|
import { downloadReleaseAsset, findReleaseAsset, githubToken, hasGithubAuth, latestRelease } from "../lib/github.js";
|
|
@@ -236,10 +237,13 @@ export async function installCommand(options = {}) {
|
|
|
236
237
|
let manifest;
|
|
237
238
|
let localTools = {};
|
|
238
239
|
if (tokenMode) {
|
|
239
|
-
manifest =
|
|
240
|
+
manifest = readManifest(manifestPath);
|
|
241
|
+
const latestManifest = await resolveLatestManifest(manifest, key, options);
|
|
242
|
+
manifest = await installToolsFromManifest(runtimeDir, manifestPath, { ...options, manifestOverride: latestManifest });
|
|
240
243
|
} else {
|
|
241
244
|
manifest = readManifest(manifestPath);
|
|
242
|
-
await
|
|
245
|
+
const latestManifest = await resolveLatestManifest(manifest, key, { ...options, tools: ["data-harness-cli"] });
|
|
246
|
+
await installToolsFromManifest(runtimeDir, manifestPath, { ...options, manifestOverride: latestManifest });
|
|
243
247
|
localTools = await installLocalTools(runtimeDir, options);
|
|
244
248
|
}
|
|
245
249
|
ok(`${Object.keys(manifest.installedTools || {}).length + Object.keys(localTools).length} 个 CLI 已安装到 bin/`);
|
package/src/commands/update.js
CHANGED
|
@@ -7,6 +7,8 @@ import { installToolsFromManifest, manifestDigest, readManifest } from "../lib/m
|
|
|
7
7
|
import { packageVersion } from "../lib/package.js";
|
|
8
8
|
import { platformKey } from "../lib/platform.js";
|
|
9
9
|
import { githubToken, latestRelease } from "../lib/github.js";
|
|
10
|
+
import { resolveLatestTool } from "../lib/tool-release.js";
|
|
11
|
+
import { protocolFromUrl, runGitWithProtocol } from "../lib/git-auth.js";
|
|
10
12
|
import { buildAndCheck, installRuntimeBundle, printDoctorSummary } from "./install.js";
|
|
11
13
|
import { collectDoctor } from "./doctor.js";
|
|
12
14
|
import { action, blank, header, ok, shortSha, skip, step, warn } from "../lib/log.js";
|
|
@@ -22,48 +24,17 @@ async function npmLatest() {
|
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
function
|
|
26
|
-
if (url.endsWith(".zip")) return "zip";
|
|
27
|
-
if (url.endsWith(".tar.gz")) return "tar.gz";
|
|
28
|
-
return "";
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function toolAssetName(tool, tag, key) {
|
|
32
|
-
const current = tool.platforms?.[key]?.url || "";
|
|
33
|
-
const suffix = archiveSuffix(current) || (key.startsWith("windows-") ? "zip" : "tar.gz");
|
|
34
|
-
return `${tool.binary}-${tag}-${key}.${suffix}`;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function releaseAsset(release, name) {
|
|
38
|
-
return (release.assets || []).find((asset) => asset.name === name);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function oneToolManifest(manifest, tool, tag, asset, key) {
|
|
27
|
+
function oneToolManifest(manifest, tool) {
|
|
42
28
|
return {
|
|
43
29
|
...manifest,
|
|
44
|
-
tools: [
|
|
45
|
-
...tool,
|
|
46
|
-
version: tag,
|
|
47
|
-
platforms: {
|
|
48
|
-
[key]: {
|
|
49
|
-
url: asset.browser_download_url || `https://github.com/${tool.repo}/releases/download/${tag}/${asset.name}`,
|
|
50
|
-
sha256: ""
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}]
|
|
30
|
+
tools: [tool]
|
|
54
31
|
};
|
|
55
32
|
}
|
|
56
33
|
|
|
57
34
|
async function maybeUpdateTool(runtimeDir, manifest, tool, options, state) {
|
|
58
35
|
const key = platformKey();
|
|
59
|
-
const
|
|
60
|
-
const tag =
|
|
61
|
-
const assetName = toolAssetName(tool, tag, key);
|
|
62
|
-
const asset = releaseAsset(release, assetName);
|
|
63
|
-
if (!asset) {
|
|
64
|
-
warn(`${tool.name} 最新 release 缺少 ${assetName},已跳过`);
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
36
|
+
const latestTool = await resolveLatestTool(tool, key, options);
|
|
37
|
+
const tag = latestTool.version;
|
|
67
38
|
const current = state.tools?.[tool.name] || {};
|
|
68
39
|
const tagChanged = current.version && current.version !== tag;
|
|
69
40
|
const firstInstall = !current.version;
|
|
@@ -77,17 +48,24 @@ async function maybeUpdateTool(runtimeDir, manifest, tool, options, state) {
|
|
|
77
48
|
options.skippedUpdates?.push(`${tool.name} ${tag}`);
|
|
78
49
|
return null;
|
|
79
50
|
}
|
|
80
|
-
const updatedManifest = oneToolManifest(manifest,
|
|
51
|
+
const updatedManifest = oneToolManifest(manifest, latestTool);
|
|
81
52
|
const installed = await installToolsFromManifest(runtimeDir, path.join(runtimeDir, ".bootstrap-cache", `${tool.name}-manifest.json`), {
|
|
82
53
|
...options,
|
|
83
54
|
manifestOverride: updatedManifest
|
|
84
55
|
});
|
|
85
|
-
const result = installed.installedTools?.[tool.name] || { version: tag
|
|
56
|
+
const result = installed.installedTools?.[tool.name] || { version: tag };
|
|
86
57
|
ok(`${tool.name} 已更新到 ${tag}`);
|
|
87
58
|
return result;
|
|
88
59
|
}
|
|
89
60
|
|
|
90
|
-
async function
|
|
61
|
+
async function updateWikisGit(wikisDir, args, options) {
|
|
62
|
+
const remote = (await run("git", ["-C", wikisDir, "remote", "get-url", "origin"], { ...options, allowFailure: true })).stdout.trim();
|
|
63
|
+
const protocol = protocolFromUrl(remote);
|
|
64
|
+
if (!protocol) return run("git", ["-C", wikisDir, ...args], options);
|
|
65
|
+
return runGitWithProtocol(protocol, ["-C", wikisDir, ...args], options);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export async function updateWikis(runtimeDir, options, state) {
|
|
91
69
|
const wikisDir = path.join(runtimeDir, "wikis");
|
|
92
70
|
if (!githubToken(options) && state.installMode !== "github-token") {
|
|
93
71
|
skip("harness-data-wikis 为本地路径模式,请手动检查");
|
|
@@ -97,9 +75,9 @@ async function updateWikis(runtimeDir, options, state) {
|
|
|
97
75
|
skip("harness-data-wikis 不是 git checkout");
|
|
98
76
|
return null;
|
|
99
77
|
}
|
|
100
|
-
await
|
|
101
|
-
const local = (await run("git", ["-C", wikisDir, "rev-parse", "HEAD"])).stdout.trim();
|
|
102
|
-
const remote = (await run("git", ["-C", wikisDir, "rev-parse", "origin/HEAD"], { allowFailure: true })).stdout.trim();
|
|
78
|
+
await updateWikisGit(wikisDir, ["fetch", "origin"], options);
|
|
79
|
+
const local = (await run("git", ["-C", wikisDir, "rev-parse", "HEAD"], options)).stdout.trim();
|
|
80
|
+
const remote = (await run("git", ["-C", wikisDir, "rev-parse", "origin/HEAD"], { ...options, allowFailure: true })).stdout.trim();
|
|
103
81
|
if (!remote || local === remote) {
|
|
104
82
|
ok(`harness-data-wikis 已是最新 ${shortSha(local)}`);
|
|
105
83
|
return null;
|
|
@@ -110,8 +88,8 @@ async function updateWikis(runtimeDir, options, state) {
|
|
|
110
88
|
options.skippedUpdates?.push(`harness-data-wikis ${shortSha(remote)}`);
|
|
111
89
|
return null;
|
|
112
90
|
}
|
|
113
|
-
await
|
|
114
|
-
const commit = (await run("git", ["-C", wikisDir, "rev-parse", "HEAD"])).stdout.trim();
|
|
91
|
+
await updateWikisGit(wikisDir, ["pull", "--ff-only"], options);
|
|
92
|
+
const commit = (await run("git", ["-C", wikisDir, "rev-parse", "HEAD"], options)).stdout.trim();
|
|
115
93
|
ok(`harness-data-wikis 已更新到 ${shortSha(commit)}`);
|
|
116
94
|
return { commit };
|
|
117
95
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { latestRelease } from "./github.js";
|
|
2
|
+
|
|
3
|
+
function archiveSuffix(asset, key) {
|
|
4
|
+
if (asset?.archive) return asset.archive;
|
|
5
|
+
if (asset?.url?.endsWith(".zip")) return "zip";
|
|
6
|
+
if (asset?.url?.endsWith(".tar.gz")) return "tar.gz";
|
|
7
|
+
return key.startsWith("windows-") ? "zip" : "tar.gz";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function toolAssetName(tool, tag, key) {
|
|
11
|
+
const suffix = archiveSuffix(tool.platforms?.[key], key);
|
|
12
|
+
return `${tool.binary}-${tag}-${key}.${suffix}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function releaseAsset(release, name) {
|
|
16
|
+
return (release.assets || []).find((asset) => asset.name === name);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function resolveLatestTool(tool, key, options = {}) {
|
|
20
|
+
const release = await latestRelease(tool.repo, options);
|
|
21
|
+
const tag = release.tag_name;
|
|
22
|
+
const name = toolAssetName(tool, tag, key);
|
|
23
|
+
const asset = releaseAsset(release, name);
|
|
24
|
+
if (!asset) {
|
|
25
|
+
throw new Error(`${tool.name} latest release ${tag} missing ${key} asset in ${tool.repo}: ${name}`);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
...tool,
|
|
29
|
+
version: tag,
|
|
30
|
+
platforms: {
|
|
31
|
+
[key]: {
|
|
32
|
+
url: asset.browser_download_url || `https://github.com/${tool.repo}/releases/download/${tag}/${asset.name}`,
|
|
33
|
+
sha256: ""
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function resolveLatestManifest(manifest, key, options = {}) {
|
|
40
|
+
const only = options.tools ? new Set(options.tools) : null;
|
|
41
|
+
const tools = [];
|
|
42
|
+
for (const tool of manifest.tools || []) {
|
|
43
|
+
if (only && !only.has(tool.name)) continue;
|
|
44
|
+
tools.push(await resolveLatestTool(tool, key, options));
|
|
45
|
+
}
|
|
46
|
+
return { ...manifest, tools };
|
|
47
|
+
}
|