@@ -5,7 +5,6 @@ import { stat } from 'fs/promises';
55import * as https from 'https' ;
66import * as path from 'path' ;
77import { match } from 'ts-pattern' ;
8- import * as url from 'url' ;
98import { promisify } from 'util' ;
109import { ConfigurationTarget , ExtensionContext , ProgressLocation , window , workspace , WorkspaceFolder } from 'vscode' ;
1110import { Logger } from 'vscode-languageclient' ;
@@ -68,7 +67,7 @@ async function callAsync(
6867 envAdd ?: IEnvVars ,
6968 callback ?: ProcessCallback
7069) : Promise < string > {
71- let newEnv : IEnvVars = await resolveServerEnvironmentPATH (
70+ let newEnv : IEnvVars = resolveServerEnvironmentPATH (
7271 workspace . getConfiguration ( 'haskell' ) . get ( 'serverEnvironment' ) || { }
7372 ) ;
7473 newEnv = { ...( process . env as IEnvVars ) , ...newEnv , ...( envAdd || { } ) } ;
@@ -135,15 +134,14 @@ async function callAsync(
135134/** Gets serverExecutablePath and fails if it's not set.
136135 */
137136async function findServerExecutable (
138- context : ExtensionContext ,
139137 logger : Logger ,
140138 folder ?: WorkspaceFolder
141139) : Promise < string > {
142140 let exePath = workspace . getConfiguration ( 'haskell' ) . get ( 'serverExecutablePath' ) as string ;
143141 logger . info ( `Trying to find the server executable in: ${ exePath } ` ) ;
144142 exePath = resolvePathPlaceHolders ( exePath , folder ) ;
145143 logger . log ( `Location after path variables substitution: ${ exePath } ` ) ;
146- if ( await executableExists ( exePath ) ) {
144+ if ( executableExists ( exePath ) ) {
147145 return exePath ;
148146 } else {
149147 const msg = `Could not find a HLS binary at ${ exePath } ! Consider installing HLS via ghcup or change "haskell.manageHLS" in your settings.` ;
@@ -153,13 +151,13 @@ async function findServerExecutable(
153151
154152/** Searches the PATH. Fails if nothing is found.
155153 */
156- async function findHLSinPATH ( context : ExtensionContext , logger : Logger , folder ?: WorkspaceFolder ) : Promise < string > {
154+ async function findHLSinPATH ( _context : ExtensionContext , logger : Logger ) : Promise < string > {
157155 // try PATH
158156 const exes : string [ ] = [ 'haskell-language-server-wrapper' , 'haskell-language-server' ] ;
159157 logger . info ( `Searching for server executables ${ exes . join ( ',' ) } in $PATH` ) ;
160158 logger . info ( `$PATH environment variable: ${ process . env . PATH } ` ) ;
161159 for ( const exe of exes ) {
162- if ( await executableExists ( exe ) ) {
160+ if ( executableExists ( exe ) ) {
163161 logger . info ( `Found server executable in $PATH: ${ exe } ` ) ;
164162 return exe ;
165163 }
@@ -189,7 +187,7 @@ export async function findHaskellLanguageServer(
189187 logger . info ( 'Finding haskell-language-server' ) ;
190188
191189 if ( workspace . getConfiguration ( 'haskell' ) . get ( 'serverExecutablePath' ) as string ) {
192- const exe = await findServerExecutable ( context , logger , folder ) ;
190+ const exe = await findServerExecutable ( logger , folder ) ;
193191 return [ exe , undefined ] ;
194192 }
195193
@@ -226,7 +224,7 @@ export async function findHaskellLanguageServer(
226224 }
227225
228226 if ( manageHLS === 'PATH' ) {
229- const exe = await findHLSinPATH ( context , logger , folder ) ;
227+ const exe = await findHLSinPATH ( context , logger ) ;
230228 return [ exe , undefined ] ;
231229 } else {
232230 // we manage HLS, make sure ghcup is installed/available
@@ -267,40 +265,42 @@ export async function findHaskellLanguageServer(
267265 latestStack = await getLatestToolFromGHCup ( context , logger , 'stack' ) ;
268266 }
269267 if ( recGHC === undefined ) {
270- recGHC = ! ( await executableExists ( 'ghc' ) )
268+ recGHC = ! executableExists ( 'ghc' )
271269 ? await getLatestAvailableToolFromGHCup ( context , logger , 'ghc' , 'recommended' )
272270 : null ;
273271 }
274272
275273 // download popups
276274 const promptBeforeDownloads = workspace . getConfiguration ( 'haskell' ) . get ( 'promptBeforeDownloads' ) as boolean ;
277275 if ( promptBeforeDownloads ) {
278- const hlsInstalled = latestHLS
279- ? await toolInstalled ( context , logger , 'hls' , latestHLS )
280- : undefined ;
281- const cabalInstalled = latestCabal
282- ? await toolInstalled ( context , logger , 'cabal' , latestCabal )
283- : undefined ;
284- const stackInstalled = latestStack
285- ? await toolInstalled ( context , logger , 'stack' , latestStack )
286- : undefined ;
276+ const hlsInstalled = latestHLS ? await toolInstalled ( context , logger , 'hls' , latestHLS ) : undefined ;
277+ const cabalInstalled = latestCabal ? await toolInstalled ( context , logger , 'cabal' , latestCabal ) : undefined ;
278+ const stackInstalled = latestStack ? await toolInstalled ( context , logger , 'stack' , latestStack ) : undefined ;
287279 const ghcInstalled = executableExists ( 'ghc' )
288- ? new InstalledTool ( 'ghc' , await callAsync ( `ghc${ exeExt } ` , [ '--numeric-version' ] , logger , undefined , undefined , false ) )
289- // if recGHC is null, that means user disabled automatic handling,
290- : ( recGHC !== null ? await toolInstalled ( context , logger , 'ghc' , recGHC ) : undefined ) ;
291- const toInstall : InstalledTool [ ] = [ hlsInstalled , cabalInstalled , stackInstalled , ghcInstalled ]
292- . filter ( ( tool ) => tool && ! tool . installed ) as InstalledTool [ ] ;
280+ ? new InstalledTool (
281+ 'ghc' ,
282+ await callAsync ( `ghc${ exeExt } ` , [ '--numeric-version' ] , logger , undefined , undefined , false )
283+ )
284+ : // if recGHC is null, that means user disabled automatic handling,
285+ recGHC !== null
286+ ? await toolInstalled ( context , logger , 'ghc' , recGHC )
287+ : undefined ;
288+ const toInstall : InstalledTool [ ] = [ hlsInstalled , cabalInstalled , stackInstalled , ghcInstalled ] . filter (
289+ ( tool ) => tool && ! tool . installed
290+ ) as InstalledTool [ ] ;
293291 if ( toInstall . length > 0 ) {
294292 const decision = await window . showInformationMessage (
295- `Need to download ${ toInstall . map ( t => t . nameWithVersion ) . join ( ', ' ) } , continue?` ,
293+ `Need to download ${ toInstall . map ( ( t ) => t . nameWithVersion ) . join ( ', ' ) } , continue?` ,
296294 'Yes' ,
297295 'No' ,
298296 "Yes, don't ask again"
299297 ) ;
300298 if ( decision === 'Yes' ) {
301- logger . info ( `User accepted download for ${ toInstall . map ( t => t . nameWithVersion ) . join ( ', ' ) } .` ) ;
299+ logger . info ( `User accepted download for ${ toInstall . map ( ( t ) => t . nameWithVersion ) . join ( ', ' ) } .` ) ;
302300 } else if ( decision === "Yes, don't ask again" ) {
303- logger . info ( `User accepted download for ${ toInstall . map ( t => t . nameWithVersion ) . join ( ', ' ) } and won't be asked again.` ) ;
301+ logger . info (
302+ `User accepted download for ${ toInstall . map ( ( t ) => t . nameWithVersion ) . join ( ', ' ) } and won't be asked again.`
303+ ) ;
304304 workspace . getConfiguration ( 'haskell' ) . update ( 'promptBeforeDownloads' , false ) ;
305305 } else {
306306 toInstall . forEach ( ( tool ) => {
@@ -353,26 +353,25 @@ export async function findHaskellLanguageServer(
353353
354354 // more download popups
355355 if ( promptBeforeDownloads ) {
356- const hlsInstalled = projectHls
357- ? await toolInstalled ( context , logger , 'hls' , projectHls )
358- : undefined ;
359- const ghcInstalled = projectGhc
360- ? await toolInstalled ( context , logger , 'ghc' , projectGhc )
361- : undefined ;
362- const toInstall : InstalledTool [ ] = [ hlsInstalled , ghcInstalled ]
363- . filter ( ( tool ) => tool && ! tool . installed ) as InstalledTool [ ] ;
356+ const hlsInstalled = projectHls ? await toolInstalled ( context , logger , 'hls' , projectHls ) : undefined ;
357+ const ghcInstalled = projectGhc ? await toolInstalled ( context , logger , 'ghc' , projectGhc ) : undefined ;
358+ const toInstall : InstalledTool [ ] = [ hlsInstalled , ghcInstalled ] . filter (
359+ ( tool ) => tool && ! tool . installed
360+ ) as InstalledTool [ ] ;
364361 if ( toInstall . length > 0 ) {
365362 const decision = await window . showInformationMessage (
366- `Need to download ${ toInstall . map ( t => t . nameWithVersion ) . join ( ', ' ) } , continue?` ,
363+ `Need to download ${ toInstall . map ( ( t ) => t . nameWithVersion ) . join ( ', ' ) } , continue?` ,
367364 { modal : true } ,
368365 'Yes' ,
369366 'No' ,
370367 "Yes, don't ask again"
371368 ) ;
372369 if ( decision === 'Yes' ) {
373- logger . info ( `User accepted download for ${ toInstall . map ( t => t . nameWithVersion ) . join ( ', ' ) } .` ) ;
370+ logger . info ( `User accepted download for ${ toInstall . map ( ( t ) => t . nameWithVersion ) . join ( ', ' ) } .` ) ;
374371 } else if ( decision === "Yes, don't ask again" ) {
375- logger . info ( `User accepted download for ${ toInstall . map ( t => t . nameWithVersion ) . join ( ', ' ) } and won't be asked again.` ) ;
372+ logger . info (
373+ `User accepted download for ${ toInstall . map ( ( t ) => t . nameWithVersion ) . join ( ', ' ) } and won't be asked again.`
374+ ) ;
376375 workspace . getConfiguration ( 'haskell' ) . update ( 'promptBeforeDownloads' , false ) ;
377376 } else {
378377 toInstall . forEach ( ( tool ) => {
@@ -400,14 +399,22 @@ export async function findHaskellLanguageServer(
400399 ...( projectGhc ? [ '--ghc' , projectGhc ] : [ ] ) ,
401400 '--install' ,
402401 ] ,
403- `Installing project specific toolchain: ${ [ [ 'hls' , projectHls ] , [ 'GHC' , projectGhc ] , [ 'cabal' , latestCabal ] , [ 'stack' , latestStack ] ] . filter ( t => t [ 1 ] ) . map ( t => `${ t [ 0 ] } -${ t [ 1 ] } ` ) . join ( ', ' ) } ` ,
402+ `Installing project specific toolchain: ${ [
403+ [ 'hls' , projectHls ] ,
404+ [ 'GHC' , projectGhc ] ,
405+ [ 'cabal' , latestCabal ] ,
406+ [ 'stack' , latestStack ] ,
407+ ]
408+ . filter ( ( t ) => t [ 1 ] )
409+ . map ( ( t ) => `${ t [ 0 ] } -${ t [ 1 ] } ` )
410+ . join ( ', ' ) } `,
404411 true
405412 ) ;
406413
407414 if ( projectHls ) {
408415 return [ path . join ( hlsBinDir , `haskell-language-server-wrapper${ exeExt } ` ) , hlsBinDir ] ;
409416 } else {
410- const exe = await findHLSinPATH ( context , logger , folder ) ;
417+ const exe = await findHLSinPATH ( context , logger ) ;
411418 return [ exe , hlsBinDir ] ;
412419 }
413420 }
@@ -470,8 +477,8 @@ async function getLatestProjectHLS(
470477 const merged = new Map < string , string [ ] > ( [ ...metadataMap , ...ghcupMap ] ) ; // right-biased
471478 // now sort and get the latest suitable version
472479 const latest = [ ...merged ]
473- . filter ( ( [ k , v ] ) => v . some ( ( x ) => x === projectGhc ) )
474- . sort ( ( [ k1 , v1 ] , [ k2 , v2 ] ) => comparePVP ( k1 , k2 ) )
480+ . filter ( ( [ _k , v ] ) => v . some ( ( x ) => x === projectGhc ) )
481+ . sort ( ( [ k1 , _v1 ] , [ k2 , _v2 ] ) => comparePVP ( k1 , k2 ) )
475482 . pop ( ) ;
476483
477484 if ( ! latest ) {
@@ -484,7 +491,7 @@ async function getLatestProjectHLS(
484491/**
485492 * Obtain the project ghc version from the HLS - Wrapper (which must be in PATH now).
486493 * Also, serves as a sanity check.
487- * @param wrapper Path to the Haskell-Language-Server wrapper
494+ * @param toolchainBindir Path to the toolchainn bin directory (added to PATH)
488495 * @param workingDir Directory to run the process, usually the root of the workspace.
489496 * @param logger Logger for feedback.
490497 * @returns The GHC version, or fail with an `Error`.
@@ -499,7 +506,7 @@ export async function getProjectGHCVersion(
499506
500507 const args = [ '--project-ghc-version' ] ;
501508
502- const newPath = await addPathToProcessPath ( toolchainBindir , logger ) ;
509+ const newPath = await addPathToProcessPath ( toolchainBindir ) ;
503510 const environmentNew : IEnvVars = {
504511 PATH : newPath ,
505512 } ;
@@ -550,14 +557,14 @@ export async function upgradeGHCup(context: ExtensionContext, logger: Logger): P
550557 }
551558}
552559
553- export async function findGHCup ( context : ExtensionContext , logger : Logger , folder ?: WorkspaceFolder ) : Promise < string > {
560+ export async function findGHCup ( _context : ExtensionContext , logger : Logger , folder ?: WorkspaceFolder ) : Promise < string > {
554561 logger . info ( 'Checking for ghcup installation' ) ;
555562 let exePath = workspace . getConfiguration ( 'haskell' ) . get ( 'ghcupExecutablePath' ) as string ;
556563 if ( exePath ) {
557564 logger . info ( `Trying to find the ghcup executable in: ${ exePath } ` ) ;
558565 exePath = resolvePathPlaceHolders ( exePath , folder ) ;
559566 logger . log ( `Location after path variables substitution: ${ exePath } ` ) ;
560- if ( await executableExists ( exePath ) ) {
567+ if ( executableExists ( exePath ) ) {
561568 return exePath ;
562569 } else {
563570 throw new Error ( `Could not find a ghcup binary at ${ exePath } !` ) ;
@@ -684,8 +691,8 @@ async function toolInstalled(
684691 version : string
685692) : Promise < InstalledTool > {
686693 const b = await callGHCup ( context , logger , [ 'whereis' , tool , version ] , undefined , false )
687- . then ( ( x ) => true )
688- . catch ( ( x ) => false ) ;
694+ . then ( ( _x ) => true )
695+ . catch ( ( _x ) => false ) ;
689696 return new InstalledTool ( tool , version , b ) ;
690697}
691698
@@ -737,7 +744,7 @@ export type ReleaseMetadata = Map<string, Map<string, Map<string, string[]>>>;
737744 */
738745async function getHLSesfromMetadata ( context : ExtensionContext , logger : Logger ) : Promise < Map < string , string [ ] > | null > {
739746 const storagePath : string = await getStoragePath ( context ) ;
740- const metadata = await getReleaseMetadata ( context , storagePath , logger ) . catch ( ( e ) => null ) ;
747+ const metadata = await getReleaseMetadata ( context , storagePath , logger ) . catch ( ( _e ) => null ) ;
741748 if ( ! metadata ) {
742749 window . showErrorMessage ( 'Could not get release metadata' ) ;
743750 return null ;
@@ -803,23 +810,23 @@ export function findSupportedHlsPerGhc(
803810/**
804811 * Download GHCUP metadata.
805812 *
806- * @param context Extension context.
813+ * @param _context Extension context.
807814 * @param storagePath Path to put in binary files and caches.
808815 * @param logger Logger for feedback.
809816 * @returns Metadata of releases, or null if the cache can not be found.
810817 */
811818async function getReleaseMetadata (
812- context : ExtensionContext ,
819+ _context : ExtensionContext ,
813820 storagePath : string ,
814821 logger : Logger
815822) : Promise < ReleaseMetadata | null > {
816823 const releasesUrl = workspace . getConfiguration ( 'haskell' ) . releasesURL
817- ? url . parse ( workspace . getConfiguration ( 'haskell' ) . releasesURL )
824+ ? new URL ( workspace . getConfiguration ( 'haskell' ) . releasesURL )
818825 : undefined ;
819826 const opts : https . RequestOptions = releasesUrl
820827 ? {
821828 host : releasesUrl . host ,
822- path : releasesUrl . path ,
829+ path : releasesUrl . pathname ,
823830 }
824831 : {
825832 host : 'raw.githubusercontent.com' ,
0 commit comments