Skip to content

Commit 21549ea

Browse files
committed
Adding rustup check command to see if there are updates on the installed channels
1 parent ec6d1af commit 21549ea

File tree

4 files changed

+92
-9
lines changed

4 files changed

+92
-9
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());

0 commit comments

Comments
 (0)