@@ -15,8 +15,7 @@ import {
15
15
IEnvVars ,
16
16
resolvePathPlaceHolders ,
17
17
} from './utils' ;
18
- import * as ghcup from './ghcup' ;
19
- import { ToolConfig , Tool } from './ghcup' ;
18
+ import { ToolConfig , Tool , initDefaultGHCup , GHCup } from './ghcup' ;
20
19
export { IEnvVars } ;
21
20
22
21
type ManageHLS = 'GHCup' | 'PATH' ;
@@ -129,7 +128,8 @@ export async function findHaskellLanguageServer(
129
128
} ;
130
129
} else {
131
130
// we manage HLS, make sure ghcup is installed/available
132
- await ghcup . upgradeGHCup ( logger ) ;
131
+ const ghcup = initDefaultGHCup ( logger , folder ) ;
132
+ await ghcup . upgrade ( ) ;
133
133
134
134
// boring init
135
135
let latestHLS : string | undefined ;
@@ -157,34 +157,32 @@ export async function findHaskellLanguageServer(
157
157
// (we need HLS and cabal/stack and ghc as fallback),
158
158
// later we may install a different toolchain that's more project-specific
159
159
if ( latestHLS === undefined ) {
160
- latestHLS = await ghcup . getLatestToolFromGHCup ( logger , 'hls' ) ;
160
+ latestHLS = await ghcup . getLatestVersion ( 'hls' ) ;
161
161
}
162
162
if ( latestCabal === undefined ) {
163
- latestCabal = await ghcup . getLatestToolFromGHCup ( logger , 'cabal' ) ;
163
+ latestCabal = await ghcup . getLatestVersion ( 'cabal' ) ;
164
164
}
165
165
if ( latestStack === undefined ) {
166
- latestStack = await ghcup . getLatestToolFromGHCup ( logger , 'stack' ) ;
166
+ latestStack = await ghcup . getLatestVersion ( 'stack' ) ;
167
167
}
168
168
if ( recGHC === undefined ) {
169
- recGHC = ! executableExists ( 'ghc' )
170
- ? await ghcup . getLatestAvailableToolFromGHCup ( logger , 'ghc' , 'recommended' )
171
- : null ;
169
+ recGHC = ! executableExists ( 'ghc' ) ? await ghcup . getLatestAvailableVersion ( 'ghc' , 'recommended' ) : null ;
172
170
}
173
171
174
172
// download popups
175
173
const promptBeforeDownloads = workspace . getConfiguration ( 'haskell' ) . get ( 'promptBeforeDownloads' ) as boolean ;
176
174
if ( promptBeforeDownloads ) {
177
- const hlsInstalled = latestHLS ? await toolInstalled ( logger , 'hls' , latestHLS ) : undefined ;
178
- const cabalInstalled = latestCabal ? await toolInstalled ( logger , 'cabal' , latestCabal ) : undefined ;
179
- const stackInstalled = latestStack ? await toolInstalled ( logger , 'stack' , latestStack ) : undefined ;
175
+ const hlsInstalled = latestHLS ? await toolInstalled ( ghcup , 'hls' , latestHLS ) : undefined ;
176
+ const cabalInstalled = latestCabal ? await toolInstalled ( ghcup , 'cabal' , latestCabal ) : undefined ;
177
+ const stackInstalled = latestStack ? await toolInstalled ( ghcup , 'stack' , latestStack ) : undefined ;
180
178
const ghcInstalled = executableExists ( 'ghc' )
181
179
? new InstalledTool (
182
180
'ghc' ,
183
181
await callAsync ( `ghc${ exeExt } ` , [ '--numeric-version' ] , logger , undefined , undefined , false ) ,
184
182
)
185
183
: // if recGHC is null, that means user disabled automatic handling,
186
184
recGHC !== null
187
- ? await toolInstalled ( logger , 'ghc' , recGHC )
185
+ ? await toolInstalled ( ghcup , 'ghc' , recGHC )
188
186
: undefined ;
189
187
const toInstall : InstalledTool [ ] = [ hlsInstalled , cabalInstalled , stackInstalled , ghcInstalled ] . filter (
190
188
( tool ) => tool && ! tool . installed ,
@@ -222,8 +220,7 @@ export async function findHaskellLanguageServer(
222
220
}
223
221
224
222
// our preliminary toolchain
225
- const latestToolchainBindir = await ghcup . callGHCup (
226
- logger ,
223
+ const latestToolchainBindir = await ghcup . call (
227
224
[
228
225
'run' ,
229
226
...( latestHLS ? [ '--hls' , latestHLS ] : [ ] ) ,
@@ -246,7 +243,7 @@ export async function findHaskellLanguageServer(
246
243
// now figure out the actual project GHC version and the latest supported HLS version
247
244
// we need for it (e.g. this might in fact be a downgrade for old GHCs)
248
245
if ( projectHls === undefined || projectGhc === undefined ) {
249
- const res = await getLatestProjectHLS ( context , logger , workingDir , latestToolchainBindir ) ;
246
+ const res = await getLatestProjectHLS ( ghcup , context , logger , workingDir , latestToolchainBindir ) ;
250
247
if ( projectHls === undefined ) {
251
248
projectHls = res [ 0 ] ;
252
249
}
@@ -257,8 +254,8 @@ export async function findHaskellLanguageServer(
257
254
258
255
// more download popups
259
256
if ( promptBeforeDownloads ) {
260
- const hlsInstalled = await toolInstalled ( logger , 'hls' , projectHls ) ;
261
- const ghcInstalled = projectGhc ? await toolInstalled ( logger , 'ghc' , projectGhc ) : undefined ;
257
+ const hlsInstalled = await toolInstalled ( ghcup , 'hls' , projectHls ) ;
258
+ const ghcInstalled = projectGhc ? await toolInstalled ( ghcup , 'ghc' , projectGhc ) : undefined ;
262
259
const toInstall : InstalledTool [ ] = [ hlsInstalled , ghcInstalled ] . filter (
263
260
( tool ) => tool && ! tool . installed ,
264
261
) as InstalledTool [ ] ;
@@ -292,8 +289,7 @@ export async function findHaskellLanguageServer(
292
289
}
293
290
294
291
// now install the proper versions
295
- const hlsBinDir = await ghcup . callGHCup (
296
- logger ,
292
+ const hlsBinDir = await ghcup . call (
297
293
[
298
294
'run' ,
299
295
...[ '--hls' , projectHls ] ,
@@ -357,6 +353,7 @@ async function promptUserForManagingHls(context: ExtensionContext, manageHlsSett
357
353
}
358
354
359
355
async function getLatestProjectHLS (
356
+ ghcup : GHCup ,
360
357
context : ExtensionContext ,
361
358
logger : Logger ,
362
359
workingDir : string ,
@@ -376,7 +373,7 @@ async function getLatestProjectHLS(
376
373
// first we get supported GHC versions from available HLS bindists (whether installed or not)
377
374
const metadataMap = ( await getHlsMetadata ( context , logger ) ) || new Map < string , string [ ] > ( ) ;
378
375
// then we get supported GHC versions from currently installed HLS versions
379
- const ghcupMap = ( await findAvailableHlsBinariesFromGHCup ( logger ) ) || new Map < string , string [ ] > ( ) ;
376
+ const ghcupMap = ( await findAvailableHlsBinariesFromGHCup ( ghcup ) ) || new Map < string , string [ ] > ( ) ;
380
377
// since installed HLS versions may support a different set of GHC versions than the bindists
381
378
// (e.g. because the user ran 'ghcup compile hls'), we need to merge both maps, preferring
382
379
// values from already installed HLSes
@@ -471,16 +468,14 @@ export function getStoragePath(context: ExtensionContext): string {
471
468
* If 'targetGhc' is omitted, picks the latest 'haskell-language-server-wrapper',
472
469
* otherwise ensures the specified GHC is supported.
473
470
*
474
- * @param context
475
- * @param logger
476
- * @returns
471
+ * @param ghcup GHCup wrapper.
472
+ * @returns A Map of the locally installed HLS versions and with which `GHC` versions they are compatible.
477
473
*/
478
474
479
- async function findAvailableHlsBinariesFromGHCup ( logger : Logger ) : Promise < Map < string , string [ ] > | null > {
480
- const hlsVersions = await ghcup . callGHCup ( logger , [ 'list' , '-t' , 'hls' , '-c' , 'installed' , '-r' ] , undefined , false ) ;
481
-
482
- const bindir = await ghcup . callGHCup ( logger , [ 'whereis' , 'bindir' ] , undefined , false ) ;
475
+ async function findAvailableHlsBinariesFromGHCup ( ghcup : GHCup ) : Promise < Map < string , string [ ] > | null > {
476
+ const hlsVersions = await ghcup . call ( [ 'list' , '-t' , 'hls' , '-c' , 'installed' , '-r' ] , undefined , false ) ;
483
477
478
+ const bindir = await ghcup . call ( [ 'whereis' , 'bindir' ] , undefined , false ) ;
484
479
const files = fs . readdirSync ( bindir ) . filter ( ( e ) => {
485
480
const stat = fs . statSync ( path . join ( bindir , e ) ) ;
486
481
return stat . isFile ( ) ;
@@ -498,16 +493,15 @@ async function findAvailableHlsBinariesFromGHCup(logger: Logger): Promise<Map<st
498
493
} ) ;
499
494
myMap . set ( hls , ghcs ) ;
500
495
} ) ;
501
-
502
496
return myMap ;
503
497
} else {
504
498
return null ;
505
499
}
506
500
}
507
501
508
- async function toolInstalled ( logger : Logger , tool : Tool , version : string ) : Promise < InstalledTool > {
502
+ async function toolInstalled ( ghcup : GHCup , tool : Tool , version : string ) : Promise < InstalledTool > {
509
503
const b = await ghcup
510
- . callGHCup ( logger , [ 'whereis' , tool , version ] , undefined , false )
504
+ . call ( [ 'whereis' , tool , version ] , undefined , false )
511
505
. then ( ( ) => true )
512
506
. catch ( ( ) => false ) ;
513
507
return new InstalledTool ( tool , version , b ) ;
@@ -650,7 +644,7 @@ async function getReleaseMetadata(storagePath: string, logger: Logger): Promise<
650
644
/**
651
645
* Convert a json value to ReleaseMetadata.
652
646
* Assumes the json is well-formed and a valid Release-Metadata.
653
- * @param obj Release Metadata without any typing information but well-formed.
647
+ * @param someObj Release Metadata without any typing information but well-formed.
654
648
* @returns Typed ReleaseMetadata.
655
649
*/
656
650
const objectToMetadata = ( someObj : any ) : ReleaseMetadata => {
0 commit comments