1#compdef west 2 3# Copyright (c) 2022 Nordic Semiconductor ASA 4# SPDX-License-Identifier: Apache-2.0 5 6# Ensure this works also when being source-ed 7compdef _west west 8 9typeset -A -g _opt_args 10 11_west_cmds() { 12 local -a builtin_cmds=( 13 'init[create a west workspace]' 14 'update[update projects described in west manifest]' 15 'list[print information about projects]' 16 'manifest[manage the west manifest]' 17 'diff["git diff" for one or more projects]' 18 'status["git status" for one or more projects]' 19 'forall[run a command in one or more local projects]' 20 'config[get or set config file values]' 21 'topdir[print the top level directory of the workspace]' 22 'help[get help for west or a command]' 23 ) 24 25 local -a zephyr_ext_cmds=( 26 'completion[display shell completion scripts]' 27 'boards[display information about supported boards]' 28 'build[compile a Zephyr application]' 29 'sign[sign a Zephyr binary for bootloader chain-loading]' 30 'flash[flash and run a binary on a board]' 31 'debug[flash and interactively debug a Zephyr application]' 32 'debugserver[connect to board and launch a debug server]' 33 'attach[interactively debug a board]' 34 'zephyr-export[export Zephyr installation as a CMake config package]' 35 'spdx[create SPDX bill of materials]' 36 'blobs[work with binary blobs]' 37 'sdk[manage SDKs]' 38 ) 39 40 local -a all_cmds=(${builtin_cmds} ${zephyr_ext_cmds}) 41 42 if [[ -v WEST_COMP_CHECK_WORKSPACE ]]; then 43 west topdir &>/dev/null 44 if [ $? -eq 0 ]; then 45 _values "west command" $all_cmds 46 else 47 _values "west command" $builtin_cmds 48 fi 49 else 50 _values "west command" $all_cmds 51 fi 52} 53 54# Completion script for Zephyr's meta-tool, west 55_west() { 56 57 58 # Global options for all commands 59 local -a global_opts=( 60 # (: * -) as exclusion list means exclude everything else 61 '(: * -)'{-h,--help}'[show help]' 62 # An exclusion list with the very option means only allow once 63 {-v,--verbose}'[enable verbosity]' 64 '(: * -)'{-V,--version}'[print version]' 65 '(-z --zephyr-base)'{-z,--zephyr-base}'[zephyr base folder]:zephyr base folder:_directories' 66 ) 67 68 typeset -A opt_args 69 local curcontext="$curcontext" context state state_descr line 70 local -a orig_words 71 72 orig_words=( ${words[@]} ) 73 74 _arguments -S -C \ 75 $global_opts \ 76 "1: :->cmds" \ 77 "*::arg:->args" \ 78 79 case "$state" in 80 cmds) 81 _west_cmds 82 ;; 83 84 args) 85 _opt_args=( ${(@kv)opt_args} ) 86 _call_function ret _west_$line[1] 87 ;; 88 esac 89} 90 91__west_x() 92{ 93 west 2>/dev/null "$@" 94} 95 96_get_west_projs() { 97 local extra_args 98 [[ -v _opt_args[-z] ]] && extra_args="-z $_opt_args[-z]" 99 [[ -v _opt_args[--zephyr-base] ]] && extra_args="-z $_opt_args[--zephyr-base]" 100 101 _west_projs=($(__west_x $extra_args list --format={name})) 102 _describe 'projs' _west_projs 103} 104 105_get_west_boards() { 106 _west_boards=( $(__west_x boards --format='{name}|{qualifiers}') ) 107 for i in {1..${#_west_boards[@]}}; do 108 local name="${_west_boards[$i]%%|*}" 109 local transformed_board="${_west_boards[$i]//|//}" 110 _west_boards[$i]="${transformed_board//,/ ${name}/}" 111 done 112 _west_boards=(${(@s/ /)_west_boards}) 113 114 _describe 'boards' _west_boards 115} 116 117_west_init() { 118 local -a opts=( 119 '(-l --local)'{--mr,--manifest-rev}'[manifest revision]:manifest rev:' 120 {--mf,--manifest-file}'[manifest file]:manifest file:' 121 '(-l --local)'{-m,--manifest}'[manifest URL]:manifest URL:_directories' 122 '(-m --manifest --mr --manifest-rev)'{-l,--local}'[use local directory as manifest repository]:local manifest repository directory:_directories' 123 ) 124 125 _arguments -S $opts \ 126 "1:workspace directory:" 127} 128 129_west_update() { 130 local -a opts=( 131 '--stats[print performance stats]' 132 '--name-cache[name-based cache]:name cache folder:_directories' 133 '--path-cache[path-based cache]:path cache folder:_directories' 134 {-f,--fetch}'[fetch strategy]:fetch strategy:(always smart)' 135 {-o,--fetch-opt}'[fetch options]:fetch options:' 136 {-n,--narrow}'[narrow fetch]' 137 {-k,--keep-descendants}'[keep manifest-rev descendants checked out]' 138 {-r,--rebase}'[rebase checked out branch onto the new manifest-rev]' 139 ) 140 141 _arguments -S $opts \ 142 "1:west proj:_get_west_projs" 143} 144 145_west_list() { 146 local -a opts=( 147 {-a,--all}'[include inactive projects]' 148 '--manifest-path-from-yaml[print performance stats]' 149 {-f,--format}'[format string]:format string:' 150 ) 151 152 _arguments -S $opts \ 153 "1:west proj:_get_west_projs" 154} 155 156_west_manifest() { 157 local -a opts=( 158 '--resolve[resolve into single manifest]' 159 '--freeze[resolve into single manifest, with SHAs]' 160 '--validate[silently validate manifest]' 161 '--path[print the path to the top level manifest file]' 162 {-o,--out}'[output file]:output file:_files' 163 ) 164 165 _arguments -S $opts 166} 167 168_west_diff() { 169 local -a opts=( 170 {-a,--all}'[include inactive projects]' 171 ) 172 173 _arguments -S $opts \ 174 "1:west proj:_get_west_projs" 175} 176 177_west_status() { 178 local -a opts=( 179 {-a,--all}'[include inactive projects]' 180 ) 181 182 _arguments -S $opts \ 183 "1:west proj:_get_west_projs" 184} 185 186_west_forall() { 187 local -a opts=( 188 '-c[command to execute]:command:' 189 {-a,--all}'[include inactive projects]' 190 ) 191 192 _arguments -S $opts \ 193 "1:west proj:_get_west_projs" 194} 195 196_west_config() { 197 local -a opts=( 198 {-l,--list}'[list all options and values]' 199 {-d,--delete}'[delete an option in one config file]' 200 {-D,--delete-all}"[delete an option everywhere it\'s set]" 201 + '(mutex)' 202 '--system[system-wide file]' 203 '--global[global user-wide file]' 204 "--local[this workspace\'s file]" 205 ) 206 207 _arguments -S $opts 208} 209 210_west_help() { 211 _west_cmds 212} 213 214_west_completion() { 215 216 _arguments -S "1:shell:(bash zsh fish)" 217} 218 219_west_boards() { 220 local -a opts=( 221 {-f,--format}'[format string]:format string:' 222 {-n,--name}'[name regex]:regex:' 223 '*--arch-root[Add an arch root]:arch root:_directories' 224 '*--board-root[Add a board root]:board root:_directories' 225 '*--soc-root[Add a soc root]:soc root:_directories' 226 ) 227 228 _arguments -S $opts 229} 230 231_west_build() { 232 local -a opts=( 233 '(-b --board)'{-b,--board}'[board to build for]:board:_get_west_boards' 234 '(-d --build-dir)'{-d,--build-dir}'[build directory to create or use]:build dir:_directories' 235 '(-f --force)'{-f,--force}'[ignore errors and continue]' 236 '--sysbuild[create multi-domain build system]' 237 '--no-sysbuild[do not create multi-domain build system]' 238 '(-c --cmake)'{-c,--cmake}'[force a cmake run]' 239 '--cmake-only[just run cmake]' 240 '--domain[execute build tool (make or ninja) for a given domain]:domain:' 241 '(-t --target)'{-t,--target}'[run build system target]:target:' 242 '(-T --test-item)'{-T,--test-item}'[Build based on test data in .yml]:test item:' 243 {-o,--build-opt}'[options to pass to build tool (make or ninja)]:tool opt:' 244 '(-n --just-print --dry-run --recon)'{-n,--just-print,--dry-run,--recon}"[just print build commands, don't run them]" 245 '(-p --pristine)'{-p,--pristine}'[pristine build setting]:pristine:(auto always never)' 246 ) 247 _arguments -S $opts \ 248 "1:source_dir:_directories" 249} 250 251_west_sign() { 252 local -a opts=( 253 '(-d --build-dir)'{-d,--build-dir}'[build directory to create or use]:build dir:_directories' 254 '(-q --quiet)'{-q,--quiet}'[suppress non-error output]' 255 '(-f --force)'{-f,--force}'[ignore errors and continue]' 256 '(-t --tool)'{-t,--tool}'[image signing tool name]:tool:(imgtool rimage)' 257 '(-p --tool-path)'{-p,--tool-path}'[path to the tool]:tool path:_directories' 258 '(-D --tool-data)'{-D,--tool-data}'[path to tool data]:tool data path:_directories' 259 '(--no-bin)--bin[produce a signed bin file]' 260 '(--bin)--no-bin[do not produce a signed bin file]' 261 '(-B --sbin)'{-B,--sbin}'[signed .bin filename]:bin filename:_files' 262 '(--no-hex)--hex[produce a signed hex file]' 263 '(--hex)--no-hex[do not produce a signed hex file]' 264 '(-H --shex)'{-H,--shex}'[signed .hex filename]:hex filename:_files' 265 ) 266 267 _arguments -S $opts 268} 269 270typeset -a -g _west_runner_opts=( 271 '(-H --context)'{-H,--context}'[print runner-specific options]' 272 '--board-dir[board directory]:board dir:_directories' 273 '(-f --file)'{-f,--file}'[path to binary]:path to binary:_files' 274 '(-t --file-type)'{-t,--file-type}'[type of binary]:type of binary:(hex bin elf)' 275 '--elf-file[path to zephyr.elf]:path to zephyr.elf:_files' 276 '--hex-file[path to zephyr.hex]:path to zephyr.hex:_files' 277 '--bin-file[path to zephyr.bin]:path to zephyr.bin:_files' 278 '--gdb[path to GDB]:path to GDB:_files' 279 '--openocd[path to openocd]:path to openocd:_files' 280 '--openocd-search[path to add to openocd search path]:openocd search:_directories' 281) 282 283_west_flash() { 284 local -a opts=( 285 '(-d --build-dir)'{-d,--build-dir}'[build directory to create or use]:build dir:_directories' 286 '(-r --runner)'{-r,--runner}'[override default runner from build-dir]:runner:' 287 '--skip-rebuild[do not refresh cmake dependencies first]' 288 '--domain[execute build tool (make or ninja) for a given domain]:domain:' 289 ) 290 291 local -a all_opts=(${_west_runner_opts} ${opts}) 292 _arguments -S $all_opts 293} 294 295_west_debug() { 296 _west_flash 297} 298 299_west_debugserver() { 300 _west_flash 301} 302 303_west_attach() { 304 _west_flash 305} 306 307_west_spdx() { 308 local -a opts=( 309 '(-i --init)'{-i,--init}'[initialize CMake file-based API]' 310 '(-d --build-dir)'{-d,--build-dir}'[build directory to create or use]:build dir:_directories' 311 '(-n --namespace-prefix)'{-n,--namespace-prefix}'[namespace prefix]:namespace prefix:' 312 '(-s --spdx-dir)'{-s,--spdx-dir}'[SPDX output directory]:spdx output dir:_directories' 313 '--analyze-includes[also analyze included header files]' 314 '--include-sdk[also generate SPDX document for SDK]' 315 ) 316 _arguments -S $opts 317} 318 319_west_blobs() { 320 local -a blob_cmds=( 321 'list[list binary blobs]' 322 'fetch[fetch binary blobs]' 323 'clean[clean working tree of binary blobs]' 324 ) 325 326 local line state 327 328 _arguments -S -C \ 329 "1: :->cmds" \ 330 "*::arg:->args" \ 331 332 case "$state" in 333 cmds) 334 _values "west blob cmds" $blob_cmds 335 ;; 336 337 args) 338 _opt_args=( ${(@kv)opt_args} ) 339 _call_function ret _west_blob_$line[1] 340 ;; 341 esac 342} 343 344_west_blob_list () { 345 local -a opts=( 346 {-f,--format}'[format string]:format string:' 347 ) 348 349 _arguments -S $opts \ 350 "1:west proj:_get_west_projs" 351} 352 353_west_blob_fetch () { 354 _arguments -S "1:west proj:_get_west_projs" 355} 356 357_west_blob_clean () { 358 _arguments -S "1:west proj:_get_west_projs" 359} 360 361# don't run the completion function when being source-ed or eval-ed 362if [ "$funcstack[1]" = "_west" ]; then 363 _west 364fi 365