@@ -38,35 +38,48 @@ export default class GprTaskProvider implements vscode.TaskProvider<vscode.Task>
3838 }
3939
4040 // eslint-disable-next-line @typescript-eslint/no-unused-vars
41- public async provideTasks ( ) : Promise < vscode . Task [ ] | undefined > {
41+ async provideTasks ( ) : Promise < vscode . Task [ ] | undefined > {
4242 if ( ! this . glsTasks ) {
4343 const project_file = await getProjectFile ( this . client ) ;
4444 const mains_result : GlsMainResult = await this . client . sendRequest ( '$/glsMains' ) ;
45- this . glsTasks = getMainBuildTasks ( project_file , mains_result . mains ) ;
45+ this . glsTasks = getBuildTasks ( project_file , mains_result . mains ) ;
4646 const execs : GlsExecutableResult = await this . client . sendRequest ( '$/glsExecutables' ) ;
4747 this . glsTasks = this . glsTasks . concat (
48- getExecutableRunTasks ( project_file , execs . executables )
48+ getBuildAndRunTasks ( project_file , mains_result . mains , execs . executables )
4949 ) ;
5050 }
5151 return this . glsTasks ;
5252 }
5353
54- resolveTask (
54+ async resolveTask (
5555 task : vscode . Task ,
5656 // eslint-disable-next-line @typescript-eslint/no-unused-vars
5757 _token : vscode . CancellationToken
58- ) : vscode . ProviderResult < vscode . Task > {
58+ ) : Promise < vscode . Task | undefined > {
5959 const definition = task . definition ;
60- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
61- const projectFile : string = definition . projectFile ;
6260 // Make sure that this looks like a execute task by checking that there is a projectFile.
63- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
64- const executableFile : string = definition . executable ;
65- if ( projectFile || projectFile === '' ) {
61+ if ( definition . type == GprTaskProvider . gprTaskType ) {
6662 // Refresh gprbuild command line
67- const args = getMainBuildArgs ( projectFile , executableFile ) ;
68- const shell = new vscode . ShellExecution ( 'gprbuild' , args ) ;
69- const title = `Build Executable for: ${ executableFile } ` ;
63+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
64+ const projectFile : string =
65+ definition . projectFile != undefined
66+ ? definition . projectFile
67+ : await getProjectFile ( this . client ) ;
68+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
69+ const args = getMainBuildArgs ( projectFile , definition . main ) ;
70+ let shell : vscode . ShellExecution ;
71+ let title : string ;
72+ if ( definition . executable != undefined ) {
73+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
74+ args . push ( '&&' , 'clear' , '&&' , definition . executable ) ;
75+ shell = new vscode . ShellExecution ( fullCommand ( 'gprbuild' , args ) ) ;
76+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
77+ title = `Build And Run Main: ${ definition . main } ` ;
78+ } else {
79+ shell = new vscode . ShellExecution ( fullCommand ( 'gprbuild' , args ) ) ;
80+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
81+ title = `Build Main: ${ definition . main } ` ;
82+ }
7083 // resolveTask requires that the same definition object be used.
7184 return new vscode . Task (
7285 definition ,
@@ -81,22 +94,35 @@ export default class GprTaskProvider implements vscode.TaskProvider<vscode.Task>
8194 }
8295}
8396
84- const getMainBuildTasks = ( project_file : string , mainFiles : string [ ] ) : vscode . Task [ ] => {
97+ /**
98+ * Generates the build and run tasks for mains
99+ * @param projectFile - the project file path
100+ * @param mainFiles - a list of main files paths
101+ * @param execs - a list of executable files paths
102+ * @returns a list of tasks
103+ */
104+ function getBuildAndRunTasks (
105+ projectFile : string ,
106+ mainFiles : string [ ] ,
107+ execs : string [ ]
108+ ) : vscode . Task [ ] {
85109 const result : vscode . Task [ ] = [ ] ;
86110 // build current project file
87111 for ( let i = 0 ; i < mainFiles . length ; i ++ ) {
88112 const kind = {
89113 type : GprTaskProvider . gprTaskType ,
90- projectFile : project_file ,
91- mainFile : vscode . workspace . asRelativePath ( mainFiles [ i ] ) ,
114+ projectFile : projectFile ,
115+ main : vscode . workspace . asRelativePath ( mainFiles [ i ] ) ,
116+ executable : vscode . workspace . asRelativePath ( execs [ i ] ) ,
92117 } ;
93- const args = getMainBuildArgs ( kind . projectFile , kind . mainFile ) ;
94- const shell = new vscode . ShellExecution ( 'gprbuild' , args ) ;
118+ const args = getMainBuildArgs ( kind . projectFile , kind . main ) ;
119+ args . push ( '&&' , 'clear' , '&&' , kind . executable ) ;
120+ const shell = new vscode . ShellExecution ( fullCommand ( 'gprbuild' , args ) ) ;
95121 const filename = mainFiles [ i ] . replace ( / ^ .* [ \\ / ] / , '' ) ;
96122 const task = new vscode . Task (
97123 kind ,
98124 vscode . TaskScope . Workspace ,
99- 'Build Executable for File ' + filename ,
125+ 'Build And Run Main: ' + filename ,
100126 'gpr' ,
101127 shell ,
102128 '$gpr'
@@ -106,23 +132,30 @@ const getMainBuildTasks = (project_file: string, mainFiles: string[]): vscode.Ta
106132 }
107133
108134 return result ;
109- } ;
135+ }
110136
111- const getExecutableRunTasks = ( project_file : string , executables : string [ ] ) : vscode . Task [ ] => {
137+ /**
138+ * Generates the build tasks for mains
139+ * @param projectFile - the project file path
140+ * @param mainFiles - a list of main files paths
141+ * @returns a list of tasks
142+ */
143+ function getBuildTasks ( projectFile : string , mainFiles : string [ ] ) : vscode . Task [ ] {
112144 const result : vscode . Task [ ] = [ ] ;
113145 // build current project file
114- for ( let i = 0 ; i < executables . length ; i ++ ) {
146+ for ( let i = 0 ; i < mainFiles . length ; i ++ ) {
115147 const kind = {
116148 type : GprTaskProvider . gprTaskType ,
117- projectFile : project_file ,
118- executable : vscode . workspace . asRelativePath ( executables [ i ] ) ,
149+ projectFile : projectFile ,
150+ main : vscode . workspace . asRelativePath ( mainFiles [ i ] ) ,
119151 } ;
120- const filename = executables [ i ] . replace ( / ^ .* [ \\ / ] / , '' ) ;
121- const shell = new vscode . ShellExecution ( './' + kind . executable , [ ] ) ;
152+ const filename = mainFiles [ i ] . replace ( / ^ .* [ \\ / ] / , '' ) ;
153+ const args = getMainBuildArgs ( kind . projectFile , kind . main ) ;
154+ const shell = new vscode . ShellExecution ( fullCommand ( 'gprbuild' , args ) ) ;
122155 const task = new vscode . Task (
123156 kind ,
124157 vscode . TaskScope . Workspace ,
125- 'Run Executable : ' + filename ,
158+ 'Build Main : ' + filename ,
126159 'gpr' ,
127160 shell ,
128161 '$gpr'
@@ -132,9 +165,15 @@ const getExecutableRunTasks = (project_file: string, executables: string[]): vsc
132165 }
133166
134167 return result ;
135- } ;
168+ }
136169
137- const getMainBuildArgs = ( projectFile ?: string , mainFile ?: string ) : string [ ] => {
170+ /**
171+ * Adds relative arguments for the target build command
172+ * @param projectFile - the project file path
173+ * @param mainFile - the main file path
174+ * @returns a list of arguments
175+ */
176+ function getMainBuildArgs ( projectFile ?: string , mainFile ?: string ) : string [ ] {
138177 const vars : string [ ] [ ] = Object . entries (
139178 vscode . workspace . getConfiguration ( 'ada' ) . get ( 'scenarioVariables' ) ?? [ ]
140179 ) ;
@@ -152,4 +191,18 @@ const getMainBuildArgs = (projectFile?: string, mainFile?: string): string[] =>
152191 args . unshift ( '-P' ) ;
153192 args . unshift ( '-d' ) ;
154193 return args ;
155- } ;
194+ }
195+
196+ /**
197+ * Return the command while ignoring unecessary spaces
198+ * @param command - the command to execute
199+ * @param args - the list of arguments
200+ * @returns a string
201+ */
202+ function fullCommand ( command : string , args : string [ ] ) {
203+ let cmd : string = command + ' ' ;
204+ for ( const arg of args ) {
205+ cmd += arg . replace ( / ^ \s + | \s + $ / g, '' ) + ' ' ;
206+ }
207+ return cmd ;
208+ }
0 commit comments