@@ -23,22 +23,36 @@ export interface CargoFeatures {
23
23
allFeatures : boolean ;
24
24
features : string [ ] ;
25
25
}
26
+
27
+ export const enum UpdatesChannel {
28
+ Stable = "stable" ,
29
+ Nightly = "nightly"
30
+ }
31
+
32
+ export const NIGHTLY_TAG = "nightly" ;
26
33
export class Config {
27
- private static readonly rootSection = "rust-analyzer" ;
28
- private static readonly requiresReloadOpts = [
34
+ readonly extensionId = "matklad.rust-analyzer" ;
35
+
36
+ private readonly rootSection = "rust-analyzer" ;
37
+ private readonly requiresReloadOpts = [
29
38
"cargoFeatures" ,
30
39
"cargo-watch" ,
31
40
"highlighting.semanticTokens" ,
32
41
"inlayHints" ,
33
42
]
34
- . map ( opt => `${ Config . rootSection } .${ opt } ` ) ;
43
+ . map ( opt => `${ this . rootSection } .${ opt } ` ) ;
35
44
36
- private static readonly extensionVersion : string = ( ( ) => {
45
+ /**
46
+ * Either `nightly` or `YYYY-MM-DD` (i.e. `stable` release)
47
+ */
48
+ private readonly extensionVersion : string = ( ( ) => {
37
49
const packageJsonVersion = vscode
38
50
. extensions
39
- . getExtension ( "matklad.rust-analyzer" ) !
51
+ . getExtension ( this . extensionId ) !
40
52
. packageJSON
41
- . version as string ; // n.n.YYYYMMDD
53
+ . version as string ;
54
+
55
+ if ( packageJsonVersion . endsWith ( NIGHTLY_TAG ) ) return NIGHTLY_TAG ;
42
56
43
57
const realVersionRegexp = / ^ \d + \. \d + \. ( \d { 4 } ) ( \d { 2 } ) ( \d { 2 } ) / ;
44
58
const [ , yyyy , mm , dd ] = packageJsonVersion . match ( realVersionRegexp ) ! ;
@@ -54,7 +68,7 @@ export class Config {
54
68
}
55
69
56
70
private refreshConfig ( ) {
57
- this . cfg = vscode . workspace . getConfiguration ( Config . rootSection ) ;
71
+ this . cfg = vscode . workspace . getConfiguration ( this . rootSection ) ;
58
72
const enableLogging = this . cfg . get ( "trace.extension" ) as boolean ;
59
73
log . setEnabled ( enableLogging ) ;
60
74
log . debug ( "Using configuration:" , this . cfg ) ;
@@ -63,7 +77,7 @@ export class Config {
63
77
private async onConfigChange ( event : vscode . ConfigurationChangeEvent ) {
64
78
this . refreshConfig ( ) ;
65
79
66
- const requiresReloadOpt = Config . requiresReloadOpts . find (
80
+ const requiresReloadOpt = this . requiresReloadOpts . find (
67
81
opt => event . affectsConfiguration ( opt )
68
82
) ;
69
83
@@ -121,8 +135,16 @@ export class Config {
121
135
}
122
136
}
123
137
138
+ get installedExtensionUpdateChannel ( ) {
139
+ if ( this . serverPath !== null ) return null ;
140
+
141
+ return this . extensionVersion === NIGHTLY_TAG
142
+ ? UpdatesChannel . Nightly
143
+ : UpdatesChannel . Stable ;
144
+ }
145
+
124
146
get serverSource ( ) : null | ArtifactSource {
125
- const serverPath = RA_LSP_DEBUG ?? this . cfg . get < null | string > ( " serverPath" ) ;
147
+ const serverPath = RA_LSP_DEBUG ?? this . serverPath ;
126
148
127
149
if ( serverPath ) {
128
150
return {
@@ -135,23 +157,47 @@ export class Config {
135
157
136
158
if ( ! prebuiltBinaryName ) return null ;
137
159
160
+ return this . createGithubReleaseSource (
161
+ prebuiltBinaryName ,
162
+ this . extensionVersion
163
+ ) ;
164
+ }
165
+
166
+ private createGithubReleaseSource ( file : string , tag : string ) : ArtifactSource . GithubRelease {
138
167
return {
139
168
type : ArtifactSource . Type . GithubRelease ,
169
+ file,
170
+ tag,
140
171
dir : this . ctx . globalStoragePath ,
141
- file : prebuiltBinaryName ,
142
- storage : this . ctx . globalState ,
143
- tag : Config . extensionVersion ,
144
- askBeforeDownload : this . cfg . get ( "updates.askBeforeDownload" ) as boolean ,
145
172
repo : {
146
173
name : "rust-analyzer" ,
147
- owner : "rust-analyzer" ,
174
+ owner : "rust-analyzer"
148
175
}
149
- } ;
176
+ }
150
177
}
151
178
179
+ get nightlyVsixSource ( ) : ArtifactSource . GithubRelease {
180
+ return this . createGithubReleaseSource ( "rust-analyzer.vsix" , NIGHTLY_TAG ) ;
181
+ }
182
+
183
+ readonly installedNightlyExtensionReleaseDate = new DateStorage (
184
+ "rust-analyzer-installed-nightly-extension-release-date" ,
185
+ this . ctx . globalState
186
+ ) ;
187
+ readonly serverReleaseDate = new DateStorage (
188
+ "rust-analyzer-server-release-date" ,
189
+ this . ctx . globalState
190
+ ) ;
191
+ readonly serverReleaseTag = new StringStorage (
192
+ "rust-analyzer-release-tag" , this . ctx . globalState
193
+ ) ;
194
+
152
195
// We don't do runtime config validation here for simplicity. More on stackoverflow:
153
196
// https://stackoverflow.com/questions/60135780/what-is-the-best-way-to-type-check-the-configuration-for-vscode-extension
154
197
198
+ private get serverPath ( ) { return this . cfg . get ( "serverPath" ) as null | string ; }
199
+ get updatesChannel ( ) { return this . cfg . get ( "updates.channel" ) as UpdatesChannel ; }
200
+ get askBeforeDownload ( ) { return this . cfg . get ( "updates.askBeforeDownload" ) as boolean ; }
155
201
get highlightingSemanticTokens ( ) { return this . cfg . get ( "highlighting.semanticTokens" ) as boolean ; }
156
202
get highlightingOn ( ) { return this . cfg . get ( "highlightingOn" ) as boolean ; }
157
203
get rainbowHighlightingOn ( ) { return this . cfg . get ( "rainbowHighlightingOn" ) as boolean ; }
@@ -189,3 +235,38 @@ export class Config {
189
235
// for internal use
190
236
get withSysroot ( ) { return this . cfg . get ( "withSysroot" , true ) as boolean ; }
191
237
}
238
+
239
+ export class StringStorage {
240
+ constructor (
241
+ private readonly key : string ,
242
+ private readonly storage : vscode . Memento
243
+ ) { }
244
+
245
+ get ( ) : null | string {
246
+ const tag = this . storage . get ( this . key , null ) ;
247
+ log . debug ( this . key , "==" , tag ) ;
248
+ return tag ;
249
+ }
250
+ async set ( tag : string ) {
251
+ log . debug ( this . key , "=" , tag ) ;
252
+ await this . storage . update ( this . key , tag ) ;
253
+ }
254
+ }
255
+ export class DateStorage {
256
+
257
+ constructor (
258
+ private readonly key : string ,
259
+ private readonly storage : vscode . Memento
260
+ ) { }
261
+
262
+ get ( ) : null | Date {
263
+ const date = this . storage . get ( this . key , null ) ;
264
+ log . debug ( this . key , "==" , date ) ;
265
+ return date ? new Date ( date ) : null ;
266
+ }
267
+
268
+ async set ( date : null | Date ) {
269
+ log . debug ( this . key , "=" , date ) ;
270
+ await this . storage . update ( this . key , date ) ;
271
+ }
272
+ }
0 commit comments