@@ -54,7 +54,13 @@ export class Chruby extends VersionManager {
54
54
rubyUri = await this . findRubyUri ( versionInfo ) ;
55
55
} else {
56
56
try {
57
- const fallback = await this . fallbackToLatestRuby ( ) ;
57
+ const fallback = await this . fallbackWithCancellation (
58
+ "No .ruby-version file found. Trying to fall back to latest installed Ruby in 10 seconds" ,
59
+ "You can create a .ruby-version file in a parent directory to configure a fallback" ,
60
+ this . findFallbackRuby . bind ( this ) ,
61
+ this . rubyVersionError . bind ( this ) ,
62
+ ) ;
63
+
58
64
versionInfo = fallback . rubyVersion ;
59
65
rubyUri = fallback . uri ;
60
66
} catch ( error : any ) {
@@ -179,7 +185,12 @@ export class Chruby extends VersionManager {
179
185
return undefined ;
180
186
}
181
187
182
- private async fallbackToLatestRuby ( ) {
188
+ private async fallbackWithCancellation < T > (
189
+ title : string ,
190
+ message : string ,
191
+ fallbackFn : ( ) => Promise < T > ,
192
+ errorFn : ( ) => Error ,
193
+ ) : Promise < T > {
183
194
let gemfileContents ;
184
195
185
196
try {
@@ -190,26 +201,22 @@ export class Chruby extends VersionManager {
190
201
// The Gemfile doesn't exist
191
202
}
192
203
193
- // If the Gemfile includes ruby version restrictions, then trying to fall back to latest Ruby may lead to errors
204
+ // If the Gemfile includes ruby version restrictions, then trying to fall back may lead to errors
194
205
if (
195
206
gemfileContents &&
196
207
/ ^ r u b y ( \s | \( ) ( " | ' ) [ \d . ] + / . test ( gemfileContents . toString ( ) )
197
208
) {
198
- throw this . rubyVersionError ( ) ;
209
+ throw errorFn ( ) ;
199
210
}
200
211
201
212
const fallback = await vscode . window . withProgress (
202
213
{
203
- title :
204
- "No .ruby-version found. Trying to fall back to latest installed Ruby in 10 seconds" ,
214
+ title,
205
215
location : vscode . ProgressLocation . Notification ,
206
216
cancellable : true ,
207
217
} ,
208
218
async ( progress , token ) => {
209
- progress . report ( {
210
- message :
211
- "You can create a .ruby-version file in a parent directory to configure a fallback" ,
212
- } ) ;
219
+ progress . report ( { message } ) ;
213
220
214
221
// If they don't cancel, we wait 10 seconds before falling back so that they are aware of what's happening
215
222
await new Promise < void > ( ( resolve ) => {
@@ -222,26 +229,20 @@ export class Chruby extends VersionManager {
222
229
} ) ;
223
230
224
231
if ( token . isCancellationRequested ) {
225
- await this . handleCancelledFallback ( ) ;
232
+ await this . handleCancelledFallback ( errorFn ) ;
226
233
227
234
// We throw this error to be able to catch and re-run activation after the user has configured a fallback
228
235
throw new RubyVersionCancellationError ( ) ;
229
236
}
230
237
231
- const fallback = await this . findFallbackRuby ( ) ;
232
-
233
- if ( ! fallback ) {
234
- throw new Error ( "Cannot find any Ruby installations" ) ;
235
- }
236
-
237
- return fallback ;
238
+ return fallbackFn ( ) ;
238
239
} ,
239
240
) ;
240
241
241
242
return fallback ;
242
243
}
243
244
244
- private async handleCancelledFallback ( ) {
245
+ private async handleCancelledFallback ( errorFn : ( ) => Error ) {
245
246
const answer = await vscode . window . showInformationMessage (
246
247
`The Ruby LSP requires a Ruby version to launch.
247
248
You can define a fallback for the system or for the Ruby LSP only` ,
@@ -250,15 +251,15 @@ export class Chruby extends VersionManager {
250
251
) ;
251
252
252
253
if ( answer === "System" ) {
253
- await this . createParentRubyVersionFile ( ) ;
254
+ await this . createParentRubyVersionFile ( errorFn ) ;
254
255
} else if ( answer === "Ruby LSP only" ) {
255
256
await this . manuallySelectRuby ( ) ;
256
257
}
257
258
258
- throw this . rubyVersionError ( ) ;
259
+ throw errorFn ( ) ;
259
260
}
260
261
261
- private async createParentRubyVersionFile ( ) {
262
+ private async createParentRubyVersionFile ( errorFn : ( ) => Error ) {
262
263
const items : vscode . QuickPickItem [ ] = [ ] ;
263
264
264
265
for ( const uri of this . rubyInstallationUris ) {
@@ -285,7 +286,7 @@ export class Chruby extends VersionManager {
285
286
} ) ;
286
287
287
288
if ( ! answer ) {
288
- throw this . rubyVersionError ( ) ;
289
+ throw errorFn ( ) ;
289
290
}
290
291
291
292
const targetDirectory = await vscode . window . showOpenDialog ( {
@@ -298,7 +299,7 @@ export class Chruby extends VersionManager {
298
299
} ) ;
299
300
300
301
if ( ! targetDirectory ) {
301
- throw this . rubyVersionError ( ) ;
302
+ throw errorFn ( ) ;
302
303
}
303
304
304
305
await vscode . workspace . fs . writeFile (
@@ -307,9 +308,10 @@ export class Chruby extends VersionManager {
307
308
) ;
308
309
}
309
310
310
- private async findFallbackRuby ( ) : Promise <
311
- { uri : vscode . Uri ; rubyVersion : RubyVersion } | undefined
312
- > {
311
+ private async findFallbackRuby ( ) : Promise < {
312
+ uri : vscode . Uri ;
313
+ rubyVersion : RubyVersion ;
314
+ } > {
313
315
for ( const uri of this . rubyInstallationUris ) {
314
316
let directories ;
315
317
@@ -352,7 +354,7 @@ export class Chruby extends VersionManager {
352
354
}
353
355
}
354
356
355
- return undefined ;
357
+ throw new Error ( "Cannot find any Ruby installations" ) ;
356
358
}
357
359
358
360
// Run the activation script using the Ruby installation we found so that we can discover gem paths
0 commit comments