dsifford / yarn-completion

Bash completion for Yarn
MIT License
277 stars 25 forks source link

"counter" and "cmd" must be set by the caller and be the appropriate type #14

Closed joma74 closed 6 years ago

joma74 commented 6 years ago

Currently any tab completion after yarn ends with this message and exit. Seems to me that a declare cmd does not make it in the check before the exit.

joma@edison:~$ homestead ssh
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-112-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

215 packages can be updated.
76 updates are security updates.

Last login: Tue Apr  3 23:03:34 2018 from 10.0.2.2
vagrant@homestead:~$ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
vagrant@homestead:~$ set -v
vagrant@homestead:~$ . ~/.yarn-completion
vagrant@homestead:~$ yarn __yarn_get_package_fields scripts
pwd
cword=1
words[0]=${!ref}${COMP_WORDS[i]}
words[1]=${!ref}${COMP_WORDS[i]}
cword=1
words=("${@:3:2}")
cword="$3"
cur="$3"
cur="$3"
cword="$3"
prev="$3"
words=("${@:3:2}")
declare -p counter cmd 2>/dev/null | awk '{ printf "%s", $2 }'
"counter" and "cmd" must be set by the caller and be the appropriate type
logout
# ~/.bash_logout: executed by bash(1) when login shell exits.

# when leaving the console clear the screen to increase privacy

if [ "$SHLVL" = 1 ]; then
    [ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q
fi
Connection to 127.0.0.1 closed.
dsifford commented 6 years ago

@joma74 Thanks for the report.

Am I reading your output correctly? I'm seeing you calling __yarn_get_package_fields directly? Is that correct?

If so, why do you need to do that?

joma74 commented 6 years ago

Hey dsifford, No, guess that belongs to the console output after the exit happened. My input ends after yarn followed by a tab.

dsifford commented 6 years ago

Hm..

I have no idea why you might be getting that error to be honest, because at no point ever could that particular error occur given that counter and cmd are set explicitly before the first and only call of __yarn_get_command. (https://github.com/dsifford/yarn-completion/blob/master/yarn-completion.bash#L745-L747)

Try to maybe comment out the check lines and see if that resolves it for you.

joma74 commented 6 years ago

Yes, and it seems that declare cmd without a value assignment makes the check not pass.

This is the debug output i'd prefered to give in the first description. Forgot again that set -x applies local only. Input is yarn followed by a tab. The console output following is due to the set -x.

vagrant@homestead:~$ yarn + declare 'prev_comp_wordbreaks=  
"'\''><=;|&(:'
+ COMP_WORDBREAKS='"'\''><=;|&(: '
+ declare cur prev words cword
+ commands=(access add autoclean bin cache check config create exec generate-lock-entry global help import info init install licenses link list login logout node outdated owner pack publish remove run tag team unlink upgrade upgrade-interactive version versions workspace workspaces why $(__yarn_get_package_fields scripts))
++ __yarn_get_package_fields scripts
++ declare field_key
++ declare field_type=object
++ declare package_dot_json
+++ pwd
++ package_dot_json=/home/vagrant/package.json
++ declare OPTIND OPTARG opt
++ getopts :gt: opt
++ shift 0
++ field_key='"scripts"'
++ [[ ! -f /home/vagrant/package.json ]]
++ return
+ declare commands
+ global_flags=(--cache-folder --check-files --cwd --emoji --flat --force --frozen-lockfile --global-folder --har --help --https-proxy --ignore-engines --ignore-optional --ignore-platform --ignore-scripts --json --link-duplicates --link-folder --modules-folder --mutex --network-concurrency --network-timeout --no-bin-links --no-emoji --no-lockfile --no-progress --non-interactive --offline --prefer-offline --preferred-cache-folder --prod --production --proxy --pure-lockfile --scripts-prepend-node-path --silent --skip-integrity-check --strict-semver --verbose --version)
+ declare global_flags
+ COMPREPLY=()
+ command -v _init_completion
+ _init_completion
+ local exclude= flag outx errx inx OPTIND=1
+ getopts n:e:o:i:s flag
+ COMPREPLY=()
+ local 'redir=@(?([0-9])<|?([0-9&])>?(>)|>&)'
+ _get_comp_words_by_ref -n '<>&' cur prev words cword
+ local exclude flag i OPTIND=1
+ words=()
+ local cur cword words
+ upargs=()
+ upvars=()
+ local upargs upvars vcur vcword vprev vwords
+ getopts c:i:n:p:w: flag -n '<>&' cur prev words cword
+ case $flag in
+ exclude='<>&'
+ getopts c:i:n:p:w: flag -n '<>&' cur prev words cword
+ [[ 6 -ge 3 ]]
+ case ${!OPTIND} in
+ vcur=cur
+ let 'OPTIND += 1'
+ [[ 6 -ge 4 ]]
+ case ${!OPTIND} in
+ vprev=prev
+ let 'OPTIND += 1'
+ [[ 6 -ge 5 ]]
+ case ${!OPTIND} in
+ vwords=words
+ let 'OPTIND += 1'
+ [[ 6 -ge 6 ]]
+ case ${!OPTIND} in
+ vcword=cword
+ let 'OPTIND += 1'
+ [[ 6 -ge 7 ]]
+ __get_cword_at_cursor_by_ref '<>&' words cword cur
+ words=()
+ local cword words
+ __reassemble_comp_words_by_ref '<>&' words cword
+ local exclude i j line ref
+ [[ -n <>& ]]
+ exclude='<>&'
+ eval cword=1
++ cword=1
+ [[ -n <>& ]]
+ line='yarn '
+ (( i=0, j=0 ))
+ (( i < 2 ))
+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval 'words[0]=${!ref}${COMP_WORDS[i]}'
++ words[0]=yarn
+ line=' '
+ [[ 0 == 1 ]]
+ (( i++, j++ ))
+ (( i < 2 ))
+ [[ 1 -gt 0 ]]
+ [[ '' == +([<>&]) ]]
+ ref='words[1]'
+ eval 'words[1]=${!ref}${COMP_WORDS[i]}'
++ words[1]=
+ line=' '
+ [[ 1 == 1 ]]
+ eval cword=1
++ cword=1
+ (( i++, j++ ))
+ (( i < 2 ))
+ [[ 2 == 1 ]]
+ local i cur index=5 'lead=yarn '
+ [[ 5 -gt 0 ]]
+ [[ -n yarn  ]]
+ [[ -n yarn ]]
+ cur='yarn '
+ (( i = 0 ))
+ (( i <= cword ))
+ [[ 5 -ge 4 ]]
+ [[ yarn != \y\a\r\n ]]
+ [[ 0 -lt 1 ]]
+ local old_size=5
+ cur=' '
+ local new_size=1
+ index=1
+ (( ++i  ))
+ (( i <= cword ))
+ [[ 1 -ge 0 ]]
+ [[ '' != '' ]]
+ [[ 1 -lt 1 ]]
+ (( ++i  ))
+ (( i <= cword ))
+ [[ -n   ]]
+ [[ ! -n '' ]]
+ cur=
+ [[ 1 -lt 0 ]]
+ local words cword cur
+ _upvars -a2 words yarn '' -v cword 1 -v cur ''
+ ((  10  ))
+ ((  10  ))
+ case $1 in
+ [[ -n 2 ]]
+ printf %d 2
+ [[ -n words ]]
+ unset -v words
+ eval 'words=("${@:3:2}")'
++ words=("${@:3:2}")
+ shift 4
+ ((  6  ))
+ case $1 in
+ [[ -n cword ]]
+ unset -v cword
+ eval 'cword="$3"'
++ cword=1
+ shift 3
+ ((  3  ))
+ case $1 in
+ [[ -n cur ]]
+ unset -v cur
+ eval 'cur="$3"'
++ cur=
+ shift 3
+ ((  0  ))
+ [[ -n cur ]]
+ upvars+=("$vcur")
+ upargs+=(-v $vcur "$cur")
+ [[ -n cword ]]
+ upvars+=("$vcword")
+ upargs+=(-v $vcword "$cword")
+ [[ -n prev ]]
+ [[ 1 -ge 1 ]]
+ upvars+=("$vprev")
+ upargs+=(-v $vprev "${words[cword - 1]}")
+ [[ -n words ]]
+ upvars+=("$vwords")
+ upargs+=(-a${#words[@]} $vwords "${words[@]}")
+ ((  4  ))
+ local cur cword prev words
+ _upvars -v cur '' -v cword 1 -v prev yarn -a2 words yarn ''
+ ((  13  ))
+ ((  13  ))
+ case $1 in
+ [[ -n cur ]]
+ unset -v cur
+ eval 'cur="$3"'
++ cur=
+ shift 3
+ ((  10  ))
+ case $1 in
+ [[ -n cword ]]
+ unset -v cword
+ eval 'cword="$3"'
++ cword=1
+ shift 3
+ ((  7  ))
+ case $1 in
+ [[ -n prev ]]
+ unset -v prev
+ eval 'prev="$3"'
++ prev=yarn
+ shift 3
+ ((  4  ))
+ case $1 in
+ [[ -n 2 ]]
+ printf %d 2
+ [[ -n words ]]
+ unset -v words
+ eval 'words=("${@:3:2}")'
++ words=("${@:3:2}")
+ shift 4
+ ((  0  ))
+ _variables
+ [[ '' =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]]
+ return 1
+ [[ '' == @(?([0-9])<|?([0-9&])>?(>)|>&)* ]]
+ [[ yarn == @(?([0-9])<|?([0-9&])>?(>)|>&) ]]
+ local i skip
+ (( i=1 ))
+ (( i < 2 ))
+ [[ '' == @(?([0-9])<|?([0-9&])>?(>)|>&)* ]]
+ i=2
+ (( 1 ))
+ (( i < 2 ))
+ [[ 1 -le 0 ]]
+ prev=yarn
+ [[ -n '' ]]
+ return 0
+ declare cmd
+ declare -i counter=1
+ __yarn_get_command
++ awk '{ printf "%s", $2 }'
++ declare -p counter cmd
+ [[ -i == \-\i\-\- ]]
+ echo '"counter" and "cmd" must be set by the caller and be the appropriate type'
"counter" and "cmd" must be set by the caller and be the appropriate type
+ exit 1
logout
++ '[' 1 = 1 ']'
++ '[' -x /usr/bin/clear_console ']'
++ /usr/bin/clear_console -q
Connection to 127.0.0.1 closed.
dsifford commented 6 years ago

Thanks for the trace.

What is the output of declare -p BASH_VERSION in the environment that this issue is occurring in?

joma74 commented 6 years ago

Here it is

vagrant@homestead:~/code$ declare -p BASH_VERSION
declare -- BASH_VERSION="4.3.48(1)-release"
dsifford commented 6 years ago

Super strange....

The issue is right here:

+ declare cmd # <--------- cmd is definitely being declared
+ declare -i counter=1
+ __yarn_get_command
++ awk '{ printf "%s", $2 }'
++ declare -p counter cmd
+ [[ -i == \-\i\-\- ]] # <------- `declare -p counter cmd` is only seeing `counter` here

For whatever reason, the system you're on is either not registering cmd or not printing a -- when the declare -p statement is invoked.

I can't fathom why this would be happening to you. I've been able to use this on several different linux distributions and osx high sierra with no problems.

Did you say that removing the check resolves the issue for you? Everything works without it, correct?

If so, the easiest fix would be for me to just pitch those lines. Looks like it might be a bash bug in that specific version of bash you're using. I'm using 4.4.19(1)-release.

joma74 commented 6 years ago

Hm, happens also on an up-to-date Ubuntu 16.04, not the former vagrant VM, despite the same bash version and nearly same Ubuntu OS.

joma@edison:~$ uname -a
Linux edison 4.13.0-38-generic #43~16.04.1-Ubuntu SMP Wed Mar 14 17:48:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
joma@edison:~$ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
joma@edison:~$ . ~/.yarn-completion 
joma@edison:~$ bash
joma@edison:~$ . ~/.yarn-completion 
joma@edison:~$ yarn "counter" and "cmd" must be set by the caller and be the appropriate type
exit
joma74 commented 6 years ago

Could not find a definitive reference for this behaviour. Consider the following.

joma@edison:~$ declare testa
joma@edison:~$ declare -p testa
bash: declare: testa: not found
joma@edison:~$ declare testa=
joma@edison:~$ declare -p testa
declare -- testa=""
joma@edison:~$ echo $0
bash

Workaround in the script of yours was declare cmd=

dsifford commented 6 years ago

I've got no problem adding in the equal sign if that fixes your issue, but assuming you've now tested on different bash versions, I think you might have an issue somewhere in your bash init scripts that is screwing up how bash is supposed to fundamentally work.

According to the GNU Bash manual for the declare builtin, it states...

[...] If a variable name is followed by =value, the value of the variable is set to value.

Also, the interface of the command is defined as...

declare [-aAfFgilnrtux] [-p] [name[=value] …]

which means that =value is not required (including the equal sign).

Also, of note: This project has been used by hundreds of different people and this issue has never been reported by anybody else. So that leads me to believe that it's an issue localized to your machine only.


TL;DR: Sure, I'll totally add in the equal sign if that's all it takes for this to work for you, but I would definitely look into you init scripts to make sure something isn't written that is screwing up how declare is supposed to work.

joma74 commented 6 years ago

Gathering, just another indication from my heroku box. 4.3.48(1)-release eeeeverywheeeere I go :smirk:

joma@edison:~/entwicklung/nodews/onesrv$ heroku run bash
Running bash on ⬢ onesrv... up, run.3954 (Free)
~ $ uname -a
Linux 0246eb53-d945-47f6-95af-b24cfe9d23c5 4.4.0-1011-aws #11-Ubuntu SMP Fri Jan 12 23:24:17 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
~ $ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
~ $ declare testa
~ $ declare -p testa
bash: declare: testa: not found
~ $ declare testa=
~ $ declare -p testa
declare -- testa=""
joma74 commented 6 years ago

Gathering, just a first contraindication GNU bash, version 4.4.12(1)-release

~$ declare testa
~$ declare -p testa
declare -- testa
~$ bash --version
GNU bash, version 4.4.12(1)-release
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
joma74 commented 6 years ago

I have opened a question on stackoverflow.

dsifford commented 6 years ago

Looks like you may have uncovered a bug in bash 4.3.48.

Any chance you can update to 4.4.x on your affected machine to confirm?

dsifford commented 6 years ago

Looking over your comment thread on stackoverflow now and I think you hit the nail on the head with your comment..

Can this be related to the bash 4.4 relase, Entry "f. The `-p' option to declare and similar builtins will display attributes for named variables even when those variables have not been assigned values (which are technically unset)."?

I'll add in the equals sign since people on bash < 4.4 might run into this.

Nice detective work.

joma74 commented 6 years ago

Thank you @dsifford for your support;

Makeing the mentioned bash release http://ftp.gnu.org/gnu/bash/bash-4.4.tar.gz from source locally, the following result nailed it for me.

~$ echo $BASH_VERSION
4.4.0(1)-release
~$ declare testa
~$ declare -p testa
declare -- testa