Suppress stderr output if --quiet is passed

Instead of checking if `options.quiet` is set whenever printing, disable
all printing to stderr if the `--quiet` flag is passed.

Although it isn't strictly necessary, I still don't construct a progress
bar if `options.quiet` is true, since progress bars might be a little
more expensive than just printing error messages.

A future diff might add checking to the `errln` and `outln` macros, so
that they don't print at all if the respective output stream is
inactive.

type: reform
This commit is contained in:
Casey Rodarmor 2020-09-08 15:21:53 -07:00
parent 39dcb5e183
commit 42e20a4a6a
No known key found for this signature in database
GPG Key ID: 556186B153EC6FE0
6 changed files with 77 additions and 30 deletions

View File

@ -114,7 +114,7 @@ jobs:
- name: Install `mdbook` - name: Install `mdbook`
uses: peaceiris/actions-mdbook@v1 uses: peaceiris/actions-mdbook@v1
with: with:
mdbook-version: latest mdbook-version: '0.4.2'
- name: Build Book - name: Build Book
run: | run: |

View File

@ -61,6 +61,10 @@ impl Env {
self.out.set_is_term(true); self.out.set_is_term(true);
} }
if args.options().quiet {
self.err.set_active(false);
}
args.run(self) args.run(self)
} }
@ -248,6 +252,29 @@ mod tests {
assert_eq!(env.out(), ""); assert_eq!(env.out(), "");
} }
#[test]
fn quiet() {
let mut env = test_env! {
args: [
"--quiet",
"torrent",
"create",
"--input",
"foo",
"--announce",
"udp:bar.com",
"--announce-tier",
"foo",
],
tree: {
foo: "",
}
};
env.status().ok();
assert_eq!(env.err(), "");
assert_eq!(env.out(), "");
}
#[test] #[test]
fn terminal() -> Result<()> { fn terminal() -> Result<()> {
let mut create_env = test_env! { let mut create_env = test_env! {

View File

@ -4,6 +4,7 @@ pub(crate) struct OutputStream {
stream: Box<dyn Write>, stream: Box<dyn Write>,
style: bool, style: bool,
term: bool, term: bool,
active: bool,
} }
impl OutputStream { impl OutputStream {
@ -12,6 +13,7 @@ impl OutputStream {
Self { Self {
stream: Box::new(io::stdout()), stream: Box::new(io::stdout()),
style: style && term, style: style && term,
active: true,
term, term,
} }
} }
@ -20,13 +22,15 @@ impl OutputStream {
Self { Self {
term: style && atty::is(atty::Stream::Stderr), term: style && atty::is(atty::Stream::Stderr),
stream: Box::new(io::stderr()), stream: Box::new(io::stderr()),
active: true,
style, style,
} }
} }
#[cfg(test)] #[cfg(test)]
pub(crate) fn new(stream: Box<dyn Write>, style: bool, term: bool) -> OutputStream { pub(crate) fn new(stream: Box<dyn Write>, style: bool, term: bool, active: bool) -> OutputStream {
Self { Self {
active,
stream, stream,
style, style,
term, term,
@ -60,14 +64,43 @@ impl OutputStream {
pub(crate) fn style(&self) -> Style { pub(crate) fn style(&self) -> Style {
Style::from_active(self.style) Style::from_active(self.style)
} }
pub(crate) fn set_active(&mut self, active: bool) {
self.active = active;
}
} }
impl Write for OutputStream { impl Write for OutputStream {
fn write(&mut self, data: &[u8]) -> io::Result<usize> { fn write(&mut self, data: &[u8]) -> io::Result<usize> {
self.stream.write(data) if self.active {
self.stream.write(data)
} else {
Ok(data.len())
}
} }
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
self.stream.flush() self.stream.flush()
} }
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn active() {
let capture = Capture::new();
let mut stream = OutputStream::new(Box::new(capture.clone()), false, false, true);
stream.write_all("hello".as_bytes()).unwrap();
assert_eq!(capture.string(), "hello");
}
#[test]
fn inactive() {
let capture = Capture::new();
let mut stream = OutputStream::new(Box::new(capture.clone()), false, false, false);
stream.write_all("hello".as_bytes()).unwrap();
assert_eq!(capture.string(), "");
}
}

View File

@ -315,9 +315,7 @@ impl Create {
) )
}; };
if !options.quiet { CreateStep::Searching { input: &input }.print(env)?;
CreateStep::Searching { input: &input }.print(env)?;
}
let content = CreateContent::from_create(&self, &input, env)?; let content = CreateContent::from_create(&self, &input, env)?;
@ -354,9 +352,7 @@ impl Create {
Some(String::from(consts::CREATED_BY_DEFAULT)) Some(String::from(consts::CREATED_BY_DEFAULT))
}; };
if !options.quiet { CreateStep::Hashing.print(env)?;
CreateStep::Hashing.print(env)?;
}
let hasher = Hasher::new( let hasher = Hasher::new(
self.md5sum, self.md5sum,
@ -374,12 +370,10 @@ impl Create {
hasher.hash_stdin(&mut env.input())? hasher.hash_stdin(&mut env.input())?
}; };
if !options.quiet { CreateStep::Writing {
CreateStep::Writing { output: &content.output,
output: &content.output,
}
.print(env)?;
} }
.print(env)?;
let info = Info { let info = Info {
name: content.name, name: content.name,
@ -449,9 +443,7 @@ impl Create {
} }
} }
if !options.quiet { errln!(env, "\u{2728}\u{2728} Done! \u{2728}\u{2728}")?;
errln!(env, "\u{2728}\u{2728} Done! \u{2728}\u{2728}")?;
}
if self.show { if self.show {
// We just created this torrent, so no extra fields have been discarded. // We just created this torrent, so no extra fields have been discarded.

View File

@ -58,9 +58,7 @@ impl Verify {
&self.input_flag, &self.input_flag,
)?; )?;
if !options.quiet { VerifyStep::Loading { metainfo: &target }.print(env)?;
VerifyStep::Loading { metainfo: &target }.print(env)?;
}
let input = env.read(target.clone())?; let input = env.read(target.clone())?;
@ -86,21 +84,17 @@ impl Verify {
None None
}; };
if !options.quiet { VerifyStep::Verifying { content: &content }.print(env)?;
VerifyStep::Verifying { content: &content }.print(env)?;
}
let status = metainfo.verify(&env.resolve(content)?, progress_bar)?; let status = metainfo.verify(&env.resolve(content)?, progress_bar)?;
status.print(env)?; status.print(env)?;
if status.good() { if status.good() {
if !options.quiet { errln!(
errln!( env,
env, "\u{2728}\u{2728} Verification succeeded! \u{2728}\u{2728}"
"\u{2728}\u{2728} Verification succeeded! \u{2728}\u{2728}" )?;
)?;
}
Ok(()) Ok(())
} else { } else {
Err(Error::Verify) Err(Error::Verify)

View File

@ -76,9 +76,10 @@ impl TestEnvBuilder {
Box::new(out.clone()), Box::new(out.clone()),
self.use_color && self.out_is_term, self.use_color && self.out_is_term,
self.out_is_term, self.out_is_term,
true,
); );
let err_stream = OutputStream::new(Box::new(err.clone()), self.err_style, false); let err_stream = OutputStream::new(Box::new(err.clone()), self.err_style, false, true);
let env = Env::new( let env = Env::new(
current_dir, current_dir,