mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-26 06:01:48 +00:00
cli: add a global --quiet
flag, which silences status messages
Note that `jj resolve` already had its own `--quiet` flag. The output with `--quiet` for that command got a lot quieter with the global `--quiet` also taking effect. That seems reasonable to me.
This commit is contained in:
parent
4962d9af3b
commit
adf3b50209
6 changed files with 50 additions and 23 deletions
|
@ -58,6 +58,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
* `--all` is now named `--all-remotes` for `jj branch list`
|
||||
|
||||
* There is a new global `--quiet` flag to silence commands' non-primary output.
|
||||
|
||||
### Fixed bugs
|
||||
|
||||
## [0.15.1] - 2024-03-06
|
||||
|
|
|
@ -2137,6 +2137,16 @@ pub struct EarlyArgs {
|
|||
/// When to colorize output (always, never, auto)
|
||||
#[arg(long, value_name = "WHEN", global = true)]
|
||||
pub color: Option<ColorChoice>,
|
||||
/// Silence non-primary command output
|
||||
///
|
||||
/// For example, `jj files` will still list files, but it won't tell you if
|
||||
/// the working copy was snapshotted or if descendants were rebased.
|
||||
///
|
||||
/// Warnings and errors will still be printed.
|
||||
#[arg(long, global = true, action = ArgAction::SetTrue)]
|
||||
// Parsing with ignore_errors will crash if this is bool, so use
|
||||
// Option<bool>.
|
||||
pub quiet: Option<bool>,
|
||||
/// Disable the pager
|
||||
#[arg(long, value_name = "WHEN", global = true, action = ArgAction::SetTrue)]
|
||||
// Parsing with ignore_errors will crash if this is bool, so use
|
||||
|
@ -2306,6 +2316,9 @@ fn handle_early_args(
|
|||
if let Some(choice) = args.color {
|
||||
args.config_toml.push(format!(r#"ui.color="{choice}""#));
|
||||
}
|
||||
if args.quiet.unwrap_or_default() {
|
||||
args.config_toml.push(r#"ui.quiet=true"#.to_string());
|
||||
}
|
||||
if args.no_pager.unwrap_or_default() {
|
||||
args.config_toml.push(r#"ui.paginate="never""#.to_owned());
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ impl Write for UiStderr<'_> {
|
|||
|
||||
pub struct Ui {
|
||||
color: bool,
|
||||
quiet: bool,
|
||||
pager_cmd: CommandNameAndArgs,
|
||||
paginate: PaginationChoice,
|
||||
progress_indicator: bool,
|
||||
|
@ -222,6 +223,10 @@ fn use_color(choice: ColorChoice) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn be_quiet(config: &config::Config) -> bool {
|
||||
config.get_bool("ui.quiet").unwrap_or_default()
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, serde::Deserialize)]
|
||||
#[serde(rename_all(deserialize = "kebab-case"))]
|
||||
pub enum PaginationChoice {
|
||||
|
@ -245,6 +250,7 @@ fn pager_setting(config: &config::Config) -> Result<CommandNameAndArgs, CommandE
|
|||
impl Ui {
|
||||
pub fn with_config(config: &config::Config) -> Result<Ui, CommandError> {
|
||||
let color = use_color(color_setting(config));
|
||||
let quiet = be_quiet(config);
|
||||
// Sanitize ANSI escape codes if we're printing to a terminal. Doesn't affect
|
||||
// ANSI escape codes that originate from the formatter itself.
|
||||
let sanitize = io::stdout().is_terminal();
|
||||
|
@ -252,6 +258,7 @@ impl Ui {
|
|||
let progress_indicator = progress_indicator_setting(config);
|
||||
Ok(Ui {
|
||||
color,
|
||||
quiet,
|
||||
formatter_factory,
|
||||
pager_cmd: pager_setting(config)?,
|
||||
paginate: pagination_setting(config)?,
|
||||
|
@ -262,6 +269,7 @@ impl Ui {
|
|||
|
||||
pub fn reset(&mut self, config: &config::Config) -> Result<(), CommandError> {
|
||||
self.color = use_color(color_setting(config));
|
||||
self.quiet = be_quiet(config);
|
||||
self.paginate = pagination_setting(config)?;
|
||||
self.pager_cmd = pager_setting(config)?;
|
||||
self.progress_indicator = progress_indicator_setting(config);
|
||||
|
@ -375,14 +383,17 @@ impl Ui {
|
|||
|
||||
/// Writer to print an update that's not part of the command's main output.
|
||||
pub fn status(&self) -> Box<dyn Write + '_> {
|
||||
Box::new(self.stderr())
|
||||
if self.quiet {
|
||||
Box::new(std::io::sink())
|
||||
} else {
|
||||
Box::new(self.stderr())
|
||||
}
|
||||
}
|
||||
|
||||
/// A formatter to print an update that's not part of the command's main
|
||||
/// output. Returns `None` if `--quiet` was requested.
|
||||
// TODO: Actually support `--quiet`
|
||||
pub fn status_formatter(&self) -> Option<Box<dyn Formatter + '_>> {
|
||||
Some(self.stderr_formatter())
|
||||
(!self.quiet).then(|| self.stderr_formatter())
|
||||
}
|
||||
|
||||
/// Writer to print hint with the default "Hint: " heading.
|
||||
|
@ -394,7 +405,7 @@ impl Ui {
|
|||
|
||||
/// Writer to print hint without the "Hint: " heading.
|
||||
pub fn hint_no_heading(&self) -> Option<LabeledWriter<Box<dyn Formatter + '_>, &'static str>> {
|
||||
Some(LabeledWriter::new(self.stderr_formatter(), "hint"))
|
||||
(!self.quiet).then(|| LabeledWriter::new(self.stderr_formatter(), "hint"))
|
||||
}
|
||||
|
||||
/// Writer to print hint with the given heading.
|
||||
|
@ -402,11 +413,7 @@ impl Ui {
|
|||
&self,
|
||||
heading: H,
|
||||
) -> Option<HeadingLabeledWriter<Box<dyn Formatter + '_>, &'static str, H>> {
|
||||
Some(HeadingLabeledWriter::new(
|
||||
self.stderr_formatter(),
|
||||
"hint",
|
||||
heading,
|
||||
))
|
||||
(!self.quiet).then(|| HeadingLabeledWriter::new(self.stderr_formatter(), "hint", heading))
|
||||
}
|
||||
|
||||
/// Writer to print warning with the default "Warning: " heading.
|
||||
|
|
|
@ -159,6 +159,10 @@ To get started, see the tutorial at https://github.com/martinvonz/jj/blob/main/d
|
|||
Possible values: `true`, `false`
|
||||
|
||||
* `--color <WHEN>` — When to colorize output (always, never, auto)
|
||||
* `--quiet` — Silence non-primary command output
|
||||
|
||||
Possible values: `true`, `false`
|
||||
|
||||
* `--no-pager` — Disable the pager
|
||||
|
||||
Possible values: `true`, `false`
|
||||
|
|
|
@ -441,6 +441,19 @@ fn test_color_ui_messages() {
|
|||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_quiet() {
|
||||
let test_env = TestEnvironment::default();
|
||||
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
|
||||
let repo_path = test_env.env_root().join("repo");
|
||||
|
||||
// Can skip message about new working copy with `--quiet`
|
||||
std::fs::write(repo_path.join("file1"), "contents").unwrap();
|
||||
let (_stdout, stderr) =
|
||||
test_env.jj_cmd_ok(&repo_path, &["--quiet", "describe", "-m=new description"]);
|
||||
insta::assert_snapshot!(stderr, @"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_early_args() {
|
||||
// Test that help output parses early args
|
||||
|
@ -535,6 +548,7 @@ fn test_help() {
|
|||
--at-operation <AT_OPERATION> Operation to load the repo at [default: @] [aliases: at-op]
|
||||
--debug Enable debug logging
|
||||
--color <WHEN> When to colorize output (always, never, auto)
|
||||
--quiet Silence non-primary command output
|
||||
--no-pager Disable the pager
|
||||
--config-toml <TOML> Additional configuration options (can be repeated)
|
||||
"###);
|
||||
|
|
|
@ -728,20 +728,7 @@ fn test_multiple_conflicts() {
|
|||
std::fs::write(&editor_script, "expect\n\0write\nresolution another_file\n").unwrap();
|
||||
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["resolve", "--quiet", "another_file"]);
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
Resolving conflicts in: another_file
|
||||
New conflicts appeared in these commits:
|
||||
vruxwmqv 3c438f88 conflict | (conflict) conflict
|
||||
To resolve the conflicts, start by updating to it:
|
||||
jj new vruxwmqvtpmx
|
||||
Then use `jj resolve`, or edit the conflict markers in the file directly.
|
||||
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
|
||||
Then run `jj squash` to move the resolution into the conflicted commit.
|
||||
Working copy now at: vruxwmqv 3c438f88 conflict | (conflict) conflict
|
||||
Parent commit : zsuskuln de7553ef a | a
|
||||
Parent commit : royxmykx f68bc2f0 b | b
|
||||
Added 0 files, modified 1 files, removed 0 files
|
||||
"###);
|
||||
insta::assert_snapshot!(stderr, @"");
|
||||
|
||||
// For the rest of the test, we call `jj resolve` several times in a row to
|
||||
// resolve each conflict in the order it chooses.
|
||||
|
|
Loading…
Reference in a new issue