]> git.lizzy.rs Git - rust.git/commitdiff
vscode: amend server installation logic to account for nightlies
authorVeetaha <gerzoh1@gmail.com>
Mon, 9 Mar 2020 17:57:55 +0000 (19:57 +0200)
committerVeetaha <gerzoh1@gmail.com>
Sat, 14 Mar 2020 00:01:46 +0000 (02:01 +0200)
editors/code/src/commands/server_version.ts
editors/code/src/installation/server.ts
editors/code/src/main.ts

index 421301b42cdfcd570cd83f0a587e7370d0aa8621..c4d84b4439eec89f906f7f0a3b155b1d7e52f502 100644 (file)
@@ -5,7 +5,7 @@ import { spawnSync } from 'child_process';
 
 export function serverVersion(ctx: Ctx): Cmd {
     return async () => {
-        const binaryPath = await ensureServerBinary(ctx.config.serverSource);
+        const binaryPath = await ensureServerBinary(ctx.config);
 
         if (binaryPath == null) {
             throw new Error(
@@ -18,4 +18,3 @@ export function serverVersion(ctx: Ctx): Cmd {
         vscode.window.showInformationMessage('rust-analyzer version : ' + version);
     };
 }
-
index ef1c45ff65906244d79cb9018eb78b950260f13e..345f30d4763d1abf88c2c7048843f0ddbb51b215 100644 (file)
@@ -1,14 +1,16 @@
 import * as vscode from "vscode";
 import * as path from "path";
-import { promises as dns } from "dns";
 import { spawnSync } from "child_process";
 
 import { ArtifactSource } from "./interfaces";
 import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info";
-import { downloadArtifact } from "./download_artifact";
+import { downloadArtifactWithProgressUi } from "./downloads";
 import { log, assert } from "../util";
+import { Config, NIGHTLY_TAG } from "../config";
+
+export async function ensureServerBinary(config: Config): Promise<null | string> {
+    const source = config.serverSource;
 
-export async function ensureServerBinary(source: null | ArtifactSource): Promise<null | string> {
     if (!source) {
         vscode.window.showErrorMessage(
             "Unfortunately we don't ship binaries for your platform yet. " +
@@ -35,18 +37,11 @@ export async function ensureServerBinary(source: null | ArtifactSource): Promise
             return null;
         }
         case ArtifactSource.Type.GithubRelease: {
-            const prebuiltBinaryPath = path.join(source.dir, source.file);
-
-            const installedVersion: null | string = getServerVersion(source.storage);
-            const requiredVersion: string = source.tag;
-
-            log.debug("Installed version:", installedVersion, "required:", requiredVersion);
-
-            if (isBinaryAvailable(prebuiltBinaryPath) && installedVersion === requiredVersion) {
-                return prebuiltBinaryPath;
+            if (!shouldDownloadServer(source, config)) {
+                return path.join(source.dir, source.file);
             }
 
-            if (source.askBeforeDownload) {
+            if (config.askBeforeDownload) {
                 const userResponse = await vscode.window.showInformationMessage(
                     `Language server version ${source.tag} for rust-analyzer is not installed. ` +
                     "Do you want to download it now?",
@@ -55,38 +50,53 @@ export async function ensureServerBinary(source: null | ArtifactSource): Promise
                 if (userResponse !== "Download now") return null;
             }
 
-            if (!await downloadServer(source)) return null;
-
-            return prebuiltBinaryPath;
+            return await downloadServer(source, config);
         }
     }
 }
 
-async function downloadServer(source: ArtifactSource.GithubRelease): Promise<boolean> {
+function shouldDownloadServer(
+    source: ArtifactSource.GithubRelease,
+    config: Config
+): boolean {
+    if (!isBinaryAvailable(path.join(source.dir, source.file))) return true;
+
+    const installed = {
+        tag: config.serverReleaseTag.get(),
+        date: config.serverReleaseDate.get()
+    };
+    const required = {
+        tag: source.tag,
+        date: config.installedNightlyExtensionReleaseDate.get()
+    };
+
+    log.debug("Installed server:", installed, "required:", required);
+
+    if (required.tag !== NIGHTLY_TAG || installed.tag !== NIGHTLY_TAG) {
+        return required.tag !== installed.tag;
+    }
+
+    assert(required.date !== null, "Extension release date should have been saved during its installation");
+    assert(installed.date !== null, "Server release date should have been saved during its installation");
+
+    return installed.date.getTime() !== required.date.getTime();
+}
+
+async function downloadServer(
+    source: ArtifactSource.GithubRelease,
+    config: Config,
+): Promise<null | string> {
     try {
         const releaseInfo = await fetchArtifactReleaseInfo(source.repo, source.file, source.tag);
 
-        await downloadArtifact(releaseInfo, source.file, source.dir, "language server");
-        await setServerVersion(source.storage, releaseInfo.releaseName);
+        await downloadArtifactWithProgressUi(releaseInfo, source.file, source.dir, "language server");
+        await Promise.all([
+            config.serverReleaseTag.set(releaseInfo.releaseName),
+            config.serverReleaseDate.set(releaseInfo.releaseDate)
+        ]);
     } catch (err) {
-        vscode.window.showErrorMessage(
-            `Failed to download language server from ${source.repo.name} ` +
-            `GitHub repository: ${err.message}`
-        );
-
-        log.error(err);
-
-        dns.resolve('example.com').then(
-            addrs => log.debug("DNS resolution for example.com was successful", addrs),
-            err => {
-                log.error(
-                    "DNS resolution for example.com failed, " +
-                    "there might be an issue with Internet availability"
-                );
-                log.error(err);
-            }
-        );
-        return false;
+        log.downloadError(err, "language server", source.repo.name);
+        return null;
     }
 
     const binaryPath = path.join(source.dir, source.file);
@@ -101,7 +111,7 @@ async function downloadServer(source: ArtifactSource.GithubRelease): Promise<boo
         "Rust analyzer language server was successfully installed ðŸ¦€"
     );
 
-    return true;
+    return binaryPath;
 }
 
 function isBinaryAvailable(binaryPath: string): boolean {
@@ -115,14 +125,3 @@ function isBinaryAvailable(binaryPath: string): boolean {
 
     return res.status === 0;
 }
-
-function getServerVersion(storage: vscode.Memento): null | string {
-    const version = storage.get<null | string>("server-version", null);
-    log.debug("Get server-version:", version);
-    return version;
-}
-
-async function setServerVersion(storage: vscode.Memento, version: string): Promise<void> {
-    log.debug("Set server-version:", version);
-    await storage.update("server-version", version.toString());
-}
index ecf53cf775fed63580b5d31accdf91f3fca274d7..ee67c750c1b13c6f6362e499f57760694a0df3f5 100644 (file)
@@ -8,6 +8,7 @@ import { activateHighlighting } from './highlighting';
 import { ensureServerBinary } from './installation/server';
 import { Config } from './config';
 import { log } from './util';
+import { ensureProperExtensionVersion } from './installation/extension';
 
 let ctx: Ctx | undefined;
 
@@ -34,7 +35,13 @@ export async function activate(context: vscode.ExtensionContext) {
 
     const config = new Config(context);
 
-    const serverPath = await ensureServerBinary(config.serverSource);
+    vscode.workspace.onDidChangeConfiguration(() => ensureProperExtensionVersion(config));
+
+    // Don't await the user response here, otherwise we will block the lsp server bootstrap
+    void ensureProperExtensionVersion(config);
+
+    const serverPath = await ensureServerBinary(config);
+
     if (serverPath == null) {
         throw new Error(
             "Rust Analyzer Language Server is not available. " +