@@ -167,84 +167,99 @@ async function transformToTerminalProfiles(
167167 logService ?: ILogService ,
168168 variableResolver ?: ( text : string [ ] ) => Promise < string [ ] > ,
169169) : Promise < ITerminalProfile [ ] > {
170- const resultProfiles : ITerminalProfile [ ] = [ ] ;
170+ const promises : Promise < ITerminalProfile | undefined > [ ] = [ ] ;
171171 for ( const [ profileName , profile ] of entries ) {
172- if ( profile === null ) { continue ; }
173- let originalPaths : ( string | ITerminalUnsafePath ) [ ] ;
174- let args : string [ ] | string | undefined ;
175- let icon : ThemeIcon | URI | { light : URI ; dark : URI } | undefined = undefined ;
176- // use calculated values if path is not specified
177- if ( 'source' in profile && ! ( 'path' in profile ) ) {
178- const source = profileSources ?. get ( profile . source ) ;
179- if ( ! source ) {
180- continue ;
181- }
182- originalPaths = source . paths ;
183-
184- // if there are configured args, override the default ones
185- args = profile . args || source . args ;
186- if ( profile . icon ) {
187- icon = validateIcon ( profile . icon ) ;
188- } else if ( source . icon ) {
189- icon = source . icon ;
190- }
191- } else {
192- originalPaths = Array . isArray ( profile . path ) ? profile . path : [ profile . path ] ;
193- args = isWindows ? profile . args : Array . isArray ( profile . args ) ? profile . args : undefined ;
194- icon = validateIcon ( profile . icon ) ;
172+ promises . push ( getValidatedProfile ( profileName , profile , defaultProfileName , fsProvider , shellEnv , logService , variableResolver ) ) ;
173+ }
174+ return ( await Promise . all ( promises ) ) . filter ( e => ! ! e ) as ITerminalProfile [ ] ;
175+ }
176+
177+ async function getValidatedProfile (
178+ profileName : string ,
179+ profile : IUnresolvedTerminalProfile ,
180+ defaultProfileName : string | undefined ,
181+ fsProvider : IFsProvider ,
182+ shellEnv : typeof process . env = process . env ,
183+ logService ?: ILogService ,
184+ variableResolver ?: ( text : string [ ] ) => Promise < string [ ] >
185+ ) : Promise < ITerminalProfile | undefined > {
186+ if ( profile === null ) {
187+ return undefined ;
188+ }
189+ let originalPaths : ( string | ITerminalUnsafePath ) [ ] ;
190+ let args : string [ ] | string | undefined ;
191+ let icon : ThemeIcon | URI | { light : URI ; dark : URI } | undefined = undefined ;
192+ // use calculated values if path is not specified
193+ if ( 'source' in profile && ! ( 'path' in profile ) ) {
194+ const source = profileSources ?. get ( profile . source ) ;
195+ if ( ! source ) {
196+ return undefined ;
195197 }
198+ originalPaths = source . paths ;
196199
197- let paths : ( string | ITerminalUnsafePath ) [ ] ;
198- if ( variableResolver ) {
199- // Convert to string[] for resolve
200- const mapped = originalPaths . map ( e => typeof e === 'string' ? e : e . path ) ;
201- const resolved = await variableResolver ( mapped ) ;
202- // Convert resolved back to (T | string)[]
203- paths = new Array ( originalPaths . length ) ;
204- for ( let i = 0 ; i < originalPaths . length ; i ++ ) {
205- if ( typeof originalPaths [ i ] === 'string' ) {
206- paths [ i ] = resolved [ i ] ;
207- } else {
208- paths [ i ] = {
209- path : resolved [ i ] ,
210- isUnsafe : true
211- } ;
212- }
213- }
214- } else {
215- paths = originalPaths . slice ( ) ;
200+ // if there are configured args, override the default ones
201+ args = profile . args || source . args ;
202+ if ( profile . icon ) {
203+ icon = validateIcon ( profile . icon ) ;
204+ } else if ( source . icon ) {
205+ icon = source . icon ;
216206 }
207+ } else {
208+ originalPaths = Array . isArray ( profile . path ) ? profile . path : [ profile . path ] ;
209+ args = isWindows ? profile . args : Array . isArray ( profile . args ) ? profile . args : undefined ;
210+ icon = validateIcon ( profile . icon ) ;
211+ }
217212
218- let requiresUnsafePath : string | undefined ;
219- if ( profile . requiresPath ) {
220- // Validate requiresPath exists
221- let actualRequiredPath : string ;
222- if ( isString ( profile . requiresPath ) ) {
223- actualRequiredPath = profile . requiresPath ;
213+ let paths : ( string | ITerminalUnsafePath ) [ ] ;
214+ if ( variableResolver ) {
215+ // Convert to string[] for resolve
216+ const mapped = originalPaths . map ( e => typeof e === 'string' ? e : e . path ) ;
217+
218+ const resolved = await variableResolver ( mapped ) ;
219+ // Convert resolved back to (T | string)[]
220+ paths = new Array ( originalPaths . length ) ;
221+ for ( let i = 0 ; i < originalPaths . length ; i ++ ) {
222+ if ( typeof originalPaths [ i ] === 'string' ) {
223+ paths [ i ] = resolved [ i ] ;
224224 } else {
225- actualRequiredPath = profile . requiresPath . path ;
226- if ( profile . requiresPath . isUnsafe ) {
227- requiresUnsafePath = actualRequiredPath ;
228- }
229- }
230- const result = await fsProvider . existsFile ( actualRequiredPath ) ;
231- if ( ! result ) {
232- continue ;
225+ paths [ i ] = {
226+ path : resolved [ i ] ,
227+ isUnsafe : true
228+ } ;
233229 }
234230 }
231+ } else {
232+ paths = originalPaths . slice ( ) ;
233+ }
235234
236- const validatedProfile = await validateProfilePaths ( profileName , defaultProfileName , paths , fsProvider , shellEnv , args , profile . env , profile . overrideName , profile . isAutoDetected , requiresUnsafePath ) ;
237- if ( validatedProfile ) {
238- validatedProfile . isAutoDetected = profile . isAutoDetected ;
239- validatedProfile . icon = icon ;
240- validatedProfile . color = profile . color ;
241- resultProfiles . push ( validatedProfile ) ;
235+ let requiresUnsafePath : string | undefined ;
236+ if ( profile . requiresPath ) {
237+ // Validate requiresPath exists
238+ let actualRequiredPath : string ;
239+ if ( isString ( profile . requiresPath ) ) {
240+ actualRequiredPath = profile . requiresPath ;
242241 } else {
243- logService ?. debug ( 'Terminal profile not validated' , profileName , originalPaths ) ;
242+ actualRequiredPath = profile . requiresPath . path ;
243+ if ( profile . requiresPath . isUnsafe ) {
244+ requiresUnsafePath = actualRequiredPath ;
245+ }
246+ }
247+ const result = await fsProvider . existsFile ( actualRequiredPath ) ;
248+ if ( ! result ) {
249+ return ;
244250 }
245251 }
246- logService ?. debug ( 'Validated terminal profiles' , resultProfiles ) ;
247- return resultProfiles ;
252+
253+ const validatedProfile = await validateProfilePaths ( profileName , defaultProfileName , paths , fsProvider , shellEnv , args , profile . env , profile . overrideName , profile . isAutoDetected , requiresUnsafePath ) ;
254+ if ( ! validatedProfile ) {
255+ logService ?. debug ( 'Terminal profile not validated' , profileName , originalPaths ) ;
256+ return undefined ;
257+ }
258+
259+ validatedProfile . isAutoDetected = profile . isAutoDetected ;
260+ validatedProfile . icon = icon ;
261+ validatedProfile . color = profile . color ;
262+ return validatedProfile ;
248263}
249264
250265function validateIcon ( icon : string | TerminalIcon | undefined ) : TerminalIcon | undefined {
0 commit comments