mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-19 19:08:08 +00:00
cli: highlight "Warning: " and "warning: " headings
This commit is contained in:
parent
78ce9eae65
commit
1ebe751c42
20 changed files with 92 additions and 57 deletions
|
@ -1210,7 +1210,7 @@ See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-workin
|
|||
let settings = &self.settings;
|
||||
if settings.user_name().is_empty() || settings.user_email().is_empty() {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
r#"Name and email not configured. Until configured, your commits will be created with the empty identity, and can't be pushed to remotes. To configure, run:
|
||||
jj config set --user user.name "Some One"
|
||||
jj config set --user user.email "someone@example.com""#
|
||||
|
@ -1596,7 +1596,7 @@ pub fn print_checkout_stats(
|
|||
}
|
||||
if stats.skipped_files != 0 {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
"{} of those updates were skipped because there were conflicting changes in the \
|
||||
working copy.",
|
||||
stats.skipped_files
|
||||
|
@ -1739,7 +1739,10 @@ fn load_template_aliases(
|
|||
.map_err(|e| e.to_string())
|
||||
.and_then(|v| aliases_map.insert(&decl, v).map_err(|e| e.to_string()));
|
||||
if let Err(s) = r {
|
||||
writeln!(ui.warning(), r#"Failed to load "{TABLE_KEY}.{decl}": {s}"#)?;
|
||||
writeln!(
|
||||
ui.warning_no_heading(),
|
||||
r#"Failed to load "{TABLE_KEY}.{decl}": {s}"#
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2549,7 +2552,7 @@ impl CliRunner {
|
|||
let new_string_args = expand_args(ui, &self.app, env::args_os(), &config).ok();
|
||||
if new_string_args.as_ref() != Some(&string_args) {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
"Command aliases cannot be loaded from -R/--repository path"
|
||||
)?;
|
||||
}
|
||||
|
|
|
@ -258,8 +258,8 @@ fn cmd_branch_create(
|
|||
|
||||
if branch_names.len() > 1 {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: Creating multiple branches: {}",
|
||||
ui.warning_with_heading("warning: "),
|
||||
"Creating multiple branches: {}",
|
||||
branch_names.join(", "),
|
||||
)?;
|
||||
}
|
||||
|
@ -321,8 +321,8 @@ fn cmd_branch_rename(
|
|||
.any(|(_, remote_ref)| remote_ref.is_tracking())
|
||||
{
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"Warning: Branch {old_branch} has tracking remote branches which were not renamed."
|
||||
ui.warning_with_heading("Warning: "),
|
||||
"Branch {old_branch} has tracking remote branches which were not renamed."
|
||||
)?;
|
||||
writeln!(
|
||||
ui.hint_with_heading("Hint: "),
|
||||
|
@ -370,8 +370,8 @@ fn cmd_branch_set(
|
|||
|
||||
if branch_names.len() > 1 {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: Updating multiple branches: {}",
|
||||
ui.warning_with_heading("warning: "),
|
||||
"Updating multiple branches: {}",
|
||||
branch_names.join(", "),
|
||||
)?;
|
||||
}
|
||||
|
@ -487,7 +487,7 @@ fn cmd_branch_delete(
|
|||
let view = workspace_command.repo().view();
|
||||
if !args.glob.is_empty() {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
"--glob has been deprecated. Please prefix the pattern with `glob:` instead."
|
||||
)?;
|
||||
}
|
||||
|
@ -514,7 +514,7 @@ fn cmd_branch_forget(
|
|||
let view = workspace_command.repo().view();
|
||||
if !args.glob.is_empty() {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
"--glob has been deprecated. Please prefix the pattern with `glob:` instead."
|
||||
)?;
|
||||
}
|
||||
|
@ -541,7 +541,10 @@ fn cmd_branch_track(
|
|||
let mut names = Vec::new();
|
||||
for (name, remote_ref) in find_remote_branches(view, &args.names)? {
|
||||
if remote_ref.is_tracking() {
|
||||
writeln!(ui.warning(), "Remote branch already tracked: {name}")?;
|
||||
writeln!(
|
||||
ui.warning_no_heading(),
|
||||
"Remote branch already tracked: {name}"
|
||||
)?;
|
||||
} else {
|
||||
names.push(name);
|
||||
}
|
||||
|
@ -574,11 +577,14 @@ fn cmd_branch_untrack(
|
|||
if name.remote == git::REMOTE_NAME_FOR_LOCAL_GIT_REPO {
|
||||
// This restriction can be lifted if we want to support untracked @git branches.
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
"Git-tracking branch cannot be untracked: {name}"
|
||||
)?;
|
||||
} else if !remote_ref.is_tracking() {
|
||||
writeln!(ui.warning(), "Remote branch not tracked yet: {name}")?;
|
||||
writeln!(
|
||||
ui.warning_no_heading(),
|
||||
"Remote branch not tracked yet: {name}"
|
||||
)?;
|
||||
} else {
|
||||
names.push(name);
|
||||
}
|
||||
|
|
|
@ -43,12 +43,12 @@ pub(crate) fn cmd_checkout(
|
|||
args: &CheckoutArgs,
|
||||
) -> Result<(), CommandError> {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: `jj checkout` is deprecated; use `jj new` instead, which is equivalent"
|
||||
ui.warning_with_heading("warning: "),
|
||||
"`jj checkout` is deprecated; use `jj new` instead, which is equivalent"
|
||||
)?;
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: `jj checkout` will be removed in a future version, and this will be a hard error"
|
||||
ui.warning_with_heading("warning: "),
|
||||
"`jj checkout` will be removed in a future version, and this will be a hard error"
|
||||
)?;
|
||||
let mut workspace_command = command.workspace_helper(ui)?;
|
||||
let target = workspace_command.resolve_single_rev(&args.revision)?;
|
||||
|
|
|
@ -78,7 +78,7 @@ new working-copy commit.
|
|||
let middle_tree = tx.repo().store().get_root_tree(&tree_id)?;
|
||||
if !args.paths.is_empty() && middle_tree.id() == base_tree.id() {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
"The given paths do not match any file: {}",
|
||||
args.paths.join(" ")
|
||||
)?;
|
||||
|
|
|
@ -257,9 +257,9 @@ pub(crate) fn cmd_config_list(
|
|||
if !wrote_values {
|
||||
// Note to stderr explaining why output is empty.
|
||||
if let Some(name) = &args.name {
|
||||
writeln!(ui.warning(), "No matching config key for {name}")?;
|
||||
writeln!(ui.warning_no_heading(), "No matching config key for {name}")?;
|
||||
} else {
|
||||
writeln!(ui.warning(), "No config to list")?;
|
||||
writeln!(ui.warning_no_heading(), "No config to list")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -703,7 +703,7 @@ fn cmd_git_clone(
|
|||
};
|
||||
if let Err(err) = clean_up_dirs() {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
"Failed to clean up {}: {}",
|
||||
canonical_wc_path.display(),
|
||||
err
|
||||
|
@ -1058,7 +1058,7 @@ struct RejectedBranchUpdateReason {
|
|||
|
||||
impl RejectedBranchUpdateReason {
|
||||
fn print(&self, ui: &Ui) -> io::Result<()> {
|
||||
writeln!(ui.warning(), "{}", self.message)?;
|
||||
writeln!(ui.warning_no_heading(), "{}", self.message)?;
|
||||
if let Some(hint) = &self.hint {
|
||||
writeln!(ui.hint_with_heading("Hint: "), "{hint}")?;
|
||||
}
|
||||
|
@ -1197,7 +1197,7 @@ fn find_branches_targeted_by_revisions<'a>(
|
|||
revision_commit_ids.extend(current_branches_revset.iter());
|
||||
if revision_commit_ids.is_empty() {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
"No branches found in the default push revset: \
|
||||
remote_branches(remote={remote_name})..@"
|
||||
)?;
|
||||
|
@ -1212,7 +1212,7 @@ fn find_branches_targeted_by_revisions<'a>(
|
|||
if commit_ids.peek().is_none() {
|
||||
let rev_str: &str = rev_str;
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
"No branches point to the specified revisions: {rev_str}"
|
||||
)?;
|
||||
}
|
||||
|
|
|
@ -62,8 +62,8 @@ pub(crate) fn cmd_init(
|
|||
if args.git || args.git_repo.is_some() {
|
||||
git::git_init(ui, command, &wc_path, colocate, args.git_repo.as_deref())?;
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: `--git` and `--git-repo` are deprecated.
|
||||
ui.warning_with_heading("warning: "),
|
||||
"`--git` and `--git-repo` are deprecated.
|
||||
Use `jj git init` instead"
|
||||
)?;
|
||||
} else {
|
||||
|
|
|
@ -249,18 +249,18 @@ pub(crate) fn cmd_log(
|
|||
if only_path == "." && workspace_command.parse_file_path(only_path)?.is_root() {
|
||||
// For users of e.g. Mercurial, where `.` indicates the current commit.
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: The argument {only_path:?} is being interpreted as a path, but this is \
|
||||
often not useful because all non-empty commits touch '.'. If you meant to show \
|
||||
the working copy commit, pass -r '@' instead."
|
||||
ui.warning_with_heading("warning: "),
|
||||
"The argument {only_path:?} is being interpreted as a path, but this is often not \
|
||||
useful because all non-empty commits touch '.'. If you meant to show the \
|
||||
working copy commit, pass -r '@' instead."
|
||||
)?;
|
||||
} else if revset.is_empty()
|
||||
&& revset::parse(only_path, &workspace_command.revset_parse_context()).is_ok()
|
||||
{
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: The argument {only_path:?} is being interpreted as a path. To specify a \
|
||||
revset, pass -r {only_path:?} instead."
|
||||
ui.warning_with_heading("warning: "),
|
||||
"The argument {only_path:?} is being interpreted as a path. To specify a revset, \
|
||||
pass -r {only_path:?} instead."
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,12 +26,12 @@ pub(crate) fn cmd_merge(
|
|||
args: &new::NewArgs,
|
||||
) -> Result<(), CommandError> {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: `jj merge` is deprecated; use `jj new` instead, which is equivalent"
|
||||
ui.warning_with_heading("warning: "),
|
||||
"`jj merge` is deprecated; use `jj new` instead, which is equivalent"
|
||||
)?;
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: `jj merge` will be removed in a future version, and this will be a hard error"
|
||||
ui.warning_with_heading("warning: "),
|
||||
"`jj merge` will be removed in a future version, and this will be a hard error"
|
||||
)?;
|
||||
if args.revisions.len() < 2 {
|
||||
return Err(cli_error("Merge requires at least two revisions"));
|
||||
|
|
|
@ -63,12 +63,12 @@ pub(crate) fn cmd_move(
|
|||
args: &MoveArgs,
|
||||
) -> Result<(), CommandError> {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent"
|
||||
ui.warning_with_heading("warning: "),
|
||||
"`jj move` is deprecated; use `jj squash` instead, which is equivalent"
|
||||
)?;
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: `jj move` will be removed in a future version, and this will be a hard error"
|
||||
ui.warning_with_heading("warning: "),
|
||||
"`jj move` will be removed in a future version, and this will be a hard error"
|
||||
)?;
|
||||
let mut workspace_command = command.workspace_helper(ui)?;
|
||||
let source = workspace_command.resolve_single_rev(args.from.as_deref().unwrap_or("@"))?;
|
||||
|
|
|
@ -383,7 +383,7 @@ fn cmd_op_abandon(
|
|||
let old_op_id = locked_ws.locked_wc().old_operation_id();
|
||||
if old_op_id != current_head_op.id() {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
"The working copy operation {} is not updated because it differs from the repo {}.",
|
||||
short_operation_hash(old_op_id),
|
||||
short_operation_hash(current_head_op.id()),
|
||||
|
|
|
@ -94,7 +94,7 @@ don't make any changes, then the operation will be aborted.
|
|||
if selected_tree_id == base_tree.id() {
|
||||
// The user selected nothing, so the first commit will be empty.
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
ui.warning_no_heading(),
|
||||
"The given paths do not match any file: {}",
|
||||
args.paths.join(" ")
|
||||
)?;
|
||||
|
|
|
@ -199,9 +199,9 @@ from the source will be moved into the destination.
|
|||
.is_ok()
|
||||
{
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"warning: The argument {only_path:?} is being interpreted as a path. To \
|
||||
specify a revset, pass -r {only_path:?} instead."
|
||||
ui.warning_with_heading("warning: "),
|
||||
"The argument {only_path:?} is being interpreted as a path. To specify a \
|
||||
revset, pass -r {only_path:?} instead."
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,9 +130,9 @@ fn cmd_util_completion(
|
|||
let mut app = command.app().clone();
|
||||
let warn = |shell| {
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"Warning: `jj util completion --{shell}` will be removed in a future version, and \
|
||||
this will be a hard error"
|
||||
ui.warning_with_heading("Warning: "),
|
||||
"`jj util completion --{shell}` will be removed in a future version, and this will be \
|
||||
a hard error"
|
||||
)?;
|
||||
writeln!(
|
||||
ui.hint_with_heading("Hint: "),
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"error" = "red"
|
||||
"warning" = "yellow"
|
||||
"hint" = "cyan"
|
||||
"warning heading" = { bold = true }
|
||||
"hint heading" = { bold = true }
|
||||
|
||||
"conflict_description" = "yellow"
|
||||
|
|
|
@ -392,7 +392,7 @@ pub fn print_failed_git_export(
|
|||
failed_branches: &[FailedRefExport],
|
||||
) -> Result<(), std::io::Error> {
|
||||
if !failed_branches.is_empty() {
|
||||
writeln!(ui.warning(), "Failed to export some branches:")?;
|
||||
writeln!(ui.warning_no_heading(), "Failed to export some branches:")?;
|
||||
let mut formatter = ui.stderr_formatter();
|
||||
for FailedRefExport { name, reason } in failed_branches {
|
||||
write!(formatter, " ")?;
|
||||
|
|
|
@ -324,7 +324,12 @@ pub fn generate_diff(
|
|||
let exit_status = child.wait().map_err(ExternalToolError::Io)?;
|
||||
tracing::info!(?cmd, ?exit_status, "The external diff generator exited:");
|
||||
if !exit_status.success() {
|
||||
writeln!(ui.warning(), "{}", format_tool_aborted(&exit_status)).ok();
|
||||
writeln!(
|
||||
ui.warning_no_heading(),
|
||||
"{}",
|
||||
format_tool_aborted(&exit_status)
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
copy_result.map_err(ExternalToolError::Io)?;
|
||||
Ok(())
|
||||
|
|
|
@ -62,7 +62,10 @@ pub fn load_revset_aliases(
|
|||
.map_err(|e| e.to_string())
|
||||
.and_then(|v| aliases_map.insert(&decl, v).map_err(|e| e.to_string()));
|
||||
if let Err(s) = r {
|
||||
writeln!(ui.warning(), r#"Failed to load "{TABLE_KEY}.{decl}": {s}"#)?;
|
||||
writeln!(
|
||||
ui.warning_no_heading(),
|
||||
r#"Failed to load "{TABLE_KEY}.{decl}": {s}"#
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -292,7 +292,7 @@ impl Ui {
|
|||
Err(e) => {
|
||||
// The pager executable couldn't be found or couldn't be run
|
||||
writeln!(
|
||||
self.warning(),
|
||||
self.warning_no_heading(),
|
||||
"Failed to spawn pager '{name}': {e}. Consider using the `:builtin` \
|
||||
pager.",
|
||||
name = self.pager_cmd.split_name(),
|
||||
|
@ -386,10 +386,19 @@ impl Ui {
|
|||
HeadingLabeledWriter::new(self.stderr_formatter(), "hint", heading)
|
||||
}
|
||||
|
||||
pub fn warning(&self) -> LabeledWriter<Box<dyn Formatter + '_>, &'static str> {
|
||||
/// Writer to print warning without the "Warning: " heading.
|
||||
pub fn warning_no_heading(&self) -> LabeledWriter<Box<dyn Formatter + '_>, &'static str> {
|
||||
LabeledWriter::new(self.stderr_formatter(), "warning")
|
||||
}
|
||||
|
||||
/// Writer to print warning with the given heading.
|
||||
pub fn warning_with_heading<H: fmt::Display>(
|
||||
&self,
|
||||
heading: H,
|
||||
) -> HeadingLabeledWriter<Box<dyn Formatter + '_>, &'static str, H> {
|
||||
HeadingLabeledWriter::new(self.stderr_formatter(), "warning", heading)
|
||||
}
|
||||
|
||||
pub fn error(&self) -> LabeledWriter<Box<dyn Formatter + '_>, &'static str> {
|
||||
LabeledWriter::new(self.stderr_formatter(), "error")
|
||||
}
|
||||
|
@ -474,7 +483,7 @@ impl Ui {
|
|||
return Ok(choice);
|
||||
}
|
||||
|
||||
writeln!(self.warning(), "unrecognized response")?;
|
||||
writeln!(self.warning_no_heading(), "unrecognized response")?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -388,6 +388,8 @@ fn test_color_config() {
|
|||
#[test]
|
||||
fn test_color_ui_messages() {
|
||||
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");
|
||||
test_env.add_config("ui.color = 'always'");
|
||||
|
||||
// hint and error
|
||||
|
@ -397,6 +399,12 @@ fn test_color_ui_messages() {
|
|||
[38;5;6mRun `jj config set --user ui.default-command log` to disable this message.[39m
|
||||
[38;5;1mError: There is no jj repo in "."[39m
|
||||
"###);
|
||||
|
||||
// warning
|
||||
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["log", "@"]);
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
[1m[38;5;3mwarning: [0m[38;5;3mThe argument "@" is being interpreted as a path. To specify a revset, pass -r "@" instead.[39m
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue