vscode: refactor platform artifact name query to switch statement, move BinarySource union variants into a namespace

This commit is contained in:
Veetaha 2020-02-09 00:27:04 +02:00
parent bdd88c2fad
commit 539daf4454
4 changed files with 93 additions and 74 deletions

View File

@ -10,7 +10,7 @@ export async function createClient(config: Config): Promise<null | lc.LanguageCl
// It might be a good idea to test if the uri points to a file.
const workspaceFolderPath = workspace.workspaceFolders?.[0]?.uri.fsPath ?? '.';
const raLspServerPath = await ensureLanguageServerBinary(config.raLspServerSource);
const raLspServerPath = await ensureLanguageServerBinary(config.langServerSource);
if (!raLspServerPath) return null;
const run: lc.Executable = {

View File

@ -1,6 +1,6 @@
import * as os from "os";
import * as vscode from 'vscode';
import { BinarySource, BinarySourceType } from "./installation/interfaces";
import { BinarySource } from "./installation/interfaces";
const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
@ -18,20 +18,7 @@ export interface CargoFeatures {
}
export class Config {
readonly raLspServerGithubArtifactName = {
linux: "ra_lsp_server-linux",
darwin: "ra_lsp_server-mac",
win32: "ra_lsp_server-windows.exe",
aix: null,
android: null,
freebsd: null,
openbsd: null,
sunos: null,
cygwin: null,
netbsd: null,
}[process.platform];
raLspServerSource!: null | BinarySource;
langServerSource!: null | BinarySource;
highlightingOn = true;
rainbowHighlightingOn = false;
@ -72,6 +59,56 @@ export class Config {
return path;
}
/**
* Name of the binary artifact for `ra_lsp_server` that is published for
* `platform` on GitHub releases. (It is also stored under the same name when
* downloaded by the extension).
*/
private static prebuiltLangServerFileName(platform: NodeJS.Platform): null | string {
switch (platform) {
case "linux": return "ra_lsp_server-linux";
case "darwin": return "ra_lsp_server-mac";
case "win32": return "ra_lsp_server-windows.exe";
// Users on these platforms yet need to manually build from sources
case "aix":
case "android":
case "freebsd":
case "openbsd":
case "sunos":
case "cygwin":
case "netbsd": return null;
// The list of platforms is exhaustive see (`NodeJS.Platform` type definition)
}
}
private static langServerBinarySource(
ctx: vscode.ExtensionContext,
config: vscode.WorkspaceConfiguration
): null | BinarySource {
const raLspServerPath = RA_LSP_DEBUG ?? config.get<null | string>("raLspServerPath");
if (raLspServerPath) {
return {
type: BinarySource.Type.ExplicitPath,
path: Config.expandPathResolving(raLspServerPath)
};
}
const prebuiltBinaryName = Config.prebuiltLangServerFileName(process.platform);
return !prebuiltBinaryName ? null : {
type: BinarySource.Type.GithubRelease,
dir: ctx.globalStoragePath,
file: prebuiltBinaryName,
repo: {
name: "rust-analyzer",
owner: "rust-analyzer",
}
};
}
// FIXME: revisit the logic for `if (.has(...)) config.get(...)` set default
// values only in one place (i.e. remove default values from non-readonly members declarations)
private refresh(ctx: vscode.ExtensionContext) {
@ -107,27 +144,7 @@ export class Config {
this.prevEnhancedTyping = this.enableEnhancedTyping;
}
{
const raLspServerPath = RA_LSP_DEBUG ?? config.get<null | string>("raLspServerPath");
if (raLspServerPath) {
this.raLspServerSource = {
type: BinarySourceType.ExplicitPath,
path: Config.expandPathResolving(raLspServerPath)
};
} else if (this.raLspServerGithubArtifactName) {
this.raLspServerSource = {
type: BinarySourceType.GithubBinary,
dir: ctx.globalStoragePath,
file: this.raLspServerGithubArtifactName,
repo: {
name: "rust-analyzer",
owner: "rust-analyzer",
}
};
} else {
this.raLspServerSource = null;
}
}
this.langServerSource = Config.langServerBinarySource(ctx, config);
if (config.has('cargo-watch.enable')) {
this.cargoWatchOptions.enable = config.get<boolean>(

View File

@ -11,43 +11,45 @@ export interface ArtifactMetadata {
downloadUrl: string;
}
/**
* Type tag for `BinarySource` discriminated union.
*/
export enum BinarySourceType { ExplicitPath, GithubBinary }
/**
* Represents the source of a binary artifact which is either specified by the user
* explicitly, or bundled by this extension from GitHub releases.
*/
export type BinarySource = ExplicitPathSource | GithubBinarySource;
export interface ExplicitPathSource {
type: BinarySourceType.ExplicitPath;
export type BinarySource = BinarySource.ExplicitPath | BinarySource.GithubRelease;
export namespace BinarySource {
/**
* Filesystem path to the binary specified by the user explicitly.
* Type tag for `BinarySource` discriminated union.
*/
path: string;
}
export interface GithubBinarySource {
type: BinarySourceType.GithubBinary;
/**
* Repository where the binary is stored.
*/
repo: GithubRepo;
/**
* Directory on the filesystem where the bundled binary is stored.
*/
dir: string;
/**
* Name of the binary file. It is stored under the same name on GitHub releases
* and in local `.dir`.
*/
file: string;
export const enum Type { ExplicitPath, GithubRelease }
export interface ExplicitPath {
type: Type.ExplicitPath;
/**
* Filesystem path to the binary specified by the user explicitly.
*/
path: string;
}
export interface GithubRelease {
type: Type.GithubRelease;
/**
* Repository where the binary is stored.
*/
repo: GithubRepo;
/**
* Directory on the filesystem where the bundled binary is stored.
*/
dir: string;
/**
* Name of the binary file. It is stored under the same name on GitHub releases
* and in local `.dir`.
*/
file: string;
}
}

View File

@ -5,12 +5,12 @@ import * as path from "path";
import { strict as assert } from "assert";
import { promises as fs } from "fs";
import { BinarySource, BinarySourceType, GithubBinarySource } from "./interfaces";
import { BinarySource } from "./interfaces";
import { fetchLatestArtifactMetadata } from "./fetch_latest_artifact_metadata";
import { downloadFile } from "./download_file";
export async function downloadLatestLanguageServer(
{file: artifactFileName, dir: installationDir, repo}: GithubBinarySource
{file: artifactFileName, dir: installationDir, repo}: BinarySource.GithubRelease
) {
const binaryMetadata = await fetchLatestArtifactMetadata(repo, artifactFileName);
@ -67,7 +67,7 @@ export async function ensureLanguageServerBinary(
}
switch (langServerSource.type) {
case BinarySourceType.ExplicitPath: {
case BinarySource.Type.ExplicitPath: {
if (isBinaryAvailable(langServerSource.path)) {
return langServerSource.path;
}
@ -78,7 +78,7 @@ export async function ensureLanguageServerBinary(
);
return null;
}
case BinarySourceType.GithubBinary: {
case BinarySource.Type.GithubRelease: {
const bundledBinaryPath = path.join(langServerSource.dir, langServerSource.file);
if (!isBinaryAvailable(bundledBinaryPath)) {
@ -106,7 +106,7 @@ export async function ensureLanguageServerBinary(
);
vscode.window.showInformationMessage(
"Rust analyzer language server was successfully installed"
"Rust analyzer language server was successfully installed 🦀"
);
}
return bundledBinaryPath;