Skip to content

Commit 92d5615

Browse files
committed
fix: Fix runnables extra env not substituting env vars
1 parent 7a62181 commit 92d5615

File tree

5 files changed

+53
-50
lines changed

5 files changed

+53
-50
lines changed

editors/code/src/config.ts

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ import type { Disposable } from "vscode";
88

99
export type RunnableEnvCfgItem = {
1010
mask?: string;
11-
env: Record<string, string>;
11+
env: { [key: string]: { toString(): string } | null };
1212
platform?: string | string[];
1313
};
14-
export type RunnableEnvCfg = Record<string, string> | RunnableEnvCfgItem[];
1514

1615
type ShowStatusBar = "always" | "never" | { documentSelector: vscode.DocumentSelector };
1716

@@ -261,18 +260,9 @@ export class Config {
261260
return this.get<boolean | undefined>("testExplorer");
262261
}
263262

264-
runnablesExtraEnv(label: string): Record<string, string> | undefined {
265-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
266-
const item = this.get<any>("runnables.extraEnv") ?? this.get<any>("runnableEnv");
267-
if (!item) return undefined;
268-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
269-
const fixRecord = (r: Record<string, any>) => {
270-
for (const key in r) {
271-
if (typeof r[key] !== "string") {
272-
r[key] = String(r[key]);
273-
}
274-
}
275-
};
263+
runnablesExtraEnv(label: string): Env {
264+
let extraEnv = this.get<RunnableEnvCfgItem[] | { [key: string]: { toString(): string } | null } | null>("runnables.extraEnv") ?? {};
265+
if (!extraEnv) return {};
276266

277267
const platform = process.platform;
278268
const checkPlatform = (it: RunnableEnvCfgItem) => {
@@ -283,19 +273,24 @@ export class Config {
283273
return true;
284274
};
285275

286-
if (item instanceof Array) {
276+
if (extraEnv instanceof Array) {
287277
const env = {};
288-
for (const it of item) {
278+
for (const it of extraEnv) {
289279
const masked = !it.mask || new RegExp(it.mask).test(label);
290280
if (masked && checkPlatform(it)) {
291281
Object.assign(env, it.env);
292282
}
293283
}
294-
fixRecord(env);
295-
return env;
284+
extraEnv = env;
296285
}
297-
fixRecord(item);
298-
return item;
286+
return substituteVariablesInEnv(
287+
Object.fromEntries(
288+
Object.entries(extraEnv).map(([k, v]) => [
289+
k,
290+
typeof v === "string" ? v : v?.toString(),
291+
]),
292+
),
293+
);
299294
}
300295

301296
get restartServerOnConfigChange() {
@@ -490,11 +485,11 @@ function computeVscodeVar(varName: string): string | null {
490485
folder === undefined
491486
? "" // no workspace opened
492487
: // could use currently opened document to detect the correct
493-
// workspace. However, that would be determined by the document
494-
// user has opened on Editor startup. Could lead to
495-
// unpredictable workspace selection in practice.
496-
// It's better to pick the first one
497-
normalizeDriveLetter(folder.uri.fsPath);
488+
// workspace. However, that would be determined by the document
489+
// user has opened on Editor startup. Could lead to
490+
// unpredictable workspace selection in practice.
491+
// It's better to pick the first one
492+
normalizeDriveLetter(folder.uri.fsPath);
498493
return fsPath;
499494
};
500495
// https://code.visualstudio.com/docs/editor/variables-reference

editors/code/src/debug.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type * as ra from "./lsp_ext";
66
import { Cargo } from "./toolchain";
77
import type { Ctx } from "./ctx";
88
import { createTaskFromRunnable, prepareEnv } from "./run";
9-
import { execute, isCargoRunnableArgs, unwrapUndefinable, log, normalizeDriveLetter } from "./util";
9+
import { execute, isCargoRunnableArgs, unwrapUndefinable, log, normalizeDriveLetter, Env } from "./util";
1010
import type { Config } from "./config";
1111

1212
// Here we want to keep track on everything that's currently running
@@ -108,9 +108,9 @@ async function getDebugConfiguration(
108108

109109
await vscode.window.showErrorMessage(
110110
`Install [CodeLLDB](command:${commandCodeLLDB} "Open CodeLLDB")` +
111-
`, [lldb-dap](command:${commandLLDBDap} "Open lldb-dap")` +
112-
`, [C/C++](command:${commandCCpp} "Open C/C++") ` +
113-
`or [Native Debug](command:${commandNativeDebug} "Open Native Debug") for debugging.`,
111+
`, [lldb-dap](command:${commandLLDBDap} "Open lldb-dap")` +
112+
`, [C/C++](command:${commandCCpp} "Open C/C++") ` +
113+
`or [Native Debug](command:${commandNativeDebug} "Open Native Debug") for debugging.`,
114114
);
115115
return;
116116
}
@@ -124,7 +124,7 @@ async function getDebugConfiguration(
124124
!isMultiFolderWorkspace || !runnableArgs.workspaceRoot
125125
? firstWorkspace
126126
: workspaceFolders.find((w) => runnableArgs.workspaceRoot?.includes(w.uri.fsPath)) ||
127-
firstWorkspace;
127+
firstWorkspace;
128128

129129
const workspace = unwrapUndefinable(maybeWorkspace);
130130
const wsFolder = normalizeDriveLetter(path.normalize(workspace.uri.fsPath));
@@ -207,7 +207,7 @@ type SourceFileMap = {
207207
};
208208

209209
async function discoverSourceFileMap(
210-
env: Record<string, string>,
210+
env: Env,
211211
cwd: string,
212212
): Promise<SourceFileMap | undefined> {
213213
const sysroot = env["RUSTC_TOOLCHAIN"];
@@ -232,7 +232,7 @@ type PropertyFetcher<Config, Input, Key extends keyof Config> = (
232232

233233
type DebugConfigProvider<Type extends string, DebugConfig extends BaseDebugConfig<Type>> = {
234234
executableProperty: keyof DebugConfig;
235-
environmentProperty: PropertyFetcher<DebugConfig, Record<string, string>, keyof DebugConfig>;
235+
environmentProperty: PropertyFetcher<DebugConfig, Env, keyof DebugConfig>;
236236
runnableArgsProperty: PropertyFetcher<DebugConfig, ra.CargoRunnableArgs, keyof DebugConfig>;
237237
sourceFileMapProperty?: keyof DebugConfig;
238238
type: Type;
@@ -276,7 +276,7 @@ const knownEngines: {
276276
"environment",
277277
Object.entries(env).map((entry) => ({
278278
name: entry[0],
279-
value: entry[1],
279+
value: entry[1] ?? "",
280280
})),
281281
],
282282
runnableArgsProperty: (runnableArgs: ra.CargoRunnableArgs) => [
@@ -306,7 +306,7 @@ const knownEngines: {
306306

307307
async function getDebugExecutable(
308308
runnableArgs: ra.CargoRunnableArgs,
309-
env: Record<string, string>,
309+
env: Env,
310310
): Promise<string> {
311311
const cargo = new Cargo(runnableArgs.workspaceRoot || ".", env);
312312
const executable = await cargo.executableFromArgs(runnableArgs);
@@ -328,7 +328,7 @@ function getDebugConfig(
328328
runnable: ra.Runnable,
329329
runnableArgs: ra.CargoRunnableArgs,
330330
executable: string,
331-
env: Record<string, string>,
331+
env: Env,
332332
sourceFileMap?: Record<string, string>,
333333
): vscode.DebugConfiguration {
334334
const {
@@ -380,14 +380,14 @@ type CodeLldbDebugConfig = {
380380
args: string[];
381381
sourceMap: Record<string, string> | undefined;
382382
sourceLanguages: ["rust"];
383-
env: Record<string, string>;
383+
env: Env;
384384
} & BaseDebugConfig<"lldb">;
385385

386386
type NativeDebugConfig = {
387387
target: string;
388388
// See https://github.com/WebFreak001/code-debug/issues/359
389389
arguments: string;
390-
env: Record<string, string>;
390+
env: Env;
391391
valuesFormatting: "prettyPrinters";
392392
} & BaseDebugConfig<"gdb">;
393393

editors/code/src/run.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { CtxInit } from "./ctx";
77
import { makeDebugConfig } from "./debug";
88
import type { Config } from "./config";
99
import type { LanguageClient } from "vscode-languageclient/node";
10-
import { log, unwrapUndefinable, type RustEditor } from "./util";
10+
import { Env, log, unwrapUndefinable, type RustEditor } from "./util";
1111

1212
const quickPickButtons = [
1313
{ iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configuration." },
@@ -124,9 +124,9 @@ export class RunnableQuickPick implements vscode.QuickPickItem {
124124

125125
export function prepareBaseEnv(
126126
inheritEnv: boolean,
127-
base?: Record<string, string>,
128-
): Record<string, string> {
129-
const env: Record<string, string> = { RUST_BACKTRACE: "short" };
127+
base?: Env,
128+
): Env {
129+
const env: Env = { RUST_BACKTRACE: "short" };
130130
if (inheritEnv) {
131131
Object.assign(env, process.env);
132132
}
@@ -138,9 +138,9 @@ export function prepareBaseEnv(
138138

139139
export function prepareEnv(
140140
inheritEnv: boolean,
141-
runnableEnv?: Record<string, string>,
142-
runnableEnvCfg?: Record<string, string>,
143-
): Record<string, string> {
141+
runnableEnv?: Env,
142+
runnableEnvCfg?: Env,
143+
): Env {
144144
const env = prepareBaseEnv(inheritEnv, runnableEnv);
145145

146146
if (runnableEnvCfg) {

editors/code/src/tasks.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from "vscode";
22
import type { Config } from "./config";
33
import * as toolchain from "./toolchain";
4+
import { Env } from "./util";
45

56
// This ends up as the `type` key in tasks.json. RLS also uses `cargo` and
67
// our configuration should be compatible with it so use the same key.
@@ -117,8 +118,8 @@ export async function buildRustTask(
117118
export async function targetToExecution(
118119
definition: TaskDefinition,
119120
options?: {
120-
env?: { [key: string]: string };
121121
cwd?: string;
122+
env?: Env;
122123
},
123124
cargo?: string,
124125
): Promise<vscode.ProcessExecution | vscode.ShellExecution> {
@@ -131,7 +132,14 @@ export async function targetToExecution(
131132
command = definition.command;
132133
args = definition.args || [];
133134
}
134-
return new vscode.ProcessExecution(command, args, options);
135+
return new vscode.ProcessExecution(command, args, {
136+
cwd: options?.cwd,
137+
env:
138+
Object.fromEntries(
139+
Object.entries(options?.env ?? {}).map(([key, value]) => [key, value ?? ""])
140+
)
141+
,
142+
});
135143
}
136144

137145
export function activateTaskProvider(config: Config): vscode.Disposable {

editors/code/src/toolchain.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as os from "os";
33
import * as path from "path";
44
import * as readline from "readline";
55
import * as vscode from "vscode";
6-
import { log, memoizeAsync, unwrapUndefinable } from "./util";
6+
import { Env, log, memoizeAsync, unwrapUndefinable } from "./util";
77
import type { CargoRunnableArgs } from "./lsp_ext";
88

99
interface CompilationArtifact {
@@ -37,8 +37,8 @@ interface CompilerMessage {
3737
export class Cargo {
3838
constructor(
3939
readonly rootFolder: string,
40-
readonly env: Record<string, string>,
41-
) {}
40+
readonly env: Env,
41+
) { }
4242

4343
// Made public for testing purposes
4444
static artifactSpec(cargoArgs: string[], executableArgs?: string[]): ArtifactSpec {
@@ -156,7 +156,7 @@ export class Cargo {
156156

157157
/** Mirrors `toolchain::cargo()` implementation */
158158
// FIXME: The server should provide this
159-
export function cargoPath(env?: Record<string, string>): Promise<string> {
159+
export function cargoPath(env?: Env): Promise<string> {
160160
if (env?.["RUSTC_TOOLCHAIN"]) {
161161
return Promise.resolve("cargo");
162162
}

0 commit comments

Comments
 (0)