yitsushi / totp-cli

Authy/Google Authenticator like TOTP CLI tool written in Go.
http://yitsushi.github.io/totp-cli/
MIT License
234 stars 26 forks source link

zsh completion doesn't work #121

Open b2cc opened 2 months ago

b2cc commented 2 months ago

Thanks for your work on totp-cli, very much appreciated!

I noticed that the zsh completion doesn't work. It seems it's trying to evaluate the cli options by calling --generate-shell-completion, however this command doesn't exist. Is there an updated version, or another way to generate the completion file?

File taken from:

~# totp-cli <TAB><TAB>
GLOBAL OPTIONS   COMMANDS  VERSION  AUTHOR  USAGE  NAME  --                                                                                                                     
Incorrect Usage               --  flag provided but not defined: -generate-shell-completion

version:

~# totp-cli --version
totp-cli version 1.8.7
yitsushi commented 2 months ago

Weird. This should enable the competition part based on the official urfave/cli docs.

It has zsh support and I comp file is coming from there repo. I just replaced the $PROG variable with a static value so we don't have to define PROG beforehand (which would be a pain and pretty ugly).

yitsushi commented 2 months ago

I checked if we are using the latest version of now and maybe it was fixed in the library, but we have the latest v2.27.1 version in the go.mod file. Only one release is newer than v2.27.1 and that's the v3.0.0-alpha9, so that's not a way ahead yet.

I don't think I can do more than that sadly.

b2cc commented 2 months ago

Hello @yitsushi , thanks for looking into this. I tried to meddle around with this some more, and also tried the bash completion instead of zsh , but somethings seems to be off in general.

E.g. if you try the bash completion, this happens:

~#  totp-cli <TAB><TAB>
Display all 104 possibilities? (y or n)
-                           CLI                         generate,                   like                        prefix                      totp-cli
1.8.7                       [command                    Generate                    list                        print                       TOTP_TOKEN
a                           command                     -generate-shell-completion  List                        provided                    under
account                     commands                    [global                     mean                        rename                      Usage:
accounts                    COMMANDS:                   GLOBAL                      NAME:                       Rename                      USAGE:
add                         defined:                    Go.                         namespace                   Set                         -v
Add                         delete                      -h                          namespace.                  set-length                  --version,
add-token,                  Delete                      -h?                         namespaces                  set-prefix                  version
all                         Did                         h                           namespaces.                 show                        VERSION:
an                          dump                        --help,                     new                         Shows                       whole
Authenticator               Dump                        help                        not                         specific                    without
AUTHOR:                     Efertone                    help,                       of                          stdin                       written
Authy/Google                <efertone@pm.me>            import                      one                         Storage                     yaml
available                   file.                       Import                      options]                    the                         you
backend.                    flag                        in                          OPTIONS:                    token.                      
but                         for                         Incorrect                   or                          tokens                      
Change                      from                        instant                     OTP                         tool                        
change-password             g                           length                      password.                   TOTP

It basically brings up the help/error message and tries to parse the help text in completable commands, which obviously doesn't work.

Are you sure your implementation is complete? Taking a look at https://github.com/yitsushi/totp-cli/blob/main/app.go, it seems that you're missing blocks like these (as described in https://cli.urfave.org/v2/examples/bash-completions/)

            {
                Name:    "add-token",
                Aliases: []string{"add"},
                Usage:   "Add new token.",
                ...,
           },

Also the parameter --generate-shell-completion should be exposed by your application it seems, which currently doesn't work. Maybe this is the main culprit here?

At least it's mentioned in: https://github.com/urfave/cli/blob/065ea5c05afc1789703bda08dcd045b5c2ce496f/godoc-current.txt#L617

yitsushi commented 2 months ago

No they are there but behind the functions

Commands: []*cli.Command{
  cmd.AddTokenCommand(),
  // ...
}

and AddTokenCommand() returns with a *cli.Command

That's the same as having it inline. I have all the fields on it: https://github.com/yitsushi/totp-cli/blob/main/internal/cmd/add_token.go#L14

I just didn't create one big array, I build it up from chunks, but the end result is the same, this gets into the Commands list, otherwise the command wouldn't even work.

&cli.Command{
  Name:      "add-token",
  Aliases:   []string{"add"},
  Usage:     "Add new token.",
  ...

As the documentation says, enabling that flag should add --generate-shell-completion automatically, and for a while it added it.


For the bash stuff. Yes because bash parses the output no matter what it is, it prints out the help because --generate-shell-completion is not there, and it just parses the help output as if it was the desired output for completion.

yitsushi commented 2 months ago

I have a feeling when a refactor happened there, they removed the part that adds the flag to the command. Based on this search: https://github.com/search?q=repo%3Aurfave%2Fcli%20GenerateShellCompletionFlag&type=code

  1. GenerateShellCompletionFlag is defined as a flag.
  2. GenerateShellCompletionFlag is never used again.
b2cc commented 2 months ago

Ok sorry, I didn't want to confuse you, my programming skills are rather barebones and I didn't notice the include.

But it would definitely be nice to have it working again, if a recent dependency update broke it maybe an earlier version of urfave/cli still works, until upstream fixes it?

yitsushi commented 2 months ago

I'll try to add the flag manually, I think the flag handling is still there, but the flag set is missing. I think if I add the flag on my side, the core will handle it.

If not, I'll try to check when it was removed and either open a PR there to add it back or just revert to older version of urfave/cli.

Looking at the work done there in the last 6-8 months, it seems v2 reached the end and they are more on the v3 path, so I don't expect much work on it.

yitsushi commented 2 months ago

and just to be fair, I never used autocomplete so I just hoped it's working, others fixed it, added extras with PRs, but as by scope it can only autocomplete commands and flags, and it can't autocomplete namespaces and token names because that's encrypted and only decrypted when a specific command was issued.

yitsushi commented 2 months ago

Well, half success 🤣

❯ ./totp-cli --generate-shell-completion
Incorrect Usage: flag provided but not defined: -generate-shell-completion

Did you mean "--generate-bash-completion"?

If I add the flag it kinda like it, but for some reasons it cuts off on -


what, it does for all flags 😱 :

❯ go run . add --length
Incorrect Usage: flag needs an argument: -length
yitsushi commented 2 months ago

It seems it's not even my side. I created a new app in an empty directory, copy paste the first example from https://cli.urfave.org/v2/examples/flags/.

It's funny it recognises the flag --lang as -lang and proceed with that, sadly the shell gen is handler weirdly and it literally checks if the flag is "--generate-bash-completion".

yitsushi commented 2 months ago

As a quick research, I don't know how to fix it now.

I checked what version I used when I moved away from my own old cli lib: v2.25.7

Created a demo app:

module asd

go 1.22.2

require github.com/urfave/cli/v2 v2.25.7

require (
        github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
        github.com/russross/blackfriday/v2 v2.1.0 // indirect
        github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
)

and the go file:

package main

import (
        "fmt"
        "log"
        "os"

        "github.com/urfave/cli/v2"
)

func main() {
        app := &cli.App{
                EnableBashCompletion: true,
                Commands: []*cli.Command{
                        {
                                Name:    "add",
                                Aliases: []string{"a"},
                                Usage:   "add a task to the list",
                                Action: func(cCtx *cli.Context) error {
                                        fmt.Println("added task: ", cCtx.Args().First())
                                        return nil
                                },
                        },
                },
        }

        if err := app.Run(os.Args); err != nil {
                log.Fatal(err)
        }
}

as a result:

❯ go run . --generate-shell-completion
Incorrect Usage: flag provided but not defined: -generate-shell-completion
...

I don't know if it every worked or not at this point.