Skip to content

Commit bba1518

Browse files
committed
Fix vscode run main task when executable is at workspace root
For eng/ide/ada_language_server#1439
1 parent 41043c3 commit bba1518

File tree

7 files changed

+62
-32
lines changed

7 files changed

+62
-32
lines changed

integration/vscode/ada/src/taskProviders.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
----------------------------------------------------------------------------*/
1717

1818
import assert from 'assert';
19-
import { basename } from 'path';
19+
import path, { basename } from 'path';
2020
import * as vscode from 'vscode';
2121
import { CMD_GPR_PROJECT_ARGS } from './commands';
2222
import { adaExtState, logger } from './extension';
@@ -406,11 +406,19 @@ export class SimpleTaskProvider implements vscode.TaskProvider {
406406
taskGroup: vscode.TaskGroup.Build,
407407
};
408408

409+
let execPath = main.execRelPath();
410+
/**
411+
* If the exec is directly at the root of the workspace,
412+
* prepend ./ to make it possible for shells to execute it.
413+
*/
414+
if (!execPath.includes(path.sep)) {
415+
execPath = './' + execPath;
416+
}
409417
const runTask: PredefinedTask = {
410418
label: getRunTaskPlainName(main),
411419
taskDef: {
412420
type: this.taskType,
413-
command: main.execRelPath(),
421+
command: execPath,
414422
args: [],
415423
},
416424
};

integration/vscode/ada/test/suite/general/tasks.test.ts

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -303,27 +303,46 @@ suite('Task Execution', function () {
303303

304304
/**
305305
* Check that the 'buildAndRunMain' task works fine with projects that
306-
* do not explicitly define an object directory.
306+
* produce the executable at the root of the workspace. In that case it is
307+
* necessary to use a leading `./` for the shell to be able to spawn the
308+
* executable.
307309
*/
308-
test('Build and run main task without object directory', async () => {
310+
test('Build and run main task when exec at workspace root', async () => {
309311
// Load a custom project that does not define any object dir by
310312
// changing the 'ada.projectFile' setting.
311313
const initialProjectFile = vscode.workspace.getConfiguration().get('ada.projectFile');
312314
try {
313315
await vscode.workspace
314316
.getConfiguration()
315-
.update(
316-
'ada.projectFile',
317-
'default_without_obj_dir' + path.sep + 'default_without_obj_dir.gpr'
318-
);
317+
.update('ada.projectFile', 'prj_exec_at_root' + path.sep + 'prj_exec_at_root.gpr');
318+
319319
/**
320320
* Wait a bit until the ALS loads the new project
321321
*/
322322
await new Promise((resolve) => setTimeout(resolve, 1000));
323+
324+
/**
325+
* Check that the task command starts with ./
326+
*/
327+
const runTask = (await vscode.tasks.fetchTasks({ type: 'ada' })).find((t) =>
328+
t.name.includes('Run main'),
329+
);
330+
assert(runTask?.execution instanceof vscode.ShellExecution);
331+
const cmdLine = getCmdLine(runTask.execution);
332+
assert(
333+
cmdLine.startsWith('.' + path.sep),
334+
`Task command doesn't start with './': ${cmdLine}`,
335+
);
336+
337+
/**
338+
* Check that the build and run task work.
339+
*/
340+
await testTask('Build main - src/main1.adb', testedTaskLabels, allProvidedTasks);
341+
await testTask('Run main - src/main1.adb', testedTaskLabels, allProvidedTasks);
323342
await testTask(
324343
'Build and run main - src/main1.adb',
325344
testedTaskLabels,
326-
allProvidedTasks
345+
allProvidedTasks,
327346
);
328347
} finally {
329348
// Reset the 'ada.projectFile' setting. If the previous value was

integration/vscode/ada/test/suite/utils.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,19 @@ export async function runTaskAndGetResult(task: vscode.Task): Promise<number | u
175175
* @param exec - a ShellExecution
176176
* @returns the command line of the ShellExecution as a string
177177
*/
178-
export function getCmdLine(exec: vscode.ShellExecution) {
179-
return [exec.command]
180-
.concat(exec.args)
181-
.map((s) => {
182-
if (typeof s == 'object') {
183-
return s.value;
184-
} else {
185-
return s;
186-
}
187-
})
188-
.join(' ');
178+
export function getCmdLine(exec: vscode.ShellExecution): string {
179+
return exec.command
180+
? [exec.command]
181+
.concat(exec.args)
182+
.map((s) => {
183+
if (typeof s == 'object') {
184+
return s.value;
185+
} else {
186+
return s;
187+
}
188+
})
189+
.join(' ')
190+
: (exec.commandLine ?? '');
189191
}
190192

191193
/**

integration/vscode/ada/test/workspaces/general/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33

44
# Generated when testing gnatsas tasks
55
/report.sarif
6+
7+
# Executables produced at the root of the workspace
8+
/main1exec
9+
/main1exec.exe

integration/vscode/ada/test/workspaces/general/default_without_obj_dir/.gitignore

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/obj/
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
project Default_Without_Obj_Dir is
1+
project Prj_Exec_At_Root is
22

33
Tools_Mains :=
44
("main1.adb",
55
"test.adb");
66

77
for Source_Dirs use ("../src/**");
8+
for Object_Dir use "obj";
89
for Main use Tools_Mains;
910

11+
-- Use this to produce the executable at the root of the workspace to test
12+
-- that the run main task will prepend './' to make it executable by the
13+
-- underlying shell.
14+
for Exec_Dir use "..";
15+
1016
package Builder is
1117
for Executable ("main1.adb") use "main1exec";
1218
end Builder;
@@ -15,4 +21,4 @@ project Default_Without_Obj_Dir is
1521
for Default_Switches ("Ada") use ("-g", "-O0");
1622
end Compiler;
1723

18-
end Default_Without_Obj_Dir;
24+
end Prj_Exec_At_Root;

0 commit comments

Comments
 (0)