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. // It might be a good idea to test if the uri points to a file.
const workspaceFolderPath = workspace.workspaceFolders?.[0]?.uri.fsPath ?? '.'; const workspaceFolderPath = workspace.workspaceFolders?.[0]?.uri.fsPath ?? '.';
const raLspServerPath = await ensureLanguageServerBinary(config.raLspServerSource); const raLspServerPath = await ensureLanguageServerBinary(config.langServerSource);
if (!raLspServerPath) return null; if (!raLspServerPath) return null;
const run: lc.Executable = { const run: lc.Executable = {

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, BinarySourceType } from "./installation/interfaces"; import { BinarySource } from "./installation/interfaces";
const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG; const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
@ -18,20 +18,7 @@ export interface CargoFeatures {
} }
export class Config { export class Config {
readonly raLspServerGithubArtifactName = { langServerSource!: null | BinarySource;
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;
highlightingOn = true; highlightingOn = true;
rainbowHighlightingOn = false; rainbowHighlightingOn = false;
@ -72,6 +59,56 @@ export class Config {
return path; 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 // 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) // values only in one place (i.e. remove default values from non-readonly members declarations)
private refresh(ctx: vscode.ExtensionContext) { private refresh(ctx: vscode.ExtensionContext) {
@ -107,27 +144,7 @@ export class Config {
this.prevEnhancedTyping = this.enableEnhancedTyping; this.prevEnhancedTyping = this.enableEnhancedTyping;
} }
{ this.langServerSource = Config.langServerBinarySource(ctx, config);
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;
}
}
if (config.has('cargo-watch.enable')) { if (config.has('cargo-watch.enable')) {
this.cargoWatchOptions.enable = config.get<boolean>( this.cargoWatchOptions.enable = config.get<boolean>(

View file

@ -11,43 +11,45 @@ export interface ArtifactMetadata {
downloadUrl: string; 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 * Represents the source of a binary 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 = ExplicitPathSource | GithubBinarySource; export type BinarySource = BinarySource.ExplicitPath | BinarySource.GithubRelease;
export interface ExplicitPathSource {
type: BinarySourceType.ExplicitPath;
export namespace BinarySource {
/** /**
* Filesystem path to the binary specified by the user explicitly. * Type tag for `BinarySource` discriminated union.
*/ */
path: string; export const enum Type { ExplicitPath, GithubRelease }
}
export interface ExplicitPath {
export interface GithubBinarySource { type: Type.ExplicitPath;
type: BinarySourceType.GithubBinary;
/**
/** * Filesystem path to the binary specified by the user explicitly.
* Repository where the binary is stored. */
*/ path: string;
repo: GithubRepo; }
/** export interface GithubRelease {
* Directory on the filesystem where the bundled binary is stored. type: Type.GithubRelease;
*/
dir: string; /**
* Repository where the binary is stored.
/** */
* Name of the binary file. It is stored under the same name on GitHub releases repo: GithubRepo;
* and in local `.dir`.
*/ /**
file: string; * 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 { strict as assert } from "assert";
import { promises as fs } from "fs"; import { promises as fs } from "fs";
import { BinarySource, BinarySourceType, GithubBinarySource } from "./interfaces"; import { BinarySource } from "./interfaces";
import { fetchLatestArtifactMetadata } from "./fetch_latest_artifact_metadata"; import { fetchLatestArtifactMetadata } from "./fetch_latest_artifact_metadata";
import { downloadFile } from "./download_file"; import { downloadFile } from "./download_file";
export async function downloadLatestLanguageServer( export async function downloadLatestLanguageServer(
{file: artifactFileName, dir: installationDir, repo}: GithubBinarySource {file: artifactFileName, dir: installationDir, repo}: BinarySource.GithubRelease
) { ) {
const binaryMetadata = await fetchLatestArtifactMetadata(repo, artifactFileName); const binaryMetadata = await fetchLatestArtifactMetadata(repo, artifactFileName);
@ -67,7 +67,7 @@ export async function ensureLanguageServerBinary(
} }
switch (langServerSource.type) { switch (langServerSource.type) {
case BinarySourceType.ExplicitPath: { case BinarySource.Type.ExplicitPath: {
if (isBinaryAvailable(langServerSource.path)) { if (isBinaryAvailable(langServerSource.path)) {
return langServerSource.path; return langServerSource.path;
} }
@ -78,7 +78,7 @@ export async function ensureLanguageServerBinary(
); );
return null; return null;
} }
case BinarySourceType.GithubBinary: { case BinarySource.Type.GithubRelease: {
const bundledBinaryPath = path.join(langServerSource.dir, langServerSource.file); const bundledBinaryPath = path.join(langServerSource.dir, langServerSource.file);
if (!isBinaryAvailable(bundledBinaryPath)) { if (!isBinaryAvailable(bundledBinaryPath)) {
@ -106,7 +106,7 @@ export async function ensureLanguageServerBinary(
); );
vscode.window.showInformationMessage( vscode.window.showInformationMessage(
"Rust analyzer language server was successfully installed" "Rust analyzer language server was successfully installed 🦀"
); );
} }
return bundledBinaryPath; return bundledBinaryPath;