mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 13:13:18 +00:00 
			
		
		
		
	Merge pull request #18586 from Veykril/push-kolxkxyntxtt
fix: Fix debug configuration querying not inheriting environment
This commit is contained in:
		
						commit
						d8c162beb1
					
				@ -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 {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        if (item instanceof Array) {
 | 
			
		||||
            item.forEach((x) => fixRecord(x.env));
 | 
			
		||||
        } else {
 | 
			
		||||
            fixRecord(item);
 | 
			
		||||
 | 
			
		||||
        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) {
 | 
			
		||||
            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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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") {
 | 
			
		||||
 | 
			
		||||
@ -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,33 +81,14 @@ 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);
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
@ -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");
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user