├── .editorconfig ├── package.json ├── .github └── workflows │ └── main.yml ├── LICENSE ├── README.md ├── tests ├── test └── utils.sh └── yarn-completion.bash /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | indent_size = 4 6 | 7 | [package.json] 8 | indent_size = 2 9 | 10 | [*.yml] 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yarn-completion", 3 | "version": "0.17.0", 4 | "repository": "https://github.com/dsifford/yarn-completion.git", 5 | "description": "shell autocompletion for yarn", 6 | "author": "Derek P Sifford ", 7 | "license": "MIT" 8 | } 9 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: [push, pull_request] 3 | jobs: 4 | test: 5 | strategy: 6 | matrix: 7 | os: [ubuntu-latest, macOS-latest] 8 | runs-on: ${{ matrix.os }} 9 | steps: 10 | - uses: actions/checkout@v1 11 | - name: install yarn 12 | run: | 13 | curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version "$(awk '/# Yarn Version:/{ print $4 }' ./yarn-completion.bash)" 14 | - name: environment setup (linux) 15 | if: matrix.os == 'ubuntu-latest' 16 | run: | 17 | sudo ln -sf "$HOME/.yarn/bin/yarn" /usr/bin/yarn 18 | sudo apt-get update 19 | sudo apt-get install -y bash-completion 20 | - name: environment setup (macOS) 21 | if: matrix.os == 'macOS-latest' 22 | run: | 23 | brew install bash-completion@2 gnu-getopt 24 | - name: test 25 | run: PATH="/usr/local/opt/gnu-getopt/bin:$PATH" ./tests/test 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Derek Sifford 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # yarn-completion ![](https://github.com/dsifford/yarn-completion/workflows/build/badge.svg) 2 | 3 | > Bash ^4.x completion for [Yarn](https://github.com/yarnpkg/yarn) 4 | 5 | ## Installation 6 | 7 | To enable on-demand completion loading, download the completion file to the predefined bash-completion user directory. 8 | 9 | ```sh 10 | mkdir -p "${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions/" 11 | curl -o "${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions/yarn" \ 12 | https://raw.githubusercontent.com/dsifford/yarn-completion/master/yarn-completion.bash 13 | ``` 14 | 15 | ### Installation on macOS with Homebrew 16 | To use this script on macOS, we need to install [bash](https://www.gnu.org/software/bash/) and [bash-completion](https://github.com/scop/bash-completion) in addition to the above script. 17 | 18 | 1. `bash` version ^4.x.x is **required**. 19 | 20 | ```bash 21 | brew install bash 22 | 23 | # Add installed bash to /etc/shells 24 | sudo echo /usr/local/bin/bash >> /etc/shells 25 | # or 26 | echo /usr/local/bin/bash | sudo tee -a /etc/shells 27 | 28 | # Set installed bash as your default login shell 29 | chsh -s /usr/local/bin/bash 30 | ``` 31 | 32 | 2. Install `bash-completion@2` if you have not done it yet: 33 | 34 | ```bash 35 | brew install bash-completion@2 36 | ## + copy one line to ~/.bash_profile as instructed by brew after bash-completion setup 37 | ``` 38 | 39 | 3. Restart Terminal. 40 | 41 | ## FAQ 42 | 43 | > Will you support bash 3? 44 | 45 | **No**. Bash 3 is now 9 years outdated (at time of writing). There is no conceivable reason why anybody would or should still be using bash 3. Upgrade to the latest version of bash. 46 | 47 | ## License 48 | 49 | MIT 50 | -------------------------------------------------------------------------------- /tests/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC2119,SC2034 3 | 4 | TEST_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) 5 | COMPLETION_SRC="$TEST_DIR"/../yarn-completion.bash 6 | 7 | # shellcheck source=./utils.sh 8 | source "$TEST_DIR"/utils.sh 9 | 10 | declare -i FALURES=0 11 | 12 | describe 'Environment checks' 13 | { 14 | it should match yarn version line in src file 15 | t=$( 16 | declare actual expected 17 | actual=$(sed -n 's/# Yarn Version: \([^ ]*\)/\1/p' "$COMPLETION_SRC") 18 | expected=$(yarn --version) 19 | if [[ $actual != "${expected%-*}" ]]; then 20 | prepend ' | ' <<- EOF 21 | ERROR: mismatched yarn version line in src file. 22 | 23 | expected: ${expected%-*} 24 | received: $actual 25 | EOF 26 | exit 1 27 | fi 28 | exit 0 29 | ) 30 | passfail "$t" 31 | } 32 | 33 | describe 'Checking top-level commands' 34 | { 35 | it should have matching commands 36 | t=$( 37 | declare output 38 | output=$(LC_ALL=C comm -3 <(get_commands) <(get_completions yarn ' ')) 39 | if [[ -n $output ]]; then 40 | prepend ' | ' <<- EOF 41 | ERROR: mismatched top-level commands found 42 | 43 | $output 44 | EOF 45 | exit 1 46 | fi 47 | exit 0 48 | ) 49 | passfail "$t" 50 | 51 | it should have matching global options 52 | t=$( 53 | declare output 54 | output=$(LC_ALL=C comm -3 <(get_options -g) <(get_completions yarn -)) 55 | if [[ -n $output ]]; then 56 | prepend ' | ' <<- EOF 57 | ERROR: mismatched global command options found 58 | 59 | $output 60 | EOF 61 | exit 1 62 | fi 63 | exit 0 64 | ) 65 | passfail "$t" 66 | } 67 | 68 | describe 'Checking top-level command options' 69 | { 70 | while read -r cmd; do 71 | it "[$cmd]" should have matching options 72 | t=$( 73 | declare output 74 | output=$(LC_ALL=C comm -3 <(get_options -g "$cmd") <(get_completions yarn "$cmd" -)) 75 | if [[ ! -z $output ]]; then 76 | prepend ' | ' <<- EOF 77 | ERROR ($cmd): mismatched options found 78 | 79 | $output 80 | EOF 81 | exit 1 82 | fi 83 | exit 0 84 | ) 85 | passfail "$t" 86 | done < <(get_commands) 87 | } 88 | 89 | echo 90 | if ((FAILURES)); then 91 | echo There were "$FAILURES" failures. 92 | else 93 | echo All tests passed successfully. 94 | fi 95 | 96 | exit $FAILURES 97 | -------------------------------------------------------------------------------- /tests/utils.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC1003 3 | 4 | for src in \ 5 | "$TEST_DIR"/../yarn-completion.bash \ 6 | /usr/share/bash-completion/bash_completion \ 7 | /usr/local/share/bash-completion/bash_completion; do 8 | # shellcheck disable=SC1090 9 | [ -f "$src" ] && source "$src" 10 | done 11 | unset src 12 | 13 | ## 14 | # Retrieve a list of bash completions for a given COMMAND. 15 | # 16 | # Usage: 17 | # get_completions COMMAND... 18 | ## 19 | get_completions() { 20 | declare COMP_LINE=$* 21 | declare -i COMP_POINT=${#COMP_LINE} 22 | declare -a COMP_WORDS=("$@") 23 | declare -i COMP_CWORD=$((${#COMP_WORDS[@]} - 1)) 24 | declare -a COMPREPLY=() 25 | 26 | _yarn 2> /dev/null 27 | 28 | if [[ "${#COMPREPLY[@]}" -gt 0 ]]; then 29 | printf '%s\n' "${COMPREPLY[@]}" | LC_ALL=C sort -u 30 | fi 31 | } 32 | 33 | ## 34 | # Retrieve a sorted list of commands or subcommands. 35 | # 36 | # Usage: 37 | # get_commands [COMMAND...] 38 | # 39 | ## 40 | get_commands() { 41 | if [[ $# -gt 0 ]]; then 42 | yarn help "$@" | sed -n ' 43 | s/^.*Usage:.*\[\([a-z|-]*\)\].*\[flags\]/\1/p 44 | ' | tr '|' '\n' 45 | else 46 | yarn help | sed -n ' 47 | /Commands:/,/^[[:blank:]]*[^-]$/{ 48 | s/[[:blank:]]*- \([a-z-]*\).*/\1/p 49 | } 50 | ' | LC_ALL=C sort -u 51 | fi 52 | } 53 | 54 | ## 55 | # Retrieve a sorted list of options for a given COMMAND. 56 | # 57 | # Usage: 58 | # get_options [-g] COMMAND 59 | # get_options -g 60 | # 61 | # Options: 62 | # -g, --global Retrieve global options. 63 | ## 64 | get_options() { 65 | declare OPTS 66 | declare -i global=0 67 | declare global_options='' 68 | declare local_options='' 69 | 70 | if ! OPTS=$(getopt -o 'g' -l 'global' -n 'get_options' -- "$@"); then 71 | exit 1 72 | fi 73 | eval set -- "$OPTS" 74 | 75 | while true; do 76 | case "$1" in 77 | -g | --global) 78 | global=1 79 | shift 80 | ;; 81 | --) 82 | shift 83 | break 84 | ;; 85 | *) 86 | exit 1 87 | ;; 88 | esac 89 | done 90 | 91 | global_options=$( 92 | yarn help | sed -n \ 93 | -e '/Options:/,/Commands:/{ 94 | s/DEPRECATED// 95 | t end 96 | s/^[[:blank:]]*\(-[[:alpha:]]\), \(--[a-z-]*\).*/\1\'$'\n''\2/p 97 | s/^[[:blank:]]*\(--[a-z-]*\), \(--[a-z-]*\).*/\1\'$'\n''\2/p 98 | s/^[[:blank:]]*\(--[a-z-]*\).*/\1/p 99 | :end 100 | }' | LC_ALL=C sort -u 101 | ) 102 | 103 | if [[ ! -z $1 ]]; then 104 | local_options=$( 105 | LC_ALL=C comm -23 \ 106 | <( 107 | yarn help "$1" | sed -n '/Options:/,/Commands:/{ 108 | s/DEPRECATED// 109 | t end 110 | s/^[[:blank:]]*\(-[[:alpha:]]\), \(--[a-z-]*\).*/\1\'$'\n''\2/p 111 | s/^[[:blank:]]*\(--[a-z-]*\), \(--[a-z-]*\).*/\1\'$'\n''\2/p 112 | s/^[[:blank:]]*\(--[a-z-]*\).*/\1/p 113 | :end 114 | }' | LC_ALL=C sort -u 115 | ) \ 116 | <(echo "$global_options") 117 | ) 118 | fi 119 | 120 | { 121 | [ ! -z "$local_options" ] && echo "$local_options" 122 | ((global)) && echo "$global_options" 123 | } | LC_ALL=C sort -u 124 | } 125 | 126 | ### 127 | # HELPERS 128 | ## 129 | 130 | describe() { 131 | echo_fill --fill = '' 132 | echo "$@" 133 | echo_fill --fill = '' 134 | } 135 | 136 | it() { 137 | echo_fill -n --columns 64 " $*" 138 | } 139 | 140 | passfail() { 141 | # shellcheck disable=SC2181 142 | if [[ $? -gt 0 ]]; then 143 | echo FAILED 144 | echo "$@" 145 | ((FAILURES++)) 146 | else 147 | echo ....OK 148 | fi 149 | } 150 | 151 | prepend() { 152 | declare str="$1" 153 | cat | sed "s/^/$str/" 154 | } 155 | 156 | ## 157 | # Print a line of text with a trailing fill. 158 | # 159 | # Usage: 160 | # echo_fill [-n] [-f CHAR -l NUMBER] ... 161 | # 162 | # -n Do not print trailing newline 163 | # -c NUMBER, --columns=NUMBER Length of line [default: 70] 164 | # -f CHAR, --fill=CHAR Character used to fill remaining columns [default: .] 165 | # 166 | ## 167 | echo_fill() { 168 | declare OPTS= 169 | declare input= 170 | declare fill='.' 171 | declare -i columns=70 172 | declare -i newline=1 173 | 174 | if ! OPTS=$(getopt -o 'f:c:n' -l 'fill:,columns:' -n 'echo_fill' -- "$@"); then 175 | exit 1 176 | fi 177 | eval set -- "$OPTS" 178 | 179 | while true; do 180 | case "$1" in 181 | -f | --fill) 182 | fill="${2:0:1}" 183 | shift 2 184 | ;; 185 | -c | --columns) 186 | columns="$2" 187 | shift 2 188 | ;; 189 | -n) 190 | newline=0 191 | shift 192 | ;; 193 | --) 194 | shift 195 | break 196 | ;; 197 | *) 198 | exit 1 199 | ;; 200 | esac 201 | done 202 | input="$*" 203 | 204 | echo -n "$input" 205 | for ((i = ${#input}; i < columns; i++)); do 206 | echo -n "$fill" 207 | done 208 | ((newline)) && echo 209 | } 210 | -------------------------------------------------------------------------------- /yarn-completion.bash: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash disable=2207 2 | # vim: set fdm=syntax fdl=0: 3 | # 4 | # Version: 0.17.0 5 | # Yarn Version: 1.22.11 6 | # 7 | # bash completion for Yarn (https://github.com/yarnpkg/yarn) 8 | # 9 | # To enable on-demand completion loading, copy this file to one of the following locations: 10 | # - $BASH_COMPLETION_USER_DIR/completions/yarn 11 | # or 12 | # - $XDG_DATA_HOME/bash-completion/completions/yarn 13 | # or 14 | # - ~/.local/share/bash-completion/completions/yarn 15 | # 16 | 17 | ### 18 | # Parses and extracts data from package.json files. 19 | # 20 | # Usage: 21 | # __yarn_get_package_fields [-g] [-t FIELDTYPE] 22 | # 23 | # Options: 24 | # -g Parse global package.json file, if available 25 | # -t FIELDTYPE The field type being parsed (array|boolean|number|object|string) [default: object] 26 | # 27 | # Notes: 28 | # If FIELDTYPE is object, then the object keys are returned. 29 | # If FIELDTYPE is array, boolean, number, or string, then the field values are returned. 30 | # must be a first-level field in the json file. 31 | ## 32 | __yarn_get_package_fields() { 33 | declare cwd=$PWD field_type=object field_key opt package_dot_json OPTIND OPTARG 34 | 35 | while [[ -n $cwd ]]; do 36 | if [[ -f "$cwd/package.json" ]]; then 37 | package_dot_json="$cwd/package.json" 38 | break 39 | fi 40 | cwd="${cwd%/*}" 41 | done 42 | 43 | while getopts ":gt:" opt; do 44 | case $opt in 45 | g) 46 | if [[ -f $HOME/.config/yarn/global/package.json ]]; then 47 | package_dot_json="$HOME/.config/yarn/global/package.json" 48 | elif [[ -f $HOME/.local/share/yarn/global/package.json ]]; then 49 | package_dot_json="$HOME/.local/share/yarn/global/package.json" 50 | elif [[ -f $HOME/.yarn/global/package.json ]]; then 51 | package_dot_json="$HOME/.yarn/global/package.json" 52 | else 53 | package_dot_json="" 54 | fi 55 | ;; 56 | t) 57 | case "$OPTARG" in 58 | array | boolean | number | object | string) 59 | field_type="$OPTARG" 60 | ;; 61 | esac 62 | ;; 63 | *) ;; 64 | 65 | esac 66 | done 67 | shift $((OPTIND - 1)) 68 | 69 | field_key='"'$1'"' 70 | 71 | [[ ! -f $package_dot_json || ! $field_key ]] && return 72 | 73 | case "$field_type" in 74 | object) 75 | sed -n '/'"$field_key"':[[:space:]]*{/,/^[[:space:]]*}/{ 76 | # exclude start and end patterns 77 | //!{ 78 | # extract the text between the first pair of double quotes 79 | s/^[[:space:]]*"\([^"]*\).*/\1/p 80 | } 81 | }' "$package_dot_json" 82 | ;; 83 | array) 84 | sed -n '/'"$field_key"':[[:space:]]*\[/,/^[[:space:]]*]/{ 85 | # exclude start and end patterns 86 | //!{ 87 | # extract the text between the first pair of double quotes 88 | s/^[[:space:]]*"\([^"]*\).*/\1/p 89 | } 90 | }' "$package_dot_json" 91 | ;; 92 | boolean | number) 93 | sed -n 's/[[:space:]]*'"$field_key"':[[:space:]]*\([a-z0-9]*\)/\1/p' "$package_dot_json" 94 | ;; 95 | string) 96 | sed -n 's/[[:space:]]*'"$field_key"':[[:space:]]*"\(.*\)".*/\1/p' "$package_dot_json" 97 | ;; 98 | esac 99 | } 100 | 101 | ### 102 | # Count all command arguments starting at a given depth, excluding flags and 103 | # flag arguments. 104 | # 105 | # Usage: 106 | # __yarn_count_args [-d INT] 107 | # 108 | # Options: 109 | # -d INT The start depth to begin counting [default: 0] 110 | # 111 | # Globals: 112 | # *args 113 | # cword 114 | ## 115 | __yarn_count_args() { 116 | args=0 117 | declare -i counter=0 depth=0 118 | declare arg_flag_pattern opt OPTIND 119 | arg_flag_pattern="@($(tr ' ' '|' <<< "${arg_flags[*]}"))" 120 | 121 | while getopts ":d:" opt; do 122 | case $opt in 123 | d) 124 | depth=$OPTARG 125 | ;; 126 | *) ;; 127 | esac 128 | done 129 | shift $((OPTIND - 1)) 130 | 131 | while ((counter < cword)); do 132 | case ${words[counter]} in 133 | -* | =) ;; 134 | *) 135 | # shellcheck disable=SC2053 136 | if [[ ${words[counter - 1]} != $arg_flag_pattern ]]; then 137 | if ((depth-- <= 0)); then 138 | ((args++)) 139 | fi 140 | fi 141 | ;; 142 | esac 143 | ((counter++)) 144 | done 145 | } 146 | 147 | ### 148 | # Retrieves the command or subcommand at a given depth, or the last occurring 149 | # command or subcommand before the cursor location if no depth is given, or if 150 | # depth exceeds cursor location. 151 | # 152 | # Usage: 153 | # __yarn_get_command [-d INT] 154 | # 155 | # Options: 156 | # -d INT Depth of command to retrieve. 157 | # 158 | # Globals: 159 | # *cmd 160 | # commands 161 | # cword 162 | # subcommands 163 | # words 164 | ## 165 | __yarn_get_command() { 166 | declare -i counter=0 cmd_depth=0 OPTIND 167 | declare cmdlist word opt 168 | 169 | while getopts ":d:" opt; do 170 | case $opt in 171 | d) 172 | cmd_depth="$OPTARG" 173 | ;; 174 | *) ;; 175 | esac 176 | done 177 | shift $((OPTIND - 1)) 178 | 179 | cmdlist="@($(tr ' ' '|' <<< "${commands[*]} ${subcommands[*]}"))" 180 | cmd=yarn 181 | 182 | while ((counter < cword)); do 183 | word="${words[counter]}" 184 | case "$word" in 185 | $cmdlist) 186 | cmd="$word" 187 | ((--cmd_depth == 0)) && break 188 | ;; 189 | esac 190 | ((counter++)) 191 | done 192 | } 193 | 194 | ### 195 | # Global fallback completion generator if all else fails. 196 | # 197 | # Usage: 198 | # __yarn_fallback 199 | # 200 | # Globals: 201 | # cur 202 | ## 203 | __yarn_fallback() { 204 | case "$cur" in 205 | -*) 206 | COMPREPLY=($(compgen -W "$(__yarn_flags)" -- "$cur")) 207 | ;; 208 | *) 209 | COMPREPLY=($(compgen -o plusdirs -f -- "$cur")) 210 | ;; 211 | esac 212 | } 213 | 214 | ### 215 | # Process and merge local and global flags after removing the flags that 216 | # have already been used. 217 | # 218 | # Usage: 219 | # __yarn_flags 220 | # 221 | # Globals: 222 | # flags 223 | # global_flags 224 | # words 225 | ## 226 | __yarn_flags() { 227 | declare word 228 | declare -a existing_flags=() 229 | 230 | for word in "${words[@]}"; do 231 | case "$word" in 232 | -*) 233 | existing_flags+=("$word") 234 | ;; 235 | esac 236 | done 237 | 238 | LC_ALL=C comm -23 \ 239 | <(echo "${flags[@]}" "${global_flags[@]}" | tr ' ' '\n' | LC_ALL=C sort -u) \ 240 | <(echo "${existing_flags[@]}" | tr ' ' '\n' | LC_ALL=C sort -u) 241 | } 242 | 243 | ### 244 | # Handles completions for flags that require, or optionally take, arguments. 245 | # 246 | # Usage: 247 | # __yarn_flag_args 248 | # 249 | # Globals: 250 | # cur 251 | # prev 252 | ## 253 | __yarn_flag_args() { 254 | declare {arg,bool,dir,file,int,special}_flag_pattern 255 | arg_flag_pattern="@($(tr ' ' '|' <<< "${arg_flags[*]}"))" 256 | 257 | # shellcheck disable=SC2053 258 | if [[ $prev != $arg_flag_pattern ]]; then 259 | return 1 260 | fi 261 | 262 | bool_flag_pattern="@($(tr ' ' '|' <<< "${bool_arg_flags[*]}"))" 263 | dir_flag_pattern="@($(tr ' ' '|' <<< "${dir_arg_flags[*]}"))" 264 | file_flag_pattern="@($(tr ' ' '|' <<< "${file_arg_flags[*]}"))" 265 | int_flag_pattern="@($(tr ' ' '|' <<< "${int_arg_flags[*]}"))" 266 | special_flag_pattern="@($(tr ' ' '|' <<< "${special_arg_flags[*]}"))" 267 | 268 | case "$prev" in 269 | $bool_flag_pattern) 270 | COMPREPLY=($(compgen -W 'true false' -- "$cur")) 271 | ;; 272 | $dir_flag_pattern) 273 | compopt -o dirnames 274 | ;; 275 | $file_flag_pattern) 276 | compopt -o default -o filenames 277 | ;; 278 | $int_flag_pattern) 279 | compopt -o nospace 280 | COMPREPLY=($(compgen -W '{0..9}' -- "$cur")) 281 | ;; 282 | $special_flag_pattern) 283 | case "$prev" in 284 | --access) 285 | COMPREPLY=($(compgen -W 'public restricted' -- "$cur")) 286 | ;; 287 | --groups) 288 | COMPREPLY=($(compgen -W 'dependencies devDependencies optionalDependencies' -- "$cur")) 289 | ;; 290 | --level) 291 | COMPREPLY=($(compgen -W 'info low moderate high critical' -- "$cur")) 292 | ;; 293 | --network-timeout) 294 | compopt -o nospace 295 | COMPREPLY=($(compgen -W '{1000..10000..1000}' -- "$cur")) 296 | ;; 297 | esac 298 | ;; 299 | esac 300 | return 0 301 | } 302 | 303 | _yarn_add() { 304 | ((depth++)) 305 | flags=( 306 | --audit -A 307 | --dev -D 308 | --exact -E 309 | --optional -O 310 | --peer -P 311 | --tilde -T 312 | --ignore-workspace-root-check -W 313 | ) 314 | return 1 315 | } 316 | 317 | _yarn_audit() { 318 | ((depth++)) 319 | flags=( 320 | --groups 321 | --level 322 | --summary 323 | ) 324 | return 1 325 | } 326 | 327 | _yarn_autoclean() { 328 | ((depth++)) 329 | flags=( 330 | --force -F 331 | --init -I 332 | ) 333 | return 1 334 | } 335 | 336 | _yarn_cache() { 337 | ((depth++)) 338 | declare cmd 339 | flags=( 340 | --pattern 341 | ) 342 | subcommands=( 343 | clean 344 | dir 345 | list 346 | ) 347 | __yarn_get_command 348 | 349 | case "$cmd" in 350 | cache) 351 | case "$cur" in 352 | -*) 353 | return 1 354 | ;; 355 | *) 356 | COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) 357 | return 0 358 | ;; 359 | esac 360 | ;; 361 | *) 362 | return 1 363 | ;; 364 | esac 365 | } 366 | 367 | _yarn_check() { 368 | ((depth++)) 369 | flags=( 370 | --integrity 371 | --verify-tree 372 | ) 373 | return 1 374 | } 375 | 376 | _yarn_config() { 377 | ((depth++)) 378 | declare cmd 379 | declare subcommands=( 380 | delete 381 | get 382 | list 383 | set 384 | ) 385 | declare known_keys=( 386 | ignore-optional 387 | ignore-platform 388 | ignore-scripts 389 | init-author-email 390 | init-author-name 391 | init-author-url 392 | init-license 393 | init-version 394 | no-progress 395 | prefix 396 | registry 397 | save-prefix 398 | user-agent 399 | version-git-message 400 | version-git-sign 401 | version-git-tag 402 | version-tag-prefix 403 | ) 404 | __yarn_get_command 405 | 406 | case "$cmd" in 407 | get | delete) 408 | case "$cur" in 409 | -*) ;; 410 | *) 411 | if [[ $prev == @(get|delete) ]]; then 412 | COMPREPLY=($(compgen -W "${known_keys[*]}" -- "$cur")) 413 | return 0 414 | fi 415 | ;; 416 | esac 417 | ;; 418 | set) 419 | case "$cur" in 420 | -*) 421 | flags=( 422 | --global 423 | ) 424 | ;; 425 | *) 426 | if [[ $prev == set ]]; then 427 | COMPREPLY=($(compgen -W "${known_keys[*]}" -- "$cur")) 428 | return 0 429 | fi 430 | ;; 431 | esac 432 | ;; 433 | config) 434 | case "$cur" in 435 | -*) ;; 436 | *) 437 | COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) 438 | return 0 439 | ;; 440 | esac 441 | ;; 442 | esac 443 | return 1 444 | } 445 | 446 | _yarn_create() { 447 | ((depth++)) 448 | declare -i args 449 | case "$cur" in 450 | -*) ;; 451 | *) 452 | __yarn_count_args -d $depth 453 | ((args == 0)) && return 0 454 | ;; 455 | esac 456 | return 1 457 | } 458 | 459 | _yarn_generate_lock_entry() { 460 | ((depth++)) 461 | flags=( 462 | --resolved 463 | --use-manifest 464 | ) 465 | return 1 466 | } 467 | 468 | _yarn_global() { 469 | ((depth++)) 470 | declare cmd cmdlist 471 | flags=( 472 | --latest 473 | --prefix 474 | ) 475 | subcommands=( 476 | add 477 | bin 478 | list 479 | remove 480 | upgrade 481 | upgrade-interactive 482 | ) 483 | cmdlist="@($(tr ' ' '|' <<< "${subcommands[*]}"))" 484 | 485 | __yarn_get_command -d 3 486 | 487 | case "$cur" in 488 | -*) ;; 489 | *) 490 | case "$cmd" in 491 | $cmdlist) 492 | "_yarn_${cmd//-/_}" 2> /dev/null 493 | return $? 494 | ;; 495 | global) 496 | COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) 497 | return 0 498 | ;; 499 | esac 500 | ;; 501 | esac 502 | 503 | return 1 504 | } 505 | 506 | _yarn_help() { 507 | ((depth++)) 508 | declare -i args 509 | case "$cur" in 510 | -*) ;; 511 | *) 512 | __yarn_count_args -d $depth 513 | if ((args == 0)); then 514 | COMPREPLY=($(compgen -W "${commands[*]}" -- "$cur")) 515 | return 0 516 | fi 517 | ;; 518 | esac 519 | return 1 520 | } 521 | 522 | _yarn_info() { 523 | ((depth++)) 524 | flags=( 525 | --json 526 | ) 527 | declare standard_fields=( 528 | author 529 | bin 530 | bugs 531 | contributors 532 | dependencies 533 | description 534 | devDependencies 535 | dist-tags 536 | engines 537 | files 538 | homepage 539 | keywords 540 | license 541 | main 542 | maintainers 543 | name 544 | optionalDependencies 545 | peerDependencies 546 | repository 547 | version 548 | versions 549 | ) 550 | 551 | declare -i args 552 | __yarn_count_args -d $depth 553 | 554 | case "$cur" in 555 | -*) ;; 556 | *) 557 | case "$args" in 558 | 0) 559 | COMPREPLY=( 560 | $(compgen -W " 561 | $(__yarn_get_package_fields dependencies) 562 | $(__yarn_get_package_fields devDependencies) 563 | " -- "$cur") 564 | ) 565 | return 0 566 | ;; 567 | 1) 568 | COMPREPLY=($(compgen -W "${standard_fields[*]}" -- "$cur")) 569 | return 0 570 | ;; 571 | esac 572 | ;; 573 | esac 574 | return 1 575 | } 576 | 577 | _yarn_init() { 578 | ((depth++)) 579 | flags=( 580 | --yes -y 581 | --private -p 582 | --install -i 583 | ) 584 | return 1 585 | } 586 | 587 | _yarn_install() { 588 | ((depth++)) 589 | flags=( 590 | --audit -A 591 | ) 592 | return 1 593 | } 594 | 595 | _yarn_licenses() { 596 | ((depth++)) 597 | declare cmd 598 | subcommands=( 599 | list 600 | generate-disclaimer 601 | ) 602 | case "$cur" in 603 | -*) ;; 604 | *) 605 | __yarn_get_command 606 | case "$cmd" in 607 | licenses) 608 | COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) 609 | return 0 610 | ;; 611 | esac 612 | ;; 613 | esac 614 | return 1 615 | } 616 | 617 | _yarn_list() { 618 | ((depth++)) 619 | flags=( 620 | --depth 621 | --pattern 622 | ) 623 | return 1 624 | } 625 | 626 | _yarn_node() { 627 | ((depth++)) 628 | flags=( 629 | --into 630 | ) 631 | return 1 632 | } 633 | 634 | _yarn_outdated() { 635 | ((depth++)) 636 | case "$cur" in 637 | -*) ;; 638 | *) 639 | COMPREPLY=( 640 | $(compgen -W " 641 | $(__yarn_get_package_fields dependencies) 642 | $(__yarn_get_package_fields devDependencies) 643 | " -- "$cur") 644 | ) 645 | return 0 646 | ;; 647 | esac 648 | return 1 649 | } 650 | 651 | _yarn_owner() { 652 | ((depth++)) 653 | declare cmd 654 | subcommands=( 655 | add 656 | list 657 | remove 658 | ) 659 | __yarn_get_command 660 | if [[ $cmd == owner ]]; then 661 | case "$cur" in 662 | -*) ;; 663 | *) 664 | COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) 665 | return 0 666 | ;; 667 | esac 668 | fi 669 | return 1 670 | } 671 | 672 | _yarn_pack() { 673 | ((depth++)) 674 | flags=( 675 | --filename -f 676 | ) 677 | return 1 678 | } 679 | 680 | _yarn_policies() { 681 | ((depth++)) 682 | declare standard_policies=( 683 | latest 684 | nightly 685 | rc 686 | ) 687 | 688 | declare -i args 689 | __yarn_count_args -d $depth 690 | 691 | case "$cur" in 692 | -*) ;; 693 | *) 694 | case "$args" in 695 | 0) 696 | COMPREPLY=($(compgen -W "${standard_policies[*]}" -- "$cur")) 697 | return 0 698 | ;; 699 | esac 700 | ;; 701 | esac 702 | return 1 703 | } 704 | 705 | _yarn_publish() { 706 | ((depth++)) 707 | flags=( 708 | --access 709 | --major 710 | --message 711 | --minor 712 | --new-version 713 | --no-commit-hooks 714 | --no-git-tag-version 715 | --patch 716 | --preid 717 | --premajor 718 | --preminor 719 | --prepatch 720 | --prerelease 721 | --tag 722 | ) 723 | return 1 724 | } 725 | 726 | _yarn_remove() { 727 | ((depth++)) 728 | declare cmd dependencies devDependencies 729 | flags=( 730 | --ignore-workspace-root-check -W 731 | ) 732 | __yarn_get_command -d 1 733 | case "$cmd" in 734 | global) 735 | dependencies=$(__yarn_get_package_fields -g dependencies) 736 | devDependencies='' 737 | ;; 738 | remove) 739 | dependencies=$(__yarn_get_package_fields dependencies) 740 | devDependencies=$(__yarn_get_package_fields devDependencies) 741 | ;; 742 | *) 743 | return 1 744 | ;; 745 | esac 746 | case "$cur" in 747 | -*) ;; 748 | *) 749 | COMPREPLY=($(compgen -W "$dependencies $devDependencies" -- "$cur")) 750 | return 0 751 | ;; 752 | esac 753 | return 1 754 | } 755 | 756 | _yarn_run() { 757 | ((depth++)) 758 | declare cmd 759 | subcommands=( 760 | env 761 | $(__yarn_get_package_fields scripts) 762 | ) 763 | __yarn_get_command 764 | if [[ $cmd == run ]]; then 765 | case "$cur" in 766 | -*) ;; 767 | *) 768 | COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) 769 | return 0 770 | ;; 771 | esac 772 | fi 773 | return 1 774 | } 775 | 776 | _yarn_tag() { 777 | ((depth++)) 778 | declare cmd 779 | subcommands=( 780 | add 781 | list 782 | remove 783 | ) 784 | __yarn_get_command 785 | case "$cmd" in 786 | tag) 787 | case "$cur" in 788 | -*) ;; 789 | *) 790 | COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) 791 | return 0 792 | ;; 793 | esac 794 | ;; 795 | esac 796 | return 1 797 | } 798 | 799 | _yarn_team() { 800 | ((depth++)) 801 | declare cmd 802 | subcommands=( 803 | add 804 | create 805 | destroy 806 | list 807 | remove 808 | ) 809 | __yarn_get_command 810 | case "$cmd" in 811 | team) 812 | case "$cur" in 813 | -*) ;; 814 | *) 815 | COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) 816 | return 0 817 | ;; 818 | esac 819 | ;; 820 | esac 821 | return 1 822 | } 823 | 824 | _yarn_unplug() { 825 | ((depth++)) 826 | flags=( 827 | --clear 828 | --clear-all 829 | ) 830 | case "$cur" in 831 | -*) ;; 832 | *) 833 | COMPREPLY=( 834 | $(compgen -W " 835 | $(__yarn_get_package_fields dependencies) 836 | $(__yarn_get_package_fields devDependencies) 837 | " -- "$cur") 838 | ) 839 | return 0 840 | ;; 841 | 842 | esac 843 | return 1 844 | } 845 | 846 | _yarn_upgrade() { 847 | ((depth++)) 848 | declare cmd dependencies devDependencies 849 | flags=( 850 | --audit -A 851 | --caret -C 852 | --exact -E 853 | --latest -L 854 | --pattern -P 855 | --scope -S 856 | --tilde -T 857 | ) 858 | __yarn_get_command -d 1 859 | case "$cmd" in 860 | global) 861 | dependencies=$(__yarn_get_package_fields -g dependencies) 862 | devDependencies='' 863 | ;; 864 | upgrade) 865 | dependencies=$(__yarn_get_package_fields dependencies) 866 | devDependencies=$(__yarn_get_package_fields devDependencies) 867 | ;; 868 | *) 869 | return 1 870 | ;; 871 | esac 872 | case "$cur" in 873 | -*) ;; 874 | *) 875 | COMPREPLY=($(compgen -W "$dependencies $devDependencies" -- "$cur")) 876 | return 0 877 | ;; 878 | esac 879 | return 1 880 | } 881 | 882 | _yarn_upgrade_interactive() { 883 | ((depth++)) 884 | flags=( 885 | --caret -C 886 | --exact -E 887 | --latest 888 | --scope -S 889 | --tilde -T 890 | ) 891 | return 1 892 | } 893 | 894 | _yarn_version() { 895 | ((depth++)) 896 | flags=( 897 | --major 898 | --message 899 | --minor 900 | --new-version 901 | --no-commit-hooks 902 | --no-git-tag-version 903 | --patch 904 | --preid 905 | --premajor 906 | --preminor 907 | --prepatch 908 | --prerelease 909 | ) 910 | return 1 911 | } 912 | 913 | _yarn_workspace() { 914 | ((depth++)) 915 | declare -i args 916 | declare workspaces_info 917 | 918 | case "$cur" in 919 | -*) ;; 920 | *) 921 | __yarn_count_args 922 | case "$args" in 923 | [0-2]) 924 | workspaces_info=$(yarn workspaces info -s 2> /dev/null) 925 | if [[ -n $workspaces_info ]]; then 926 | mapfile -t < <( 927 | sed -n 's/^ \{2\}"\([^"]*\)": {$/\1/p' <<< "$workspaces_info" 928 | ) 929 | COMPREPLY=($(compgen -W "${MAPFILE[*]}" -- "$cur")) 930 | fi 931 | return 0 932 | ;; 933 | 3) 934 | COMPREPLY=($(compgen -W "${commands[*]}" -- "$cur")) 935 | return 0 936 | ;; 937 | *) 938 | declare cmd 939 | workspaces_info=$(yarn workspaces info -s 2> /dev/null) 940 | 941 | if [[ -n $workspaces_info ]]; then 942 | PWD=$( 943 | sed -n '/^ \{2\}"'"${COMP_WORDS[2]}"'": {$/,/^ \{2\}},\{0,1\}$/{ 944 | s/^ \{4\}"location": "\([^"]*\)",$/\1/p 945 | }' <<< "$workspaces_info" 946 | ) 947 | fi 948 | 949 | __yarn_get_command -d 3 950 | "_yarn_${cmd//-/_}" 2> /dev/null 951 | return $? 952 | ;; 953 | esac 954 | ;; 955 | esac 956 | return 1 957 | } 958 | 959 | _yarn_workspaces() { 960 | ((depth++)) 961 | declare cmd 962 | subcommands=( 963 | info 964 | run 965 | ) 966 | __yarn_get_command -d 4 967 | case "$cmd" in 968 | workspaces) 969 | case "$cur" in 970 | -*) ;; 971 | *) 972 | COMPREPLY=($(compgen -W "${subcommands[*]}" -- "$cur")) 973 | return 0 974 | ;; 975 | esac 976 | ;; 977 | info) 978 | return 0 979 | ;; 980 | run) 981 | __yarn_run 982 | return 0 983 | ;; 984 | esac 985 | return 1 986 | } 987 | 988 | _yarn_why() { 989 | ((depth++)) 990 | case "$cur" in 991 | -*) ;; 992 | ./*) 993 | compopt -o filenames 994 | ;; 995 | *) 996 | declare modules 997 | modules=$(yarn list --depth 0 | sed -n 's/.* \([a-zA-Z0-9@].*\)@.*/\1/p') || return 1 998 | COMPREPLY=($(compgen -W "$modules" -- "$cur")) 999 | return 0 1000 | ;; 1001 | esac 1002 | return 1 1003 | } 1004 | 1005 | _yarn_yarn() { 1006 | ((depth++)) 1007 | case "$cur" in 1008 | -*) ;; 1009 | *) 1010 | COMPREPLY=($(compgen -W "${commands[*]}" -- "$cur")) 1011 | return 0 1012 | ;; 1013 | esac 1014 | return 1 1015 | } 1016 | 1017 | _yarn() { 1018 | # shellcheck disable=SC2064 1019 | trap " 1020 | PWD=$PWD 1021 | $(shopt -p extglob) 1022 | set +o pipefail 1023 | " RETURN 1024 | 1025 | shopt -s extglob 1026 | set -o pipefail 1027 | 1028 | declare cur cmd prev 1029 | declare -a words 1030 | declare -i cword counter=1 depth=1 1031 | declare -ar commands=( 1032 | access 1033 | add 1034 | audit 1035 | autoclean 1036 | bin 1037 | cache 1038 | check 1039 | config 1040 | create 1041 | exec 1042 | generate-lock-entry 1043 | global 1044 | help 1045 | import 1046 | info 1047 | init 1048 | install 1049 | licenses 1050 | link 1051 | list 1052 | login 1053 | logout 1054 | node 1055 | outdated 1056 | owner 1057 | pack 1058 | policies 1059 | publish 1060 | remove 1061 | run 1062 | tag 1063 | team 1064 | unlink 1065 | unplug 1066 | upgrade 1067 | upgrade-interactive 1068 | version 1069 | versions 1070 | why 1071 | workspace 1072 | workspaces 1073 | $(__yarn_get_package_fields scripts) 1074 | ) 1075 | declare -a subcommands=() 1076 | 1077 | declare -ar bool_arg_flags=( 1078 | --emoji 1079 | --production --prod 1080 | --scripts-prepend-node-path 1081 | ) 1082 | declare -ar dir_arg_flags=( 1083 | --cache-folder 1084 | --cwd 1085 | --global-folder 1086 | --into 1087 | --link-folder 1088 | --modules-folder 1089 | --preferred-cache-folder 1090 | --prefix 1091 | ) 1092 | declare -ar file_arg_flags=( 1093 | --filename -f 1094 | --use-manifest 1095 | --use-yarnrc 1096 | ) 1097 | declare -ar int_arg_flags=( 1098 | --depth 1099 | --network-concurrency 1100 | ) 1101 | declare -ar special_arg_flags=( 1102 | --access 1103 | --groups 1104 | --level 1105 | --network-timeout 1106 | ) 1107 | declare -ar optional_arg_flags=( 1108 | --emoji 1109 | --prod 1110 | --production 1111 | --scripts-prepend-node-path 1112 | ) 1113 | declare -ar skipped_arg_flags=( 1114 | --https-proxy 1115 | --message 1116 | --mutex 1117 | --new-version 1118 | --otp 1119 | --pattern -P 1120 | --proxy 1121 | --registry 1122 | --resolved 1123 | --scope -S 1124 | --tag 1125 | ) 1126 | declare -ar arg_flags=( 1127 | "${bool_arg_flags[@]}" 1128 | "${dir_arg_flags[@]}" 1129 | "${file_arg_flags[@]}" 1130 | "${int_arg_flags[@]}" 1131 | "${special_arg_flags[@]}" 1132 | "${optional_arg_flags[@]}" 1133 | "${skipped_arg_flags[@]}" 1134 | ) 1135 | 1136 | declare -ar global_flags=( 1137 | --cache-folder 1138 | --check-files 1139 | --cwd 1140 | --disable-pnp 1141 | --emoji 1142 | --enable-pnp --pnp 1143 | --flat 1144 | --focus 1145 | --force 1146 | --frozen-lockfile 1147 | --global-folder 1148 | --har 1149 | --help -h 1150 | --https-proxy 1151 | --ignore-engines 1152 | --ignore-optional 1153 | --ignore-platform 1154 | --ignore-scripts 1155 | --json 1156 | --link-duplicates 1157 | --link-folder 1158 | --modules-folder 1159 | --mutex 1160 | --network-concurrency 1161 | --network-timeout 1162 | --no-bin-links 1163 | --no-default-rc 1164 | --no-lockfile 1165 | --non-interactive 1166 | --no-node-version-check 1167 | --no-progress 1168 | --offline 1169 | --otp 1170 | --prefer-offline 1171 | --preferred-cache-folder 1172 | --prod 1173 | --production 1174 | --proxy 1175 | --pure-lockfile 1176 | --registry 1177 | --scripts-prepend-node-path 1178 | --silent -s 1179 | --skip-integrity-check 1180 | --strict-semver 1181 | --update-checksums 1182 | --use-yarnrc 1183 | --verbose 1184 | --version -v 1185 | ) 1186 | declare -a flags=() 1187 | 1188 | COMPREPLY=() 1189 | if command -v _get_comp_words_by_ref > /dev/null; then 1190 | _get_comp_words_by_ref -n = -n @ -n : cur prev words cword 1191 | elif command -v _init_completion > /dev/null; then 1192 | _init_completion 1193 | fi 1194 | 1195 | __yarn_get_command -d 1 1196 | 1197 | __yarn_flag_args || "_yarn_${cmd//-/_}" 2> /dev/null || __yarn_fallback 1198 | 1199 | if command -v __ltrim_colon_completions > /dev/null; then 1200 | __ltrim_colon_completions "$cur" 1201 | fi 1202 | } 1203 | 1204 | if [[ ${BASH_VERSINFO[0]} -ge 4 && ${BASH_VERSINFO[1]} -ge 4 ]]; then 1205 | complete -o nosort -F _yarn yarn 1206 | else 1207 | complete -F _yarn yarn 1208 | fi 1209 | --------------------------------------------------------------------------------