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

Difficulty with complete -C commands #30

Open
mbenson opened this issue Oct 6, 2021 · 13 comments
Open

Difficulty with complete -C commands #30

mbenson opened this issue Oct 6, 2021 · 13 comments

Comments

@mbenson
Copy link

mbenson commented Oct 6, 2021

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

@cykerway
Copy link
Owner

cykerway commented Oct 7, 2021

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?

@mbenson
Copy link
Author

mbenson commented Oct 7, 2021

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!

@cykerway
Copy link
Owner

cykerway commented Oct 9, 2021

Several points:

  1. You didn't report your bash version. Run bash --version to see if it's 4.4 or higher.
  2. Support for Mac is experimental. It'd be great if you can reproduce the bug on a Linux system.
  3. I wonder if you have pasted the alias body literally, since I don't expect $@ in an alias body.

@mbenson
Copy link
Author

mbenson commented Oct 11, 2021

  1. GNU bash, version 5.1.8(1)-release (x86_64-apple-darwin20.3.0)
  2. Will attempt
  3. 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 :

 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.

@mbenson
Copy link
Author

mbenson commented Oct 11, 2021

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

@mbenson
Copy link
Author

mbenson commented Oct 15, 2021

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.

@cykerway
Copy link
Owner

cykerway commented Oct 19, 2021

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.

@cykerway
Copy link
Owner

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

@cykerway cykerway changed the title Difficulty with symlink commands Difficulty with complete -C commands Oct 19, 2021
@cykerway
Copy link
Owner

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.

@mbenson
Copy link
Author

mbenson commented Oct 19, 2021

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?

@cykerway
Copy link
Owner

cykerway commented Oct 19, 2021

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 scop/bash-completion#631.

@mbenson
Copy link
Author

mbenson commented Oct 19, 2021

Was just about to go create it but wanted to look like I had some idea what I was talking about ;) . Thanks again.

Repository owner deleted a comment from mrpanday93 Feb 15, 2024
@zzJinux
Copy link

zzJinux commented Mar 10, 2024

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.

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

No branches or pull requests

3 participants