After opening a new bash, I was wondering that the exercism completion wasn’t working, so I had a look into the generated script and found the path to the binary in front of all function names
Removing /home/jan/.asdf/installs/exercism/v3.5.7/bin/ from the whole script made the script work.
All the generated scripts (bash, zsh, powershell, fish) contain the path
# bash completion V2 for /home/jan/.asdf/installs/exercism/v3.5.7/bin/exercism -*- shell-script -*-
__/home/jan/.asdf/installs/exercism/v3.5.7/bin/exercism_debug()
{
if [[ -n ${BASH_COMP_DEBUG_FILE-} ]]; then
echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
fi
}
# Macs have bash3 for which the bash-completion package doesn't include
# _init_completion. This is a minimal version of that function.
__/home/jan/.asdf/installs/exercism/v3.5.7/bin/exercism_init_completion()
{
COMPREPLY=()
_get_comp_words_by_ref "$@" cur prev words cword
}
# ...
if [[ $(type -t compopt) = "builtin" ]]; then
complete -o default -F __start_/home/jan/.asdf/installs/exercism/v3.5.7/bin/exercism /home/jan/.asdf/installs/exercism/v3.5.7/bin/exercism
else
complete -o default -o nospace -F __start_/home/jan/.asdf/installs/exercism/v3.5.7/bin/exercism /home/jan/.asdf/installs/exercism/v3.5.7/bin/exercism
fi
# ex: ts=4 sw=4 et filetype=sh
That isn’t an official installation method for the CLI but something a community member appears to have made. You’ll need to get support from them unfortunately.
When I simply download the binary from GitHub and place it in my $PATH, everything is fine:
$ wget -O - https://github.com/exercism/cli/releases/download/v3.5.7/exercism-3.5.7-linux-x86_64.tar.gz | tar -xzp -C ~/.bin/ exercism
$ PATH=~/.bin exercism completion bash | head -n3
# bash completion V2 for exercism -*- shell-script -*-
__exercism_debug()
But when the exercism binary is installed via ASDF, the path to the binary is used:
$ exercism completion bash | head -n3
# bash completion V2 for /home/jan/.asdf/installs/exercism/v3.5.7/bin/exercism -*- shell-script -*-
__/home/jan/.asdf/installs/exercism/v3.5.7/bin/exercism_debug()
The cobra package which exercism uses for the CLI adds the completion command and it uses c.Name (command name) for prefixing the function names. It seems like, when using ASDF, that name is the file path, not only “exercism”…
ChatGPT pointed me to this: cmd/root.go#L17. The Use option tells cobra what to use to prefix the autocompletions functions. It uses getCommandName() which is os.Args[0] which contains the full path to the binary.
Even though it might be cool to have the full path to the binary in the help message does not mean it should also be used for the completion
I made a comment on the GitHub issue before I saw this thread. exercism completion "works for me"™
$ command exercism completion bash | head -n 15
# bash completion V2 for exercism -*- shell-script -*-
__exercism_debug()
{
if [[ -n ${BASH_COMP_DEBUG_FILE-} ]]; then
echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
fi
}
# Macs have bash3 for which the bash-completion package doesn't include
# _init_completion. This is a minimal version of that function.
__exercism_init_completion()
{
COMPREPLY=()
_get_comp_words_by_ref "$@" cur prev words cword
...
I’m wondering what it is about your setup that is triggered by two underscores.
It has to do with asdf running a shim binary to select the proper version to run and then uses the full path to make the actual binary run. If you include the full path to run the exercism completion command, you always get the full path added to the completions:
I suspect that’s generated automatically by cobra. If we don’t override the default message, it makes some sense the displayed message wouldn’t be in our repo.
@BNAndras Yes, one could override the full message but I am unsure whether this is really the way we should go I guess changing the value of Use would be easier.
Currently the value is taken from os.Args[0] but maybe we should use path.Base(os.Args[0]) instead. This way /home/jan/.asdf/installs/exercism/v3.5.7/bin/exercism would become exercism.
The result of getCommandName() is also used for config.SetDefaultDirName(...) which takes the base name of the given command name, so I think doing path.Base(os.Args[0]) should be fine
PR reopened.
When I get to a computer, I’ll have to check all uses of that function to make sure that doesn’t break anything before approving. The code itself looks fine.
I’m not sure that this change is “correct” behavior. The usage string should show the full path. If I have multiple exercism executables at different paths, the usage string should show what I invoked and not just the base path. /tmp/a/exercism --help and /tmp/b/exercism --help should not show the same usage. I think having them set up different completion paths is also correct.
You can place the executable you care about into the PATH and invoke it without a wrapper that changes the actual path. Or hand edit the completion output.
Perhaps there’s some more configuration that can be done in the cobra library, but if it’s a tradeoff between completion that works or the full path in the usage, I’d vote for completion.
Isaac, it’s not about “different completion paths”, the exercism binary generates the completion scripts, and if the full path is given to invoke the binary then the completions get incorrect function names.
If I want different completions for /foo/a and /bar/a, I believe that’s valid and correct. I might have two versions of the tool installed in two locations. I should be able to have a working, and independent, completion for /tmp/v1/exercism vs /tmp/v2/exercism which shouldn’t conflict. I believe this behavior is “working completion” and that trimming the path is incorrect.
Tangentially, I’m surprised to see that bash function with slashes actually work.
$ type -a __exercism_debug
bash: type: __exercism_debug: not found
$ type -a __/opt/homebrew/bin/exercism_debug
__/opt/homebrew/bin/exercism_debug is a function
__/opt/homebrew/bin/exercism_debug ()
{
if [[ -n ${BASH_COMP_DEBUG_FILE-} ]]; then
echo "$*" >> "${BASH_COMP_DEBUG_FILE}";
fi
}
$ BASH_COMP_DEBUG_FILE=/dev/fd/1
$ __/opt/homebrew/bin/exercism_debug hello world
hello world