Merge pull request #18586 from Veykril/push-kolxkxyntxtt

fix: Fix debug configuration querying not inheriting environment
This commit is contained in:
Lukas Wirth 2024-12-02 12:16:33 +00:00 committed by GitHub
commit d8c162beb1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 42 additions and 154 deletions

View file

@ -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;
}

View file

@ -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") {

View file

@ -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;

View file

@ -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");
});
});
}