Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions editors/code/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import type { Disposable } from "vscode";

export type RunnableEnvCfgItem = {
mask?: string;
env: Record<string, string>;
env: { [key: string]: { toString(): string } | null };
platform?: string | string[];
};
export type RunnableEnvCfg = Record<string, string> | RunnableEnvCfgItem[];

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

Expand Down Expand Up @@ -261,18 +260,13 @@ export class Config {
return this.get<boolean | undefined>("testExplorer");
}

runnablesExtraEnv(label: string): Record<string, string> | undefined {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const item = this.get<any>("runnables.extraEnv") ?? this.get<any>("runnableEnv");
if (!item) return undefined;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const fixRecord = (r: Record<string, any>) => {
for (const key in r) {
if (typeof r[key] !== "string") {
r[key] = String(r[key]);
}
}
};
runnablesExtraEnv(label: string): Env {
const serverEnv = this.serverExtraEnv;
let extraEnv =
this.get<
RunnableEnvCfgItem[] | { [key: string]: { toString(): string } | null } | null
>("runnables.extraEnv") ?? {};
if (!extraEnv) return serverEnv;

const platform = process.platform;
const checkPlatform = (it: RunnableEnvCfgItem) => {
Expand All @@ -283,19 +277,25 @@ export class Config {
return true;
};

if (item instanceof Array) {
if (extraEnv instanceof Array) {
const env = {};
for (const it of item) {
for (const it of extraEnv) {
const masked = !it.mask || new RegExp(it.mask).test(label);
if (masked && checkPlatform(it)) {
Object.assign(env, it.env);
}
}
fixRecord(env);
return env;
extraEnv = env;
}
fixRecord(item);
return item;
const runnableExtraEnv = substituteVariablesInEnv(
Object.fromEntries(
Object.entries(extraEnv).map(([k, v]) => [
k,
typeof v === "string" ? v : v?.toString(),
]),
),
);
return { ...runnableExtraEnv, ...serverEnv };
}

get restartServerOnConfigChange() {
Expand Down
29 changes: 15 additions & 14 deletions editors/code/src/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ import type * as ra from "./lsp_ext";
import { Cargo } from "./toolchain";
import type { Ctx } from "./ctx";
import { createTaskFromRunnable, prepareEnv } from "./run";
import { execute, isCargoRunnableArgs, unwrapUndefinable, log, normalizeDriveLetter } from "./util";
import {
execute,
isCargoRunnableArgs,
unwrapUndefinable,
log,
normalizeDriveLetter,
Env,
} from "./util";
import type { Config } from "./config";

// Here we want to keep track on everything that's currently running
Expand Down Expand Up @@ -206,10 +213,7 @@ type SourceFileMap = {
destination: string;
};

async function discoverSourceFileMap(
env: Record<string, string>,
cwd: string,
): Promise<SourceFileMap | undefined> {
async function discoverSourceFileMap(env: Env, cwd: string): Promise<SourceFileMap | undefined> {
const sysroot = env["RUSTC_TOOLCHAIN"];
if (sysroot) {
// let's try to use the default toolchain
Expand All @@ -232,7 +236,7 @@ type PropertyFetcher<Config, Input, Key extends keyof Config> = (

type DebugConfigProvider<Type extends string, DebugConfig extends BaseDebugConfig<Type>> = {
executableProperty: keyof DebugConfig;
environmentProperty: PropertyFetcher<DebugConfig, Record<string, string>, keyof DebugConfig>;
environmentProperty: PropertyFetcher<DebugConfig, Env, keyof DebugConfig>;
runnableArgsProperty: PropertyFetcher<DebugConfig, ra.CargoRunnableArgs, keyof DebugConfig>;
sourceFileMapProperty?: keyof DebugConfig;
type: Type;
Expand Down Expand Up @@ -276,7 +280,7 @@ const knownEngines: {
"environment",
Object.entries(env).map((entry) => ({
name: entry[0],
value: entry[1],
value: entry[1] ?? "",
})),
],
runnableArgsProperty: (runnableArgs: ra.CargoRunnableArgs) => [
Expand Down Expand Up @@ -304,10 +308,7 @@ const knownEngines: {
},
};

async function getDebugExecutable(
runnableArgs: ra.CargoRunnableArgs,
env: Record<string, string>,
): Promise<string> {
async function getDebugExecutable(runnableArgs: ra.CargoRunnableArgs, env: Env): Promise<string> {
const cargo = new Cargo(runnableArgs.workspaceRoot || ".", env);
const executable = await cargo.executableFromArgs(runnableArgs);

Expand All @@ -328,7 +329,7 @@ function getDebugConfig(
runnable: ra.Runnable,
runnableArgs: ra.CargoRunnableArgs,
executable: string,
env: Record<string, string>,
env: Env,
sourceFileMap?: Record<string, string>,
): vscode.DebugConfiguration {
const {
Expand Down Expand Up @@ -380,14 +381,14 @@ type CodeLldbDebugConfig = {
args: string[];
sourceMap: Record<string, string> | undefined;
sourceLanguages: ["rust"];
env: Record<string, string>;
env: Env;
} & BaseDebugConfig<"lldb">;

type NativeDebugConfig = {
target: string;
// See https://github.com/WebFreak001/code-debug/issues/359
arguments: string;
env: Record<string, string>;
env: Env;
valuesFormatting: "prettyPrinters";
} & BaseDebugConfig<"gdb">;

Expand Down
15 changes: 4 additions & 11 deletions editors/code/src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { CtxInit } from "./ctx";
import { makeDebugConfig } from "./debug";
import type { Config } from "./config";
import type { LanguageClient } from "vscode-languageclient/node";
import { log, unwrapUndefinable, type RustEditor } from "./util";
import { Env, log, unwrapUndefinable, type RustEditor } from "./util";

const quickPickButtons = [
{ iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configuration." },
Expand Down Expand Up @@ -122,11 +122,8 @@ export class RunnableQuickPick implements vscode.QuickPickItem {
}
}

export function prepareBaseEnv(
inheritEnv: boolean,
base?: Record<string, string>,
): Record<string, string> {
const env: Record<string, string> = { RUST_BACKTRACE: "short" };
export function prepareBaseEnv(inheritEnv: boolean, base?: Env): Env {
const env: Env = { RUST_BACKTRACE: "short" };
if (inheritEnv) {
Object.assign(env, process.env);
}
Expand All @@ -136,11 +133,7 @@ export function prepareBaseEnv(
return env;
}

export function prepareEnv(
inheritEnv: boolean,
runnableEnv?: Record<string, string>,
runnableEnvCfg?: Record<string, string>,
): Record<string, string> {
export function prepareEnv(inheritEnv: boolean, runnableEnv?: Env, runnableEnvCfg?: Env): Env {
const env = prepareBaseEnv(inheritEnv, runnableEnv);

if (runnableEnvCfg) {
Expand Down
10 changes: 8 additions & 2 deletions editors/code/src/tasks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as vscode from "vscode";
import type { Config } from "./config";
import * as toolchain from "./toolchain";
import { Env } from "./util";

// This ends up as the `type` key in tasks.json. RLS also uses `cargo` and
// our configuration should be compatible with it so use the same key.
Expand Down Expand Up @@ -117,8 +118,8 @@ export async function buildRustTask(
export async function targetToExecution(
definition: TaskDefinition,
options?: {
env?: { [key: string]: string };
cwd?: string;
env?: Env;
},
cargo?: string,
): Promise<vscode.ProcessExecution | vscode.ShellExecution> {
Expand All @@ -131,7 +132,12 @@ export async function targetToExecution(
command = definition.command;
args = definition.args || [];
}
return new vscode.ProcessExecution(command, args, options);
return new vscode.ProcessExecution(command, args, {
cwd: options?.cwd,
env: Object.fromEntries(
Object.entries(options?.env ?? {}).map(([key, value]) => [key, value ?? ""]),
),
});
}

export function activateTaskProvider(config: Config): vscode.Disposable {
Expand Down
6 changes: 3 additions & 3 deletions editors/code/src/toolchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as os from "os";
import * as path from "path";
import * as readline from "readline";
import * as vscode from "vscode";
import { log, memoizeAsync, unwrapUndefinable } from "./util";
import { Env, log, memoizeAsync, unwrapUndefinable } from "./util";
import type { CargoRunnableArgs } from "./lsp_ext";

interface CompilationArtifact {
Expand Down Expand Up @@ -37,7 +37,7 @@ interface CompilerMessage {
export class Cargo {
constructor(
readonly rootFolder: string,
readonly env: Record<string, string>,
readonly env: Env,
) {}

// Made public for testing purposes
Expand Down Expand Up @@ -156,7 +156,7 @@ export class Cargo {

/** Mirrors `toolchain::cargo()` implementation */
// FIXME: The server should provide this
export function cargoPath(env?: Record<string, string>): Promise<string> {
export function cargoPath(env?: Env): Promise<string> {
if (env?.["RUSTC_TOOLCHAIN"]) {
return Promise.resolve("cargo");
}
Expand Down
Loading