-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Custom subcommand suggestions on error #5935
Comments
clap::Error
Clone
, make it easier to add/remove its propertiesclap::Error
s: make it Clone
, allow removing its properties
clap::Error
s: make it Clone
, allow removing its properties
This jumps immediately to a solution, particularly one that requires advanced clap use to implement. Let's step back and focus on the core of the problem
With our It would be great to offer something similar for subcommands. Current workarounds
I don't see I have considered the idea of an Action for subcommands and for custom Actions. I've not done custom The challenge with subcommands is how to handle them. See also
In designing something, we may want to consider how it interacts with #2222.
We've not developed a good set of principles for when to show |
So all of that will benefit you and all future clap developers. However, working through some of that would also be a lot of work. Extending If you could list out more precisely what new APIs you are wanting, that'd be a big help. Also, could you clarify why you need |
Thank you very much for thinking about this and the many interesting points! I'm not sure whether you saw the edits I made to the question after the original version.
We should consider what I called "Alternative 2" above, which would be customized for my particular problem. However, there would still be some use for editing More generally, this FR could be split into many, and I'm not sure which of the possible features that could be implemented are most feasible and make the most sense. I described my main suggestion, and I'll try to motivate it again below (in another comment), but whether that's the right approach is still a question in my mind. For the rest of your first comment above, it's full of interesting ideas, but I don't think they quite address the part of my problem that I can't solve (though many of them might be better ways to address the part of the problem that we already have a workaround for). I could easily have misunderstood something.
Something similar to But if the problem with creating native-looking Except for creating/modifying the
I am not very familiar with
This is a bit tangential to most of this issue; being able to manually remove "Usage" from an error would be nice, but it doesn't make or break a solution to this problem. Still, I think it's a good idea to look further into this. At the moment, my understanding of when "Usage:" should be shown is minimal, all I know is that "I saw one case where I will write more, hopefully shortly, but this comment is getting long. |
TLDR: Making PreludeThe approach that seems most direct to me would be to provide a way to create a This could either be a new error created from nothing or it could be a way to take the error created by (In theory, creating
Very naively, if we allow editing More technically, the immediate reason I need I'm not 100% sure that There's certainly no terrible performance cost to cloning SuggestionActually, I think making It is not clearly documented (Update: #5938, unless you think it's obvious), but after looking more carefully at Less importantly, I'd still want a Or, if we're OK with breaking changes, we could change the signature of Either way, we don't need |
Here's a naive patch that makes diff --git a/clap_builder/src/error/format.rs b/clap_builder/src/error/format.rs
index 4c22bc2d9d..db6bed9391 100644
--- a/clap_builder/src/error/format.rs
+++ b/clap_builder/src/error/format.rs
@@ -33,6 +33,7 @@
///
/// </div>
#[non_exhaustive]
+#[derive(Clone)]
pub struct KindFormatter;
impl ErrorFormatter for KindFormatter {
@@ -59,6 +60,7 @@
/// This follows the [rustc diagnostic style guide](https://rustc-dev-guide.rust-lang.org/diagnostics.html#suggestion-style-guide).
#[non_exhaustive]
#[cfg(feature = "error-context")]
+#[derive(Clone)]
pub struct RichFormatter;
#[cfg(feature = "error-context")]
diff --git a/clap_builder/src/error/mod.rs b/clap_builder/src/error/mod.rs
index 7bd627375c..bf822e9e2d 100644
--- a/clap_builder/src/error/mod.rs
+++ b/clap_builder/src/error/mod.rs
@@ -14,6 +14,7 @@
fmt::{self, Debug, Display, Formatter},
io,
result::Result as StdResult,
+ sync::Arc,
};
// Internal
@@ -57,18 +58,19 @@
/// See [`Command::error`] to create an error.
///
/// [`Command::error`]: crate::Command::error
+#[derive(Clone)]
pub struct Error<F: ErrorFormatter = DefaultFormatter> {
inner: Box<ErrorInner>,
phantom: std::marker::PhantomData<F>,
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
struct ErrorInner {
kind: ErrorKind,
#[cfg(feature = "error-context")]
context: FlatMap<ContextKind, ContextValue>,
message: Option<Message>,
- source: Option<Box<dyn error::Error + Send + Sync>>,
+ source: Option<Arc<dyn error::Error + Send + Sync>>,
help_flag: Option<Cow<'static, str>>,
styles: Styles,
color_when: ColorChoice,
@@ -300,7 +302,7 @@
}
pub(crate) fn set_source(mut self, source: Box<dyn error::Error + Send + Sync>) -> Self {
- self.inner.source = Some(source);
+ self.inner.source = Some(source.into());
self
}
@@ -892,7 +894,7 @@
}
#[cfg(feature = "debug")]
-#[derive(Debug)]
+#[derive(Debug, Clone)]
struct Backtrace(backtrace::Backtrace);
#[cfg(feature = "debug")]
@@ -911,7 +913,7 @@
}
#[cfg(not(feature = "debug"))]
-#[derive(Debug)]
+#[derive(Debug, Clone)]
struct Backtrace;
#[cfg(not(feature = "debug"))]
@@ -930,5 +932,5 @@
#[test]
fn check_auto_traits() {
- static_assertions::assert_impl_all!(Error: Send, Sync, Unpin);
+ static_assertions::assert_impl_all!(Error: Send, Sync, Unpin, Clone);
} Update: Maybe I'd also require implementors of |
Why would you still need to manually create an error for
|
Please complete the following tasks
(I looked, but it wasn't easy to search; I could have missed something)
Clap Version
4.5.31
Describe your use case
In jj-vcs/jj#5845 (see especially the discussion at jj-vcs/jj#5845 (comment)), I needed to modify the suggested command of a
clap::Error
.The motivation is that
jj
does not have ajj clone
command, which brand new users experimented withjj
are likely to try. Currently, it uselessly suggestsjj config
as an alternative. I'd like it to point the users to the correctjj git clone
command.Less importantly, I'd love to remove the "Usage" message that does not seem useful.
In other words, we currently have:
I'd like to modify the error so that it says:
(Aside: either way, the command would be followed by a hint like """Hint: You can configure
aliases.clone=["git", "clone"]
if you wantjj clone
to default to the Git backend.""", but that's done independently ofclap
)Describe the solution you'd like
I'd like something like the following to work, improving on https://docs.rs/clap/latest/clap/error/struct.Error.html#method.insert:
In other words, I'd like
clap::Error
to beClone
(perhaps by wrapping the non-clonable parts of it in anArc
) and to be able to remove error contexts.Moreover, I'd like the above to result in an error that gets formatted nicely, with color and the text above.
Alternatives, if applicable
Alternative 1
Currently, jj-vcs/jj#5845 can only add an hint to the confusingly verbose message. The result is:
Screenshot of a slightly older version:
Alternative 2
clap
could provide a facility for "when the user types in command A, suggest command B", extending the recent "do not suggest these commands" functionality.Alternative 3
I also tried to recreate the error manually, but the result lost formatting, and I'm afraid to forget to copy something important.
resulted in losing color in the output :
Still, if the above worked, it'd be an (imperfect) alternative,
The text was updated successfully, but these errors were encountered: