@@ -13,11 +13,14 @@ import { setupMSVC } from "./msvc/msvc"
13
13
import { setupNinja } from "./ninja/ninja"
14
14
import { setupOpencppcoverage } from "./opencppcoverage/opencppcoverage"
15
15
import { setupPython } from "./python/python"
16
+ import mri from "mri"
16
17
17
18
import semverValid from "semver/functions/valid"
18
19
import { getVersion } from "./default_versions"
19
20
import { setupGcc } from "./gcc/gcc"
21
+ import { InstallationInfo } from "./utils/setup/setupBin"
20
22
23
+ /** The setup functions */
21
24
const setups = {
22
25
cmake : setupCmake ,
23
26
ninja : setupNinja ,
@@ -36,6 +39,7 @@ const setups = {
36
39
msvc : setupMSVC ,
37
40
}
38
41
42
+ /** The tools that can be installed */
39
43
const tools : Array < keyof typeof setups > = [
40
44
"cmake" ,
41
45
"ninja" ,
@@ -54,22 +58,35 @@ const tools: Array<keyof typeof setups> = [
54
58
"msvc" ,
55
59
]
56
60
57
- type Inputs = "compiler" | keyof typeof setups
61
+ /** The possible inputs to the program */
62
+ type Inputs = keyof typeof setups | "compiler" | "architecture"
58
63
59
- function maybeGetInput ( key : Inputs ) {
60
- const value = core . getInput ( key . toLowerCase ( ) )
61
- if ( value !== "false" && value !== "" ) {
62
- return value
63
- }
64
- return undefined // skip installation
65
- }
64
+ // an array of possible inputs
65
+ const inputs : Array < Inputs > = [ "compiler" , "architecture" , ...tools ]
66
+
67
+ /** The main entry function */
68
+ export async function main ( args : string [ ] ) : Promise < number > {
69
+ // parse options using mri or github actions
70
+ const opts = mri < Record < Inputs , string | undefined > > ( args , {
71
+ string : inputs ,
72
+ default : Object . fromEntries ( inputs . map ( ( inp ) => [ inp , maybeGetInput ( inp ) ] ) ) ,
73
+ } )
66
74
67
- export async function main ( ) : Promise < number > {
68
- const arch = core . getInput ( "architecture" ) || process . arch
75
+ // cpu architecture
76
+ const arch = opts . architecture ?? process . arch
77
+
78
+ // the installation dir for the tools that are downloaded directly
69
79
const setupCppDir = process . env . SETUP_CPP_DIR ?? "~/setup_cpp"
80
+
81
+ // report messages
82
+ const successMessages : string [ ] = [ ]
83
+ const errorMessages : string [ ] = [ ]
84
+
85
+ // installing the specified compiler
86
+ const maybeCompiler = opts . compiler
70
87
try {
71
- const maybeCompiler = maybeGetInput ( "compiler" )
72
88
if ( maybeCompiler !== undefined ) {
89
+ // detecting the compiler version. Devide the given string by `-` and use the second element as the version
73
90
const compilerAndMaybeVersion = maybeCompiler . split ( "-" )
74
91
const compiler = compilerAndMaybeVersion [ 0 ]
75
92
let version : string | undefined
@@ -82,6 +99,7 @@ export async function main(): Promise<number> {
82
99
}
83
100
}
84
101
102
+ // install the compiler. We allow some aliases for the compiler name
85
103
switch ( compiler ) {
86
104
case "llvm" :
87
105
case "clang" :
@@ -107,61 +125,79 @@ export async function main(): Promise<number> {
107
125
break
108
126
}
109
127
default : {
110
- core . error ( `Unsupported compiler ${ compiler } ` )
128
+ errorMessages . push ( `Unsupported compiler ${ compiler } ` )
111
129
}
112
130
}
113
131
}
132
+ } catch ( e ) {
133
+ errorMessages . push ( `Failed to install the ${ maybeCompiler } ` )
134
+ }
135
+
136
+ // installing the specified tools
137
+
138
+ // loop over the tools and run their setup function
139
+ for ( const tool of tools ) {
140
+ // get the version or "true" or undefined for this tool from the options
141
+ const value = opts [ tool ]
142
+
143
+ // skip if undefined
144
+ if ( value !== undefined ) {
145
+ // get the setup function
146
+ const setupFunction = setups [ tool ]
147
+
148
+ // runnig the setup function for this tool
149
+ try {
150
+ // eslint-disable-next-line no-await-in-loop
151
+ const installationInfo = await setupFunction ( getVersion ( tool , value ) , setupCppDir , arch )
114
152
115
- const toolsSucceeded : string [ ] = [ ]
116
- const toolsErrored : string [ ] = [ ]
117
- for ( const tool of tools ) {
118
- const version = maybeGetInput ( tool )
119
- if ( version !== undefined ) {
120
- const setupFunction = setups [ tool ]
121
-
122
- try {
123
- // eslint-disable-next-line no-await-in-loop
124
- const installationInfo = await setupFunction ( getVersion ( tool , version ) , setupCppDir , arch )
125
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
126
- if ( installationInfo !== undefined ) {
127
- let success = `${ tool } was successfully installed`
128
- if ( "installDir" in installationInfo ) {
129
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
130
- // @ts -ignore typescript is confused about the existence of installDir
131
- success += `\nThe installation direcotry is ${ installationInfo . installDir } `
132
- }
133
- if ( installationInfo . binDir !== "" ) {
134
- success += `\nThe binary direcotry is ${ installationInfo . binDir } `
135
- }
136
- toolsSucceeded . push ( success )
137
- } else {
138
- toolsSucceeded . push ( `${ tool } was successfully installed` )
139
- }
140
- } catch ( e ) {
141
- toolsErrored . push ( `${ tool } failed to install` )
153
+ // preparing a report string
154
+ if ( installationInfo !== undefined ) {
155
+ successMessages . push ( getSuccessMessage ( tool , installationInfo ) )
156
+ } else {
157
+ successMessages . push ( `${ tool } was successfully installed` )
142
158
}
159
+ } catch ( e ) {
160
+ // push error message to the logger
161
+ errorMessages . push ( `${ tool } failed to install` )
143
162
}
144
163
}
145
-
146
- console . log ( "\n\n\n" )
147
- toolsSucceeded . forEach ( ( tool ) => core . info ( tool ) )
148
- toolsErrored . forEach ( ( tool ) => core . error ( tool ) )
149
- } catch ( err ) {
150
- core . error ( err as string | Error )
151
- core . setFailed ( "install-cpp failed" )
152
- return 1
153
164
}
154
165
166
+ // report the messages in the end
167
+ console . log ( "\n\n\n" )
168
+ successMessages . forEach ( ( tool ) => core . info ( tool ) )
169
+ errorMessages . forEach ( ( tool ) => core . error ( tool ) )
170
+
155
171
core . info ( "install-cpp finished" )
156
- return 0
172
+ return errorMessages . length === 0 ? 0 : 1 // exit with non-zero if any error message
157
173
}
158
-
159
- main ( )
174
+ // Run main
175
+ main ( process . argv )
160
176
. then ( ( ret ) => {
161
177
process . exitCode = ret
162
178
} )
163
179
. catch ( ( error ) => {
164
- core . error ( "main() failed !" )
180
+ core . error ( "main() panicked !" )
165
181
core . error ( error as string | Error )
166
182
process . exitCode = 1
167
183
} )
184
+
185
+ /** Get an object from github actions */
186
+ function maybeGetInput ( key : string ) {
187
+ const value = core . getInput ( key . toLowerCase ( ) )
188
+ if ( value !== "false" && value !== "" ) {
189
+ return value
190
+ }
191
+ return undefined // skip installation
192
+ }
193
+
194
+ function getSuccessMessage ( tool : string , installationInfo : InstallationInfo ) {
195
+ let success = `${ tool } was successfully installed`
196
+ if ( "installDir" in installationInfo ) {
197
+ success += `\nThe installation direcotry is ${ installationInfo . installDir } `
198
+ }
199
+ if ( installationInfo . binDir !== "" ) {
200
+ success += `\nThe binary direcotry is ${ installationInfo . binDir } `
201
+ }
202
+ return success
203
+ }
0 commit comments