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

Commit 681e0a9

Browse files
authored
Merge pull request #230 from ziglang/techatrix/version-manager
introduce a fully featured version manager
2 parents 304a36a + 11eb5db commit 681e0a9

14 files changed

+1325
-591
lines changed

.vscodeignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
.github/**
12
.vscode/**
23
.vscode-test/**
34
out/test/**
45
src/**
56
.gitignore
7+
.prettierignore
8+
eslint.config.mjs
69
**/tsconfig.json
710
**/tslint.json
811
**/*.map

package-lock.json

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
".zig",
3737
".zon"
3838
],
39+
"aliases": [
40+
"Zig"
41+
],
3942
"configuration": "./language-configuration.json"
4043
}
4144
],
@@ -68,11 +71,6 @@
6871
"type": "object",
6972
"title": "Zig",
7073
"properties": {
71-
"zig.initialSetupDone": {
72-
"type": "boolean",
73-
"default": false,
74-
"description": "Has the initial setup been done yet?"
75-
},
7674
"zig.buildOnSave": {
7775
"type": "boolean",
7876
"default": false,
@@ -105,13 +103,12 @@
105103
"zig.path": {
106104
"scope": "machine-overridable",
107105
"type": "string",
108-
"description": "Set a custom path to the Zig binary. The string \"zig\" means lookup zig in PATH."
106+
"description": "Set a custom path to the `zig` executable. Example: `C:/zig-windows-x86_64-0.13.0/zig.exe`. The string \"zig\" means lookup zig in PATH."
109107
},
110-
"zig.checkForUpdate": {
108+
"zig.version": {
111109
"scope": "resource",
112-
"type": "boolean",
113-
"description": "Whether to automatically check for new updates",
114-
"default": true
110+
"type": "string",
111+
"description": "Specify which Zig version should be installed. Takes priority over a `.zigversion` file or a `build.zig.zon` with `minimum_zig_version`."
115112
},
116113
"zig.formattingProvider": {
117114
"scope": "resource",
@@ -150,16 +147,21 @@
150147
],
151148
"default": "off"
152149
},
153-
"zig.zls.checkForUpdate": {
150+
"zig.zls.enabled": {
154151
"scope": "resource",
155-
"type": "boolean",
156-
"description": "Whether to automatically check for new updates",
157-
"default": true
152+
"type": "string",
153+
"description": "Whether to enable the optional ZLS Language Server",
154+
"enum": [
155+
"ask",
156+
"off",
157+
"on"
158+
],
159+
"default": "ask"
158160
},
159161
"zig.zls.path": {
160162
"scope": "machine-overridable",
161163
"type": "string",
162-
"description": "Path to `zls` executable. Example: `C:/zls/zig-cache/bin/zls.exe`. The string \"zls\" means lookup ZLS in PATH.",
164+
"description": "Set a custom path to the `zls` executable. Example: `C:/zls/zig-cache/bin/zls.exe`. The string \"zls\" means lookup ZLS in PATH.",
163165
"format": "path"
164166
},
165167
"zig.zls.enableSnippets": {
@@ -336,28 +338,18 @@
336338
"category": "Zig Setup"
337339
},
338340
{
339-
"command": "zig.update",
340-
"title": "Check for Zig Updates",
341-
"category": "Zig Setup"
342-
},
343-
{
344-
"command": "zig.zls.install",
345-
"title": "Install Server",
341+
"command": "zig.zls.enable",
342+
"title": "Enable Language Server",
346343
"category": "Zig Language Server"
347344
},
348345
{
349346
"command": "zig.zls.startRestart",
350-
"title": "Start / Restart Server",
347+
"title": "Start / Restart Language Server",
351348
"category": "Zig Language Server"
352349
},
353350
{
354351
"command": "zig.zls.stop",
355-
"title": "Stop Server",
356-
"category": "Zig Language Server"
357-
},
358-
{
359-
"command": "zig.zls.update",
360-
"title": "Check for Server Updates",
352+
"title": "Stop Language Server",
361353
"category": "Zig Language Server"
362354
}
363355
],
@@ -379,23 +371,25 @@
379371
"lint": "eslint ."
380372
},
381373
"devDependencies": {
374+
"@types/libsodium-wrappers": "^0.7.14",
382375
"@types/lodash-es": "^4.17.12",
383376
"@types/mocha": "^2.2.48",
384377
"@types/node": "^18.0.0",
385378
"@types/vscode": "^1.80.0",
386379
"@types/which": "^2.0.1",
380+
"@vscode/test-electron": "^2.3.9",
387381
"@vscode/vsce": "^2.24.0",
388382
"esbuild": "^0.12.1",
389383
"eslint": "^8.57.0",
390384
"eslint-config-prettier": "^9.1.0",
391385
"prettier": "3.2.5",
392386
"typescript": "^5.4.3",
393-
"typescript-eslint": "^7.4.0",
394-
"@vscode/test-electron": "^2.3.9"
387+
"typescript-eslint": "^7.4.0"
395388
},
396389
"dependencies": {
397390
"axios": "^1.7.4",
398391
"camelcase": "^7.0.1",
392+
"libsodium-wrappers": "^0.7.15",
399393
"lodash-es": "^4.17.21",
400394
"semver": "^7.5.2",
401395
"vscode-languageclient": "8.0.2-next.5",

src/extension.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import vscode from "vscode";
22

33
import { activate as activateZls, deactivate as deactivateZls } from "./zls";
4-
import ZigCompilerProvider from "./zigCompilerProvider";
4+
import { deactivate as deactivateSetupZig, setupZig } from "./zigSetup";
5+
import ZigDiagnosticsProvider from "./zigDiagnosticsProvider";
56
import ZigMainCodeLensProvider from "./zigMainCodeLens";
67
import ZigTestRunnerProvider from "./zigTestRunnerProvider";
78
import { registerDocumentFormatting } from "./zigFormat";
8-
import { setupZig } from "./zigSetup";
99

1010
export async function activate(context: vscode.ExtensionContext) {
1111
await setupZig(context).finally(() => {
12-
const compiler = new ZigCompilerProvider();
12+
const compiler = new ZigDiagnosticsProvider();
1313
compiler.activate(context.subscriptions);
1414

1515
context.subscriptions.push(registerDocumentFormatting());
@@ -31,4 +31,5 @@ export async function activate(context: vscode.ExtensionContext) {
3131

3232
export async function deactivate() {
3333
await deactivateZls();
34+
await deactivateSetupZig();
3435
}

src/minisign.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/**
2+
* Ported from: https://github.com/mlugg/setup-zig/blob/main/main.js (MIT)
3+
*/
4+
5+
import sodium from "libsodium-wrappers";
6+
7+
export interface Key {
8+
id: Buffer;
9+
key: Buffer;
10+
}
11+
12+
// Parse a minisign key represented as a base64 string.
13+
// Throws exceptions on invalid keys.
14+
export function parseKey(keyString: string): Key {
15+
const keyInfo = Buffer.from(keyString, "base64");
16+
17+
const id = keyInfo.subarray(2, 10);
18+
const key = keyInfo.subarray(10);
19+
20+
if (key.byteLength !== sodium.crypto_sign_PUBLICKEYBYTES) {
21+
throw new Error("invalid public key given");
22+
}
23+
24+
return {
25+
id: id,
26+
key: key,
27+
};
28+
}
29+
30+
export interface Signature {
31+
algorithm: Buffer;
32+
keyID: Buffer;
33+
signature: Buffer;
34+
}
35+
36+
// Parse a buffer containing the contents of a minisign signature file.
37+
// Throws exceptions on invalid signature files.
38+
export function parseSignature(sigBuf: Buffer): Signature {
39+
const untrustedHeader = Buffer.from("untrusted comment: ");
40+
41+
// Validate untrusted comment header, and skip
42+
if (!sigBuf.subarray(0, untrustedHeader.byteLength).equals(untrustedHeader)) {
43+
throw new Error("file format not recognised");
44+
}
45+
sigBuf = sigBuf.subarray(untrustedHeader.byteLength);
46+
47+
// Skip untrusted comment
48+
sigBuf = sigBuf.subarray(sigBuf.indexOf("\n") + 1);
49+
50+
// Read and skip signature info
51+
const sigInfoEnd = sigBuf.indexOf("\n");
52+
const sigInfo = Buffer.from(sigBuf.subarray(0, sigInfoEnd).toString(), "base64");
53+
sigBuf = sigBuf.subarray(sigInfoEnd + 1);
54+
55+
// Extract components of signature info
56+
const algorithm = sigInfo.subarray(0, 2);
57+
const keyID = sigInfo.subarray(2, 10);
58+
const signature = sigInfo.subarray(10);
59+
60+
// We don't look at the trusted comment or global signature, so we're done.
61+
62+
return {
63+
algorithm: algorithm,
64+
keyID: keyID,
65+
signature: signature,
66+
};
67+
}
68+
69+
// Given a parsed key, parsed signature file, and raw file content, verifies the
70+
// signature. Does not throw. Returns 'true' if the signature is valid for this
71+
// file, 'false' otherwise.
72+
export function verifySignature(pubkey: Key, signature: Signature, fileContent: Buffer) {
73+
let signedContent;
74+
if (signature.algorithm.equals(Buffer.from("ED"))) {
75+
signedContent = sodium.crypto_generichash(sodium.crypto_generichash_BYTES_MAX, fileContent);
76+
} else {
77+
signedContent = fileContent;
78+
}
79+
80+
if (!signature.keyID.equals(pubkey.id)) {
81+
return false;
82+
}
83+
84+
if (!sodium.crypto_sign_verify_detached(signature.signature, signedContent, pubkey.key)) {
85+
return false;
86+
}
87+
88+
// Since we don't use the trusted comment, we don't bother verifying the global signature.
89+
// If we were to start using the trusted comment for any purpose, we must add this.
90+
91+
return true;
92+
}

0 commit comments

Comments
 (0)