diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-02-16 11:54:38 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-02-16 11:54:38 +0000 |
commit | a15c8739b9a6da223e1f3a6ff6aa868913c0dbf4 (patch) | |
tree | 5694d395b08c416bf60d7206e0380a3859cfe1e2 /editors | |
parent | 617b5b3b31cf0b461829810640e28a9090a5b957 (diff) | |
parent | 325eba58a286c147f19dada5f205aa9e2ec6f391 (diff) |
Merge #3162
3162: Feature: vscode always downloads only the matching ra_lsp_server version r=matklad a=Veetaha
I tried to separate logically connected changes into separate commits, so enjoy!
Now TypeScript extension saves installed binary version in global state and always checks that the installed binary version equals the version of the TypeScript extension itself (to prevent version drifts).
Also, changed `fetchLatestArtifactReleaseInfo()` to `fetchArtifactReleaseInfo()` that takes an optional release tag (when not specified fetches the latest release). The version without a release tag will be useful in the future when adding auto-checking for updates.
I decided not to do `Download latest language server` command (I have stated the rationale for this in #3073) and let the extension itself decide which version of the binary it wants. This way the users will be able to get the latest `ra_lsp_server` binary after the approaching 2020-02-17 release, without having to manually delete the outdated one from `~/.config/Code/User/globalStorage/matklad.rust-analyzer`!
Closes #3073
Co-authored-by: Veetaha <[email protected]>
Diffstat (limited to 'editors')
-rw-r--r-- | editors/code/package.json | 2 | ||||
-rw-r--r-- | editors/code/src/client.ts | 2 | ||||
-rw-r--r-- | editors/code/src/config.ts | 17 | ||||
-rw-r--r-- | editors/code/src/ctx.ts | 4 | ||||
-rw-r--r-- | editors/code/src/installation/download_artifact.ts | 58 | ||||
-rw-r--r-- | editors/code/src/installation/fetch_artifact_release_info.ts (renamed from editors/code/src/installation/fetch_latest_artifact_release_info.ts) | 16 | ||||
-rw-r--r-- | editors/code/src/installation/interfaces.ts | 13 | ||||
-rw-r--r-- | editors/code/src/installation/server.ts | 168 |
8 files changed, 176 insertions, 104 deletions
diff --git a/editors/code/package.json b/editors/code/package.json index a607c2148..96b8e9eb0 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -6,7 +6,7 @@ | |||
6 | "private": true, | 6 | "private": true, |
7 | "icon": "icon.png", | 7 | "icon": "icon.png", |
8 | "//": "The real version is in release.yaml, this one just needs to be bigger", | 8 | "//": "The real version is in release.yaml, this one just needs to be bigger", |
9 | "version": "0.2.0-dev", | 9 | "version": "0.2.20200211-dev", |
10 | "publisher": "matklad", | 10 | "publisher": "matklad", |
11 | "repository": { | 11 | "repository": { |
12 | "url": "https://github.com/rust-analyzer/rust-analyzer.git", | 12 | "url": "https://github.com/rust-analyzer/rust-analyzer.git", |
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 12c97be2f..efef820ab 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts | |||
@@ -11,7 +11,7 @@ export async function createClient(config: Config): Promise<null | lc.LanguageCl | |||
11 | // It might be a good idea to test if the uri points to a file. | 11 | // It might be a good idea to test if the uri points to a file. |
12 | const workspaceFolderPath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ?? '.'; | 12 | const workspaceFolderPath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ?? '.'; |
13 | 13 | ||
14 | const serverPath = await ensureServerBinary(config.serverBinarySource); | 14 | const serverPath = await ensureServerBinary(config.serverSource); |
15 | if (!serverPath) return null; | 15 | if (!serverPath) return null; |
16 | 16 | ||
17 | const run: lc.Executable = { | 17 | const run: lc.Executable = { |
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 8c033052b..70cb0a612 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts | |||
@@ -24,6 +24,19 @@ export class Config { | |||
24 | ] | 24 | ] |
25 | .map(opt => `${Config.rootSection}.${opt}`); | 25 | .map(opt => `${Config.rootSection}.${opt}`); |
26 | 26 | ||
27 | private static readonly extensionVersion: string = (() => { | ||
28 | const packageJsonVersion = vscode | ||
29 | .extensions | ||
30 | .getExtension("matklad.rust-analyzer")! | ||
31 | .packageJSON | ||
32 | .version as string; // n.n.YYYYMMDD | ||
33 | |||
34 | const realVersionRegexp = /^\d+\.\d+\.(\d{4})(\d{2})(\d{2})/; | ||
35 | const [, yyyy, mm, dd] = packageJsonVersion.match(realVersionRegexp)!; | ||
36 | |||
37 | return `${yyyy}-${mm}-${dd}`; | ||
38 | })(); | ||
39 | |||
27 | private cfg!: vscode.WorkspaceConfiguration; | 40 | private cfg!: vscode.WorkspaceConfiguration; |
28 | 41 | ||
29 | constructor(private readonly ctx: vscode.ExtensionContext) { | 42 | constructor(private readonly ctx: vscode.ExtensionContext) { |
@@ -98,7 +111,7 @@ export class Config { | |||
98 | } | 111 | } |
99 | } | 112 | } |
100 | 113 | ||
101 | get serverBinarySource(): null | BinarySource { | 114 | get serverSource(): null | BinarySource { |
102 | const serverPath = RA_LSP_DEBUG ?? this.cfg.get<null | string>("raLspServerPath"); | 115 | const serverPath = RA_LSP_DEBUG ?? this.cfg.get<null | string>("raLspServerPath"); |
103 | 116 | ||
104 | if (serverPath) { | 117 | if (serverPath) { |
@@ -116,6 +129,8 @@ export class Config { | |||
116 | type: BinarySource.Type.GithubRelease, | 129 | type: BinarySource.Type.GithubRelease, |
117 | dir: this.ctx.globalStoragePath, | 130 | dir: this.ctx.globalStoragePath, |
118 | file: prebuiltBinaryName, | 131 | file: prebuiltBinaryName, |
132 | storage: this.ctx.globalState, | ||
133 | version: Config.extensionVersion, | ||
119 | repo: { | 134 | repo: { |
120 | name: "rust-analyzer", | 135 | name: "rust-analyzer", |
121 | owner: "rust-analyzer", | 136 | owner: "rust-analyzer", |
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index 70042a479..9fcf2ec38 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts | |||
@@ -60,6 +60,10 @@ export class Ctx { | |||
60 | this.pushCleanup(d); | 60 | this.pushCleanup(d); |
61 | } | 61 | } |
62 | 62 | ||
63 | get globalState(): vscode.Memento { | ||
64 | return this.extCtx.globalState; | ||
65 | } | ||
66 | |||
63 | get subscriptions(): Disposable[] { | 67 | get subscriptions(): Disposable[] { |
64 | return this.extCtx.subscriptions; | 68 | return this.extCtx.subscriptions; |
65 | } | 69 | } |
diff --git a/editors/code/src/installation/download_artifact.ts b/editors/code/src/installation/download_artifact.ts new file mode 100644 index 000000000..de655f8f4 --- /dev/null +++ b/editors/code/src/installation/download_artifact.ts | |||
@@ -0,0 +1,58 @@ | |||
1 | import * as vscode from "vscode"; | ||
2 | import * as path from "path"; | ||
3 | import { promises as fs } from "fs"; | ||
4 | import { strict as assert } from "assert"; | ||
5 | |||
6 | import { ArtifactReleaseInfo } from "./interfaces"; | ||
7 | import { downloadFile } from "./download_file"; | ||
8 | import { throttle } from "throttle-debounce"; | ||
9 | |||
10 | /** | ||
11 | * Downloads artifact from given `downloadUrl`. | ||
12 | * Creates `installationDir` if it is not yet created and put the artifact under | ||
13 | * `artifactFileName`. | ||
14 | * Displays info about the download progress in an info message printing the name | ||
15 | * of the artifact as `displayName`. | ||
16 | */ | ||
17 | export async function downloadArtifact( | ||
18 | {downloadUrl, releaseName}: ArtifactReleaseInfo, | ||
19 | artifactFileName: string, | ||
20 | installationDir: string, | ||
21 | displayName: string, | ||
22 | ) { | ||
23 | await fs.mkdir(installationDir).catch(err => assert.strictEqual( | ||
24 | err?.code, | ||
25 | "EEXIST", | ||
26 | `Couldn't create directory "${installationDir}" to download `+ | ||
27 | `${artifactFileName} artifact: ${err.message}` | ||
28 | )); | ||
29 | |||
30 | const installationPath = path.join(installationDir, artifactFileName); | ||
31 | |||
32 | console.time(`Downloading ${artifactFileName}`); | ||
33 | await vscode.window.withProgress( | ||
34 | { | ||
35 | location: vscode.ProgressLocation.Notification, | ||
36 | cancellable: false, // FIXME: add support for canceling download? | ||
37 | title: `Downloading ${displayName} (${releaseName})` | ||
38 | }, | ||
39 | async (progress, _cancellationToken) => { | ||
40 | let lastPrecentage = 0; | ||
41 | const filePermissions = 0o755; // (rwx, r_x, r_x) | ||
42 | await downloadFile(downloadUrl, installationPath, filePermissions, throttle( | ||
43 | 200, | ||
44 | /* noTrailing: */ true, | ||
45 | (readBytes, totalBytes) => { | ||
46 | const newPercentage = (readBytes / totalBytes) * 100; | ||
47 | progress.report({ | ||
48 | message: newPercentage.toFixed(0) + "%", | ||
49 | increment: newPercentage - lastPrecentage | ||
50 | }); | ||
51 | |||
52 | lastPrecentage = newPercentage; | ||
53 | }) | ||
54 | ); | ||
55 | } | ||
56 | ); | ||
57 | console.timeEnd(`Downloading ${artifactFileName}`); | ||
58 | } | ||
diff --git a/editors/code/src/installation/fetch_latest_artifact_release_info.ts b/editors/code/src/installation/fetch_artifact_release_info.ts index 29ee029a7..7d497057a 100644 --- a/editors/code/src/installation/fetch_latest_artifact_release_info.ts +++ b/editors/code/src/installation/fetch_artifact_release_info.ts | |||
@@ -3,24 +3,30 @@ import { GithubRepo, ArtifactReleaseInfo } from "./interfaces"; | |||
3 | 3 | ||
4 | const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; | 4 | const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; |
5 | 5 | ||
6 | |||
6 | /** | 7 | /** |
7 | * Fetches the latest release from GitHub `repo` and returns metadata about | 8 | * Fetches the release with `releaseTag` (or just latest release when not specified) |
8 | * `artifactFileName` shipped with this release or `null` if no such artifact was published. | 9 | * from GitHub `repo` and returns metadata about `artifactFileName` shipped with |
10 | * this release or `null` if no such artifact was published. | ||
9 | */ | 11 | */ |
10 | export async function fetchLatestArtifactReleaseInfo( | 12 | export async function fetchArtifactReleaseInfo( |
11 | repo: GithubRepo, artifactFileName: string | 13 | repo: GithubRepo, artifactFileName: string, releaseTag?: string |
12 | ): Promise<null | ArtifactReleaseInfo> { | 14 | ): Promise<null | ArtifactReleaseInfo> { |
13 | 15 | ||
14 | const repoOwner = encodeURIComponent(repo.owner); | 16 | const repoOwner = encodeURIComponent(repo.owner); |
15 | const repoName = encodeURIComponent(repo.name); | 17 | const repoName = encodeURIComponent(repo.name); |
16 | 18 | ||
17 | const apiEndpointPath = `/repos/${repoOwner}/${repoName}/releases/latest`; | 19 | const apiEndpointPath = releaseTag |
20 | ? `/repos/${repoOwner}/${repoName}/releases/tags/${releaseTag}` | ||
21 | : `/repos/${repoOwner}/${repoName}/releases/latest`; | ||
22 | |||
18 | const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath; | 23 | const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath; |
19 | 24 | ||
20 | // We skip runtime type checks for simplicity (here we cast from `any` to `GithubRelease`) | 25 | // We skip runtime type checks for simplicity (here we cast from `any` to `GithubRelease`) |
21 | 26 | ||
22 | console.log("Issuing request for released artifacts metadata to", requestUrl); | 27 | console.log("Issuing request for released artifacts metadata to", requestUrl); |
23 | 28 | ||
29 | // FIXME: handle non-ok response | ||
24 | const response: GithubRelease = await fetch(requestUrl, { | 30 | const response: GithubRelease = await fetch(requestUrl, { |
25 | headers: { Accept: "application/vnd.github.v3+json" } | 31 | headers: { Accept: "application/vnd.github.v3+json" } |
26 | }) | 32 | }) |
diff --git a/editors/code/src/installation/interfaces.ts b/editors/code/src/installation/interfaces.ts index 93ea577d4..e40839e4b 100644 --- a/editors/code/src/installation/interfaces.ts +++ b/editors/code/src/installation/interfaces.ts | |||
@@ -1,3 +1,5 @@ | |||
1 | import * as vscode from "vscode"; | ||
2 | |||
1 | export interface GithubRepo { | 3 | export interface GithubRepo { |
2 | name: string; | 4 | name: string; |
3 | owner: string; | 5 | owner: string; |
@@ -50,6 +52,17 @@ export namespace BinarySource { | |||
50 | * and in local `.dir`. | 52 | * and in local `.dir`. |
51 | */ | 53 | */ |
52 | file: string; | 54 | file: string; |
55 | |||
56 | /** | ||
57 | * Tag of github release that denotes a version required by this extension. | ||
58 | */ | ||
59 | version: string; | ||
60 | |||
61 | /** | ||
62 | * Object that provides `get()/update()` operations to store metadata | ||
63 | * about the actual binary, e.g. its actual version. | ||
64 | */ | ||
65 | storage: vscode.Memento; | ||
53 | } | 66 | } |
54 | 67 | ||
55 | } | 68 | } |
diff --git a/editors/code/src/installation/server.ts b/editors/code/src/installation/server.ts index 406e2299c..80cb719e3 100644 --- a/editors/code/src/installation/server.ts +++ b/editors/code/src/installation/server.ts | |||
@@ -1,63 +1,15 @@ | |||
1 | import * as vscode from "vscode"; | 1 | import * as vscode from "vscode"; |
2 | import * as path from "path"; | 2 | import * as path from "path"; |
3 | import { strict as assert } from "assert"; | 3 | import { strict as assert } from "assert"; |
4 | import { promises as fs } from "fs"; | ||
5 | import { promises as dns } from "dns"; | 4 | import { promises as dns } from "dns"; |
6 | import { spawnSync } from "child_process"; | 5 | import { spawnSync } from "child_process"; |
7 | import { throttle } from "throttle-debounce"; | ||
8 | 6 | ||
9 | import { BinarySource } from "./interfaces"; | 7 | import { BinarySource } from "./interfaces"; |
10 | import { fetchLatestArtifactReleaseInfo } from "./fetch_latest_artifact_release_info"; | 8 | import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info"; |
11 | import { downloadFile } from "./download_file"; | 9 | import { downloadArtifact } from "./download_artifact"; |
12 | |||
13 | export async function downloadLatestServer( | ||
14 | {file: artifactFileName, dir: installationDir, repo}: BinarySource.GithubRelease | ||
15 | ) { | ||
16 | const { releaseName, downloadUrl } = (await fetchLatestArtifactReleaseInfo( | ||
17 | repo, artifactFileName | ||
18 | ))!; | ||
19 | |||
20 | await fs.mkdir(installationDir).catch(err => assert.strictEqual( | ||
21 | err?.code, | ||
22 | "EEXIST", | ||
23 | `Couldn't create directory "${installationDir}" to download `+ | ||
24 | `language server binary: ${err.message}` | ||
25 | )); | ||
26 | |||
27 | const installationPath = path.join(installationDir, artifactFileName); | ||
28 | |||
29 | console.time("Downloading ra_lsp_server"); | ||
30 | await vscode.window.withProgress( | ||
31 | { | ||
32 | location: vscode.ProgressLocation.Notification, | ||
33 | cancellable: false, // FIXME: add support for canceling download? | ||
34 | title: `Downloading language server (${releaseName})` | ||
35 | }, | ||
36 | async (progress, _cancellationToken) => { | ||
37 | let lastPrecentage = 0; | ||
38 | const filePermissions = 0o755; // (rwx, r_x, r_x) | ||
39 | await downloadFile(downloadUrl, installationPath, filePermissions, throttle( | ||
40 | 200, | ||
41 | /* noTrailing: */ true, | ||
42 | (readBytes, totalBytes) => { | ||
43 | const newPercentage = (readBytes / totalBytes) * 100; | ||
44 | progress.report({ | ||
45 | message: newPercentage.toFixed(0) + "%", | ||
46 | increment: newPercentage - lastPrecentage | ||
47 | }); | ||
48 | |||
49 | lastPrecentage = newPercentage; | ||
50 | }) | ||
51 | ); | ||
52 | } | ||
53 | ); | ||
54 | console.timeEnd("Downloading ra_lsp_server"); | ||
55 | } | ||
56 | export async function ensureServerBinary( | ||
57 | serverSource: null | BinarySource | ||
58 | ): Promise<null | string> { | ||
59 | 10 | ||
60 | if (!serverSource) { | 11 | export async function ensureServerBinary(source: null | BinarySource): Promise<null | string> { |
12 | if (!source) { | ||
61 | vscode.window.showErrorMessage( | 13 | vscode.window.showErrorMessage( |
62 | "Unfortunately we don't ship binaries for your platform yet. " + | 14 | "Unfortunately we don't ship binaries for your platform yet. " + |
63 | "You need to manually clone rust-analyzer repository and " + | 15 | "You need to manually clone rust-analyzer repository and " + |
@@ -69,80 +21,104 @@ export async function ensureServerBinary( | |||
69 | return null; | 21 | return null; |
70 | } | 22 | } |
71 | 23 | ||
72 | switch (serverSource.type) { | 24 | switch (source.type) { |
73 | case BinarySource.Type.ExplicitPath: { | 25 | case BinarySource.Type.ExplicitPath: { |
74 | if (isBinaryAvailable(serverSource.path)) { | 26 | if (isBinaryAvailable(source.path)) { |
75 | return serverSource.path; | 27 | return source.path; |
76 | } | 28 | } |
77 | 29 | ||
78 | vscode.window.showErrorMessage( | 30 | vscode.window.showErrorMessage( |
79 | `Unable to run ${serverSource.path} binary. ` + | 31 | `Unable to run ${source.path} binary. ` + |
80 | `To use the pre-built language server, set "rust-analyzer.raLspServerPath" ` + | 32 | `To use the pre-built language server, set "rust-analyzer.raLspServerPath" ` + |
81 | "value to `null` or remove it from the settings to use it by default." | 33 | "value to `null` or remove it from the settings to use it by default." |
82 | ); | 34 | ); |
83 | return null; | 35 | return null; |
84 | } | 36 | } |
85 | case BinarySource.Type.GithubRelease: { | 37 | case BinarySource.Type.GithubRelease: { |
86 | const prebuiltBinaryPath = path.join(serverSource.dir, serverSource.file); | 38 | const prebuiltBinaryPath = path.join(source.dir, source.file); |
39 | |||
40 | const installedVersion: null | string = getServerVersion(source.storage); | ||
41 | const requiredVersion: string = source.version; | ||
87 | 42 | ||
88 | if (isBinaryAvailable(prebuiltBinaryPath)) { | 43 | console.log("Installed version:", installedVersion, "required:", requiredVersion); |
44 | |||
45 | if (isBinaryAvailable(prebuiltBinaryPath) && installedVersion == requiredVersion) { | ||
46 | // FIXME: check for new releases and notify the user to update if possible | ||
89 | return prebuiltBinaryPath; | 47 | return prebuiltBinaryPath; |
90 | } | 48 | } |
91 | 49 | ||
92 | const userResponse = await vscode.window.showInformationMessage( | 50 | const userResponse = await vscode.window.showInformationMessage( |
93 | "Language server binary for rust-analyzer was not found. " + | 51 | `Language server version ${source.version} for rust-analyzer is not installed. ` + |
94 | "Do you want to download it now?", | 52 | "Do you want to download it now?", |
95 | "Download now", "Cancel" | 53 | "Download now", "Cancel" |
96 | ); | 54 | ); |
97 | if (userResponse !== "Download now") return null; | 55 | if (userResponse !== "Download now") return null; |
98 | 56 | ||
99 | try { | 57 | if (!await downloadServer(source)) return null; |
100 | await downloadLatestServer(serverSource); | ||
101 | } catch (err) { | ||
102 | vscode.window.showErrorMessage( | ||
103 | `Failed to download language server from ${serverSource.repo.name} ` + | ||
104 | `GitHub repository: ${err.message}` | ||
105 | ); | ||
106 | 58 | ||
107 | console.error(err); | 59 | return prebuiltBinaryPath; |
60 | } | ||
61 | } | ||
62 | } | ||
108 | 63 | ||
109 | dns.resolve('example.com').then( | 64 | async function downloadServer(source: BinarySource.GithubRelease): Promise<boolean> { |
110 | addrs => console.log("DNS resolution for example.com was successful", addrs), | 65 | try { |
111 | err => { | 66 | const releaseInfo = (await fetchArtifactReleaseInfo(source.repo, source.file, source.version))!; |
112 | console.error( | 67 | |
113 | "DNS resolution for example.com failed, " + | 68 | await downloadArtifact(releaseInfo, source.file, source.dir, "language server"); |
114 | "there might be an issue with Internet availability" | 69 | await setServerVersion(source.storage, releaseInfo.releaseName); |
115 | ); | 70 | } catch (err) { |
116 | console.error(err); | 71 | vscode.window.showErrorMessage( |
117 | } | 72 | `Failed to download language server from ${source.repo.name} ` + |
118 | ); | 73 | `GitHub repository: ${err.message}` |
74 | ); | ||
75 | |||
76 | console.error(err); | ||
119 | 77 | ||
120 | return null; | 78 | dns.resolve('example.com').then( |
79 | addrs => console.log("DNS resolution for example.com was successful", addrs), | ||
80 | err => { | ||
81 | console.error( | ||
82 | "DNS resolution for example.com failed, " + | ||
83 | "there might be an issue with Internet availability" | ||
84 | ); | ||
85 | console.error(err); | ||
121 | } | 86 | } |
87 | ); | ||
88 | return false; | ||
89 | } | ||
122 | 90 | ||
123 | if (!isBinaryAvailable(prebuiltBinaryPath)) assert(false, | 91 | if (!isBinaryAvailable(path.join(source.dir, source.file))) assert(false, |
124 | `Downloaded language server binary is not functional.` + | 92 | `Downloaded language server binary is not functional.` + |
125 | `Downloaded from: ${JSON.stringify(serverSource)}` | 93 | `Downloaded from: ${JSON.stringify(source, null, 4)}` |
126 | ); | 94 | ); |
127 | 95 | ||
96 | vscode.window.showInformationMessage( | ||
97 | "Rust analyzer language server was successfully installed 🦀" | ||
98 | ); | ||
128 | 99 | ||
129 | vscode.window.showInformationMessage( | 100 | return true; |
130 | "Rust analyzer language server was successfully installed 🦀" | 101 | } |
131 | ); | ||
132 | 102 | ||
133 | return prebuiltBinaryPath; | 103 | function isBinaryAvailable(binaryPath: string): boolean { |
134 | } | 104 | const res = spawnSync(binaryPath, ["--version"]); |
135 | } | ||
136 | 105 | ||
137 | function isBinaryAvailable(binaryPath: string) { | 106 | // ACHTUNG! `res` type declaration is inherently wrong, see |
138 | const res = spawnSync(binaryPath, ["--version"]); | 107 | // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/42221 |
139 | 108 | ||
140 | // ACHTUNG! `res` type declaration is inherently wrong, see | 109 | console.log("Checked binary availablity via --version", res); |
141 | // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/42221 | 110 | console.log(binaryPath, "--version output:", res.output?.map(String)); |
142 | 111 | ||
143 | console.log("Checked binary availablity via --version", res); | 112 | return res.status === 0; |
144 | console.log(binaryPath, "--version output:", res.output?.map(String)); | 113 | } |
145 | 114 | ||
146 | return res.status === 0; | 115 | function getServerVersion(storage: vscode.Memento): null | string { |
147 | } | 116 | const version = storage.get<null | string>("server-version", null); |
117 | console.log("Get server-version:", version); | ||
118 | return version; | ||
119 | } | ||
120 | |||
121 | async function setServerVersion(storage: vscode.Memento, version: string): Promise<void> { | ||
122 | console.log("Set server-version:", version); | ||
123 | await storage.update("server-version", version.toString()); | ||
148 | } | 124 | } |