Skip to content
Draft
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Features:

Bug Fixes:

- Fix tasks defined in `.code-workspace` files getting stuck with `Cannot read properties of undefined (reading 'path')` error. [#4529](https://github.com/microsoft/vscode-cmake-tools/issues/4529)
- Fix CMake script path links not working in CHS/CSY/FRA/PLK locales due to localized quotes. [#4383](https://github.com/microsoft/vscode-cmake-tools/issues/4383)
- Fix user-level tasks defined in `~/.config/Code/User/tasks.json` causing infinite spinner. [#4659](https://github.com/microsoft/vscode-cmake-tools/pull/4659)
- Fix `cmake.compileFile` failing to find compilation info when using presets without `CMAKE_EXPORT_COMPILE_COMMANDS`. [#4484](https://github.com/microsoft/vscode-cmake-tools/issues/4484)
Expand Down
23 changes: 17 additions & 6 deletions src/cmakeTaskProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,7 @@ export class CMakeTaskProvider implements vscode.TaskProvider {
const execution: any = task.execution;
if (!execution) {
const definition: CMakeTaskDefinition = <any>task.definition;
// task.scope can be a WorkspaceFolder, TaskScope.Global, or TaskScope.Workspace.
// Only use it as a WorkspaceFolder if it's an object (not a number or null).
const workspaceFolder: vscode.WorkspaceFolder | undefined = (task.scope && typeof task.scope === 'object') ? task.scope as vscode.WorkspaceFolder : undefined;
const workspaceFolder = CMakeTaskProvider.getWorkspaceFolderFromTask(task);
const resolvedTask: CMakeTask = new vscode.Task(definition, workspaceFolder ?? vscode.TaskScope.Workspace, definition.label, CMakeTaskProvider.CMakeSourceStr,
new vscode.CustomExecution(async (resolvedDefinition: vscode.TaskDefinition): Promise<vscode.Pseudoterminal> =>
new CustomBuildTaskTerminal(resolvedDefinition.command, resolvedDefinition.targets, workspaceFolder, resolvedDefinition.preset, resolvedDefinition.options)
Expand All @@ -244,9 +242,7 @@ export class CMakeTaskProvider implements vscode.TaskProvider {
const execution: any = task.execution;
if (!execution) {
const definition: CMakeTaskDefinition = <any>task.definition;
// task.scope can be a WorkspaceFolder, TaskScope.Global, or TaskScope.Workspace.
// Only use it as a WorkspaceFolder if it's an object (not a number or null).
const workspaceFolder: vscode.WorkspaceFolder | undefined = (task.scope && typeof task.scope === 'object') ? task.scope as vscode.WorkspaceFolder : undefined;
const workspaceFolder = CMakeTaskProvider.getWorkspaceFolderFromTask(task);
const resolvedTask: CMakeTask = new vscode.Task(definition, workspaceFolder ?? vscode.TaskScope.Workspace, definition.label, CMakeTaskProvider.CMakeSourceStr,
new vscode.CustomExecution(async (resolvedDefinition: vscode.TaskDefinition): Promise<vscode.Pseudoterminal> =>
new CustomBuildTaskTerminal(resolvedDefinition.command, resolvedDefinition.targets, workspaceFolder, resolvedDefinition.preset, resolvedDefinition.options)
Expand All @@ -256,6 +252,21 @@ export class CMakeTaskProvider implements vscode.TaskProvider {
return task;
}

/**
* Extracts the workspace folder from a task's scope.
* task.scope can be a WorkspaceFolder, TaskScope.Global, or TaskScope.Workspace.
* When the scope is not a WorkspaceFolder (e.g. tasks defined in .code-workspace files),
* falls back to the active project's workspace folder or the first available workspace folder.
*/
private static getWorkspaceFolderFromTask(task: CMakeTask): vscode.WorkspaceFolder | undefined {
if (task.scope && typeof task.scope === 'object') {
return task.scope as vscode.WorkspaceFolder;
}
// For tasks defined in .code-workspace files, task.scope is TaskScope.Workspace (a number).
// Try to resolve a workspace folder from the active project or available workspace folders.
return getActiveProject()?.workspaceFolder ?? vscode.workspace.workspaceFolders?.[0];
}

public static async findBuildTask(workspaceFolder: string, presetName?: string, targets?: string[], expansionOptions?: expand.ExpansionOptions): Promise<CMakeTask | undefined> {
// Fetch all CMake task from `tasks.json` files.
const allTasks: vscode.Task[] = await vscode.tasks.fetchTasks({ type: CMakeTaskProvider.CMakeScriptType });
Expand Down