vscode: care about alwaysDownloadServer option before asking

Also renamed BinarySource to ArtifactSource in anticipation of
nightlies installation that requires downloading
not a binary itself but .vsix package, thus generalized
to `artifact` term
This commit is contained in:
Veetaha
2020-03-08 00:01:48 +02:00
parent 9dae94a78d
commit c29a502e25
3 changed files with 31 additions and 23 deletions

View File

@@ -1,6 +1,6 @@
import * as os from "os"; import * as os from "os";
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { BinarySource } from "./installation/interfaces"; import { ArtifactSource } from "./installation/interfaces";
import { log } from "./util"; import { log } from "./util";
const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG; const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
@@ -114,12 +114,12 @@ export class Config {
} }
} }
get serverSource(): null | BinarySource { get serverSource(): null | ArtifactSource {
const serverPath = RA_LSP_DEBUG ?? this.cfg.get<null | string>("serverPath"); const serverPath = RA_LSP_DEBUG ?? this.cfg.get<null | string>("serverPath");
if (serverPath) { if (serverPath) {
return { return {
type: BinarySource.Type.ExplicitPath, type: ArtifactSource.Type.ExplicitPath,
path: Config.replaceTildeWithHomeDir(serverPath) path: Config.replaceTildeWithHomeDir(serverPath)
}; };
} }
@@ -129,11 +129,12 @@ export class Config {
if (!prebuiltBinaryName) return null; if (!prebuiltBinaryName) return null;
return { return {
type: BinarySource.Type.GithubRelease, type: ArtifactSource.Type.GithubRelease,
dir: this.ctx.globalStoragePath, dir: this.ctx.globalStoragePath,
file: prebuiltBinaryName, file: prebuiltBinaryName,
storage: this.ctx.globalState, storage: this.ctx.globalState,
version: Config.extensionVersion, tag: Config.extensionVersion,
askBeforeDownload: !(this.cfg.get("alwaysDownloadServer") as boolean),
repo: { repo: {
name: "rust-analyzer", name: "rust-analyzer",
owner: "rust-analyzer", owner: "rust-analyzer",

View File

@@ -14,14 +14,14 @@ export interface ArtifactReleaseInfo {
} }
/** /**
* Represents the source of a binary artifact which is either specified by the user * Represents the source of a an artifact which is either specified by the user
* explicitly, or bundled by this extension from GitHub releases. * explicitly, or bundled by this extension from GitHub releases.
*/ */
export type BinarySource = BinarySource.ExplicitPath | BinarySource.GithubRelease; export type ArtifactSource = ArtifactSource.ExplicitPath | ArtifactSource.GithubRelease;
export namespace BinarySource { export namespace ArtifactSource {
/** /**
* Type tag for `BinarySource` discriminated union. * Type tag for `ArtifactSource` discriminated union.
*/ */
export const enum Type { ExplicitPath, GithubRelease } export const enum Type { ExplicitPath, GithubRelease }
@@ -56,13 +56,18 @@ export namespace BinarySource {
/** /**
* Tag of github release that denotes a version required by this extension. * Tag of github release that denotes a version required by this extension.
*/ */
version: string; tag: string;
/** /**
* Object that provides `get()/update()` operations to store metadata * Object that provides `get()/update()` operations to store metadata
* about the actual binary, e.g. its actual version. * about the actual binary, e.g. its actual version.
*/ */
storage: vscode.Memento; storage: vscode.Memento;
/**
* Ask for the user permission before downloading the artifact.
*/
askBeforeDownload: boolean;
} }
} }

View File

@@ -3,12 +3,12 @@ import * as path from "path";
import { promises as dns } from "dns"; import { promises as dns } from "dns";
import { spawnSync } from "child_process"; import { spawnSync } from "child_process";
import { BinarySource } from "./interfaces"; import { ArtifactSource } from "./interfaces";
import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info"; import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info";
import { downloadArtifact } from "./download_artifact"; import { downloadArtifact } from "./download_artifact";
import { log, assert } from "../util"; import { log, assert } from "../util";
export async function ensureServerBinary(source: null | BinarySource): Promise<null | string> { export async function ensureServerBinary(source: null | ArtifactSource): Promise<null | string> {
if (!source) { if (!source) {
vscode.window.showErrorMessage( vscode.window.showErrorMessage(
"Unfortunately we don't ship binaries for your platform yet. " + "Unfortunately we don't ship binaries for your platform yet. " +
@@ -22,7 +22,7 @@ export async function ensureServerBinary(source: null | BinarySource): Promise<n
} }
switch (source.type) { switch (source.type) {
case BinarySource.Type.ExplicitPath: { case ArtifactSource.Type.ExplicitPath: {
if (isBinaryAvailable(source.path)) { if (isBinaryAvailable(source.path)) {
return source.path; return source.path;
} }
@@ -34,11 +34,11 @@ export async function ensureServerBinary(source: null | BinarySource): Promise<n
); );
return null; return null;
} }
case BinarySource.Type.GithubRelease: { case ArtifactSource.Type.GithubRelease: {
const prebuiltBinaryPath = path.join(source.dir, source.file); const prebuiltBinaryPath = path.join(source.dir, source.file);
const installedVersion: null | string = getServerVersion(source.storage); const installedVersion: null | string = getServerVersion(source.storage);
const requiredVersion: string = source.version; const requiredVersion: string = source.tag;
log.debug("Installed version:", installedVersion, "required:", requiredVersion); log.debug("Installed version:", installedVersion, "required:", requiredVersion);
@@ -46,12 +46,14 @@ export async function ensureServerBinary(source: null | BinarySource): Promise<n
return prebuiltBinaryPath; return prebuiltBinaryPath;
} }
if (source.askBeforeDownload) {
const userResponse = await vscode.window.showInformationMessage( const userResponse = await vscode.window.showInformationMessage(
`Language server version ${source.version} for rust-analyzer is not installed. ` + `Language server version ${source.tag} for rust-analyzer is not installed. ` +
"Do you want to download it now?", "Do you want to download it now?",
"Download now", "Cancel" "Download now", "Cancel"
); );
if (userResponse !== "Download now") return null; if (userResponse !== "Download now") return null;
}
if (!await downloadServer(source)) return null; if (!await downloadServer(source)) return null;
@@ -60,9 +62,9 @@ export async function ensureServerBinary(source: null | BinarySource): Promise<n
} }
} }
async function downloadServer(source: BinarySource.GithubRelease): Promise<boolean> { async function downloadServer(source: ArtifactSource.GithubRelease): Promise<boolean> {
try { try {
const releaseInfo = await fetchArtifactReleaseInfo(source.repo, source.file, source.version); const releaseInfo = await fetchArtifactReleaseInfo(source.repo, source.file, source.tag);
await downloadArtifact(releaseInfo, source.file, source.dir, "language server"); await downloadArtifact(releaseInfo, source.file, source.dir, "language server");
await setServerVersion(source.storage, releaseInfo.releaseName); await setServerVersion(source.storage, releaseInfo.releaseName);