about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-01-24 13:27:19 +0000
committerbors <bors@rust-lang.org>2023-01-24 13:27:19 +0000
commite86bac92f485ff8f17a3fe49f8f7e7a10bacfecc (patch)
treeacc8ee87c2b2e61f337807c41bd97cdc4cbd2b4e
parentcd4ac0d87b0c40c9ac1cea299718c723ea93a162 (diff)
parentec9476015ce966fc4238408baef7a7ad1b3db5d8 (diff)
downloadrust-e86bac92f485ff8f17a3fe49f8f7e7a10bacfecc.tar.gz
rust-e86bac92f485ff8f17a3fe49f8f7e7a10bacfecc.zip
Auto merge of #14019 - Veykril:ts-bin-og, r=Veykril
Substitute VSCode variables more generally
-rw-r--r--editors/code/src/bootstrap.ts98
-rw-r--r--editors/code/src/config.ts64
-rw-r--r--editors/code/src/ctx.ts6
-rw-r--r--editors/code/src/debug.ts2
-rw-r--r--editors/code/src/util.ts2
5 files changed, 87 insertions, 85 deletions
diff --git a/editors/code/src/bootstrap.ts b/editors/code/src/bootstrap.ts
index cabc7407172..b38fa06a85c 100644
--- a/editors/code/src/bootstrap.ts
+++ b/editors/code/src/bootstrap.ts
@@ -1,6 +1,6 @@
 import * as vscode from "vscode";
 import * as os from "os";
-import { Config, substituteVSCodeVariables } from "./config";
+import { Config } from "./config";
 import { log, isValidExecutable } from "./util";
 import { PersistentState } from "./persistent_state";
 import { exec } from "child_process";
@@ -31,58 +31,12 @@ export async function bootstrap(
 
     return path;
 }
-
-async function patchelf(dest: vscode.Uri): Promise<void> {
-    await vscode.window.withProgress(
-        {
-            location: vscode.ProgressLocation.Notification,
-            title: "Patching rust-analyzer for NixOS",
-        },
-        async (progress, _) => {
-            const expression = `
-            {srcStr, pkgs ? import <nixpkgs> {}}:
-                pkgs.stdenv.mkDerivation {
-                    name = "rust-analyzer";
-                    src = /. + srcStr;
-                    phases = [ "installPhase" "fixupPhase" ];
-                    installPhase = "cp $src $out";
-                    fixupPhase = ''
-                    chmod 755 $out
-                    patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out
-                    '';
-                }
-            `;
-            const origFile = vscode.Uri.file(dest.fsPath + "-orig");
-            await vscode.workspace.fs.rename(dest, origFile, { overwrite: true });
-            try {
-                progress.report({ message: "Patching executable", increment: 20 });
-                await new Promise((resolve, reject) => {
-                    const handle = exec(
-                        `nix-build -E - --argstr srcStr '${origFile.fsPath}' -o '${dest.fsPath}'`,
-                        (err, stdout, stderr) => {
-                            if (err != null) {
-                                reject(Error(stderr));
-                            } else {
-                                resolve(stdout);
-                            }
-                        }
-                    );
-                    handle.stdin?.write(expression);
-                    handle.stdin?.end();
-                });
-            } finally {
-                await vscode.workspace.fs.delete(origFile);
-            }
-        }
-    );
-}
-
 async function getServer(
     context: vscode.ExtensionContext,
     config: Config,
     state: PersistentState
 ): Promise<string | undefined> {
-    const explicitPath = serverPath(config);
+    const explicitPath = process.env.__RA_LSP_SERVER_DEBUG ?? config.serverPath;
     if (explicitPath) {
         if (explicitPath.startsWith("~/")) {
             return os.homedir() + explicitPath.slice("~".length);
@@ -131,9 +85,6 @@ async function getServer(
     );
     return undefined;
 }
-function serverPath(config: Config): string | null {
-    return process.env.__RA_LSP_SERVER_DEBUG ?? substituteVSCodeVariables(config.serverPath);
-}
 
 async function isNixOs(): Promise<boolean> {
     try {
@@ -146,3 +97,48 @@ async function isNixOs(): Promise<boolean> {
         return false;
     }
 }
+
+async function patchelf(dest: vscode.Uri): Promise<void> {
+    await vscode.window.withProgress(
+        {
+            location: vscode.ProgressLocation.Notification,
+            title: "Patching rust-analyzer for NixOS",
+        },
+        async (progress, _) => {
+            const expression = `
+            {srcStr, pkgs ? import <nixpkgs> {}}:
+                pkgs.stdenv.mkDerivation {
+                    name = "rust-analyzer";
+                    src = /. + srcStr;
+                    phases = [ "installPhase" "fixupPhase" ];
+                    installPhase = "cp $src $out";
+                    fixupPhase = ''
+                    chmod 755 $out
+                    patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out
+                    '';
+                }
+            `;
+            const origFile = vscode.Uri.file(dest.fsPath + "-orig");
+            await vscode.workspace.fs.rename(dest, origFile, { overwrite: true });
+            try {
+                progress.report({ message: "Patching executable", increment: 20 });
+                await new Promise((resolve, reject) => {
+                    const handle = exec(
+                        `nix-build -E - --argstr srcStr '${origFile.fsPath}' -o '${dest.fsPath}'`,
+                        (err, stdout, stderr) => {
+                            if (err != null) {
+                                reject(Error(stderr));
+                            } else {
+                                resolve(stdout);
+                            }
+                        }
+                    );
+                    handle.stdin?.write(expression);
+                    handle.stdin?.end();
+                });
+            } finally {
+                await vscode.workspace.fs.delete(origFile);
+            }
+        }
+    );
+}
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index eb4f965291f..ce1142df3a8 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -1,5 +1,6 @@
-import * as path from "path";
+import * as Is from "vscode-languageclient/lib/common/utils/is";
 import * as os from "os";
+import * as path from "path";
 import * as vscode from "vscode";
 import { Env } from "./client";
 import { log } from "./util";
@@ -47,7 +48,7 @@ export class Config {
     }
 
     private refreshLogging() {
-        log.setEnabled(this.traceExtension);
+        log.setEnabled(this.traceExtension ?? false);
         log.info("Extension version:", this.package.version);
 
         const cfg = Object.entries(this.cfg).filter(([_, val]) => !(val instanceof Function));
@@ -163,18 +164,24 @@ export class Config {
      * ```
      * So this getter handles this quirk by not requiring the caller to use postfix `!`
      */
-    private get<T>(path: string): T {
-        return this.cfg.get<T>(path)!;
+    private get<T>(path: string): T | undefined {
+        return substituteVSCodeVariables(this.cfg.get<T>(path));
     }
 
     get serverPath() {
         return this.get<null | string>("server.path") ?? this.get<null | string>("serverPath");
     }
+
     get serverExtraEnv(): Env {
         const extraEnv =
             this.get<{ [key: string]: string | number } | null>("server.extraEnv") ?? {};
-        return Object.fromEntries(
-            Object.entries(extraEnv).map(([k, v]) => [k, typeof v !== "string" ? v.toString() : v])
+        return substituteVariablesInEnv(
+            Object.fromEntries(
+                Object.entries(extraEnv).map(([k, v]) => [
+                    k,
+                    typeof v !== "string" ? v.toString() : v,
+                ])
+            )
         );
     }
     get traceExtension() {
@@ -216,13 +223,13 @@ export class Config {
         if (sourceFileMap !== "auto") {
             // "/rustc/<id>" used by suggestions only.
             const { ["/rustc/<id>"]: _, ...trimmed } =
-                this.get<Record<string, string>>("debug.sourceFileMap");
+                this.get<Record<string, string>>("debug.sourceFileMap") ?? {};
             sourceFileMap = trimmed;
         }
 
         return {
             engine: this.get<string>("debug.engine"),
-            engineSettings: this.get<object>("debug.engineSettings"),
+            engineSettings: this.get<object>("debug.engineSettings") ?? {},
             openDebugPane: this.get<boolean>("debug.openDebugPane"),
             sourceFileMap: sourceFileMap,
         };
@@ -247,37 +254,27 @@ export class Config {
     }
 }
 
-const VarRegex = new RegExp(/\$\{(.+?)\}/g);
-
-export function substituteVSCodeVariableInString(val: string): string {
-    return val.replace(VarRegex, (substring: string, varName) => {
-        if (typeof varName === "string") {
-            return computeVscodeVar(varName) || substring;
-        } else {
-            return substring;
-        }
-    });
-}
-
-export function substituteVSCodeVariables(resp: any): any {
-    if (typeof resp === "string") {
-        return substituteVSCodeVariableInString(resp);
-    } else if (resp && Array.isArray(resp)) {
+export function substituteVSCodeVariables<T>(resp: T): T {
+    if (Is.string(resp)) {
+        return substituteVSCodeVariableInString(resp) as T;
+    } else if (resp && Is.array<any>(resp)) {
         return resp.map((val) => {
             return substituteVSCodeVariables(val);
-        });
+        }) as T;
     } else if (resp && typeof resp === "object") {
         const res: { [key: string]: any } = {};
         for (const key in resp) {
             const val = resp[key];
             res[key] = substituteVSCodeVariables(val);
         }
-        return res;
-    } else if (typeof resp === "function") {
-        return null;
+        return res as T;
+    } else if (Is.func(resp)) {
+        throw new Error("Unexpected function type in substitution");
     }
     return resp;
 }
+
+// FIXME: Merge this with `substituteVSCodeVariables` above
 export function substituteVariablesInEnv(env: Env): Env {
     const missingDeps = new Set<string>();
     // vscode uses `env:ENV_NAME` for env vars resolution, and it's easier
@@ -355,6 +352,17 @@ export function substituteVariablesInEnv(env: Env): Env {
     return resolvedEnv;
 }
 
+const VarRegex = new RegExp(/\$\{(.+?)\}/g);
+function substituteVSCodeVariableInString(val: string): string {
+    return val.replace(VarRegex, (substring: string, varName) => {
+        if (Is.string(varName)) {
+            return computeVscodeVar(varName) || substring;
+        } else {
+            return substring;
+        }
+    });
+}
+
 function computeVscodeVar(varName: string): string | null {
     const workspaceFolder = () => {
         const folders = vscode.workspace.workspaceFolders ?? [];
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index 1860924c6de..8b04182155d 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -2,7 +2,7 @@ import * as vscode from "vscode";
 import * as lc from "vscode-languageclient/node";
 import * as ra from "./lsp_ext";
 
-import { Config, substituteVariablesInEnv, substituteVSCodeVariables } from "./config";
+import { Config, substituteVSCodeVariables } from "./config";
 import { createClient } from "./client";
 import { isRustDocument, isRustEditor, log, RustEditor } from "./util";
 import { ServerStatusParams } from "./lsp_ext";
@@ -152,9 +152,7 @@ export class Ctx {
                     throw new Error(message);
                 }
             );
-            const newEnv = substituteVariablesInEnv(
-                Object.assign({}, process.env, this.config.serverExtraEnv)
-            );
+            const newEnv = Object.assign({}, process.env, this.config.serverExtraEnv);
             const run: lc.Executable = {
                 command: this._serverPath,
                 options: { env: newEnv },
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts
index bd45599227e..268b70b4fbb 100644
--- a/editors/code/src/debug.ts
+++ b/editors/code/src/debug.ts
@@ -84,7 +84,7 @@ async function getDebugConfiguration(
             debugEngine = vscode.extensions.getExtension(engineId);
             if (debugEngine) break;
         }
-    } else {
+    } else if (debugOptions.engine) {
         debugEngine = vscode.extensions.getExtension(debugOptions.engine);
     }
 
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index cd91932bb60..a92c90f7ff4 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -117,7 +117,7 @@ export function isValidExecutable(path: string): boolean {
 
     const res = spawnSync(path, ["--version"], { encoding: "utf8" });
 
-    const printOutput = res.error && (res.error as any).code !== "ENOENT" ? log.warn : log.debug;
+    const printOutput = res.error ? log.warn : log.info;
     printOutput(path, "--version:", res);
 
     return res.status === 0;