Skip to content

Commit d7ab128

Browse files
committed
Use alire if alire.toml file in workspace
and `alr` executable in the `PATH` to launch all GNAT tasks. Like `alr exec -- gprbuild ...` Closes eng/ide/ada_language_server#1115
1 parent 26699e7 commit d7ab128

File tree

1 file changed

+82
-55
lines changed

1 file changed

+82
-55
lines changed

integration/vscode/ada/src/gnatTaskProvider.ts

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

1818
import * as vscode from 'vscode';
19+
import commandExists = require('command-exists');
1920
import { SymbolKind } from 'vscode';
2021

2122
/**
@@ -27,8 +28,8 @@ type ExtraArgCallback = () => Promise<string>;
2728
* Tool description
2829
*/
2930
interface TaskProperties {
30-
tool: string; // Executable like gprbuild, gprclean, gnatprove, etc.
31-
args: string[]; // Static list of arguments
31+
command: string[]; // Executable like gprbuild, gprclean, gnatprove,
32+
// etc. and static list of arguments
3233
extra: ExtraArgCallback | undefined; // Dynamic argument callback if any
3334
// Args and extra argument will be wrapped with getGnatArgs if this is set.
3435
title: string; // Title like 'Examine project'
@@ -94,73 +95,79 @@ const getGnatArgs = (args: string[]): string[] => {
9495
*/
9596
const knownTaskKinds: { [id: string]: TaskProperties } = {
9697
examineProject: {
97-
tool: 'gnatprove',
98-
args: getGnatArgs(['--mode=flow']),
98+
command: getGnatArgs(['gnatprove', '--mode=flow']),
9999
extra: undefined,
100100
title: 'Examine project',
101101
},
102102
examineFile: {
103-
tool: 'gnatprove',
104-
args: getGnatArgs(['--mode=flow', '-u', '${fileBasename}']),
103+
command: getGnatArgs(['gnatprove', '--mode=flow', '-u', '${fileBasename}']),
105104
extra: undefined,
106105
title: 'Examine file',
107106
},
108107
examineSubprogram: {
109-
tool: 'gnatprove',
110-
args: ['--mode=flow'],
108+
command: ['gnatprove', '--mode=flow'],
111109
extra: limitSubp,
112110
title: 'Examine subprogram',
113111
},
114112
proveProject: {
115-
tool: 'gnatprove',
116-
args: getGnatArgs([]),
113+
command: getGnatArgs(['gnatprove']),
117114
extra: undefined,
118115
title: 'Prove project',
119116
},
120117
proveFile: {
121-
tool: 'gnatprove',
122-
args: getGnatArgs(['-u', '${fileBasename}']),
118+
command: getGnatArgs(['gnatprove', '-u', '${fileBasename}']),
123119
extra: undefined,
124120
title: 'Prove file',
125121
},
126122
proveSubprogram: {
127-
tool: 'gnatprove',
128-
args: [],
123+
command: ['gnatprove'],
129124
extra: limitSubp,
130125
title: 'Prove subprogram',
131126
},
132127
proveRegion: {
133-
tool: 'gnatprove',
134-
args: ['-u', '${fileBasename}'],
128+
command: ['gnatprove', '-u', '${fileBasename}'],
135129
extra: limitRegion,
136130
title: 'Prove selected region',
137131
},
138132
proveLine: {
139-
tool: 'gnatprove',
140-
args: getGnatArgs(['-u', '${fileBasename}', '--limit-line=${fileBasename}:${lineNumber}']),
133+
command: getGnatArgs([
134+
'gnatprove',
135+
'-u',
136+
'${fileBasename}',
137+
'--limit-line=${fileBasename}:${lineNumber}',
138+
]),
141139
extra: undefined,
142140
title: 'Prove line',
143141
},
144142
buildProject: {
145-
tool: 'gprbuild',
146-
args: getGnatArgs([]),
143+
command: getGnatArgs(['gprbuild']),
147144
extra: undefined,
148145
title: 'Build current project',
149146
},
150147
checkFile: {
151-
tool: 'gprbuild',
152-
args: getGnatArgs(['-q', '-f', '-c', '-u', '-gnatc', '${fileBasename}']),
148+
command: getGnatArgs(['gprbuild', '-q', '-f', '-c', '-u', '-gnatc', '${fileBasename}']),
153149
extra: undefined,
154150
title: 'Check current file',
155151
},
156152
cleanProject: {
157-
tool: 'gprclean',
158-
args: commonArgs([]), // No -cargs -gnatef is accepted by gprclean
153+
command: commonArgs(['gprbuild']), // No -cargs -gnatef is accepted by gprclean
159154
extra: undefined,
160155
title: 'Clean current project',
161156
},
162157
};
163158

159+
// Alire `exec` command if we have `alr` installed and `alire.toml`
160+
async function alire(): Promise<string[]> {
161+
return vscode.workspace.findFiles('alire.toml').then((found) =>
162+
found.length == 0
163+
? [] // not alire.toml found, return no command
164+
: // if alire.toml found, search for `alr`
165+
commandExists('alr')
166+
.then(() => ['alr', 'exec', '--'])
167+
.catch(() => [])
168+
);
169+
}
170+
164171
/**
165172
* Task provider itself
166173
*/
@@ -173,9 +180,12 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
173180
}
174181

175182
// eslint-disable-next-line @typescript-eslint/no-unused-vars
176-
provideTasks(_token: vscode.CancellationToken): vscode.Task[] {
183+
provideTasks(_token: vscode.CancellationToken): vscode.ProviderResult<vscode.Task[]> {
177184
if (!this.gnatTasks) {
178-
this.gnatTasks = getTasks();
185+
return getTasks().then((list) => {
186+
this.gnatTasks = list;
187+
return list;
188+
});
179189
}
180190
return this.gnatTasks;
181191
}
@@ -197,8 +207,25 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
197207
// We have a callback, evaluate it to get an extra argument and
198208
// wrap all args with getGnatArgs
199209
return item.extra().then((extra) => {
200-
const args = getGnatArgs(item.args.concat(extraArgs, extra ? [extra] : []));
201-
const shell = new vscode.ShellExecution(item.tool, args);
210+
return alire().then((alr) => {
211+
const cmd = getGnatArgs(
212+
alr.concat(item.command, extraArgs, extra ? [extra] : [])
213+
);
214+
const shell = new vscode.ShellExecution(cmd[0], cmd.slice(1));
215+
return new vscode.Task(
216+
definition,
217+
vscode.TaskScope.Workspace, // scope
218+
task.name,
219+
'ada', // source
220+
shell,
221+
'$ada' // problemMatchers
222+
);
223+
});
224+
});
225+
} else {
226+
return alire().then((alr) => {
227+
const cmd = alr.concat(item.command, extraArgs);
228+
const shell = new vscode.ShellExecution(cmd[0], cmd.slice(1));
202229
return new vscode.Task(
203230
definition,
204231
vscode.TaskScope.Workspace, // scope
@@ -208,16 +235,6 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
208235
'$ada' // problemMatchers
209236
);
210237
});
211-
} else {
212-
const shell = new vscode.ShellExecution(item.tool, item.args.concat(extraArgs));
213-
return new vscode.Task(
214-
definition,
215-
vscode.TaskScope.Workspace, // scope
216-
task.name,
217-
'ada', // source
218-
shell,
219-
'$ada' // problemMatchers
220-
);
221238
}
222239
} else {
223240
return task;
@@ -228,25 +245,35 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
228245
/**
229246
* Return all known tasks
230247
*/
231-
const getTasks = (): vscode.Task[] => {
232-
const result: vscode.Task[] = [];
248+
async function getTasks(): Promise<vscode.Task[]> {
249+
return alire().then((alr) => {
250+
const result: vscode.Task[] = [];
233251

234-
for (const taskKind in knownTaskKinds) {
235-
const item: TaskProperties = knownTaskKinds[taskKind];
236-
const title: string = item.title;
237-
const kind = {
238-
type: GnatTaskProvider.gnatType,
239-
projectFile: '${config:ada.projectFile}',
240-
taskKind: taskKind,
241-
};
242-
const shell = new vscode.ShellExecution(item.tool, item.args);
243-
const task = new vscode.Task(kind, vscode.TaskScope.Workspace, title, 'ada', shell, '$ada');
244-
task.group = vscode.TaskGroup.Build;
245-
result.push(task);
246-
}
252+
for (const taskKind in knownTaskKinds) {
253+
const item: TaskProperties = knownTaskKinds[taskKind];
254+
const title: string = item.title;
255+
const kind = {
256+
type: GnatTaskProvider.gnatType,
257+
projectFile: '${config:ada.projectFile}',
258+
taskKind: taskKind,
259+
};
260+
const cmd = alr.concat(item.command);
261+
const shell = new vscode.ShellExecution(cmd[0], cmd.slice(1));
262+
const task = new vscode.Task(
263+
kind,
264+
vscode.TaskScope.Workspace,
265+
title,
266+
'ada',
267+
shell,
268+
'$ada'
269+
);
270+
task.group = vscode.TaskGroup.Build;
271+
result.push(task);
272+
}
247273

248-
return result;
249-
};
274+
return result;
275+
});
276+
}
250277

251278
/**
252279
* Return the DocumentSymbol associated to the subprogram enclosing the

0 commit comments

Comments
 (0)