Skip to content

Commit 9c264a1

Browse files
authored
Merge pull request #1980 from chunk0tronic/show_updates
rustup check
2 parents ec6d1af + 540ccc6 commit 9c264a1

File tree

10 files changed

+204
-32
lines changed

10 files changed

+204
-32
lines changed

src/cli/rustup_mode.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub fn main() -> Result<()> {
4949
},
5050
("install", Some(m)) => update(cfg, m)?,
5151
("update", Some(m)) => update(cfg, m)?,
52+
("check", Some(_)) => check_updates(cfg)?,
5253
("uninstall", Some(m)) => toolchain_remove(cfg, m)?,
5354
("default", Some(m)) => default_(cfg, m)?,
5455
("toolchain", Some(c)) => match c.subcommand() {
@@ -200,6 +201,10 @@ pub fn cli() -> App<'static, 'static> {
200201
.takes_value(false),
201202
),
202203
)
204+
.subcommand(
205+
SubCommand::with_name("check")
206+
.about("Check for updates to Rust toolchains")
207+
)
203208
.subcommand(
204209
SubCommand::with_name("default")
205210
.about("Set the default toolchain")
@@ -668,6 +673,48 @@ fn default_(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
668673
Ok(())
669674
}
670675

676+
fn check_updates(cfg: &Cfg) -> Result<()> {
677+
let mut t = term2::stdout();
678+
let channels = cfg.list_channels()?;
679+
680+
for channel in channels {
681+
match channel {
682+
(ref name, Ok(ref toolchain)) => {
683+
let current_version = toolchain.show_version()?;
684+
let dist_version = toolchain.show_dist_version()?;
685+
let _ = t.attr(term2::Attr::Bold);
686+
write!(t, "{} - ", name)?;
687+
match (current_version, dist_version) {
688+
(None, None) => {
689+
let _ = t.fg(term2::color::BRIGHT_RED);
690+
writeln!(t, "Cannot identify installed or update versions")?;
691+
}
692+
(Some(cv), None) => {
693+
let _ = t.fg(term2::color::BRIGHT_GREEN);
694+
write!(t, "Up to date")?;
695+
let _ = t.reset();
696+
writeln!(t, " : {}", cv)?;
697+
}
698+
(Some(cv), Some(dv)) => {
699+
let _ = t.fg(term2::color::BRIGHT_YELLOW);
700+
write!(t, "Update available")?;
701+
let _ = t.reset();
702+
writeln!(t, " : {} -> {}", cv, dv)?;
703+
}
704+
(None, Some(dv)) => {
705+
let _ = t.fg(term2::color::BRIGHT_YELLOW);
706+
write!(t, "Update available")?;
707+
let _ = t.reset();
708+
writeln!(t, " : (Unknown version) -> {}", dv)?;
709+
}
710+
}
711+
}
712+
(_, Err(err)) => return Err(err.into()),
713+
}
714+
}
715+
Ok(())
716+
}
717+
671718
fn update(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
672719
let self_update = !m.is_present("no-self-update") && !self_update::NEVER_SELF_UPDATE;
673720
if let Some(names) = m.values_of("toolchain") {

src/config.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -390,22 +390,28 @@ impl Cfg {
390390
}
391391
}
392392

393-
pub fn update_all_channels(
394-
&self,
395-
force_update: bool,
396-
) -> Result<Vec<(String, Result<UpdateStatus>)>> {
393+
pub fn list_channels(&self) -> Result<Vec<(String, Result<Toolchain<'_>>)>> {
397394
let toolchains = self.list_toolchains()?;
398395

399396
// Convert the toolchain strings to Toolchain values
400397
let toolchains = toolchains.into_iter();
401398
let toolchains = toolchains.map(|n| (n.clone(), self.get_toolchain(&n, true)));
402399

403400
// Filter out toolchains that don't track a release channel
404-
let toolchains = toolchains
405-
.filter(|&(_, ref t)| t.as_ref().map(Toolchain::is_tracking).unwrap_or(false));
401+
Ok(toolchains
402+
.filter(|&(_, ref t)| t.as_ref().map(Toolchain::is_tracking).unwrap_or(false))
403+
.collect())
404+
}
405+
406+
pub fn update_all_channels(
407+
&self,
408+
force_update: bool,
409+
) -> Result<Vec<(String, Result<UpdateStatus>)>> {
410+
let channels = self.list_channels()?;
411+
let channels = channels.into_iter();
406412

407413
// Update toolchains and collect the results
408-
let toolchains = toolchains.map(|(n, t)| {
414+
let channels = channels.map(|(n, t)| {
409415
let t = t.and_then(|t| {
410416
let t = t.install_from_dist(force_update);
411417
if let Err(ref e) = t {
@@ -417,7 +423,7 @@ impl Cfg {
417423
(n, t)
418424
});
419425

420-
Ok(toolchains.collect())
426+
Ok(channels.collect())
421427
}
422428

423429
pub fn check_metadata_version(&self) -> Result<()> {

src/dist/dist.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ fn update_from_dist_<'a>(
679679
}
680680
}
681681

682-
fn dl_v2_manifest<'a>(
682+
pub fn dl_v2_manifest<'a>(
683683
download: DownloadCfg<'a>,
684684
update_hash: Option<&Path>,
685685
toolchain: &ToolchainDesc,

src/toolchain.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,36 @@ impl<'a> Toolchain<'a> {
470470
})
471471
}
472472

473+
pub fn show_version(&self) -> Result<Option<String>> {
474+
if !self.exists() {
475+
return Err(ErrorKind::ToolchainNotInstalled(self.name.to_owned()).into());
476+
}
477+
478+
let toolchain = &self.name;
479+
let toolchain = ToolchainDesc::from_str(toolchain)?;
480+
481+
let prefix = InstallPrefix::from(self.path.to_owned());
482+
let manifestation = Manifestation::open(prefix, toolchain.target.clone())?;
483+
484+
match manifestation.load_manifest()? {
485+
Some(manifest) => Ok(Some(manifest.get_rust_version()?.to_string())),
486+
None => Ok(None),
487+
}
488+
}
489+
490+
pub fn show_dist_version(&self) -> Result<Option<String>> {
491+
let update_hash = self.update_hash()?;
492+
493+
match crate::dist::dist::dl_v2_manifest(
494+
self.download_cfg(),
495+
update_hash.as_ref().map(|p| &**p),
496+
&self.desc()?,
497+
)? {
498+
Some((manifest, _)) => Ok(Some(manifest.get_rust_version()?.to_string())),
499+
None => Ok(None),
500+
}
501+
}
502+
473503
pub fn list_components(&self) -> Result<Vec<ComponentStatus>> {
474504
if !self.exists() {
475505
return Err(ErrorKind::ToolchainNotInstalled(self.name.to_owned()).into());

tests/cli-exact.rs

Lines changed: 90 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
pub mod mock;
55

66
use crate::mock::clitools::{
7-
self, expect_err_ex, expect_ok, expect_ok_ex, this_host_triple, Config, Scenario,
7+
self, expect_err_ex, expect_ok, expect_ok_ex, expect_stdout_ok, set_current_dist_date,
8+
this_host_triple, Config, Scenario,
89
};
910

1011
macro_rules! for_host {
@@ -14,7 +15,7 @@ macro_rules! for_host {
1415
}
1516

1617
fn setup(f: &dyn Fn(&mut Config)) {
17-
clitools::setup(Scenario::SimpleV2, f);
18+
clitools::setup(Scenario::ArchivesV2, f);
1819
}
1920

2021
#[test]
@@ -31,7 +32,7 @@ fn update() {
3132
),
3233
for_host!(
3334
r"info: syncing channel updates for 'nightly-{0}'
34-
info: latest update on 2015-01-02, rust version 1.3.0
35+
info: latest update on 2015-01-02, rust version 1.3.0 (hash-n-2)
3536
info: downloading component 'rustc'
3637
info: downloading component 'cargo'
3738
info: downloading component 'rust-std'
@@ -68,6 +69,89 @@ fn update_again() {
6869
});
6970
}
7071

72+
#[test]
73+
fn check_updates_none() {
74+
setup(&|config| {
75+
set_current_dist_date(config, "2015-01-01");
76+
expect_ok(config, &["rustup", "update", "stable", "--no-self-update"]);
77+
expect_ok(config, &["rustup", "update", "beta", "--no-self-update"]);
78+
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
79+
expect_stdout_ok(
80+
config,
81+
&["rustup", "check"],
82+
for_host!(
83+
r"stable-{0} - Up to date : 1.0.0 (hash-s-1)
84+
beta-{0} - Up to date : 1.1.0 (hash-b-1)
85+
nightly-{0} - Up to date : 1.2.0 (hash-n-1)
86+
"
87+
),
88+
);
89+
})
90+
}
91+
92+
#[test]
93+
fn check_updates_some() {
94+
setup(&|config| {
95+
set_current_dist_date(config, "2015-01-01");
96+
expect_ok(config, &["rustup", "update", "stable", "--no-self-update"]);
97+
expect_ok(config, &["rustup", "update", "beta", "--no-self-update"]);
98+
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
99+
set_current_dist_date(config, "2015-01-02");
100+
expect_stdout_ok(
101+
config,
102+
&["rustup", "check"],
103+
for_host!(
104+
r"stable-{0} - Update available : 1.0.0 (hash-s-1) -> 1.1.0 (hash-s-2)
105+
beta-{0} - Update available : 1.1.0 (hash-b-1) -> 1.2.0 (hash-b-2)
106+
nightly-{0} - Update available : 1.2.0 (hash-n-1) -> 1.3.0 (hash-n-2)
107+
"
108+
),
109+
);
110+
})
111+
}
112+
113+
#[test]
114+
fn check_updates_with_update() {
115+
setup(&|config| {
116+
set_current_dist_date(config, "2015-01-01");
117+
expect_ok(config, &["rustup", "update", "stable", "--no-self-update"]);
118+
expect_ok(config, &["rustup", "update", "beta", "--no-self-update"]);
119+
expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]);
120+
expect_stdout_ok(
121+
config,
122+
&["rustup", "check"],
123+
for_host!(
124+
r"stable-{0} - Up to date : 1.0.0 (hash-s-1)
125+
beta-{0} - Up to date : 1.1.0 (hash-b-1)
126+
nightly-{0} - Up to date : 1.2.0 (hash-n-1)
127+
"
128+
),
129+
);
130+
set_current_dist_date(config, "2015-01-02");
131+
expect_stdout_ok(
132+
config,
133+
&["rustup", "check"],
134+
for_host!(
135+
r"stable-{0} - Update available : 1.0.0 (hash-s-1) -> 1.1.0 (hash-s-2)
136+
beta-{0} - Update available : 1.1.0 (hash-b-1) -> 1.2.0 (hash-b-2)
137+
nightly-{0} - Update available : 1.2.0 (hash-n-1) -> 1.3.0 (hash-n-2)
138+
"
139+
),
140+
);
141+
expect_ok(config, &["rustup", "update", "beta", "--no-self-update"]);
142+
expect_stdout_ok(
143+
config,
144+
&["rustup", "check"],
145+
for_host!(
146+
r"stable-{0} - Update available : 1.0.0 (hash-s-1) -> 1.1.0 (hash-s-2)
147+
beta-{0} - Up to date : 1.2.0 (hash-b-2)
148+
nightly-{0} - Update available : 1.2.0 (hash-n-1) -> 1.3.0 (hash-n-2)
149+
"
150+
),
151+
);
152+
})
153+
}
154+
71155
#[test]
72156
fn default() {
73157
setup(&|config| {
@@ -82,7 +166,7 @@ fn default() {
82166
),
83167
for_host!(
84168
r"info: syncing channel updates for 'nightly-{0}'
85-
info: latest update on 2015-01-02, rust version 1.3.0
169+
info: latest update on 2015-01-02, rust version 1.3.0 (hash-n-2)
86170
info: downloading component 'rustc'
87171
info: downloading component 'cargo'
88172
info: downloading component 'rust-std'
@@ -342,7 +426,7 @@ fn update_invalid_toolchain() {
342426
&["rustup", "update", "nightly-2016-03-1"],
343427
r"",
344428
r"info: syncing channel updates for 'nightly-2016-03-1'
345-
info: latest update on 2015-01-02, rust version 1.3.0
429+
info: latest update on 2015-01-02, rust version 1.3.0 (hash-n-2)
346430
error: target '2016-03-1' not found in channel. Perhaps check https://forge.rust-lang.org/platform-support.html for available targets
347431
",
348432
);
@@ -357,7 +441,7 @@ fn default_invalid_toolchain() {
357441
&["rustup", "default", "nightly-2016-03-1"],
358442
r"",
359443
r"info: syncing channel updates for 'nightly-2016-03-1'
360-
info: latest update on 2015-01-02, rust version 1.3.0
444+
info: latest update on 2015-01-02, rust version 1.3.0 (hash-n-2)
361445
error: target '2016-03-1' not found in channel. Perhaps check https://forge.rust-lang.org/platform-support.html for available targets
362446
",
363447
);

tests/cli-rustup.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ fn rustup_stable() {
4646
),
4747
for_host!(
4848
r"info: syncing channel updates for 'stable-{0}'
49-
info: latest update on 2015-01-02, rust version 1.1.0
49+
info: latest update on 2015-01-02, rust version 1.1.0 (hash-s-2)
5050
info: downloading component 'rustc'
5151
info: downloading component 'cargo'
5252
info: downloading component 'rust-std'
@@ -108,7 +108,7 @@ fn rustup_all_channels() {
108108
),
109109
for_host!(
110110
r"info: syncing channel updates for 'stable-{0}'
111-
info: latest update on 2015-01-02, rust version 1.1.0
111+
info: latest update on 2015-01-02, rust version 1.1.0 (hash-s-2)
112112
info: downloading component 'rustc'
113113
info: downloading component 'cargo'
114114
info: downloading component 'rust-std'
@@ -122,7 +122,7 @@ info: installing component 'cargo'
122122
info: installing component 'rust-std'
123123
info: installing component 'rust-docs'
124124
info: syncing channel updates for 'beta-{0}'
125-
info: latest update on 2015-01-02, rust version 1.2.0
125+
info: latest update on 2015-01-02, rust version 1.2.0 (hash-b-2)
126126
info: downloading component 'rustc'
127127
info: downloading component 'cargo'
128128
info: downloading component 'rust-std'
@@ -136,7 +136,7 @@ info: installing component 'cargo'
136136
info: installing component 'rust-std'
137137
info: installing component 'rust-docs'
138138
info: syncing channel updates for 'nightly-{0}'
139-
info: latest update on 2015-01-02, rust version 1.3.0
139+
info: latest update on 2015-01-02, rust version 1.3.0 (hash-n-2)
140140
info: downloading component 'rustc'
141141
info: downloading component 'cargo'
142142
info: downloading component 'rust-std'
@@ -177,7 +177,7 @@ fn rustup_some_channels_up_to_date() {
177177
),
178178
for_host!(
179179
r"info: syncing channel updates for 'stable-{0}'
180-
info: latest update on 2015-01-02, rust version 1.1.0
180+
info: latest update on 2015-01-02, rust version 1.1.0 (hash-s-2)
181181
info: downloading component 'rustc'
182182
info: downloading component 'cargo'
183183
info: downloading component 'rust-std'
@@ -192,7 +192,7 @@ info: installing component 'rust-std'
192192
info: installing component 'rust-docs'
193193
info: syncing channel updates for 'beta-{0}'
194194
info: syncing channel updates for 'nightly-{0}'
195-
info: latest update on 2015-01-02, rust version 1.3.0
195+
info: latest update on 2015-01-02, rust version 1.3.0 (hash-n-2)
196196
info: downloading component 'rustc'
197197
info: downloading component 'cargo'
198198
info: downloading component 'rust-std'
@@ -240,7 +240,7 @@ fn default() {
240240
),
241241
for_host!(
242242
r"info: syncing channel updates for 'nightly-{0}'
243-
info: latest update on 2015-01-02, rust version 1.3.0
243+
info: latest update on 2015-01-02, rust version 1.3.0 (hash-n-2)
244244
info: downloading component 'rustc'
245245
info: downloading component 'cargo'
246246
info: downloading component 'rust-std'

tests/cli-self-upd.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ fn first_install_exact() {
869869
",
870870
for_host!(
871871
r"info: syncing channel updates for 'stable-{0}'
872-
info: latest update on 2015-01-02, rust version 1.1.0
872+
info: latest update on 2015-01-02, rust version 1.1.0 (hash-s-2)
873873
info: downloading component 'rustc'
874874
info: downloading component 'cargo'
875875
info: downloading component 'rust-std'

0 commit comments

Comments
 (0)