1
1
import * as vscode from "vscode" ;
2
2
import * as path from "path" ;
3
- import { promises as dns } from "dns" ;
4
3
import { spawnSync } from "child_process" ;
5
4
6
5
import { ArtifactSource } from "./interfaces" ;
7
6
import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info" ;
8
- import { downloadArtifact } from "./download_artifact " ;
7
+ import { downloadArtifactWithProgressUi } from "./downloads " ;
9
8
import { log , assert } from "../util" ;
9
+ import { Config , NIGHTLY_TAG } from "../config" ;
10
+
11
+ export async function ensureServerBinary ( config : Config ) : Promise < null | string > {
12
+ const source = config . serverSource ;
10
13
11
- export async function ensureServerBinary ( source : null | ArtifactSource ) : Promise < null | string > {
12
14
if ( ! source ) {
13
15
vscode . window . showErrorMessage (
14
16
"Unfortunately we don't ship binaries for your platform yet. " +
@@ -35,18 +37,11 @@ export async function ensureServerBinary(source: null | ArtifactSource): Promise
35
37
return null ;
36
38
}
37
39
case ArtifactSource . Type . GithubRelease : {
38
- const prebuiltBinaryPath = path . join ( source . dir , source . file ) ;
39
-
40
- const installedVersion : null | string = getServerVersion ( source . storage ) ;
41
- const requiredVersion : string = source . tag ;
42
-
43
- log . debug ( "Installed version:" , installedVersion , "required:" , requiredVersion ) ;
44
-
45
- if ( isBinaryAvailable ( prebuiltBinaryPath ) && installedVersion === requiredVersion ) {
46
- return prebuiltBinaryPath ;
40
+ if ( ! shouldDownloadServer ( source , config ) ) {
41
+ return path . join ( source . dir , source . file ) ;
47
42
}
48
43
49
- if ( source . askBeforeDownload ) {
44
+ if ( config . askBeforeDownload ) {
50
45
const userResponse = await vscode . window . showInformationMessage (
51
46
`Language server version ${ source . tag } for rust-analyzer is not installed. ` +
52
47
"Do you want to download it now?" ,
@@ -55,38 +50,53 @@ export async function ensureServerBinary(source: null | ArtifactSource): Promise
55
50
if ( userResponse !== "Download now" ) return null ;
56
51
}
57
52
58
- if ( ! await downloadServer ( source ) ) return null ;
59
-
60
- return prebuiltBinaryPath ;
53
+ return await downloadServer ( source , config ) ;
61
54
}
62
55
}
63
56
}
64
57
65
- async function downloadServer ( source : ArtifactSource . GithubRelease ) : Promise < boolean > {
58
+ function shouldDownloadServer (
59
+ source : ArtifactSource . GithubRelease ,
60
+ config : Config
61
+ ) : boolean {
62
+ if ( ! isBinaryAvailable ( path . join ( source . dir , source . file ) ) ) return true ;
63
+
64
+ const installed = {
65
+ tag : config . serverReleaseTag . get ( ) ,
66
+ date : config . serverReleaseDate . get ( )
67
+ } ;
68
+ const required = {
69
+ tag : source . tag ,
70
+ date : config . installedNightlyExtensionReleaseDate . get ( )
71
+ } ;
72
+
73
+ log . debug ( "Installed server:" , installed , "required:" , required ) ;
74
+
75
+ if ( required . tag !== NIGHTLY_TAG || installed . tag !== NIGHTLY_TAG ) {
76
+ return required . tag !== installed . tag ;
77
+ }
78
+
79
+ assert ( required . date !== null , "Extension release date should have been saved during its installation" ) ;
80
+ assert ( installed . date !== null , "Server release date should have been saved during its installation" ) ;
81
+
82
+ return installed . date . getTime ( ) !== required . date . getTime ( ) ;
83
+ }
84
+
85
+ async function downloadServer (
86
+ source : ArtifactSource . GithubRelease ,
87
+ config : Config ,
88
+ ) : Promise < null | string > {
66
89
try {
67
90
const releaseInfo = await fetchArtifactReleaseInfo ( source . repo , source . file , source . tag ) ;
68
91
69
- await downloadArtifact ( releaseInfo , source . file , source . dir , "language server" ) ;
70
- await setServerVersion ( source . storage , releaseInfo . releaseName ) ;
92
+ await downloadArtifactWithProgressUi ( releaseInfo , source . file , source . dir , "language server" ) ;
93
+ await Promise . all ( [
94
+ config . serverReleaseTag . set ( releaseInfo . releaseName ) ,
95
+ config . serverReleaseDate . set ( releaseInfo . releaseDate )
96
+ ] ) ;
71
97
} catch ( err ) {
72
- vscode . window . showErrorMessage (
73
- `Failed to download language server from ${ source . repo . name } ` +
74
- `GitHub repository: ${ err . message } `
75
- ) ;
76
-
77
- log . error ( err ) ;
78
-
79
- dns . resolve ( 'example.com' ) . then (
80
- addrs => log . debug ( "DNS resolution for example.com was successful" , addrs ) ,
81
- err => {
82
- log . error (
83
- "DNS resolution for example.com failed, " +
84
- "there might be an issue with Internet availability"
85
- ) ;
86
- log . error ( err ) ;
87
- }
88
- ) ;
89
- return false ;
98
+ log . downloadError ( err , "language server" , source . repo . name ) ;
99
+ return null ;
90
100
}
91
101
92
102
const binaryPath = path . join ( source . dir , source . file ) ;
@@ -101,7 +111,7 @@ async function downloadServer(source: ArtifactSource.GithubRelease): Promise<boo
101
111
"Rust analyzer language server was successfully installed 🦀"
102
112
) ;
103
113
104
- return true ;
114
+ return binaryPath ;
105
115
}
106
116
107
117
function isBinaryAvailable ( binaryPath : string ) : boolean {
@@ -115,14 +125,3 @@ function isBinaryAvailable(binaryPath: string): boolean {
115
125
116
126
return res . status === 0 ;
117
127
}
118
-
119
- function getServerVersion ( storage : vscode . Memento ) : null | string {
120
- const version = storage . get < null | string > ( "server-version" , null ) ;
121
- log . debug ( "Get server-version:" , version ) ;
122
- return version ;
123
- }
124
-
125
- async function setServerVersion ( storage : vscode . Memento , version : string ) : Promise < void > {
126
- log . debug ( "Set server-version:" , version ) ;
127
- await storage . update ( "server-version" , version . toString ( ) ) ;
128
- }
0 commit comments