mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +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
4 changed files with 42 additions and 154 deletions
|
@ -261,9 +261,9 @@ export class Config {
|
||||||
return this.get<boolean | undefined>("testExplorer");
|
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");
|
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>) => {
|
const fixRecord = (r: Record<string, any>) => {
|
||||||
for (const key in r) {
|
for (const key in r) {
|
||||||
if (typeof r[key] !== "string") {
|
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) {
|
if (item instanceof Array) {
|
||||||
item.forEach((x) => fixRecord(x.env));
|
const env = {};
|
||||||
} else {
|
for (const it of item) {
|
||||||
fixRecord(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;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,8 +148,16 @@ async function getDebugConfiguration(
|
||||||
return path.normalize(p).replace(wsFolder, `\${workspaceFolder${workspaceQualifier}}`);
|
return path.normalize(p).replace(wsFolder, `\${workspaceFolder${workspaceQualifier}}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const env = prepareEnv(inheritEnv, runnable.label, runnableArgs, config.runnablesExtraEnv);
|
const executable = await getDebugExecutable(
|
||||||
const executable = await getDebugExecutable(runnableArgs, env);
|
runnableArgs,
|
||||||
|
prepareEnv(true, {}, config.runnablesExtraEnv(runnable.label)),
|
||||||
|
);
|
||||||
|
|
||||||
|
const env = prepareEnv(
|
||||||
|
inheritEnv,
|
||||||
|
runnableArgs.environment,
|
||||||
|
config.runnablesExtraEnv(runnable.label),
|
||||||
|
);
|
||||||
let sourceFileMap = debugOptions.sourceFileMap;
|
let sourceFileMap = debugOptions.sourceFileMap;
|
||||||
|
|
||||||
if (sourceFileMap === "auto") {
|
if (sourceFileMap === "auto") {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import * as tasks from "./tasks";
|
||||||
|
|
||||||
import type { CtxInit } from "./ctx";
|
import type { CtxInit } from "./ctx";
|
||||||
import { makeDebugConfig } from "./debug";
|
import { makeDebugConfig } from "./debug";
|
||||||
import type { Config, RunnableEnvCfg, RunnableEnvCfgItem } from "./config";
|
import type { Config } from "./config";
|
||||||
import type { LanguageClient } from "vscode-languageclient/node";
|
import type { LanguageClient } from "vscode-languageclient/node";
|
||||||
import { unwrapUndefinable, type RustEditor } from "./util";
|
import { unwrapUndefinable, type RustEditor } from "./util";
|
||||||
|
|
||||||
|
@ -81,32 +81,13 @@ export function prepareBaseEnv(
|
||||||
|
|
||||||
export function prepareEnv(
|
export function prepareEnv(
|
||||||
inheritEnv: boolean,
|
inheritEnv: boolean,
|
||||||
label: string,
|
runnableEnv?: Record<string, string>,
|
||||||
runnableArgs: ra.CargoRunnableArgs,
|
runnableEnvCfg?: Record<string, string>,
|
||||||
runnableEnvCfg?: RunnableEnvCfg,
|
|
||||||
): Record<string, string> {
|
): Record<string, string> {
|
||||||
const env = prepareBaseEnv(inheritEnv, runnableArgs.environment);
|
const env = prepareBaseEnv(inheritEnv, runnableEnv);
|
||||||
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 (runnableEnvCfg) {
|
if (runnableEnvCfg) {
|
||||||
if (Array.isArray(runnableEnvCfg)) {
|
Object.assign(env, 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;
|
return env;
|
||||||
|
@ -140,7 +121,11 @@ export async function createTaskFromRunnable(
|
||||||
};
|
};
|
||||||
options = {
|
options = {
|
||||||
cwd: runnableArgs.workspaceRoot || ".",
|
cwd: runnableArgs.workspaceRoot || ".",
|
||||||
env: prepareEnv(true, runnable.label, runnableArgs, config.runnablesExtraEnv),
|
env: prepareEnv(
|
||||||
|
true,
|
||||||
|
runnableArgs.environment,
|
||||||
|
config.runnablesExtraEnv(runnable.label),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const runnableArgs = runnable.args;
|
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…
Reference in a new issue