complete-alias
complete-alias copied to clipboard
Difficulty with `complete -C` commands
I use certain utility packages to manage multiple versions of a given utility. One such is tfenv
to manage Terraform. This sets up my PATH
such that the executable file named terraform
is symlinked to a script that invokes the appropriate actual instance. Command completion works without issue. I would like to set up an alias, e.g.:
alias tfinit='terraform init ... $@'
but I find that this gives me errors like:
-bash: compgen: warning: -C option may not work as you expect
Is this possible? What can I do to help complete-alias DWIM?
Thanks, Matt
Is there a minimum working example? I mean, something that can be reproduced exactly?
At least tell me if you are on Linux or Mac, bash version, and show me the output of ls -l terraform
and cat terraform
?
Sorry, it didn't occur to me to tell you my OS. :P I'm on MacOS.
> ls -l `which terraform`
lrwxr-xr-x 1 foo admin 35 Oct 6 10:20 /usr/local/bin/terraform -> ../Cellar/tfenv/2.2.2/bin/terraform
tfenv
's version of terraform
can be viewed at https://github.com/tfutils/tfenv/blob/master/bin/terraform .
If you think it would be helpful I could try to create a Dockerfile
with my setup, assuming the problem is reproducible in Linux.
Thanks for a cool utility!
Several points:
- You didn't report your bash version. Run
bash --version
to see if it's 4.4 or higher. - Support for Mac is experimental. It'd be great if you can reproduce the bug on a Linux system.
- I wonder if you have pasted the alias body literally, since I don't expect
$@
in an alias body.
-
GNU bash, version 5.1.8(1)-release (x86_64-apple-darwin20.3.0)
- Will attempt
- My original, complete, alias was:
f() { terraform init --backend-config="username=REDACTED --backend-config="password=`cat REDACTED_FILE` $@; unset -f f; }; f
Prompted by your comment I simplified to:
terraform init --backend-config="username=REDACTED" --backend-config=password=${REDACTED_VAR}"
...and reran complete -F _complete_alias tfinit
. With this I have a bit more error text. The following reflects my typing tfinit
and pressing <TAB>:
tfinit -bash: ((: == 1 : syntax error: operand expected (error token is "== 1 ")
-bash: compgen: warning: -C option may not work as you expect
Terraform has no command named "compgen".
To see all of Terraform's top-level commands, run:
terraform -help
Additionally I tried moving the init
command to the end of the alias, after the ``--backend-config` switch options (and subsequently rerunning the command to set up the completion), but still to no avail.
Dockerfile
to reproduce on Debian 10/Buster:
FROM wolfsoftwareltd/tfenv-debian
ARG CA_VERSION=1.18.0
RUN apt-get update && apt install bash-completion && \
echo source /etc/profile.d/bash_completion.sh >> .bashrc && \
curl -L https://github.com/cykerway/complete-alias/archive/refs/tags/${CA_VERSION}.tar.gz | tar zx --strip-components=1 complete-alias-${CA_VERSION}/complete_alias && \
.tfenv/bin/tfenv install && .tfenv/bin/tfenv use && .tfenv/bin/terraform -install-autocomplete && \
echo source ./complete_alias >> .bashrc && \
echo alias tfinit=\'terraform init\' >> .bashrc && \
echo complete -F _complete_alias tfinit >> .bashrc
Dockerfile
to reproduce:
FROM wolfsoftwareltd/tfenv-debian
ARG CA_VERSION=1.18.0
RUN apt-get update && apt install bash-completion && \
echo source /etc/profile.d/bash_completion.sh >> .bashrc && \
curl -L https://github.com/cykerway/complete-alias/archive/refs/tags/${CA_VERSION}.tar.gz | tar zx --strip-components=1 complete-alias-${CA_VERSION}/complete_alias && \
.tfenv/bin/tfenv install && .tfenv/bin/tfenv use && .tfenv/bin/terraform -install-autocomplete && \
echo source ./complete_alias >> .bashrc && \
echo alias tfinit=\'terraform init\' >> .bashrc && \
echo complete -F _complete_alias tfinit >> .bashrc
Run this container and try to complete tfinit
; error is reproduced.
First of all, I need some minor modifications to successfully reproduce the bug:
FROM wolfsoftwareltd/tfenv-debian
ARG CA_VERSION=1.18.0
RUN apt-get update && apt-get install bash-completion unzip && \
echo source /etc/profile.d/bash_completion.sh >> .bashrc && \
curl -L https://github.com/cykerway/complete-alias/archive/refs/tags/${CA_VERSION}.tar.gz | tar zx --strip-components=1 complete-alias-${CA_VERSION}/complete_alias && \
.anyenv/envs/tfenv/bin/tfenv install && .anyenv/envs/tfenv/bin/tfenv use && .anyenv/envs/tfenv/bin/terraform -install-autocomplete && \
echo source ./complete_alias >> .bashrc && \
echo alias tfinit=\'terraform init\' >> .bashrc && \
echo complete -F _complete_alias tfinit >> .bashrc
Now tab-complete tfinit
does give the error you pointed out.
However, I don't think this is an alias problem. To see why, you can try this Dockerfile
instead:
FROM wolfsoftwareltd/tfenv-debian
RUN apt-get update && apt-get install bash-completion unzip && \
echo source /etc/profile.d/bash_completion.sh >> .bashrc && \
.anyenv/envs/tfenv/bin/tfenv install && .anyenv/envs/tfenv/bin/tfenv use && .anyenv/envs/tfenv/bin/terraform -install-autocomplete
Now tab-complete terraform
works as usual, but tab-complete sudo terraform
fails:
bash: compgen: warning: -C option may not work as you expect
...
There seems to be some problem when using complete -C
with sudo
. If you run complete -p terraform
then you'd see its completion is done with -C
. And as you see, the root cause is not here in complete-alias
(because the bug emerges even without aliases). So I'd suggest you pivot to https://github.com/scop/bash-completion and create an issue there and see what they say. You can simply tell them tab-complete terraform
is working but sudo terraform
is not, with this second Dockerfile
. You can then link the issue back here if you want, because this issue would depend on that one.
Furthermore, terraform
is an interesting binary because it knows about auto completion, which can complicate the problem.
Instead, I can give you a simpler example if you decide to report the bug upstream:
complete -C 'echo' foo
sudo foo <tab>
gives the error:
-bash: compgen: warning: -C option may not work as you expect
I don't think this has anything to do with symlinks. I think the problem happens because of complete -C
. The function _command_offset
from bash-completion
does not handle such commands perfectly.
Thanks for the in-depth analysis! A question: were you able to determine that sudo
is used by tfenv
in some way I had not noticed, or are you rather saying that sudo
and tfenv
/terraform
are both susceptible to the same problem with complete -C
?
I don't know if tfenv
uses sudo
or not, but both complete-alias
and sudo
utilize the same function _command_offset
provided by bash-completion
. That seems to be the problematic thing here. If this alone doesn't solve the problem, then we need to look at terraform
itself.
BTW, I shall create the upstream issue for you. Created as https://github.com/scop/bash-completion/issues/631.
Was just about to go create it but wanted to look like I had some idea what I was talking about ;) . Thanks again.
I had a similar issue when I tried to alias terraform
to tf
. I found a workaround:
alias tf=terraform
complete -C /path/to/terraform tf
In your case, it's a little more complicated:
alias tfinit='terraform init'
complete -C 'COMP_LINE="terraform init${COMP_LINE:6}" COMP_POINT=$((COMP_POINT+8)) terraform' tfinit
# 6 == len('tfinit')
# 8 == len('terraform init') - len('tfinit')
The key is to trick terraform
into thinking it's completing terraform init blah blah
.