@@ -8,55 +8,64 @@ import TelemetryReporter from 'vscode-extension-telemetry';
8
8
import { exec } from './utils' ;
9
9
import { Release , getRelease } from '@hashicorp/js-releases' ;
10
10
11
+ const extensionVersion = vscode . extensions . getExtension ( 'hashicorp.terraform' ) . packageJSON . version ;
12
+
11
13
export class LanguageServerInstaller {
12
14
constructor (
15
+ private directory : string ,
13
16
private reporter : TelemetryReporter
14
17
) { }
15
18
16
- public async install ( directory : string ) : Promise < void > {
17
- const extensionVersion = vscode . extensions . getExtension ( 'hashicorp.terraform' ) . packageJSON . version ;
18
- const userAgent = `Terraform-VSCode/${ extensionVersion } VSCode/${ vscode . version } ` ;
19
- let isInstalled = false ;
19
+ private userAgent = `Terraform-VSCode/${ extensionVersion } VSCode/${ vscode . version } ` ;
20
+ private release : Release ;
21
+
22
+ public async needsInstall ( ) : Promise < boolean > {
23
+ try {
24
+ this . release = await getRelease ( "terraform-ls" , "latest" , this . userAgent ) ;
25
+ } catch ( err ) {
26
+ // if the releases site is inaccessible, report it and skip the install
27
+ this . reporter . sendTelemetryException ( err ) ;
28
+ return false ;
29
+ }
30
+
20
31
let installedVersion : string ;
21
32
try {
22
- installedVersion = await getLsVersion ( directory ) ;
23
- isInstalled = true ;
33
+ installedVersion = await getLsVersion ( this . directory ) ;
24
34
} catch ( err ) {
25
- // Most of the time, getLsVersion would produce "ENOENT: no such file or directory"
35
+ // Most of the time, getLsVersion will produce "ENOENT: no such file or directory"
26
36
// on a fresh installation (unlike upgrade). It’s also possible that the file or directory
27
37
// is inaccessible for some other reason, but we catch that separately.
28
38
if ( err . code !== 'ENOENT' ) {
29
39
this . reporter . sendTelemetryException ( err ) ;
30
40
throw err ;
31
41
}
32
- isInstalled = false ;
42
+ return true ; // yes to new install
33
43
}
34
44
35
- const currentRelease = await getRelease ( "terraform-ls" , "latest" , userAgent ) ;
36
- if ( isInstalled ) {
37
- this . reporter . sendTelemetryEvent ( 'foundLsInstalled' , { terraformLsVersion : installedVersion } ) ;
38
- if ( semver . gt ( currentRelease . version , installedVersion , { includePrerelease : true } ) ) {
39
- const selected = await vscode . window . showInformationMessage ( `A new language server release is available: ${ currentRelease . version } . Install now?` , 'Install' , 'Cancel' ) ;
40
- if ( selected !== 'Install' ) { // selected is undefined if the user closes the message
41
- return ;
42
- }
43
- } else {
44
- return ;
45
- }
45
+ this . reporter . sendTelemetryEvent ( 'foundLsInstalled' , { terraformLsVersion : installedVersion } ) ;
46
+ const upgrade = semver . gt ( this . release . version , installedVersion , { includePrerelease : true } ) ;
47
+ if ( upgrade ) {
48
+ const selected = await vscode . window . showInformationMessage ( `A new language server release is available: ${ this . release . version } . Install now?` , 'Install' , 'Cancel' ) ;
49
+ return ( selected === "Install" ) ;
50
+ } else {
51
+ return false ; // no upgrade available
46
52
}
53
+ }
47
54
55
+ public async install ( ) : Promise < void > {
56
+ this . reporter . sendTelemetryEvent ( 'installingLs' , { terraformLsVersion : this . release . version } ) ;
48
57
try {
49
- this . reporter . sendTelemetryEvent ( 'installingLs' , { terraformLsVersion : currentRelease . version } ) ;
50
- await this . installPkg ( currentRelease , directory , userAgent ) ;
58
+ await this . installPkg ( this . release ) ;
51
59
} catch ( err ) {
52
60
vscode . window . showErrorMessage ( `Unable to install terraform-ls: ${ err . message } ` ) ;
53
61
throw err ;
54
62
}
55
63
56
- this . showChangelog ( currentRelease . version ) ;
64
+ this . showChangelog ( this . release . version ) ;
57
65
}
58
66
59
- async installPkg ( release : Release , installDir : string , userAgent : string ) : Promise < void > {
67
+ async installPkg ( release : Release ) : Promise < void > {
68
+ const installDir = this . directory ;
60
69
const destination = `${ installDir } /terraform-ls_v${ release . version } .zip` ;
61
70
fs . mkdirSync ( installDir , { recursive : true } ) ; // create install directory if missing
62
71
@@ -67,7 +76,7 @@ export class LanguageServerInstaller {
67
76
throw new Error ( `Install error: no matching terraform-ls binary for ${ os } /${ arch } ` ) ;
68
77
}
69
78
try {
70
- this . removeOldBinary ( installDir ) ;
79
+ this . removeOldBinary ( ) ;
71
80
} catch {
72
81
// ignore missing binary (new install)
73
82
}
@@ -78,20 +87,20 @@ export class LanguageServerInstaller {
78
87
title : "Installing terraform-ls"
79
88
} , async ( progress ) => {
80
89
progress . report ( { increment : 30 } ) ;
81
- await release . download ( build . url , destination , userAgent ) ;
90
+ await release . download ( build . url , destination , this . userAgent ) ;
82
91
progress . report ( { increment : 30 } ) ;
83
92
await release . verify ( destination , build . filename )
84
93
progress . report ( { increment : 30 } ) ;
85
94
return release . unpack ( installDir , destination )
86
95
} ) ;
87
96
}
88
97
89
- removeOldBinary ( directory : string ) : void {
90
- fs . unlinkSync ( lsBinPath ( directory ) ) ;
98
+ removeOldBinary ( ) : void {
99
+ fs . unlinkSync ( lsBinPath ( this . directory ) ) ;
91
100
}
92
101
93
- public async cleanupZips ( directory : string ) : Promise < string [ ] > {
94
- return del ( `${ directory } /terraform-ls*.zip` , { force : true } ) ;
102
+ public async cleanupZips ( ) : Promise < string [ ] > {
103
+ return del ( `${ this . directory } /terraform-ls*.zip` , { force : true } ) ;
95
104
}
96
105
97
106
showChangelog ( version : string ) : void {
0 commit comments