Skip to content

Commit f7579b7

Browse files
0xPoerbtcollins
authored andcommitted
replace term with termcolor
- moves terminal into currentprocess abstraction, because termcolor doesn't accept a file handle, rather it takes an enum indirectly referencing the global state of stdout/stderr. - provides write/fg/bg/locked etc as before - abstracts over TestWriter, or termcolor's own concrete types - still permits completely terminal-free operation where desired (e.g. future JSON RPC on stdin/stdout) Signed-off-by: hi-rustin <rustin.liu@gmail.com> Signed-off-by: Robert Collins <robertc@robertcollins.net>
1 parent 120331b commit f7579b7

File tree

16 files changed

+546
-497
lines changed

16 files changed

+546
-497
lines changed

Cargo.lock

Lines changed: 1 addition & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ sharded-slab = "0.1.1"
8080
strsim = "0.10"
8181
tar = "0.4.26"
8282
tempfile.workspace = true
83-
term = "=0.5.1" # FIXME(issue #1818, #1826, and friends)
83+
termcolor.workspace = true
8484
thiserror.workspace = true
8585
threadpool = "1"
8686
tokio = { workspace = true, optional = true }
@@ -184,6 +184,7 @@ opentelemetry-otlp = { version = "0.11.0" }
184184
proptest = "1.1.0"
185185
rustup-macros = { path = "rustup-macros" }
186186
tempfile = "3.5"
187+
termcolor = "1.2"
187188
thiserror = "1.0"
188189
tokio = { version = "1.26.0", default-features = false, features = [
189190
"rt-multi-thread",

src/cli.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ pub mod proxy_mode;
1111
pub mod rustup_mode;
1212
pub mod self_update;
1313
pub mod setup_mode;
14-
mod term2;
1514
mod topical_doc;

src/cli/common.rs

Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@ use std::{cmp, env};
1010
use anyhow::{anyhow, Context, Result};
1111
use git_testament::{git_testament, render_testament};
1212
use lazy_static::lazy_static;
13-
use term2::Terminal;
1413

1514
use super::self_update;
16-
use super::term2;
17-
use crate::currentprocess::argsource::ArgSource;
1815
use crate::currentprocess::{
16+
argsource::ArgSource,
1917
filesource::{StdinSource, StdoutSource},
18+
terminalsource,
2019
varsource::VarSource,
2120
};
2221
use crate::utils::notifications as util_notifications;
@@ -32,7 +31,7 @@ use crate::{Cfg, Notification};
3231
pub(crate) const WARN_COMPLETE_PROFILE: &str = "downloading with complete profile isn't recommended unless you are a developer of the rust language";
3332

3433
pub(crate) fn confirm(question: &str, default: bool) -> Result<bool> {
35-
write!(process().stdout(), "{question} ")?;
34+
write!(process().stdout().lock(), "{question} ")?;
3635
let _ = std::io::stdout().flush();
3736
let input = read_line()?;
3837

@@ -43,7 +42,7 @@ pub(crate) fn confirm(question: &str, default: bool) -> Result<bool> {
4342
_ => false,
4443
};
4544

46-
writeln!(process().stdout())?;
45+
writeln!(process().stdout().lock())?;
4746

4847
Ok(r)
4948
}
@@ -55,11 +54,14 @@ pub(crate) enum Confirm {
5554
}
5655

5756
pub(crate) fn confirm_advanced() -> Result<Confirm> {
58-
writeln!(process().stdout())?;
59-
writeln!(process().stdout(), "1) Proceed with installation (default)")?;
60-
writeln!(process().stdout(), "2) Customize installation")?;
61-
writeln!(process().stdout(), "3) Cancel installation")?;
62-
write!(process().stdout(), ">")?;
57+
writeln!(process().stdout().lock())?;
58+
writeln!(
59+
process().stdout().lock(),
60+
"1) Proceed with installation (default)"
61+
)?;
62+
writeln!(process().stdout().lock(), "2) Customize installation")?;
63+
writeln!(process().stdout().lock(), "3) Cancel installation")?;
64+
write!(process().stdout().lock(), ">")?;
6365

6466
let _ = std::io::stdout().flush();
6567
let input = read_line()?;
@@ -70,17 +72,17 @@ pub(crate) fn confirm_advanced() -> Result<Confirm> {
7072
_ => Confirm::No,
7173
};
7274

73-
writeln!(process().stdout())?;
75+
writeln!(process().stdout().lock())?;
7476

7577
Ok(r)
7678
}
7779

7880
pub(crate) fn question_str(question: &str, default: &str) -> Result<String> {
79-
writeln!(process().stdout(), "{question} [{default}]")?;
81+
writeln!(process().stdout().lock(), "{question} [{default}]")?;
8082
let _ = std::io::stdout().flush();
8183
let input = read_line()?;
8284

83-
writeln!(process().stdout())?;
85+
writeln!(process().stdout().lock())?;
8486

8587
if input.is_empty() {
8688
Ok(default.to_string())
@@ -91,12 +93,12 @@ pub(crate) fn question_str(question: &str, default: &str) -> Result<String> {
9193

9294
pub(crate) fn question_bool(question: &str, default: bool) -> Result<bool> {
9395
let default_text = if default { "(Y/n)" } else { "(y/N)" };
94-
writeln!(process().stdout(), "{question} {default_text}")?;
96+
writeln!(process().stdout().lock(), "{question} {default_text}")?;
9597

9698
let _ = std::io::stdout().flush();
9799
let input = read_line()?;
98100

99-
writeln!(process().stdout())?;
101+
writeln!(process().stdout().lock())?;
100102

101103
if input.is_empty() {
102104
Ok(default)
@@ -212,10 +214,10 @@ fn show_channel_updates(
212214
) -> Result<()> {
213215
let data = updates.into_iter().map(|(pkg, result)| {
214216
let (banner, color) = match &result {
215-
Ok(UpdateStatus::Installed) => ("installed", Some(term2::color::GREEN)),
216-
Ok(UpdateStatus::Updated(_)) => ("updated", Some(term2::color::GREEN)),
217+
Ok(UpdateStatus::Installed) => ("installed", Some(terminalsource::Color::Green)),
218+
Ok(UpdateStatus::Updated(_)) => ("updated", Some(terminalsource::Color::Green)),
217219
Ok(UpdateStatus::Unchanged) => ("unchanged", None),
218-
Err(_) => ("update failed", Some(term2::color::RED)),
220+
Err(_) => ("update failed", Some(terminalsource::Color::Red)),
219221
};
220222

221223
let (previous_version, version) = match &pkg {
@@ -253,7 +255,7 @@ fn show_channel_updates(
253255
Ok((pkg, banner, width, color, version, previous_version))
254256
});
255257

256-
let mut t = term2::stdout();
258+
let mut t = process().stdout().terminal();
257259

258260
let data: Vec<_> = data.collect::<Result<_>>()?;
259261
let max_width = data
@@ -263,20 +265,20 @@ fn show_channel_updates(
263265
for (pkg, banner, width, color, version, previous_version) in data {
264266
let padding = max_width - width;
265267
let padding: String = " ".repeat(padding);
266-
let _ = write!(t, " {padding}");
267-
let _ = t.attr(term2::Attr::Bold);
268+
let _ = write!(t.lock(), " {padding}");
269+
let _ = t.attr(terminalsource::Attr::Bold);
268270
if let Some(color) = color {
269271
let _ = t.fg(color);
270272
}
271-
let _ = write!(t, "{pkg} {banner}");
273+
let _ = write!(t.lock(), "{pkg} {banner}");
272274
let _ = t.reset();
273-
let _ = write!(t, " - {version}");
275+
let _ = write!(t.lock(), " - {version}");
274276
if let Some(previous_version) = previous_version {
275-
let _ = write!(t, " (from {previous_version})");
277+
let _ = write!(t.lock(), " (from {previous_version})");
276278
}
277-
let _ = writeln!(t);
279+
let _ = writeln!(t.lock());
278280
}
279-
let _ = writeln!(t);
281+
let _ = writeln!(t.lock());
280282

281283
Ok(())
282284
}
@@ -294,7 +296,7 @@ pub(crate) fn update_all_channels(
294296

295297
let show_channel_updates = || {
296298
if !toolchains.is_empty() {
297-
writeln!(process().stdout())?;
299+
writeln!(process().stdout().lock())?;
298300

299301
let t = toolchains
300302
.into_iter()
@@ -374,7 +376,7 @@ where
374376
}
375377

376378
pub(crate) fn list_targets(distributable: DistributableToolchain<'_>) -> Result<utils::ExitCode> {
377-
let mut t = term2::stdout();
379+
let mut t = process().stdout().terminal();
378380
let manifestation = distributable.get_manifestation()?;
379381
let config = manifestation.read_config()?.unwrap_or_default();
380382
let manifest = distributable.get_manifest()?;
@@ -387,11 +389,11 @@ pub(crate) fn list_targets(distributable: DistributableToolchain<'_>) -> Result<
387389
.as_ref()
388390
.expect("rust-std should have a target");
389391
if component.installed {
390-
let _ = t.attr(term2::Attr::Bold);
391-
let _ = writeln!(t, "{target} (installed)");
392+
let _ = t.attr(terminalsource::Attr::Bold);
393+
let _ = writeln!(t.lock(), "{target} (installed)");
392394
let _ = t.reset();
393395
} else if component.available {
394-
let _ = writeln!(t, "{target}");
396+
let _ = writeln!(t.lock(), "{target}");
395397
}
396398
}
397399
}
@@ -402,7 +404,7 @@ pub(crate) fn list_targets(distributable: DistributableToolchain<'_>) -> Result<
402404
pub(crate) fn list_installed_targets(
403405
distributable: DistributableToolchain<'_>,
404406
) -> Result<utils::ExitCode> {
405-
let mut t = term2::stdout();
407+
let t = process().stdout();
406408
let manifestation = distributable.get_manifestation()?;
407409
let config = manifestation.read_config()?.unwrap_or_default();
408410
let manifest = distributable.get_manifest()?;
@@ -415,7 +417,7 @@ pub(crate) fn list_installed_targets(
415417
.as_ref()
416418
.expect("rust-std should have a target");
417419
if component.installed {
418-
writeln!(t, "{target}")?;
420+
writeln!(t.lock(), "{target}")?;
419421
}
420422
}
421423
}
@@ -425,35 +427,36 @@ pub(crate) fn list_installed_targets(
425427
pub(crate) fn list_components(
426428
distributable: DistributableToolchain<'_>,
427429
) -> Result<utils::ExitCode> {
428-
let mut t = term2::stdout();
430+
let mut t = process().stdout().terminal();
431+
429432
let manifestation = distributable.get_manifestation()?;
430433
let config = manifestation.read_config()?.unwrap_or_default();
431434
let manifest = distributable.get_manifest()?;
432435
let components = manifest.query_components(distributable.desc(), &config)?;
433436
for component in components {
434437
let name = component.name;
435438
if component.installed {
436-
t.attr(term2::Attr::Bold)?;
437-
writeln!(t, "{name} (installed)")?;
439+
t.attr(terminalsource::Attr::Bold)?;
440+
writeln!(t.lock(), "{name} (installed)")?;
438441
t.reset()?;
439442
} else if component.available {
440-
writeln!(t, "{name}")?;
443+
writeln!(t.lock(), "{name}")?;
441444
}
442445
}
443446

444447
Ok(utils::ExitCode(0))
445448
}
446449

447450
pub(crate) fn list_installed_components(distributable: DistributableToolchain<'_>) -> Result<()> {
448-
let mut t = term2::stdout();
451+
let t = process().stdout();
449452
let manifestation = distributable.get_manifestation()?;
450453
let config = manifestation.read_config()?.unwrap_or_default();
451454
let manifest = distributable.get_manifest()?;
452455
let components = manifest.query_components(distributable.desc(), &config)?;
453456

454457
for component in components {
455458
if component.installed {
456-
writeln!(t, "{}", component.name)?;
459+
writeln!(t.lock(), "{}", component.name)?;
457460
}
458461
}
459462
Ok(())
@@ -478,7 +481,7 @@ fn print_toolchain_path(
478481
String::new()
479482
};
480483
writeln!(
481-
process().stdout(),
484+
process().stdout().lock(),
482485
"{}{}{}{}",
483486
&toolchain,
484487
if_default,
@@ -496,7 +499,7 @@ pub(crate) fn list_toolchains(cfg: &Cfg, verbose: bool) -> Result<utils::ExitCod
496499
.map(Into::into)
497500
.collect::<Vec<_>>();
498501
if toolchains.is_empty() {
499-
writeln!(process().stdout(), "no installed toolchains")?;
502+
writeln!(process().stdout().lock(), "no installed toolchains")?;
500503
} else {
501504
let def_toolchain_name = cfg.get_default()?.map(|t| (&t).into());
502505
let cwd = utils::current_dir()?;
@@ -534,7 +537,7 @@ pub(crate) fn list_overrides(cfg: &Cfg) -> Result<utils::ExitCode> {
534537
let overrides = cfg.settings_file.with(|s| Ok(s.overrides.clone()))?;
535538

536539
if overrides.is_empty() {
537-
writeln!(process().stdout(), "no overrides")?;
540+
writeln!(process().stdout().lock(), "no overrides")?;
538541
} else {
539542
let mut any_not_exist = false;
540543
for (k, v) in overrides {
@@ -543,15 +546,15 @@ pub(crate) fn list_overrides(cfg: &Cfg) -> Result<utils::ExitCode> {
543546
any_not_exist = true;
544547
}
545548
writeln!(
546-
process().stdout(),
549+
process().stdout().lock(),
547550
"{:<40}\t{:<20}",
548551
utils::format_path_for_display(&k)
549552
+ if dir_exists { "" } else { " (not a directory)" },
550553
v
551554
)?
552555
}
553556
if any_not_exist {
554-
writeln!(process().stdout())?;
557+
writeln!(process().stdout().lock())?;
555558
info!(
556559
"you may remove overrides for non-existent directories with
557560
`rustup override unset --nonexistent`"
@@ -576,43 +579,51 @@ pub(crate) fn version() -> &'static str {
576579
pub(crate) fn dump_testament() -> Result<utils::ExitCode> {
577580
use git_testament::GitModification::*;
578581
writeln!(
579-
process().stdout(),
582+
process().stdout().lock(),
580583
"Rustup version renders as: {}",
581584
version()
582585
)?;
583586
writeln!(
584-
process().stdout(),
587+
process().stdout().lock(),
585588
"Current crate version: {}",
586589
env!("CARGO_PKG_VERSION")
587590
)?;
588591
if TESTAMENT.branch_name.is_some() {
589592
writeln!(
590-
process().stdout(),
593+
process().stdout().lock(),
591594
"Built from branch: {}",
592595
TESTAMENT.branch_name.unwrap()
593596
)?;
594597
} else {
595-
writeln!(process().stdout(), "Branch information missing")?;
598+
writeln!(process().stdout().lock(), "Branch information missing")?;
596599
}
597-
writeln!(process().stdout(), "Commit info: {}", TESTAMENT.commit)?;
600+
writeln!(
601+
process().stdout().lock(),
602+
"Commit info: {}",
603+
TESTAMENT.commit
604+
)?;
598605
if TESTAMENT.modifications.is_empty() {
599-
writeln!(process().stdout(), "Working tree is clean")?;
606+
writeln!(process().stdout().lock(), "Working tree is clean")?;
600607
} else {
601608
for fmod in TESTAMENT.modifications {
602609
match fmod {
603-
Added(f) => writeln!(process().stdout(), "Added: {}", String::from_utf8_lossy(f))?,
610+
Added(f) => writeln!(
611+
process().stdout().lock(),
612+
"Added: {}",
613+
String::from_utf8_lossy(f)
614+
)?,
604615
Removed(f) => writeln!(
605-
process().stdout(),
616+
process().stdout().lock(),
606617
"Removed: {}",
607618
String::from_utf8_lossy(f)
608619
)?,
609620
Modified(f) => writeln!(
610-
process().stdout(),
621+
process().stdout().lock(),
611622
"Modified: {}",
612623
String::from_utf8_lossy(f)
613624
)?,
614625
Untracked(f) => writeln!(
615-
process().stdout(),
626+
process().stdout().lock(),
616627
"Untracked: {}",
617628
String::from_utf8_lossy(f)
618629
)?,

0 commit comments

Comments
 (0)