Skip to content
This repository was archived by the owner on Mar 19, 2024. It is now read-only.

Commit 15b8f31

Browse files
authored
Add toolchain update checking on startup (#34)
* Toolchain updating * Check for toolchain update at startup * Check for toolchain update after switching toolchain * Only prompts to update if update has _'rls-preview'_ * Skips check if toolchain is dated _(e.g. nightly-2017-12-12)_ * Enabled/disable in settings _(default enabled)_ * Chang _'switched toolchain'_ prompt to a _success_ style one * Add toolchain update info to readme features * Add 'other packages not required' note to readme _Install_ section
1 parent 5c647a2 commit 15b8f31

File tree

4 files changed

+103
-64
lines changed

4 files changed

+103
-64
lines changed

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,21 @@ Rust language support for Atom-IDE, powered by the Rust Language Server (RLS).
99
- Go to definition (`ctrl` or `cmd` click)
1010
- Type information and Documentation on hover (hold `ctrl` or `cmd` for more information)
1111
- Rls toolchain selection in package settings
12+
- Rls toolchain update checking at startup
1213
- Rls configuration using `rls.toml` file at project root, see [rls#configuration](https://github.com/rust-lang-nursery/rls#configuration)
1314
```toml
1415
# rls.toml
1516
features = ["serde"]
1617
```
1718

1819
## Install
19-
2020
You can install from the command line with:
21-
2221
```
2322
$ apm install ide-rust
2423
```
25-
2624
Or you can install from Settings view by searching for `ide-rust`.
2725

26+
No other packages or manual setup is required as these will be handled with user prompts after install.
2827

2928
## Overriding Rls
3029
The Rls command can be specified manually, for example to run from local source code:
@@ -47,5 +46,4 @@ If stuff isn't working you can try **enabling logging** to debug:
4746
This will spit out language server message logging into the atom console. Check if requests/responses are being sent or are incorrect. It will also include any Rls stderr messages (as warnings) which may point to Rls bugs.
4847

4948
## License
50-
5149
MIT License. See the [license](LICENSE) for more details.

lib/index.js

Lines changed: 92 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const cp = require("child_process")
22
const os = require("os")
33
const path = require("path")
4+
const toml = require('toml')
45
const _ = require('underscore-plus')
56
const RlsProject = require('./rls-project.js')
67
const { CompositeDisposable, Disposable } = require('atom')
@@ -61,6 +62,34 @@ function atomPrompt(message, options, buttons) {
6162
})
6263
}
6364

65+
/** @return {Promise<string>} new version of update available (falsy otherwise) */
66+
function checkForToolchainUpdates() {
67+
const toolchain = configToolchain()
68+
69+
return exec(`rustup run ${toolchain} rustc --version`).then(({ stdout }) => {
70+
return new Promise((resolve, reject) => {
71+
require("https").get(`https://static.rust-lang.org/dist/channel-rust-${toolchain}.toml`,
72+
res => {
73+
if (res.statusCode !== 200) {
74+
return reject(new Error(`check for toolchain update failed, status: ${res.statusCode}`))
75+
}
76+
77+
res.setEncoding("utf8")
78+
let body = ""
79+
res.on("data", data => body += data)
80+
res.on("end", () => {
81+
// use a subsection as toml is slow to parse fully
82+
let rustcInfo = body.match(/(\[pkg\.rustc\][^\[]*)/m)
83+
if (!rustcInfo) return reject(new Error('could not split channel toml output'))
84+
let rustcVersion = toml.parse(rustcInfo[1]).pkg.rustc.version.trim()
85+
resolve(!stdout.trim().endsWith(rustcVersion) && body.includes('rls-preview') &&
86+
`rustc ${rustcVersion}`)
87+
})
88+
})
89+
})
90+
})
91+
}
92+
6493
// Installs rustup
6594
function installRustup() {
6695
return exec("curl https://sh.rustup.rs -sSf | sh -s -- -y")
@@ -253,10 +282,69 @@ class RustLanguageClient extends AutoLanguageClient {
253282
' For example ***beta*** or ***nightly-2017-11-01***.',
254283
type: 'string',
255284
default: 'nightly'
285+
},
286+
checkForToolchainUpdates: {
287+
description: 'Check on startup for toolchain updates, prompting to install if available',
288+
type: 'boolean',
289+
default: true
256290
}
257291
}
258292
}
259293

294+
/**
295+
* @param {string} reason Reason for the restart, shown in the prompt
296+
* TODO I'd actually like to restart all servers with the new toolchain here
297+
* but this doesn't currently seem possible see https://github.com/atom/atom-languageclient/issues/135
298+
* Until it is possible a 'Reload' prompt is helpful
299+
*/
300+
_restartLanguageServers(reason) {
301+
atom.notifications.addSuccess(reason, {
302+
_src: 'ide-rust',
303+
dismissable: true,
304+
detail: 'Close and reopen editor windows or reload atom to ensure usage of the new toolchain',
305+
buttons: [{
306+
text: 'Reload',
307+
className: 'btn-warning',
308+
onDidClick: () => atom.commands.dispatch(window, 'window:reload')
309+
}]
310+
})
311+
}
312+
313+
// check for toolchain updates if installed & not dated
314+
_promptToUpdateToolchain() {
315+
const toolchain = configToolchain()
316+
const datedRegex = /-\d{4,}-\d{2}-\d{2}$/
317+
318+
if (atom.config.get('ide-rust.checkForToolchainUpdates') && !datedRegex.test(toolchain)) {
319+
checkForToolchainUpdates()
320+
.then(newVersion => {
321+
if (newVersion) {
322+
atom.notifications.addInfo(`Rls \`${toolchain}\` toolchain update available`, {
323+
description: newVersion,
324+
_src: 'ide-rust',
325+
dismissable: true,
326+
buttons: [{
327+
text: 'Update',
328+
onDidClick: () => {
329+
clearIdeRustInfos()
330+
331+
let updatePromise = exec(`rustup update ${toolchain}`)
332+
.then(() => checkToolchain())
333+
.then(() => checkRls())
334+
.then(() => this._restartLanguageServers(`Updated Rls toolchain`))
335+
.catch(e => console.error(e))
336+
this.busySignalService && this.busySignalService.reportBusyWhile(
337+
`Updating rust \`${toolchain}\` toolchain`,
338+
() => updatePromise)
339+
}
340+
}]
341+
})
342+
}
343+
})
344+
.catch(e => console.error(e))
345+
}
346+
}
347+
260348
activate() {
261349
super.activate()
262350

@@ -279,21 +367,12 @@ class RustLanguageClient extends AutoLanguageClient {
279367
_.debounce(({ newValue }) => {
280368
checkToolchain(this.busySignalService)
281369
.then(() => checkRls(this.busySignalService))
282-
.then(() => {
283-
// TODO I'd actually like to restart all servers with the new toolchain here
284-
// but this doesn't currently seem possible see https://github.com/atom/atom-languageclient/issues/135
285-
// Until it is possible the 'Reload' button should help
286-
atomPrompt(`Switched Rls toolchain to \`${newValue}\``, {
287-
detail: 'Close and reopen editor windows or reload ' +
288-
'atom to ensure usage of the new toolchain',
289-
buttons: [{
290-
text: 'Reload',
291-
onDidClick: () => atom.commands.dispatch(window, 'window:reload')
292-
}]
293-
})
294-
})
370+
.then(() => this._restartLanguageServers(`Switched Rls toolchain to \`${newValue}\``))
371+
.then(() => this._promptToUpdateToolchain())
295372
}, 1000)
296373
))
374+
375+
this._promptToUpdateToolchain()
297376
}
298377

299378
deactivate() {

package-lock.json

Lines changed: 7 additions & 45 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
"atom": ">=1.21.0"
1919
},
2020
"dependencies": {
21-
"atom-languageclient": "^0.7.2",
22-
"atom-package-deps": "^4.6.0",
21+
"atom-languageclient": "^0.7.3",
22+
"atom-package-deps": "^4.6.1",
2323
"toml": "^2.3.3",
2424
"underscore-plus": "^1.6.6"
2525
},

0 commit comments

Comments
 (0)