about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/editors/code
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-12-02 12:58:43 +0100
committerLukas Wirth <lukastw97@gmail.com>2024-12-02 13:02:31 +0100
commit5a52142eeafd00fcda88f60f9fe0aee8f912c625 (patch)
tree76510d96d25d80f4fac9b4be600040e75103254d /src/tools/rust-analyzer/editors/code
parentb747197a8278c90f0ff198ccf8a17335f53f9022 (diff)
downloadrust-5a52142eeafd00fcda88f60f9fe0aee8f912c625.tar.gz
rust-5a52142eeafd00fcda88f60f9fe0aee8f912c625.zip
Fix debug configuration querying not inheriting environment
Diffstat (limited to 'src/tools/rust-analyzer/editors/code')
-rw-r--r--src/tools/rust-analyzer/editors/code/src/config.ts27
-rw-r--r--src/tools/rust-analyzer/editors/code/src/debug.ts12
-rw-r--r--src/tools/rust-analyzer/editors/code/src/run.ts35
-rw-r--r--src/tools/rust-analyzer/editors/code/tests/unit/runnable_env.test.ts122
4 files changed, 42 insertions, 154 deletions
diff --git a/src/tools/rust-analyzer/editors/code/src/config.ts b/src/tools/rust-analyzer/editors/code/src/config.ts
index 67bc72f1e12..f979d545471 100644
--- a/src/tools/rust-analyzer/editors/code/src/config.ts
+++ b/src/tools/rust-analyzer/editors/code/src/config.ts
@@ -261,9 +261,9 @@ export class Config {
         return this.get<boolean | undefined>("testExplorer");
     }
 
-    get runnablesExtraEnv() {
+    runnablesExtraEnv(label: string): Record<string, string> | undefined {
         const item = this.get<any>("runnables.extraEnv") ?? this.get<any>("runnableEnv");
-        if (!item) return item;
+        if (!item) return undefined;
         const fixRecord = (r: Record<string, any>) => {
             for (const key in r) {
                 if (typeof r[key] !== "string") {
@@ -271,11 +271,28 @@ export class Config {
                 }
             }
         };
+
+        const platform = process.platform;
+        const checkPlatform = (it: RunnableEnvCfgItem) => {
+            if (it.platform) {
+                const platforms = Array.isArray(it.platform) ? it.platform : [it.platform];
+                return platforms.indexOf(platform) >= 0;
+            }
+            return true;
+        };
+
         if (item instanceof Array) {
-            item.forEach((x) => fixRecord(x.env));
-        } else {
-            fixRecord(item);
+            const env = {};
+            for (const it of item) {
+                const masked = !it.mask || new RegExp(it.mask).test(label);
+                if (masked && checkPlatform(it)) {
+                    Object.assign(env, it.env);
+                }
+            }
+            fixRecord(env);
+            return env;
         }
+        fixRecord(item);
         return item;
     }
 
diff --git a/src/tools/rust-analyzer/editors/code/src/debug.ts b/src/tools/rust-analyzer/editors/code/src/debug.ts
index 9e2e3d2185b..f21ca2e8f96 100644
--- a/src/tools/rust-analyzer/editors/code/src/debug.ts
+++ b/src/tools/rust-analyzer/editors/code/src/debug.ts
@@ -148,8 +148,16 @@ async function getDebugConfiguration(
         return path.normalize(p).replace(wsFolder, `\${workspaceFolder${workspaceQualifier}}`);
     }
 
-    const env = prepareEnv(inheritEnv, runnable.label, runnableArgs, config.runnablesExtraEnv);
-    const executable = await getDebugExecutable(runnableArgs, env);
+    const executable = await getDebugExecutable(
+        runnableArgs,
+        prepareEnv(true, {}, config.runnablesExtraEnv(runnable.label)),
+    );
+
+    const env = prepareEnv(
+        inheritEnv,
+        runnableArgs.environment,
+        config.runnablesExtraEnv(runnable.label),
+    );
     let sourceFileMap = debugOptions.sourceFileMap;
 
     if (sourceFileMap === "auto") {
diff --git a/src/tools/rust-analyzer/editors/code/src/run.ts b/src/tools/rust-analyzer/editors/code/src/run.ts
index 8a82a5a58cf..f71ab7ffbd8 100644
--- a/src/tools/rust-analyzer/editors/code/src/run.ts
+++ b/src/tools/rust-analyzer/editors/code/src/run.ts
@@ -5,7 +5,7 @@ import * as tasks from "./tasks";
 
 import type { CtxInit } from "./ctx";
 import { makeDebugConfig } from "./debug";
-import type { Config, RunnableEnvCfg, RunnableEnvCfgItem } from "./config";
+import type { Config } from "./config";
 import type { LanguageClient } from "vscode-languageclient/node";
 import { unwrapUndefinable, type RustEditor } from "./util";
 
@@ -81,32 +81,13 @@ export function prepareBaseEnv(
 
 export function prepareEnv(
     inheritEnv: boolean,
-    label: string,
-    runnableArgs: ra.CargoRunnableArgs,
-    runnableEnvCfg?: RunnableEnvCfg,
+    runnableEnv?: Record<string, string>,
+    runnableEnvCfg?: Record<string, string>,
 ): Record<string, string> {
-    const env = prepareBaseEnv(inheritEnv, runnableArgs.environment);
-    const platform = process.platform;
-
-    const checkPlatform = (it: RunnableEnvCfgItem) => {
-        if (it.platform) {
-            const platforms = Array.isArray(it.platform) ? it.platform : [it.platform];
-            return platforms.indexOf(platform) >= 0;
-        }
-        return true;
-    };
+    const env = prepareBaseEnv(inheritEnv, runnableEnv);
 
     if (runnableEnvCfg) {
-        if (Array.isArray(runnableEnvCfg)) {
-            for (const it of runnableEnvCfg) {
-                const masked = !it.mask || new RegExp(it.mask).test(label);
-                if (masked && checkPlatform(it)) {
-                    Object.assign(env, it.env);
-                }
-            }
-        } else {
-            Object.assign(env, runnableEnvCfg);
-        }
+        Object.assign(env, runnableEnvCfg);
     }
 
     return env;
@@ -140,7 +121,11 @@ export async function createTaskFromRunnable(
         };
         options = {
             cwd: runnableArgs.workspaceRoot || ".",
-            env: prepareEnv(true, runnable.label, runnableArgs, config.runnablesExtraEnv),
+            env: prepareEnv(
+                true,
+                runnableArgs.environment,
+                config.runnablesExtraEnv(runnable.label),
+            ),
         };
     } else {
         const runnableArgs = runnable.args;
diff --git a/src/tools/rust-analyzer/editors/code/tests/unit/runnable_env.test.ts b/src/tools/rust-analyzer/editors/code/tests/unit/runnable_env.test.ts
deleted file mode 100644
index f0a62a3cce2..00000000000
--- a/src/tools/rust-analyzer/editors/code/tests/unit/runnable_env.test.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-import * as assert from "assert";
-import { prepareEnv } from "../../src/run";
-import type { RunnableEnvCfg } from "../../src/config";
-import type { Context } from ".";
-import type * as ra from "../../src/lsp_ext";
-
-function makeRunnable(label: string): ra.Runnable {
-    return {
-        label,
-        kind: "cargo",
-        args: {
-            cargoArgs: [],
-            cwd: ".",
-            executableArgs: [],
-        },
-    };
-}
-
-function fakePrepareEnv(runnableName: string, config?: RunnableEnvCfg): Record<string, string> {
-    const runnable = makeRunnable(runnableName);
-    const runnableArgs = runnable.args as ra.CargoRunnableArgs;
-    return prepareEnv(false, runnable.label, runnableArgs, config);
-}
-
-export async function getTests(ctx: Context) {
-    await ctx.suite("Runnable env", (suite) => {
-        suite.addTest("Global config works", async () => {
-            const binEnv = fakePrepareEnv("run project_name", { GLOBAL: "g" });
-            assert.strictEqual(binEnv["GLOBAL"], "g");
-
-            const testEnv = fakePrepareEnv("test some::mod::test_name", { GLOBAL: "g" });
-            assert.strictEqual(testEnv["GLOBAL"], "g");
-        });
-
-        suite.addTest("null mask works", async () => {
-            const config = [
-                {
-                    env: { DATA: "data" },
-                },
-            ];
-            const binEnv = fakePrepareEnv("run project_name", config);
-            assert.strictEqual(binEnv["DATA"], "data");
-
-            const testEnv = fakePrepareEnv("test some::mod::test_name", config);
-            assert.strictEqual(testEnv["DATA"], "data");
-        });
-
-        suite.addTest("order works", async () => {
-            const config = [
-                {
-                    env: { DATA: "data" },
-                },
-                {
-                    env: { DATA: "newdata" },
-                },
-            ];
-            const binEnv = fakePrepareEnv("run project_name", config);
-            assert.strictEqual(binEnv["DATA"], "newdata");
-
-            const testEnv = fakePrepareEnv("test some::mod::test_name", config);
-            assert.strictEqual(testEnv["DATA"], "newdata");
-        });
-
-        suite.addTest("mask works", async () => {
-            const config = [
-                {
-                    env: { DATA: "data" },
-                },
-                {
-                    mask: "^run",
-                    env: { DATA: "rundata" },
-                },
-                {
-                    mask: "special_test$",
-                    env: { DATA: "special_test" },
-                },
-            ];
-            const binEnv = fakePrepareEnv("run project_name", config);
-            assert.strictEqual(binEnv["DATA"], "rundata");
-
-            const testEnv = fakePrepareEnv("test some::mod::test_name", config);
-            assert.strictEqual(testEnv["DATA"], "data");
-
-            const specialTestEnv = fakePrepareEnv("test some::mod::special_test", config);
-            assert.strictEqual(specialTestEnv["DATA"], "special_test");
-        });
-
-        suite.addTest("exact test name works", async () => {
-            const config = [
-                {
-                    env: { DATA: "data" },
-                },
-                {
-                    mask: "some::mod::test_name",
-                    env: { DATA: "test special" },
-                },
-            ];
-            const testEnv = fakePrepareEnv("test some::mod::test_name", config);
-            assert.strictEqual(testEnv["DATA"], "test special");
-
-            const specialTestEnv = fakePrepareEnv("test some::mod::another_test", config);
-            assert.strictEqual(specialTestEnv["DATA"], "data");
-        });
-
-        suite.addTest("test mod name works", async () => {
-            const config = [
-                {
-                    env: { DATA: "data" },
-                },
-                {
-                    mask: "some::mod",
-                    env: { DATA: "mod special" },
-                },
-            ];
-            const testEnv = fakePrepareEnv("test some::mod::test_name", config);
-            assert.strictEqual(testEnv["DATA"], "mod special");
-
-            const specialTestEnv = fakePrepareEnv("test some::mod::another_test", config);
-            assert.strictEqual(specialTestEnv["DATA"], "mod special");
-        });
-    });
-}