Skip to content

Commit 4b912e8

Browse files
committed
Support --force for rustup update
1 parent 6ab0843 commit 4b912e8

File tree

8 files changed

+66
-41
lines changed

8 files changed

+66
-41
lines changed

src/rustup-cli/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ fn show_channel_updates(cfg: &Cfg, toolchains: Vec<(String, rustup::Result<Updat
189189
Ok(())
190190
}
191191

192-
pub fn update_all_channels(cfg: &Cfg, self_update: bool) -> Result<()> {
192+
pub fn update_all_channels(cfg: &Cfg, self_update: bool, force_update: bool) -> Result<()> {
193193

194-
let toolchains = try!(cfg.update_all_channels());
194+
let toolchains = try!(cfg.update_all_channels(force_update));
195195

196196
if toolchains.is_empty() {
197197
info!("no updatable toolchains installed");

src/rustup-cli/rustup_mode.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,11 @@ pub fn cli() -> App<'static, 'static> {
144144
.help("Don't perform self update when running the `rustup` command")
145145
.long("no-self-update")
146146
.takes_value(false)
147-
.hidden(true)))
147+
.hidden(true))
148+
.arg(Arg::with_name("force")
149+
.help("Force an update, even if some components are missing")
150+
.long("force")
151+
.takes_value(false)))
148152
.subcommand(SubCommand::with_name("default")
149153
.about("Set the default toolchain")
150154
.after_help(DEFAULT_HELP)
@@ -462,7 +466,7 @@ fn update(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
462466
let toolchain = try!(cfg.get_toolchain(name, false));
463467

464468
let status = if !toolchain.is_custom() {
465-
Some(try!(toolchain.install_from_dist()))
469+
Some(try!(toolchain.install_from_dist(m.is_present("force"))))
466470
} else if !toolchain.exists() {
467471
return Err(ErrorKind::ToolchainNotInstalled(toolchain.name().to_string()).into());
468472
} else {
@@ -475,7 +479,11 @@ fn update(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
475479
}
476480
}
477481
} else {
478-
try!(common::update_all_channels(cfg, !m.is_present("no-self-update") && !self_update::NEVER_SELF_UPDATE));
482+
try!(common::update_all_channels(
483+
cfg,
484+
!m.is_present("no-self-update") && !self_update::NEVER_SELF_UPDATE,
485+
m.is_present("force"),
486+
));
479487
}
480488

481489
Ok(())

src/rustup-cli/self_update.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ fn maybe_install_rust(toolchain_str: &str, default_host_triple: &str, verbose: b
747747
// Set host triple first as it will affect resolution of toolchain_str
748748
try!(cfg.set_default_host_triple(default_host_triple));
749749
let toolchain = try!(cfg.get_toolchain(toolchain_str, false));
750-
let status = try!(toolchain.install_from_dist());
750+
let status = try!(toolchain.install_from_dist(false));
751751
try!(cfg.set_default(toolchain_str));
752752
println!("");
753753
try!(common::show_channel_update(cfg, toolchain_str, Ok(status)));

src/rustup-dist/src/dist.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,8 @@ pub fn update_from_dist<'a>(download: DownloadCfg<'a>,
462462
toolchain: &ToolchainDesc,
463463
prefix: &InstallPrefix,
464464
add: &[Component],
465-
remove: &[Component])
465+
remove: &[Component],
466+
force_update: bool)
466467
-> Result<Option<String>> {
467468

468469
let fresh_install = !prefix.path().exists();
@@ -472,7 +473,8 @@ pub fn update_from_dist<'a>(download: DownloadCfg<'a>,
472473
toolchain,
473474
prefix,
474475
add,
475-
remove);
476+
remove,
477+
force_update);
476478

477479
// Don't leave behind an empty / broken installation directory
478480
if res.is_err() && fresh_install {
@@ -485,12 +487,13 @@ pub fn update_from_dist<'a>(download: DownloadCfg<'a>,
485487
}
486488

487489
pub fn update_from_dist_<'a>(download: DownloadCfg<'a>,
488-
update_hash: Option<&Path>,
489-
toolchain: &ToolchainDesc,
490-
prefix: &InstallPrefix,
491-
add: &[Component],
492-
remove: &[Component])
493-
-> Result<Option<String>> {
490+
update_hash: Option<&Path>,
491+
toolchain: &ToolchainDesc,
492+
prefix: &InstallPrefix,
493+
add: &[Component],
494+
remove: &[Component],
495+
force_update: bool)
496+
-> Result<Option<String>> {
494497

495498
let toolchain_str = toolchain.to_string();
496499
let manifestation = try!(Manifestation::open(prefix.clone(), toolchain.target.clone()));
@@ -507,6 +510,7 @@ pub fn update_from_dist_<'a>(download: DownloadCfg<'a>,
507510
(download.notify_handler)(Notification::DownloadedManifest(&m.date, m.get_rust_version().ok()));
508511
return match try!(manifestation.update(&m,
509512
changes,
513+
force_update,
510514
&download,
511515
download.notify_handler.clone())) {
512516
UpdateStatus::Unchanged => Ok(None),

src/rustup-dist/src/manifestation.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,14 @@ impl Manifestation {
9191
/// distribution manifest to "rustlib/rustup-dist.toml" and a
9292
/// configuration containing the component name-target pairs to
9393
/// "rustlib/rustup-config.toml".
94-
pub fn update(&self,
95-
new_manifest: &Manifest,
96-
changes: Changes,
97-
download_cfg: &DownloadCfg,
98-
notify_handler: &Fn(Notification)) -> Result<UpdateStatus> {
94+
pub fn update(
95+
&self,
96+
new_manifest: &Manifest,
97+
changes: Changes,
98+
force_update: bool,
99+
download_cfg: &DownloadCfg,
100+
notify_handler: &Fn(Notification),
101+
) -> Result<UpdateStatus> {
99102

100103
// Some vars we're going to need a few times
101104
let temp_cfg = download_cfg.temp_cfg;
@@ -119,7 +122,11 @@ impl Manifestation {
119122
update.missing_essential_components(&self.target_triple)?;
120123

121124
// Validate that the requested components are available
122-
update.unavailable_components(new_manifest)?;
125+
match update.unavailable_components(new_manifest) {
126+
Ok(_) => {},
127+
_ if force_update => {},
128+
Err(e) => return Err(e),
129+
}
123130

124131
let altered = temp_cfg.dist_server != DEFAULT_DIST_SERVER;
125132

src/rustup/config.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ impl Cfg {
269269
Err(Error::from(reason_err))
270270
.chain_err(|| ErrorKind::OverrideToolchainNotInstalled(name.to_string()))
271271
} else {
272-
try!(toolchain.install_from_dist());
272+
try!(toolchain.install_from_dist(false));
273273
Ok(Some((toolchain, reason)))
274274
}
275275
}
@@ -336,8 +336,6 @@ impl Cfg {
336336
})
337337
}
338338

339-
340-
341339
pub fn list_toolchains(&self) -> Result<Vec<String>> {
342340
if utils::is_directory(&self.toolchains_dir) {
343341
let mut toolchains: Vec<_> = try!(utils::read_dir("toolchains", &self.toolchains_dir))
@@ -354,7 +352,7 @@ impl Cfg {
354352
}
355353
}
356354

357-
pub fn update_all_channels(&self) -> Result<Vec<(String, Result<UpdateStatus>)>> {
355+
pub fn update_all_channels(&self, force_update: bool) -> Result<Vec<(String, Result<UpdateStatus>)>> {
358356
let toolchains = try!(self.list_toolchains());
359357

360358
// Convert the toolchain strings to Toolchain values
@@ -369,7 +367,7 @@ impl Cfg {
369367
// Update toolchains and collect the results
370368
let toolchains = toolchains.map(|(n, t)| {
371369
let t = t.and_then(|t| {
372-
let t = t.install_from_dist();
370+
let t = t.install_from_dist(force_update);
373371
if let Err(ref e) = t {
374372
(self.notify_handler)(Notification::NonFatalError(e));
375373
}
@@ -414,7 +412,7 @@ impl Cfg {
414412
binary: &str) -> Result<Command> {
415413
let ref toolchain = try!(self.get_toolchain(toolchain, false));
416414
if install_if_missing && !toolchain.exists() {
417-
try!(toolchain.install_from_dist());
415+
try!(toolchain.install_from_dist(false));
418416
}
419417

420418
if let Some(cmd) = try!(self.maybe_do_cargo_fallback(toolchain, binary)) {

src/rustup/install.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,17 @@ pub enum InstallMethod<'a> {
1616
Copy(&'a Path),
1717
Link(&'a Path),
1818
Installer(&'a Path, &'a temp::Cfg),
19-
Dist(&'a dist::ToolchainDesc, Option<&'a Path>, DownloadCfg<'a>),
19+
// bool is whether to force an update
20+
Dist(&'a dist::ToolchainDesc, Option<&'a Path>, DownloadCfg<'a>, bool),
2021
}
2122

2223
impl<'a> InstallMethod<'a> {
2324
pub fn run(self, path: &Path, notify_handler: &Fn(Notification)) -> Result<bool> {
2425
if path.exists() {
2526
// Don't uninstall first for Dist method
2627
match self {
27-
InstallMethod::Dist(_, _, _) |
28-
InstallMethod::Installer(_, _) => {}
28+
InstallMethod::Dist(..) |
29+
InstallMethod::Installer(..) => {}
2930
_ => {
3031
try!(uninstall(path, notify_handler));
3132
}
@@ -45,15 +46,18 @@ impl<'a> InstallMethod<'a> {
4546
try!(InstallMethod::tar_gz(src, path, &temp_cfg, notify_handler));
4647
Ok(true)
4748
}
48-
InstallMethod::Dist(toolchain, update_hash, dl_cfg) => {
49+
InstallMethod::Dist(toolchain, update_hash, dl_cfg, force_update) => {
4950
let prefix = &InstallPrefix::from(path.to_owned());
5051
let maybe_new_hash =
5152
try!(dist::update_from_dist(
5253
dl_cfg,
5354
update_hash,
5455
toolchain,
5556
prefix,
56-
&[], &[]));
57+
&[],
58+
&[],
59+
force_update,
60+
));
5761

5862
if let Some(hash) = maybe_new_hash {
5963
if let Some(hash_file) = update_hash {

src/rustup/toolchain.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ impl<'a> Toolchain<'a> {
145145
match install_method {
146146
InstallMethod::Copy(_) |
147147
InstallMethod::Link(_) |
148-
InstallMethod::Installer(_, _) => self.is_custom(),
149-
InstallMethod::Dist(_, _, _) => !self.is_custom(),
148+
InstallMethod::Installer(..) => self.is_custom(),
149+
InstallMethod::Dist(..) => !self.is_custom(),
150150
}
151151
}
152152
fn update_hash(&self) -> Result<Option<PathBuf>> {
@@ -166,22 +166,23 @@ impl<'a> Toolchain<'a> {
166166
}
167167
}
168168

169-
pub fn install_from_dist(&self) -> Result<UpdateStatus> {
169+
pub fn install_from_dist(&self, force_update: bool) -> Result<UpdateStatus> {
170170
if try!(self.cfg.telemetry_enabled()) {
171-
return self.install_from_dist_with_telemetry();
171+
return self.install_from_dist_with_telemetry(force_update);
172172
}
173-
self.install_from_dist_inner()
173+
self.install_from_dist_inner(force_update)
174174
}
175175

176-
pub fn install_from_dist_inner(&self) -> Result<UpdateStatus> {
176+
pub fn install_from_dist_inner(&self, force_update: bool) -> Result<UpdateStatus> {
177177
let update_hash = try!(self.update_hash());
178178
self.install(InstallMethod::Dist(&try!(self.desc()),
179179
update_hash.as_ref().map(|p| &**p),
180-
self.download_cfg()))
180+
self.download_cfg(),
181+
force_update))
181182
}
182183

183-
pub fn install_from_dist_with_telemetry(&self) -> Result<UpdateStatus> {
184-
let result = self.install_from_dist_inner();
184+
pub fn install_from_dist_with_telemetry(&self, force_update: bool) -> Result<UpdateStatus> {
185+
let result = self.install_from_dist_inner(force_update);
185186

186187
match result {
187188
Ok(us) => {
@@ -210,7 +211,8 @@ impl<'a> Toolchain<'a> {
210211
let update_hash = try!(self.update_hash());
211212
self.install_if_not_installed(InstallMethod::Dist(&try!(self.desc()),
212213
update_hash.as_ref().map(|p| &**p),
213-
self.download_cfg()))
214+
self.download_cfg(),
215+
false))
214216
}
215217
pub fn is_custom(&self) -> bool {
216218
ToolchainDesc::from_str(&self.name).is_err()
@@ -603,6 +605,7 @@ impl<'a> Toolchain<'a> {
603605

604606
try!(manifestation.update(&manifest,
605607
changes,
608+
false,
606609
&self.download_cfg(),
607610
self.download_cfg().notify_handler.clone()));
608611

@@ -652,6 +655,7 @@ impl<'a> Toolchain<'a> {
652655

653656
try!(manifestation.update(&manifest,
654657
changes,
658+
false,
655659
&self.download_cfg(),
656660
self.download_cfg().notify_handler.clone()));
657661

0 commit comments

Comments
 (0)