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