Skip to content
This repository was archived by the owner on Nov 25, 2025. It is now read-only.

Commit d5430e3

Browse files
committed
add support for Mach's Nominated Zig versions
1 parent 5e37e61 commit d5430e3

File tree

2 files changed

+60
-24
lines changed

2 files changed

+60
-24
lines changed

src/zigSetup.ts

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -67,30 +67,32 @@ async function findClosestSatisfyingZigVersion(
6767
}
6868

6969
/**
70-
* Returns a sorted list of all versions that are provided by [index.json](https://ziglang.org/download/index.json).
70+
* Returns a sorted list of all versions that are provided by Zig's [index.json](https://ziglang.org/download/index.json) and Mach's [index.json](https://pkg.machengine.org/zig/index.json).
71+
* [Nominated Zig versions](https://machengine.org/docs/nominated-zig/#nominated-zig-history) are sorted to the bottom.
72+
*
7173
* Throws an exception when no network connection is available.
7274
*/
7375
async function getVersions(): Promise<ZigVersion[]> {
74-
const indexJson = (await axios.get<VersionIndex>("https://ziglang.org/download/index.json", {})).data;
76+
const [zigIndexJson, machIndexJson] = await Promise.all([
77+
axios.get<VersionIndex>("https://ziglang.org/download/index.json", {}),
78+
axios.get<VersionIndex>("https://pkg.machengine.org/zig/index.json", {}),
79+
]);
80+
const indexJson = { ...machIndexJson.data, ...zigIndexJson.data };
81+
7582
const hostName = getHostZigName();
7683
const result: ZigVersion[] = [];
77-
for (let key in indexJson) {
78-
const value = indexJson[key];
79-
let version: semver.SemVer;
80-
if (key === "master") {
81-
key = "nightly";
82-
version = new semver.SemVer((value as unknown as { version: string }).version);
83-
} else {
84-
version = new semver.SemVer(key);
85-
}
84+
for (const [key, value] of Object.entries(indexJson)) {
85+
const name = key === "master" ? "nightly" : key;
86+
const version = new semver.SemVer(value.version ?? key);
8687
const release = value[hostName];
8788
if (release) {
8889
result.push({
89-
name: key,
90+
name: name,
9091
version: version,
9192
url: release.tarball,
9293
sha: release.shasum,
93-
notes: (value as { notes?: string }).notes,
94+
notes: value.notes,
95+
isMach: name.includes("mach"),
9496
});
9597
}
9698
}
@@ -99,37 +101,61 @@ async function getVersions(): Promise<ZigVersion[]> {
99101
`no pre-built Zig is available for your system '${hostName}', you can build it yourself using https://github.com/ziglang/zig-bootstrap`,
100102
);
101103
}
102-
result.sort((lhs, rhs) => semver.compare(rhs.version, lhs.version));
104+
sortVersions(result);
103105
return result;
104106
}
105107

108+
function sortVersions(versions: { name?: string; version: semver.SemVer; isMach: boolean }[]) {
109+
versions.sort((lhs, rhs) => {
110+
// Mach versions except `mach-latest` move to the end
111+
if (lhs.name !== "mach-latest" && rhs.name !== "mach-latest" && lhs.isMach !== rhs.isMach)
112+
return +lhs.isMach - +rhs.isMach;
113+
return semver.compare(rhs.version, lhs.version);
114+
});
115+
}
116+
106117
async function selectVersionAndInstall(context: vscode.ExtensionContext) {
107118
const offlineVersions = await versionManager.query(versionManagerConfig);
108119

109120
const versions: {
121+
name?: string;
110122
version: semver.SemVer;
111123
/** Whether the version already installed in global extension storage */
112124
offline: boolean;
113125
/** Whether is available in `index.json` */
114126
online: boolean;
127+
/** Whether the version one of [Mach's nominated Zig versions](https://machengine.org/docs/nominated-zig/#nominated-zig-history) */
128+
isMach: boolean;
115129
}[] = offlineVersions.map((version) => ({
116130
version: version,
117131
offline: true,
118132
online: false,
133+
isMach: false /* We can't tell if a version is Mach while being offline */,
119134
}));
120135

121136
try {
122-
outer: for (const onlineVersion of await getVersions()) {
137+
const onlineVersions = await getVersions();
138+
outer: for (const onlineVersion of onlineVersions) {
123139
for (const version of versions) {
124140
if (semver.eq(version.version, onlineVersion.version)) {
141+
version.name ??= onlineVersion.name;
125142
version.online = true;
143+
version.isMach = onlineVersion.isMach;
144+
}
145+
}
146+
147+
for (const version of versions) {
148+
if (semver.eq(version.version, onlineVersion.version) && version.name === onlineVersion.name) {
126149
continue outer;
127150
}
128151
}
152+
129153
versions.push({
154+
name: onlineVersion.name,
130155
version: onlineVersion.version,
131156
online: true,
132-
offline: false,
157+
offline: !!offlineVersions.find((item) => semver.eq(item.version, onlineVersion.version)),
158+
isMach: onlineVersion.isMach,
133159
});
134160
}
135161
} catch (err) {
@@ -145,7 +171,7 @@ async function selectVersionAndInstall(context: vscode.ExtensionContext) {
145171
}
146172
}
147173

148-
versions.sort((lhs, rhs) => semver.compare(rhs.version, lhs.version));
174+
sortVersions(versions);
149175
const placeholderVersion = versions.find((item) => item.version.prerelease.length === 0)?.version;
150176

151177
const items: vscode.QuickPickItem[] = [];
@@ -183,12 +209,20 @@ async function selectVersionAndInstall(context: vscode.ExtensionContext) {
183209
},
184210
);
185211

212+
let seenMachVersion = false;
186213
for (const item of versions) {
187-
const isNightly = item.online && item.version.prerelease.length !== 0;
214+
const useName = item.isMach || item.version.prerelease.length !== 0;
215+
if (item.isMach && !seenMachVersion && item.name !== "mach-latest") {
216+
seenMachVersion = true;
217+
items.push({
218+
label: "Mach's Nominated Zig versions",
219+
kind: vscode.QuickPickItemKind.Separator,
220+
});
221+
}
188222
items.push({
189-
label: isNightly ? "nightly" : item.version.raw,
223+
label: (useName ? item.name : null) ?? item.version.raw,
190224
description: item.offline ? "already installed" : undefined,
191-
detail: isNightly ? item.version.raw : undefined,
225+
detail: useName ? (item.name ? item.version.raw : undefined) : undefined,
192226
});
193227
}
194228

@@ -218,9 +252,7 @@ async function selectVersionAndInstall(context: vscode.ExtensionContext) {
218252
await vscode.workspace.getConfiguration("zig").update("path", uris[0].path, true);
219253
break;
220254
default:
221-
const version = new semver.SemVer(
222-
selection.label === "nightly" ? selection.detail ?? selection.label : selection.label,
223-
);
255+
const version = new semver.SemVer(selection.detail ?? selection.label);
224256
await context.workspaceState.update("zig-version", version.raw);
225257
await installZig(context);
226258
break;

src/zigUtil.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,15 @@ export interface ZigVersion {
173173
url: string;
174174
sha: string;
175175
notes?: string;
176+
isMach: boolean;
176177
}
177178

178179
export type VersionIndex = Record<
179180
string,
180-
Record<string, undefined | { tarball: string; shasum: string; size: string }>
181+
{
182+
version?: string;
183+
notes?: string;
184+
} & Record<string, undefined | { tarball: string; shasum: string; size: string }>
181185
>;
182186

183187
export function getWorkspaceFolder(filePath: string): vscode.WorkspaceFolder | undefined {

0 commit comments

Comments
 (0)