Skip to content

Substitute variables in task "args" #1544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 8, 2025
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
12 changes: 11 additions & 1 deletion src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ const configuration = {
};

const vsCodeVariableRegex = new RegExp(/\$\{(.+?)\}/g);
function substituteVariablesInString(val: string): string {
export function substituteVariablesInString(val: string): string {
return val.replace(vsCodeVariableRegex, (substring: string, varName: string) =>
typeof varName === "string" ? computeVscodeVar(varName) || substring : substring
);
Expand All @@ -494,14 +494,24 @@ function computeVscodeVar(varName: string): string | null {
return vscode.workspace.workspaceFolders?.at(0)?.uri.fsPath ?? "";
};

const file = () => vscode.window.activeTextEditor?.document?.uri?.fsPath || "";

// https://code.visualstudio.com/docs/editor/variables-reference
// Variables to be substituted should be added here.
const supportedVariables: { [k: string]: () => string } = {
workspaceFolder,
fileWorkspaceFolder: workspaceFolder,
workspaceFolderBasename: () => path.basename(workspaceFolder()),
cwd: () => process.cwd(),
userHome: () => os.homedir(),
pathSeparator: () => path.sep,
file,
relativeFile: () => path.relative(workspaceFolder(), file()),
relativeFileDirname: () => path.dirname(path.relative(workspaceFolder(), file())),
fileBasename: () => path.basename(file()),
fileExtname: () => path.extname(file()),
fileDirname: () => path.dirname(file()),
fileDirnameBasename: () => path.basename(path.dirname(file())),
};

return varName in supportedVariables ? supportedVariables[varName]() : null;
Expand Down
7 changes: 5 additions & 2 deletions src/tasks/SwiftPluginTaskProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import { PackagePlugin } from "../SwiftPackage";
import { swiftRuntimeEnv } from "../utilities/utilities";
import { SwiftExecution } from "../tasks/SwiftExecution";
import { resolveTaskCwd } from "../utilities/tasks";
import configuration, { PluginPermissionConfiguration } from "../configuration";
import configuration, {
PluginPermissionConfiguration,
substituteVariablesInString,
} from "../configuration";
import { SwiftTask } from "./SwiftTaskProvider";
import { SwiftToolchain } from "../toolchain/toolchain";

Expand Down Expand Up @@ -86,7 +89,7 @@ export class SwiftPluginTaskProvider implements vscode.TaskProvider {
"package",
...this.pluginArguments(task.definition as PluginPermissionConfiguration),
task.definition.command,
...task.definition.args,
...(task.definition.args ?? []).map(substituteVariablesInString),
];
swiftArgs = currentFolder.toolchain.buildFlags.withAdditionalFlags(swiftArgs);

Expand Down
9 changes: 7 additions & 2 deletions src/tasks/SwiftTaskProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import * as vscode from "vscode";
import { WorkspaceContext } from "../WorkspaceContext";
import { FolderContext } from "../FolderContext";
import { Product } from "../SwiftPackage";
import configuration, { ShowBuildStatusOptions } from "../configuration";
import configuration, {
ShowBuildStatusOptions,
substituteVariablesInString,
} from "../configuration";
import { swiftRuntimeEnv } from "../utilities/utilities";
import { Version } from "../utilities/version";
import { SwiftToolchain } from "../toolchain/toolchain";
Expand Down Expand Up @@ -442,7 +445,9 @@ export class SwiftTaskProvider implements vscode.TaskProvider {
platform = task.definition.macos;
}
// get args and cwd values from either platform specific block or base
const args = platform?.args ?? task.definition.args;
const args = (platform?.args ?? task.definition.args ?? []).map(
substituteVariablesInString
);
const env = platform?.env ?? task.definition.env;
const fullCwd = resolveTaskCwd(task, platform?.cwd ?? task.definition.cwd);
const fullEnv = {
Expand Down
26 changes: 26 additions & 0 deletions test/unit-tests/tasks/SwiftPluginTaskProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import * as vscode from "vscode";
import * as assert from "assert";
import * as os from "os";
import * as path from "path";
import { match } from "sinon";
import { WorkspaceContext } from "../../../src/WorkspaceContext";
Expand Down Expand Up @@ -269,5 +270,30 @@ suite("SwiftPluginTaskProvider Unit Test Suite", () => {
"my-plugin",
]);
});

test("substitutes variables", async () => {
const taskProvider = new SwiftPluginTaskProvider(instance(workspaceContext));
const task = new vscode.Task(
{
type: "swift-plugin",
args: ["${cwd}", "${userHome}"],
command: "my-plugin",
},
workspaceFolder,
"MyPlugin",
"swift"
);
const resolvedTask = taskProvider.resolveTask(
task,
new vscode.CancellationTokenSource().token
);
const swiftExecution = resolvedTask.execution as SwiftExecution;
assert.deepEqual(swiftExecution.args, [
"package",
"my-plugin",
process.cwd(),
os.homedir(),
]);
});
});
});
26 changes: 26 additions & 0 deletions test/unit-tests/tasks/SwiftTaskProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import * as vscode from "vscode";
import * as assert from "assert";
import * as os from "os";
import { match } from "sinon";
import { WorkspaceContext } from "../../../src/WorkspaceContext";
import {
Expand Down Expand Up @@ -330,6 +331,31 @@ suite("SwiftTaskProvider Unit Test Suite", () => {
assert.equal(swiftExecution.command, "/path/to/bin/swift");
});

test("substitutes variables", () => {
const taskProvider = new SwiftTaskProvider(instance(workspaceContext));
const task = new vscode.Task(
{
type: "swift",
args: ["run", "PackageExe", "--", "${cwd}", "${userHome}"],
},
workspaceFolder,
"run PackageExe",
"swift"
);
const resolvedTask = taskProvider.resolveTask(
task,
new vscode.CancellationTokenSource().token
);
const swiftExecution = resolvedTask.execution as SwiftExecution;
assert.deepEqual(swiftExecution.args, [
"run",
"PackageExe",
"--",
process.cwd(),
os.homedir(),
]);
});

suite("Platform cwd", () => {
test("includes macos cwd", () => {
platformMock.setValue("darwin");
Expand Down
Loading