Skip to content

Commit 3c3a27f

Browse files
authored
Merge pull request #2615 from hi-rustin/rustin-patch-feat
feature: include self-update status in check
2 parents 373c808 + 27455a9 commit 3c3a27f

File tree

5 files changed

+153
-74
lines changed

5 files changed

+153
-74
lines changed

src/cli/rustup_mode.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ use std::str::FromStr;
88

99
use clap::{App, AppSettings, Arg, ArgGroup, ArgMatches, Shell, SubCommand};
1010

11-
use super::common;
1211
use super::errors::*;
1312
use super::help::*;
1413
use super::self_update;
1514
use super::term2;
1615
use super::term2::Terminal;
1716
use super::topical_doc;
17+
use super::{common, self_update::get_available_rustup_version};
1818
use crate::dist::dist::{
1919
PartialTargetTriple, PartialToolchainDesc, Profile, TargetTriple, ToolchainDesc,
2020
};
@@ -316,7 +316,7 @@ pub fn cli() -> App<'static, 'static> {
316316
.takes_value(false),
317317
),
318318
)
319-
.subcommand(SubCommand::with_name("check").about("Check for updates to Rust toolchains"))
319+
.subcommand(SubCommand::with_name("check").about("Check for updates to Rust toolchains and rustup"))
320320
.subcommand(
321321
SubCommand::with_name("default")
322322
.about("Set the default toolchain")
@@ -890,6 +890,27 @@ fn check_updates(cfg: &Cfg) -> Result<utils::ExitCode> {
890890
(_, Err(err)) => return Err(err.into()),
891891
}
892892
}
893+
894+
// Get current rustup version
895+
let current_version = env!("CARGO_PKG_VERSION");
896+
897+
// Get available rustup version
898+
let available_version = get_available_rustup_version()?;
899+
900+
let _ = t.attr(term2::Attr::Bold);
901+
write!(t, "{} - ", "rustup")?;
902+
903+
if current_version != available_version {
904+
let _ = t.fg(term2::color::YELLOW);
905+
write!(t, "Update available")?;
906+
let _ = t.reset();
907+
writeln!(t, " : {} -> {}", current_version, available_version)?;
908+
} else {
909+
let _ = t.fg(term2::color::GREEN);
910+
write!(t, "Up to date")?;
911+
let _ = t.reset();
912+
writeln!(t, " : {}", current_version)?;
913+
}
893914
Ok(utils::ExitCode(0))
894915
}
895916

src/cli/self_update.rs

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,46 +1010,17 @@ pub fn prepare_update() -> Result<Option<PathBuf>> {
10101010
#[cfg(windows)]
10111011
let triple = dist::TargetTriple::from_host().unwrap_or(triple);
10121012

1013+
// Get update root.
10131014
let update_root = process()
10141015
.var("RUSTUP_UPDATE_ROOT")
10151016
.unwrap_or_else(|_| String::from(UPDATE_ROOT));
10161017

1017-
let tempdir = tempfile::Builder::new()
1018-
.prefix("rustup-update")
1019-
.tempdir()
1020-
.chain_err(|| "error creating temp directory")?;
1021-
10221018
// Get current version
10231019
let current_version = env!("CARGO_PKG_VERSION");
10241020

1025-
// Download available version
1021+
// Get available version
10261022
info!("checking for self-updates");
1027-
let release_file_url = format!("{}/release-stable.toml", update_root);
1028-
let release_file_url = utils::parse_url(&release_file_url)?;
1029-
let release_file = tempdir.path().join("release-stable.toml");
1030-
utils::download_file(&release_file_url, &release_file, None, &|_| ())?;
1031-
let release_toml_str = utils::read_file("rustup release", &release_file)?;
1032-
let release_toml: toml::Value = toml::from_str(&release_toml_str)
1033-
.map_err(|_| Error::from("unable to parse rustup release file"))?;
1034-
1035-
let schema = release_toml
1036-
.get("schema-version")
1037-
.ok_or_else(|| Error::from("no schema key in rustup release file"))?
1038-
.as_str()
1039-
.ok_or_else(|| Error::from("invalid schema key in rustup release file"))?;
1040-
1041-
let available_version = release_toml
1042-
.get("version")
1043-
.ok_or_else(|| Error::from("no version key in rustup release file"))?
1044-
.as_str()
1045-
.ok_or_else(|| Error::from("invalid version key in rustup release file"))?;
1046-
1047-
if schema != "1" {
1048-
return Err(Error::from(&*format!(
1049-
"unknown schema version '{}' in rustup release file",
1050-
schema
1051-
)));
1052-
}
1023+
let available_version = get_available_rustup_version()?;
10531024

10541025
// If up-to-date
10551026
if available_version == current_version {
@@ -1075,6 +1046,47 @@ pub fn prepare_update() -> Result<Option<PathBuf>> {
10751046
Ok(Some(setup_path))
10761047
}
10771048

1049+
pub fn get_available_rustup_version() -> Result<String> {
1050+
let update_root = process()
1051+
.var("RUSTUP_UPDATE_ROOT")
1052+
.unwrap_or_else(|_| String::from(UPDATE_ROOT));
1053+
let tempdir = tempfile::Builder::new()
1054+
.prefix("rustup-update")
1055+
.tempdir()
1056+
.chain_err(|| "error creating temp directory")?;
1057+
1058+
// Parse the release file.
1059+
let release_file_url = format!("{}/release-stable.toml", update_root);
1060+
let release_file_url = utils::parse_url(&release_file_url)?;
1061+
let release_file = tempdir.path().join("release-stable.toml");
1062+
utils::download_file(&release_file_url, &release_file, None, &|_| ())?;
1063+
let release_toml_str = utils::read_file("rustup release", &release_file)?;
1064+
let release_toml: toml::Value = toml::from_str(&release_toml_str)
1065+
.map_err(|_| Error::from("unable to parse rustup release file"))?;
1066+
1067+
// Check the release file schema.
1068+
let schema = release_toml
1069+
.get("schema-version")
1070+
.ok_or_else(|| Error::from("no schema key in rustup release file"))?
1071+
.as_str()
1072+
.ok_or_else(|| Error::from("invalid schema key in rustup release file"))?;
1073+
if schema != "1" {
1074+
return Err(Error::from(&*format!(
1075+
"unknown schema version '{}' in rustup release file",
1076+
schema
1077+
)));
1078+
}
1079+
1080+
// Get the version.
1081+
let available_version = release_toml
1082+
.get("version")
1083+
.ok_or_else(|| Error::from("no version key in rustup release file"))?
1084+
.as_str()
1085+
.ok_or_else(|| Error::from("invalid version key in rustup release file"))?;
1086+
1087+
Ok(String::from(available_version))
1088+
}
1089+
10781090
pub fn cleanup_self_updater() -> Result<()> {
10791091
let cargo_home = utils::cargo_home()?;
10801092
let setup = cargo_home.join(&format!("bin/rustup-init{}", EXE_SUFFIX));

tests/cli-exact.rs

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

66
use crate::mock::clitools::{
7-
self, expect_err_ex, expect_ok, expect_ok_ex, expect_stdout_ok, set_current_dist_date, Config,
8-
Scenario,
7+
self, expect_err_ex, expect_ok, expect_ok_ex, expect_stdout_ok, self_update_setup,
8+
set_current_dist_date, Config, Scenario,
99
};
1010
use rustup::for_host;
1111
use rustup::test::this_host_triple;
@@ -107,6 +107,48 @@ nightly-{0} - Update available : 1.2.0 (hash-nightly-1) -> 1.3.0 (hash-nightly-2
107107
})
108108
}
109109

110+
#[test]
111+
fn check_updates_self() {
112+
let test_version = "2.0.0";
113+
114+
self_update_setup(
115+
&|config, _| {
116+
let current_version = env!("CARGO_PKG_VERSION");
117+
118+
expect_stdout_ok(
119+
config,
120+
&["rustup", "check"],
121+
&format!(
122+
r"rustup - Update available : {} -> {}
123+
",
124+
current_version, test_version
125+
),
126+
);
127+
},
128+
test_version,
129+
)
130+
}
131+
132+
#[test]
133+
fn check_updates_self_no_change() {
134+
let current_version = env!("CARGO_PKG_VERSION");
135+
136+
self_update_setup(
137+
&|config, _| {
138+
expect_stdout_ok(
139+
config,
140+
&["rustup", "check"],
141+
&format!(
142+
r"rustup - Up to date : {}
143+
",
144+
current_version
145+
),
146+
);
147+
},
148+
current_version,
149+
)
150+
}
151+
110152
#[test]
111153
fn check_updates_with_update() {
112154
setup(&|config| {

tests/cli-self-upd.rs

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,38 +17,15 @@ use rustup::Notification;
1717

1818
use crate::mock::clitools::{
1919
self, expect_component_executable, expect_component_not_executable, expect_err, expect_err_ex,
20-
expect_ok, expect_ok_contains, expect_ok_ex, expect_stderr_ok, expect_stdout_ok, run, Config,
21-
Scenario,
20+
expect_ok, expect_ok_contains, expect_ok_ex, expect_stderr_ok, expect_stdout_ok,
21+
output_release_file, run, self_update_setup, Config, Scenario,
2222
};
2323
use crate::mock::dist::calc_hash;
2424

2525
const TEST_VERSION: &str = "1.1.1";
2626

2727
pub fn update_setup(f: &dyn Fn(&Config, &Path)) {
28-
clitools::setup(Scenario::SimpleV2, &|config| {
29-
// Create a mock self-update server
30-
let self_dist_tmp = tempfile::Builder::new()
31-
.prefix("self_dist")
32-
.tempdir()
33-
.unwrap();
34-
let self_dist = self_dist_tmp.path();
35-
36-
let trip = this_host_triple();
37-
let dist_dir = self_dist.join(&format!("archive/{}/{}", TEST_VERSION, trip));
38-
let dist_exe = dist_dir.join(&format!("rustup-init{}", EXE_SUFFIX));
39-
let rustup_bin = config.exedir.join(&format!("rustup-init{}", EXE_SUFFIX));
40-
41-
fs::create_dir_all(dist_dir).unwrap();
42-
output_release_file(self_dist, "1", TEST_VERSION);
43-
fs::copy(&rustup_bin, &dist_exe).unwrap();
44-
// Modify the exe so it hashes different
45-
raw::append_file(&dist_exe, "").unwrap();
46-
47-
let root_url = format!("file://{}", self_dist.display());
48-
config.rustup_update_root = Some(root_url);
49-
50-
f(config, self_dist);
51-
});
28+
self_update_setup(f, TEST_VERSION)
5229
}
5330

5431
/// Empty dist server, rustup installed with no toolchain
@@ -76,18 +53,6 @@ fn setup_installed(f: &dyn Fn(&Config)) {
7653
})
7754
}
7855

79-
fn output_release_file(dist_dir: &Path, schema: &str, version: &str) {
80-
let contents = format!(
81-
r#"
82-
schema-version = "{}"
83-
version = "{}"
84-
"#,
85-
schema, version
86-
);
87-
let file = dist_dir.join("release-stable.toml");
88-
utils::write_file("release", &file, &contents).unwrap();
89-
}
90-
9156
#[test]
9257
/// This is the primary smoke test testing the full end to end behaviour of the
9358
/// installation code path: everything that is output, the proxy installation,

tests/mock/clitools.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,45 @@ pub fn setup(s: Scenario, f: &dyn Fn(&mut Config)) {
189189
assert!(!PathBuf::from("./bogus-cargo-home").exists());
190190
}
191191

192+
pub fn self_update_setup(f: &dyn Fn(&Config, &Path), version: &str) {
193+
setup(Scenario::SimpleV2, &|config| {
194+
// Create a mock self-update server
195+
let self_dist_tmp = tempfile::Builder::new()
196+
.prefix("self_dist")
197+
.tempdir()
198+
.unwrap();
199+
let self_dist = self_dist_tmp.path();
200+
201+
let trip = this_host_triple();
202+
let dist_dir = self_dist.join(&format!("archive/{}/{}", version, trip));
203+
let dist_exe = dist_dir.join(&format!("rustup-init{}", EXE_SUFFIX));
204+
let rustup_bin = config.exedir.join(&format!("rustup-init{}", EXE_SUFFIX));
205+
206+
fs::create_dir_all(dist_dir).unwrap();
207+
output_release_file(self_dist, "1", version);
208+
fs::copy(&rustup_bin, &dist_exe).unwrap();
209+
// Modify the exe so it hashes different
210+
raw::append_file(&dist_exe, "").unwrap();
211+
212+
let root_url = format!("file://{}", self_dist.display());
213+
config.rustup_update_root = Some(root_url);
214+
215+
f(config, self_dist);
216+
});
217+
}
218+
219+
pub fn output_release_file(dist_dir: &Path, schema: &str, version: &str) {
220+
let contents = format!(
221+
r#"
222+
schema-version = "{}"
223+
version = "{}"
224+
"#,
225+
schema, version
226+
);
227+
let file = dist_dir.join("release-stable.toml");
228+
utils::write_file("release", &file, &contents).unwrap();
229+
}
230+
192231
impl Config {
193232
pub fn current_dir(&self) -> PathBuf {
194233
self.workdir.borrow().clone()

0 commit comments

Comments
 (0)