Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add global --quiet flag to suppress non-primary output #3401

Merged
merged 6 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cli/examples/custom-command/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn run_custom_command(
.write()?;
tx.finish(ui, "Frobnicate")?;
writeln!(
ui.stderr(),
ui.status(),
"Frobnicated revision: {}",
workspace_command.format_commit_summary(&new_commit)
)?;
Expand Down
118 changes: 70 additions & 48 deletions cli/src/cli_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ impl CommandHelper {
repo_loader.op_store(),
|op_heads| {
writeln!(
ui.stderr(),
ui.status(),
"Concurrent modification detected, resolving automatically.",
)?;
let base_repo = repo_loader.load_at(&op_heads[0])?;
Expand All @@ -339,7 +339,7 @@ impl CommandHelper {
let num_rebased = tx.mut_repo().rebase_descendants(&self.settings)?;
if num_rebased > 0 {
writeln!(
ui.stderr(),
ui.status(),
"Rebased {num_rebased} descendant commits onto commits rewritten \
by other operation"
)?;
Expand Down Expand Up @@ -531,7 +531,7 @@ impl WorkspaceCommandHelper {
locked_ws.finish(self.user_repo.repo.op_id().clone())?;
if old_git_head.is_present() {
writeln!(
ui.stderr(),
ui.status(),
"Reset the working copy parent to the new Git HEAD."
)?;
} else {
Expand Down Expand Up @@ -570,13 +570,13 @@ impl WorkspaceCommandHelper {
let num_rebased = tx.mut_repo().rebase_descendants(&self.settings)?;
if num_rebased > 0 {
writeln!(
ui.stderr(),
ui.status(),
"Rebased {num_rebased} descendant commits off of commits rewritten from git"
)?;
}
self.finish_transaction(ui, tx, "import git refs")?;
writeln!(
ui.stderr(),
ui.status(),
"Done importing changes from the underlying Git repo."
)?;
Ok(())
Expand Down Expand Up @@ -1117,7 +1117,7 @@ See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-workin
let num_rebased = mut_repo.rebase_descendants(&self.settings)?;
if num_rebased > 0 {
writeln!(
ui.stderr(),
ui.status(),
"Rebased {num_rebased} descendant commits onto updated working copy"
)?;
}
Expand Down Expand Up @@ -1147,16 +1147,17 @@ See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-workin
new_commit,
)?;
if Some(new_commit) != maybe_old_commit {
let mut formatter = ui.stderr_formatter();
let template = self.commit_summary_template();
write!(formatter, "Working copy now at: ")?;
formatter.with_label("working_copy", |fmt| template.format(new_commit, fmt))?;
writeln!(formatter)?;
for parent in new_commit.parents() {
// "Working copy now at: "
write!(formatter, "Parent commit : ")?;
template.format(&parent, formatter.as_mut())?;
if let Some(mut formatter) = ui.status_formatter() {
let template = self.commit_summary_template();
write!(formatter, "Working copy now at: ")?;
formatter.with_label("working_copy", |fmt| template.format(new_commit, fmt))?;
writeln!(formatter)?;
for parent in new_commit.parents() {
// "Working copy now at: "
write!(formatter, "Parent commit : ")?;
template.format(&parent, formatter.as_mut())?;
writeln!(formatter)?;
}
}
}
if let Some(stats) = stats {
Expand All @@ -1177,12 +1178,12 @@ See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-workin
description: impl Into<String>,
) -> Result<(), CommandError> {
if !tx.mut_repo().has_changes() {
writeln!(ui.stderr(), "Nothing changed.")?;
writeln!(ui.status(), "Nothing changed.")?;
return Ok(());
}
let num_rebased = tx.mut_repo().rebase_descendants(&self.settings)?;
if num_rebased > 0 {
writeln!(ui.stderr(), "Rebased {num_rebased} descendant commits")?;
writeln!(ui.status(), "Rebased {num_rebased} descendant commits")?;
}

let old_repo = tx.base_repo().clone();
Expand Down Expand Up @@ -1236,6 +1237,9 @@ See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-workin
ui: &mut Ui,
old_repo: &Arc<ReadonlyRepo>,
) -> Result<(), CommandError> {
let Some(mut fmt) = ui.status_formatter() else {
return Ok(());
};
let old_view = old_repo.view();
let new_repo = self.repo().as_ref();
let new_view = new_repo.view();
Expand Down Expand Up @@ -1279,7 +1283,6 @@ See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-workin
.retain(|change_id, _commits| !removed_conflicts_by_change_id.contains_key(change_id));

// TODO: Also report new divergence and maybe resolved divergence
let mut fmt = ui.stderr_formatter();
let template = self.commit_summary_template();
if !resolved_conflicts_by_change_id.is_empty() {
writeln!(
Expand Down Expand Up @@ -1597,7 +1600,7 @@ pub fn print_checkout_stats(
) -> Result<(), std::io::Error> {
if stats.added_files > 0 || stats.updated_files > 0 || stats.removed_files > 0 {
writeln!(
ui.stderr(),
ui.status(),
"Added {} files, modified {} files, removed {} files",
stats.added_files,
stats.updated_files,
Expand All @@ -1611,13 +1614,15 @@ pub fn print_checkout_stats(
working copy.",
stats.skipped_files
)?;
writeln!(
ui.hint_default(),
"Inspect the changes compared to the intended target with `jj diff --from {}`.
if let Some(mut writer) = ui.hint_default() {
writeln!(
writer,
"Inspect the changes compared to the intended target with `jj diff --from {}`.
Discard the conflicting changes with `jj restore --from {}`.",
short_commit_hash(new_commit.id()),
short_commit_hash(new_commit.id())
)?;
short_commit_hash(new_commit.id()),
short_commit_hash(new_commit.id())
)?;
}
}
Ok(())
}
Expand All @@ -1638,21 +1643,25 @@ pub fn print_trackable_remote_branches(ui: &Ui, view: &View) -> io::Result<()> {
return Ok(());
}

writeln!(
ui.hint_default(),
"The following remote branches aren't associated with the existing local branches:"
)?;
let mut formatter = ui.stderr_formatter();
for full_name in &remote_branch_names {
write!(formatter, " ")?;
writeln!(formatter.labeled("branch"), "{full_name}")?;
}
drop(formatter);
writeln!(
ui.hint_default(),
"Run `jj branch track {names}` to keep local branches updated on future pulls.",
names = remote_branch_names.join(" "),
)?;
if let Some(mut writer) = ui.hint_default() {
writeln!(
writer,
"The following remote branches aren't associated with the existing local branches:"
)?;
}
if let Some(mut formatter) = ui.status_formatter() {
for full_name in &remote_branch_names {
write!(formatter, " ")?;
writeln!(formatter.labeled("branch"), "{full_name}")?;
}
}
if let Some(mut writer) = ui.hint_default() {
writeln!(
writer,
"Run `jj branch track {names}` to keep local branches updated on future pulls.",
names = remote_branch_names.join(" "),
)?;
}
Ok(())
}

Expand Down Expand Up @@ -2128,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
Expand Down Expand Up @@ -2194,14 +2213,14 @@ fn resolve_default_command(
if matches.subcommand_name().is_none() {
let args = get_string_or_array(config, "ui.default-command").optional()?;
if args.is_none() {
writeln!(
ui.hint_default(),
"Use `jj -h` for a list of available commands."
)?;
writeln!(
ui.hint_no_heading(),
"Run `jj config set --user ui.default-command log` to disable this message."
)?;
if let Some(mut writer) = ui.hint_default() {
writeln!(writer, "Use `jj -h` for a list of available commands.")?;
writeln!(
writer,
"Run `jj config set --user ui.default-command log` to disable this \
message."
)?;
}
}
let default_command = args.unwrap_or_else(|| vec!["log".to_string()]);

Expand Down Expand Up @@ -2297,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());
}
Expand Down
21 changes: 11 additions & 10 deletions cli/src/command_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ fn try_handle_command_result(
CommandErrorKind::Config => {
print_error(ui, "Config error: ", err, hints)?;
writeln!(
ui.hint_no_heading(),
ui.stderr_formatter().labeled("hint"),
"For help, see https://github.com/martinvonz/jj/blob/main/docs/config.md."
)?;
Ok(ExitCode::from(1))
Expand Down Expand Up @@ -619,23 +619,24 @@ fn print_error_sources(ui: &Ui, source: Option<&dyn error::Error>) -> io::Result

fn print_error_hints(ui: &Ui, hints: &[ErrorHint]) -> io::Result<()> {
for hint in hints {
match hint {
ErrorHint::PlainText(message) => {
writeln!(ui.hint_default(), "{message}")?;
}
ErrorHint::Formatted(recorded) => {
ui.stderr_formatter().with_label("hint", |formatter| {
write!(formatter.labeled("heading"), "Hint: ")?;
ui.stderr_formatter().with_label("hint", |formatter| {
write!(formatter.labeled("heading"), "Hint: ")?;
match hint {
ErrorHint::PlainText(message) => {
writeln!(formatter, "{message}")?;
Ok(())
}
ErrorHint::Formatted(recorded) => {
recorded.replay(formatter)?;
// Formatted hint is usually multi-line text, and it's
// convenient if trailing "\n" doesn't have to be omitted.
if !recorded.data().ends_with(b"\n") {
writeln!(formatter)?;
}
Ok(())
})?;
}
}
}
})?;
}
Ok(())
}
Expand Down
45 changes: 23 additions & 22 deletions cli/src/commands/abandon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub(crate) fn cmd_abandon(
.evaluate_to_commits()?
.try_collect()?;
if to_abandon.is_empty() {
writeln!(ui.stderr(), "No revisions to abandon.")?;
writeln!(ui.status(), "No revisions to abandon.")?;
return Ok(());
}
workspace_command.check_rewritable(&to_abandon)?;
Expand All @@ -66,28 +66,29 @@ pub(crate) fn cmd_abandon(
}
let num_rebased = tx.mut_repo().rebase_descendants(command.settings())?;

if to_abandon.len() == 1 {
write!(ui.stderr(), "Abandoned commit ")?;
tx.base_workspace_helper()
.write_commit_summary(ui.stderr_formatter().as_mut(), &to_abandon[0])?;
writeln!(ui.stderr())?;
} else if !args.summary {
let mut formatter = ui.stderr_formatter();
let template = tx.base_workspace_helper().commit_summary_template();
writeln!(formatter, "Abandoned the following commits:")?;
for commit in &to_abandon {
write!(formatter, " ")?;
template.format(commit, formatter.as_mut())?;
writeln!(formatter)?;
if let Some(mut formatter) = ui.status_formatter() {
if to_abandon.len() == 1 {
write!(formatter, "Abandoned commit ")?;
tx.base_workspace_helper()
.write_commit_summary(formatter.as_mut(), &to_abandon[0])?;
writeln!(ui.status())?;
} else if !args.summary {
let template = tx.base_workspace_helper().commit_summary_template();
writeln!(formatter, "Abandoned the following commits:")?;
for commit in &to_abandon {
write!(formatter, " ")?;
template.format(commit, formatter.as_mut())?;
writeln!(formatter)?;
}
} else {
writeln!(formatter, "Abandoned {} commits.", &to_abandon.len())?;
}
if num_rebased > 0 {
writeln!(
formatter,
"Rebased {num_rebased} descendant commits onto parents of abandoned commits"
)?;
}
} else {
writeln!(ui.stderr(), "Abandoned {} commits.", &to_abandon.len())?;
}
if num_rebased > 0 {
writeln!(
ui.stderr(),
"Rebased {num_rebased} descendant commits onto parents of abandoned commits"
)?;
}
let transaction_description = if to_abandon.len() == 1 {
format!("abandon commit {}", to_abandon[0].id().hex())
Expand Down
6 changes: 3 additions & 3 deletions cli/src/commands/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ where
let result = routine();
let after = Instant::now();
writeln!(
ui.stderr(),
ui.status(),
"First run took {:?} and produced: {:?}",
after.duration_since(before),
result
Expand Down Expand Up @@ -203,7 +203,7 @@ fn bench_revset<M: Measurement>(
group: &mut BenchmarkGroup<M>,
revset: &str,
) -> Result<(), CommandError> {
writeln!(ui.stderr(), "----------Testing revset: {revset}----------")?;
writeln!(ui.status(), "----------Testing revset: {revset}----------")?;
let expression = revset::optimize(workspace_command.parse_revset(revset)?.expression().clone());
// Time both evaluation and iteration.
let routine = |workspace_command: &WorkspaceCommandHelper, expression: Rc<RevsetExpression>| {
Expand All @@ -220,7 +220,7 @@ fn bench_revset<M: Measurement>(
let result = routine(workspace_command, expression.clone());
let after = Instant::now();
writeln!(
ui.stderr(),
ui.status(),
"First run took {:?} and produced {result} commits",
after.duration_since(before),
)?;
Expand Down
Loading