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

cli: add shell completion subcommand #329

Merged
merged 2 commits into from Feb 5, 2024

Conversation

liuhangbin
Copy link
Contributor

@liuhangbin liuhangbin commented Jan 8, 2024

As the clap_complete dynamic module is unstable and hard-codes the
subcommand as complete, which conflicts with the current collect
subcommand. Let's still use the legacy static way to generate the
completion file.

Usage:
$ retis generate -h
Generate completions file for a specified shell

Usage: retis generate [OPTIONS]

Options:
--shell Specify shell to complete for [possible values: bash, elvish, fish, powershell, zsh]
--register Path to write completion-registration to
-h, --help Print help

$ retis generate --shell bash --register .
$ source retis.bash

Close: #68

v5: Remove fn thin() from impl SubCommand. Update doc description.
v4: Update docs/install.md about how to auto-complete. Fix collect subcommand auto-completion.
v3: Rename subcommand to sh-complete. Move the generate.rs to new folder generate/completion.rs. Rename struct Generate to struct Complete as we rename generate.rs to completion.rs.
v2: Use static generator as dynamic generator use hard-code parameter complete, which conflicts with collect.

@liuhangbin
Copy link
Contributor Author

Hmm, I saw error

error: accessing first element with `self
                           .untracked.get(0)`
  --> src/process/series.rs:84:19
   |
84 |                   < self
   |  ___________________^
85 | |                     .untracked
86 | |                     .get(0)
   | |___________________________^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#get_first
   = note: `-D clippy::get-first` implied by `-D warnings`
   = help: to override `-D warnings` add `#[allow(clippy::get_first)]`
help: try
   |
84 ~                 < self
85 +                     .untracked.front()
   |

error: could not compile `retis` (bin "retis") due to previous error

when doing self-checking. But I didn't expect it to be caused by my patch. I will check it.

Copy link
Contributor

@atenart atenart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While testing found a few issues or things that might be improved:

  • Completion for the retis collect sub-command does not work.
  • complete sub-command is hidden, which is good, but it is used while inferring other sub-commands. This makes retis c for collection to not work anymore. As complete is a "special" command it would be good to exclude it from that, or maybe the only way is to define a _complete sub-command instead.
  • PR miss changes in Cargo.lock.

Once the above is done, please add a section in the documentation about how to enable auto-completion (I think it's as simple as adding source <(retis complete --shell bash --register -) in .bashrc.

Thanks!

Cargo.toml Outdated Show resolved Hide resolved
src/cli/cli.rs Outdated Show resolved Hide resolved
@atenart
Copy link
Contributor

atenart commented Jan 8, 2024

Hmm, I saw error

error: accessing first element with `self
                           .untracked.get(0)`
  --> src/process/series.rs:84:19
   |
84 |                   < self
   |  ___________________^
85 | |                     .untracked
86 | |                     .get(0)
   | |___________________________^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#get_first
   = note: `-D clippy::get-first` implied by `-D warnings`
   = help: to override `-D warnings` add `#[allow(clippy::get_first)]`
help: try
   |
84 ~                 < self
85 +                     .untracked.front()
   |

error: could not compile `retis` (bin "retis") due to previous error

when doing self-checking. But I didn't expect it to be caused by my patch. I will check it.

Welcome to the Rust world :D This is triggered by an update in the linter (cargo clippy). I have a similar fix in all of my PRs too, first one that will be merged will fix it.

@liuhangbin
Copy link
Contributor Author

  • Completion for the retis collect sub-command does not work.

I will check this. Looks like I need to register the dynamic cmd after ran_subcommand.

  • complete sub-command is hidden, which is good, but it is used while inferring other sub-commands. This makes retis c for collection to not work anymore. As complete is a "special" command it would be good to exclude it from that, or maybe the only way is to define a _complete sub-command instead.

Currently the complete is hard-coded in clap_complete. Do you mean to use the static complete method by adding a new parameter _complete?

Thanks
Hangbin

@atenart
Copy link
Contributor

atenart commented Jan 9, 2024

  • complete sub-command is hidden, which is good, but it is used while inferring other sub-commands. This makes retis c for collection to not work anymore. As complete is a "special" command it would be good to exclude it from that, or maybe the only way is to define a _complete sub-command instead.

Currently the complete is hard-coded in clap_complete. Do you mean to use the static complete method by adding a new parameter _complete?

No, I think the dynamic completion is quite nice and easier to maintain. Isn't there a way to rename the dynamic completion command or to define it explicitly rather than using the default one?

@atenart atenart added this to the v1.4 milestone Jan 9, 2024
@liuhangbin
Copy link
Contributor Author

No, I think the dynamic completion is quite nice and easier to maintain. Isn't there a way to rename the dynamic completion command or to define it explicitly rather than using the default one?

From the code it looks like the parameter is hardcode. I have opened an issue for clap, let's see what the maintainer replies.

@liuhangbin
Copy link
Contributor Author

liuhangbin commented Jan 10, 2024

Currently the complete is hard-coded in clap_complete. Do you mean to use the static complete method by adding a new parameter _complete?

No, I think the dynamic completion is quite nice and easier to maintain. Isn't there a way to rename the dynamic completion command or to define it explicitly rather than using the default one?

Emm, I just found that we can hide a parameter with .hide(ture) when adding a new parameter. So how about adding a hiding static parameter generate first? and change to dynamic when the dynamic completion supports self-defined parameter. With this, we will not affect the current usage result. e.g.

# retis -h
Trace packets on the Linux kernel

Usage: retis [OPTIONS] <COMMAND>

Commands:
  collect  Collect network events
  print    Print stored events to stdout
  sort     Sort stored events in series based on tracking id
  pcap     Generate a PCAP file from stored events
  profile  Manage Profiles

Options:
      --log-level <LOG_LEVEL>  Log level [default: info] [possible values: error, warn, info, debug, trace]
  -p, --profile <PROFILE>      Comma separated list of profile names to apply
      --kconf <KCONF>          Path to kernel configuration (e.g. /boot/config-6.3.8-200.fc38.x86_64; default: auto-detect)
  -h, --help                   Print help (see more with '--help')
  -V, --version                Print version

# source <(retis -g bash)
# retis -g <tab>
bash        elvish      fish        powershell  zsh
# retis --generate <tab>
bash        elvish      fish        powershell  zsh
# retis p<tab>
print    pcap     profile

If choose to use this way, should I add the parameter as COMMAND or OPTIONS?

@atenart
Copy link
Contributor

atenart commented Jan 10, 2024

Currently the complete is hard-coded in clap_complete. Do you mean to use the static complete method by adding a new parameter _complete?

No, I think the dynamic completion is quite nice and easier to maintain. Isn't there a way to rename the dynamic completion command or to define it explicitly rather than using the default one?

Emm, I just found that we can hide a parameter with .hide(ture) when adding a new parameter.

I don't think it absolutely has to be hidden, but to ease the use of Retis the command name should at least not conflict with the other commands (at least collect and sort) to allow using retis c for example.

So how about adding a hiding static parameter generate first? and change to dynamic when the dynamic completion supports self-defined parameter. With this, we will not affect the current usage result. e.g.

Let me summarize my understanding; we have two choices:

  1. clap_complete::generator::generate. This generates a standalone completion script at runtime.
  2. clap_complete::dynamic::shells::CompleteCommand. This can be used to query Retis at runtime about completion and is not a stable API.

The big difference is the output of 1 needs to be generated for each upgrade in the user's machine to match current commands and options, while 2 queries the current Retis binary and is by definition always up to date.

Using source <(retis complete) in .bashrc can make 1 work a bit like 2 most of the time, except after an upgrade as the sourced script would not match the new version of the binary. This is not perfect but might be better than the alternatives.

From the maintainer of clap,

dynamic completions are also very early in their development so I also generally recommend people use static completions at this time but I encourage fixes and improvements on dynamic completions.

This makes me wonder if dynamic completion would still be a possibility. Looks like it's not advertised (I can understand why) but apart from potential bugs, are there missing functionalities (for Bash for example)?

If choose to use this way, should I add the parameter as COMMAND or OPTIONS?

A dedicated command please. For the name, maybe generate-completion would be best, to 1) not conflict with other commands for inference and for completion and 2) not conflict with a broader complete or _complete command once dynamic support is there.

@liuhangbin
Copy link
Contributor Author

liuhangbin commented Jan 11, 2024

Emm, I just found that we can hide a parameter with .hide(ture) when adding a new parameter.

I don't think it absolutely has to be hidden, but to ease the use of Retis the command name should at least not conflict with the other commands (at least collect and sort) to allow using retis c for example.

OK

So how about adding a hiding static parameter generate first? and change to dynamic when the dynamic completion supports self-defined parameter. With this, we will not affect the current usage result. e.g.

Let me summarize my understanding; we have two choices:

  1. clap_complete::generator::generate. This generates a standalone completion script at runtime.
  2. clap_complete::dynamic::shells::CompleteCommand. This can be used to query Retis at runtime about completion and is not a stable API.

The big difference is the output of 1 needs to be generated for each upgrade in the user's machine to match current commands and options, while 2 queries the current Retis binary and is by definition always up to date.

Using source <(retis complete) in .bashrc can make 1 work a bit like 2 most of the time, except after an upgrade as the sourced script would not match the new version of the binary. This is not perfect but might be better than the alternatives.

correct

From the maintainer of clap,

dynamic completions are also very early in their development so I also generally recommend people use static completions at this time but I encourage fixes and improvements on dynamic completions.

This makes me wonder if dynamic completion would still be a possibility. Looks like it's not advertised (I can understand why) but apart from potential bugs, are there missing functionalities (for Bash for example)?

I'm not sure either. There is no document about it...

If choose to use this way, should I add the parameter as COMMAND or OPTIONS?

A dedicated command please. For the name, maybe generate-completion would be best, to 1) not conflict with other commands for inference and for completion and 2) not conflict with a broader complete or _complete command once dynamic support is there.

OK, let me try it first.

@liuhangbin
Copy link
Contributor Author

liuhangbin commented Jan 12, 2024

OK, let me try it first.

Tried to use subcommand but not work. I even copied the clap_complete example and change the

    Command::new("completion")
        .arg(
            Arg::new("generator")
                .long("generate")
                .value_parser(value_parser!(Shell)),
        )
        .subcommand(value_hint_command)

to

   let generate = Command::new("generate")
        .arg(
            Arg::new("shell")
                .long("shell")
                .value_parser(value_parser!(Shell)),
        );
    Command::new("completion")
        .subcommand(value_hint_command)
        .subcommand(generate)

It also does not work and reports error Mismatch between definition and access of 'shell'. Unknown argument or group id.. I need to check how matches.get_one::<Shell>("shell") get the parameter.

@liuhangbin
Copy link
Contributor Author

It also does not work and reports error Mismatch between definition and access of 'shell'. Unknown argument or group id.. I need to check how matches.get_one::<Shell>("shell") get the parameter.

OK, I read the doc and found that I need to use subcommand_matches when checking subcommand...

@liuhangbin liuhangbin changed the title cli: add bash completion script cli: add shell completion subcommand Jan 17, 2024
@liuhangbin
Copy link
Contributor Author

liuhangbin commented Jan 17, 2024

Hi @atenart , recently I use generate as subcommand becase it's shorter than generate-completion. The parameters are the same with dynamic complete, with --shell and --register. With this, there is no need to change if we want to move to dynamic complete in the future.

Please tell me if you still want to use generate-completion as subcommand.

BTW, There is no '-c' or '-o' auto-complete for collect subcommand. But I feel this is the collect parameter's problem. Because other subcommands could show there parameters with -h. e.g.

$ retis pcap -h
Generate a PCAP file from stored events

Usage: retis pcap [OPTIONS] --probe <PROBE> [INPUT]

Arguments:
  [INPUT]  File from which to read events [default: retis.data]

Options:
  -p, --probe <PROBE>  Filter events from this probe. Probes should follow the [TYPE:]TARGET pattern.
                       See `retis collect --help` for more details on the probe format.
  -o, --out <OUT>      Write the generated PCAP output to a file rather than stdio
  -h, --help           Print help

$ retis collect -h
^C

I will check the reason recently.

Copy link
Contributor

@atenart atenart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nits, but most importantly the completion for the complete command still does not work for me. Only -h and --help are available when hitting <tab> while we should see other parameters (eg. --stack or --filter):

# retis collect -<tab>
-h      --help

Please tell me if you still want to use generate-completion as subcommand.

I find generate to be too generic for a command that "only" generates a completion script. The issue with complete would be a conflict with collect for the c use though. If we want to use a sort command name we could go with _complete, but I'm not super sure.

An alternative could be to make something like retis generate completion ....

@vlrpl WDYT?

There is no '-c' or '-o' auto-complete for collect subcommand. But I feel this is the collect parameter's problem.

Agreed. Same with --profile. This might be solved with dynamic completion once they also add support for custom implementation of authorized values.

src/process/cli/mod.rs Outdated Show resolved Hide resolved
src/cli/cli.rs Outdated Show resolved Hide resolved
src/process/cli/generate.rs Outdated Show resolved Hide resolved
src/process/cli/generate.rs Outdated Show resolved Hide resolved
@vlrpl
Copy link
Contributor

vlrpl commented Jan 17, 2024

A few nits, but most importantly the completion for the complete command still does not work for me. Only -h and --help are available when hitting <tab> while we should see other parameters (eg. --stack or --filter):

# retis collect -<tab>
-h      --help

Please tell me if you still want to use generate-completion as subcommand.

I find generate to be too generic for a command that "only" generates a completion script. The issue with complete would be a conflict with collect for the c use though. If we want to use a sort command name we could go with _complete, but I'm not super sure.

An alternative could be to make something like retis generate completion ....

@vlrpl WDYT?

I think that naming is always hard :)
I agree that generate is too vague (whereas makes sense in a cli context, instead)
retis generate completion makes sense but it's hard to say in advance if generate will serve any other purpose in the future. I would stick with "one" subcommand (as a personal preference).
Maybe sh-completion (or sh-complete or something similar)?

There is no '-c' or '-o' auto-complete for collect subcommand. But I feel this is the collect parameter's problem.

Agreed. Same with --profile. This might be solved with dynamic completion once they also add support for custom implementation of authorized values.

@atenart
Copy link
Contributor

atenart commented Jan 22, 2024

The PR looks mostly good, but still have the below issue.

A few nits, but most importantly the completion for the complete command still does not work for me. Only -h and --help are available when hitting <tab> while we should see other parameters (eg. --stack or --filter):

# retis collect -<tab>
-h      --help

I had a quick look at this and I'm confident the issue is because of this:

impl SubCommand for Collect {
    fn thin(&self) -> Result<Command> {                                         
        Ok(Command::new("collect").about("Collect network events"))             
    }
}

IMO the correct fix would be to define the same command as what's done in the new function from the same impl. With that we should have the correct completion for all arguments of collect. @amorenoz does that sound right?

We should even be able to generate the list of modules and set a PossibleValuesParser so we also have completion for the available collectors.

@liuhangbin
Copy link
Contributor Author

IMO the correct fix would be to define the same command as what's done in the new function from the same impl. With that we should have the correct completion for all arguments of collect. @amorenoz does that sound right?

Hi @atenart , do you want to do this on this PR or a separate PR?

@atenart
Copy link
Contributor

atenart commented Jan 26, 2024

IMO the correct fix would be to define the same command as what's done in the new function from the same impl. With that we should have the correct completion for all arguments of collect. @amorenoz does that sound right?

Hi @atenart , do you want to do this on this PR or a separate PR?

The first part is a requirement for the collect command to be supported by the auto-completion, as it's the most used command by far I think it should be done in this PR.

The second part, about the auto-completion of collectors for the -c arg, can be done in a follow-up PR or in this one; your choice. I think it should be done by the time we release 1.4 though.

@liuhangbin
Copy link
Contributor Author

The first part is a requirement for the collect command to be supported by the auto-completion, as it's the most used command by far I think it should be done in this PR.

OK, I will see how to fix it.

The second part, about the auto-completion of collectors for the -c arg, can be done in a follow-up PR or in this one; your choice. I think it should be done by the time we release 1.4 though.

I'd prefer to fix it on a separate PR. I will put it on my next week's todo list. When 1.4 will be released?

@atenart
Copy link
Contributor

atenart commented Jan 26, 2024

The first part is a requirement for the collect command to be supported by the auto-completion, as it's the most used command by far I think it should be done in this PR.

OK, I will see how to fix it.

Thanks!

The second part, about the auto-completion of collectors for the -c arg, can be done in a follow-up PR or in this one; your choice. I think it should be done by the time we release 1.4 though.

I'd prefer to fix it on a separate PR. I will put it on my next week's todo list. When 1.4 will be released?

Target is end of March.

@liuhangbin
Copy link
Contributor Author

Target is end of March.

OK. 2 months should be enough.

@liuhangbin
Copy link
Contributor Author

liuhangbin commented Jan 28, 2024

IMO the correct fix would be to define the same command as what's done in the new function from the same impl. With that we should have the correct completion for all arguments of collect. @amorenoz does that sound right?

The first part is a requirement for the collect command to be supported by the auto-completion, as it's the most used command by far I think it should be done in this PR.

Hi @atenart , I checked this issue. As you said, the collect only returns thin parameter when built. To fix it, we need to get all the parameters. So either we return full parameter for collect, like

diff --git a/src/collect/cli.rs b/src/collect/cli.rs
index 93294883275c..fc348d035f27 100644
--- a/src/collect/cli.rs
+++ b/src/collect/cli.rs
@@ -149,7 +149,7 @@ impl SubCommand for Collect {
     }

     fn thin(&self) -> Result<Command> {
-        Ok(Command::new("collect").about("Collect network events"))
+        self.full()
     }

     fn name(&self) -> String {

Or let all subcommands return full parameter.

diff --git a/src/cli/cli.rs b/src/cli/cli.rs
index 459783eeaff1..eb4c1939153b 100644
--- a/src/cli/cli.rs
+++ b/src/cli/cli.rs
@@ -271,9 +271,9 @@ impl ThinCli {
             .disable_help_subcommand(true)
             .infer_subcommands(true)
             .subcommand_required(true);
-        // Add thin subcommands so that the main help shows them.
+        // Add full subcommands so that the main help shows them.
         for sub in self.subcommands.iter() {
-            command = command.subcommand(sub.thin().expect("thin command failed"));
+            command = command.subcommand(sub.full().expect("full command failed"));
         }

         // Determine the subcommand that was run while ignoring errors from yet-to-be-defined

I'd prefer the second way, which should resolve all subcommand auto-completion. What do you think?

The second part, about the auto-completion of collectors for the -c arg, can be done in a follow-up PR or in this one; your choice. I think it should be done by the time we release 1.4 though.

For this one, if we could get the possible values during let mut cli = get_cli()?.build();, then we can do auto-completion. But this looks not easy as we only load the modules and replace the ran subcommand with the full subcommand when call the subcommand. Here is the code

    /// Perform full CLI parsing and validation
    pub(crate) fn run(mut self) -> Result<CliConfig, ClapError> {
        self.enhance_profile().map_err(|err| {
            self.command
                .error(ErrorKind::InvalidValue, format!("{err}"))
        })?;

...

        // Replace the ran subcommand with the full subcommand.
        self.command = self
            .command
            .mut_subcommand(self.subcommand.name(), |_| self.subcommand.full().unwrap());

Do you have any idea?

@atenart
Copy link
Contributor

atenart commented Jan 29, 2024

IMO the correct fix would be to define the same command as what's done in the new function from the same impl. With that we should have the correct completion for all arguments of collect. @amorenoz does that sound right?

The first part is a requirement for the collect command to be supported by the auto-completion, as it's the most used command by far I think it should be done in this PR.

Hi @atenart , I checked this issue. As you said, the collect only returns thin parameter when built. To fix it, we need to get all the parameters. So either we return full parameter for collect, like

[...]

Or let all subcommands return full parameter.

diff --git a/src/cli/cli.rs b/src/cli/cli.rs
index 459783eeaff1..eb4c1939153b 100644
--- a/src/cli/cli.rs
+++ b/src/cli/cli.rs
@@ -271,9 +271,9 @@ impl ThinCli {
             .disable_help_subcommand(true)
             .infer_subcommands(true)
             .subcommand_required(true);
-        // Add thin subcommands so that the main help shows them.
+        // Add full subcommands so that the main help shows them.
         for sub in self.subcommands.iter() {
-            command = command.subcommand(sub.thin().expect("thin command failed"));
+            command = command.subcommand(sub.full().expect("full command failed"));
         }

         // Determine the subcommand that was run while ignoring errors from yet-to-be-defined

I'd prefer the second way, which should resolve all subcommand auto-completion. What do you think?

I agree, this seems to be the best option.

The second part, about the auto-completion of collectors for the -c arg, can be done in a follow-up PR or in this one; your choice. I think it should be done by the time we release 1.4 though.

For this one, if we could get the possible values during let mut cli = get_cli()?.build();, then we can do auto-completion. But this looks not easy as we only load the modules and replace the ran subcommand with the full subcommand when call the subcommand. Here is the code
Do you have any idea?

Yes, that does not look straightforward, the cli handling might need some reworking to properly support this. Also not only the --collectors completion needs such rework, but the completion of collectors args too, eg. --skb-sections from the skb collector or --ovs-track from ovs.

I made a quick experiment and this seems to work. But would need some rework (eg. register_cli is now called multiple times, which is why the following discard the error returned) and proper investigation to have a clean implementation.

diff --git a/src/cli/cli.rs b/src/cli/cli.rs
index 5a203ea167e0..45ab063a710e 100644
--- a/src/cli/cli.rs
+++ b/src/cli/cli.rs
@@ -100,7 +100,7 @@ pub(crate) trait SubCommand {
     /// Generate the clap Command to be used for "full" parsing.
     ///
     /// This method should be called after all dynamic options have been registered.
-    fn full(&self) -> Result<Command>;
+    fn full(&mut self) -> Result<Command>;
 
     /// Updates internal structures with clap's ArgMatches.
     fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), ClapError>;
@@ -165,7 +165,7 @@ where
         Ok(<Self as clap::CommandFactory>::command())
     }
 
-    fn full(&self) -> Result<Command> {
+    fn full(&mut self) -> Result<Command> {
         Ok(<Self as clap::CommandFactory>::command())
     }
 
@@ -272,8 +272,8 @@ impl ThinCli {
             .infer_subcommands(true)
             .subcommand_required(true);
         // Add thin subcommands so that the main help shows them.
-        for sub in self.subcommands.iter() {
-            command = command.subcommand(sub.thin().expect("thin command failed"));
+        for sub in self.subcommands.iter_mut() {
+            command = command.subcommand(sub.full().expect("thin command failed"));
         }
 
         // Determine the subcommand that was run while ignoring errors from yet-to-be-defined
diff --git a/src/collect/cli.rs b/src/collect/cli.rs
index 93294883275c..c0ff1a514811 100644
--- a/src/collect/cli.rs
+++ b/src/collect/cli.rs
@@ -164,7 +164,7 @@ impl SubCommand for Collect {
         Some(&mut self.collectors)
     }
 
-    fn full(&self) -> Result<Command> {
+    fn full(&mut self) -> Result<Command> {
         let long_about = "Collect events using 'collectors'.\n\n \
             Collectors are modules that extract \
             events from different places of the kernel or userspace daemons \
@@ -173,8 +173,13 @@ impl SubCommand for Collect {
 
         // Determine all registerd collectors and specify both the possible values and the default
         // value of the "collectors" argument
-        let possible_collectors =
-            Vec::from_iter(self.collectors.modules().iter().map(|x| x.to_str()));
+        let mut modules = crate::get_modules()?;
+        let collectors = modules.collectors();
+        let _ = collectors.values().try_for_each(|c| c.register_cli(&mut self.collectors));
+        let possible_collectors: Vec<&'static str> = collectors
+            .keys()
+            .map(|m| m.to_str())
+            .collect();
 
         let full_command = self
             .collectors
diff --git a/src/collect/collector.rs b/src/collect/collector.rs
index 0697f4ef0360..1860b1275062 100644
--- a/src/collect/collector.rs
+++ b/src/collect/collector.rs
@@ -473,7 +473,7 @@ impl SubCommandRunner for CollectRunner {
     fn run(&mut self, cli: FullCli, modules: Modules) -> Result<()> {
         // Initialize collectors.
         let mut collectors = Collectors::new(modules)?;
-        let cli = collectors.register_cli(cli)?;
+        let cli = cli.run()?;
         collectors.init(&cli)?;
         collectors.start()?;
         // Starts a loop.
diff --git a/src/generate/completion.rs b/src/generate/completion.rs
index 1052ddfa28ed..65063546c533 100644
--- a/src/generate/completion.rs
+++ b/src/generate/completion.rs
@@ -54,7 +54,7 @@ impl SubCommand for Complete {
         Ok(<Self as clap::CommandFactory>::command())
     }
 
-    fn full(&self) -> Result<Command> {
+    fn full(&mut self) -> Result<Command> {
         Ok(<Self as clap::CommandFactory>::command())
     }

please add a section in the documentation about how to enable auto-completion (I think it's as simple as adding source <(retis complete --shell bash --register -) in .bashrc.

Also please do not forget this when submitting the final version :)

@amorenoz if you have some time, can you check if the above sounds right?

Copy link
Contributor

@atenart atenart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I'm sorry, one last thing: can you remove fn thin() from impl SubCommand otherwise this PR would "introduce" dead code.

If you can while at it, can you ellaborate a bit more in the doc about auto-completion? Maybe "Retis can generate completion files for shells (Bash, Zsh, Fish...). For example to enable auto-completion of Retis command in Bash, ...".

Thanks!

Add full subcommands for the main help so we can find them when do
auto-completion. At the same time remove all thin implementation
since it's not used anymore.

Update the collect full command about info at the same time.

Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
As the clap_complete dynamic module is unstable and hard-codes the
subcommand as `complete`, which conflicts with the current `collect`
subcommand. Let's still use the legacy static way to generate the
completion file.

Usage:
$ retis sh-complete -h
Generate completions file for a specified shell

Usage: retis sh-complete [OPTIONS]

Options:
      --shell <SHELL>        Specify shell to complete for [possible values: bash, elvish, fish, powershell, zsh]
      --register <REGISTER>  Path to write completion-registration to
  -h, --help                 Print help

$ retis sh-complete --shell bash --register .
$ source retis.bash

Close: retis-org#68
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Copy link
Contributor

@atenart atenart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks a lot for your contribution!

@atenart atenart merged commit 80da937 into retis-org:main Feb 5, 2024
3 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add bash completion script
3 participants