#compdef task typeset -A opt_args TASK_CMD="${TASK_EXE:-task}" compdef _task "$TASK_CMD" _GO_TASK_COMPLETION_LIST_OPTION="${GO_TASK_COMPLETION_LIST_OPTION:---list-all}" # Check if an experiment is enabled function __task_is_experiment_enabled() { local experiment=$1 task --experiments 2>/dev/null | grep -q "^\* ${experiment}:.*on" } # Listing commands from Taskfile.yml function __task_list() { local -a scripts cmd local -i enabled=0 local taskfile item task desc cmd=($TASK_CMD) taskfile=${(Qv)opt_args[(i)-t|--taskfile]} taskfile=${taskfile//\~/$HOME} for arg in "${words[@]:0:$CURRENT}"; do if [[ "$arg" = "--" ]]; then # Use default completion for words after `--` as they are CLI_ARGS. _default return 0 fi done if [[ -n "$taskfile" && -f "$taskfile" ]]; then cmd+=(--taskfile "$taskfile") fi if output=$("${cmd[@]}" $_GO_TASK_COMPLETION_LIST_OPTION 2>/dev/null); then enabled=1 fi (( enabled )) || return 0 scripts=() for item in "${(@)${(f)output}[2,-1]#\* }"; do task="${item%%:[[:space:]]*}" desc="${item##[^[:space:]]##[[:space:]]##}" scripts+=( "${task//:/\\:}:$desc" ) done _describe 'Task to run' scripts } _task() { local -a standard_args operation_args standard_args=( '(-C --concurrency)'{-C,--concurrency}'[limit number of concurrent tasks]: ' '(-p --parallel)'{-p,--parallel}'[run command-line tasks in parallel]' '(-F --failfast)'{-F,--failfast}'[when running tasks in parallel, stop all tasks if one fails]' '(-f --force)'{-f,--force}'[run even if task is up-to-date]' '(-c --color)'{-c,--color}'[colored output]' '(--completion)--completion[generate shell completion script]:shell:(bash zsh fish powershell)' '(-d --dir)'{-d,--dir}'[dir to run in]:execution dir:_dirs' '(--disable-fuzzy)--disable-fuzzy[disable fuzzy matching for task names]' '(-n --dry)'{-n,--dry}'[compiles and prints tasks without executing]' '(--dry)--dry[dry-run mode, compile and print tasks only]' '(-x --exit-code)'{-x,--exit-code}'[pass-through exit code of task command]' '(--experiments)--experiments[list available experiments]' '(-g --global)'{-g,--global}'[run global Taskfile from home directory]' '(--insecure)--insecure[allow insecure Taskfile downloads]' '(-I --interval)'{-I,--interval}'[interval to watch for changes]:duration: ' '(-j --json)'{-j,--json}'[format task list as JSON]' '(--nested)--nested[nest namespaces when listing as JSON]' '(--no-status)--no-status[ignore status when listing as JSON]' '(-o --output)'{-o,--output}'[set output style]:style:(interleaved group prefixed)' '(--output-group-begin)--output-group-begin[message template before grouped output]:template text: ' '(--output-group-end)--output-group-end[message template after grouped output]:template text: ' '(--output-group-error-only)--output-group-error-only[hide output from successful tasks]' '(-s --silent)'{-s,--silent}'[disable echoing]' '(--sort)--sort[set task sorting order]:order:(default alphanumeric none)' '(--status)--status[exit non-zero if supplied tasks not up-to-date]' '(--summary)--summary[show summary\: field from tasks instead of running them]' '(-t --taskfile)'{-t,--taskfile}'[specify a different taskfile]:taskfile:_files' '(-v --verbose)'{-v,--verbose}'[verbose mode]' '(-w --watch)'{-w,--watch}'[watch-mode for given tasks, re-run when inputs change]' '(-y --yes)'{-y,--yes}'[assume yes to all prompts]' ) # Experimental flags (dynamically added based on enabled experiments) # Options (modify behavior) if __task_is_experiment_enabled "GENTLE_FORCE"; then standard_args+=('(--force-all)--force-all[force execution of task and all dependencies]') fi if __task_is_experiment_enabled "REMOTE_TASKFILES"; then standard_args+=( '(--offline --download)--offline[use only local or cached Taskfiles]' '(--timeout)--timeout[timeout for remote Taskfile downloads]:duration: ' '(--expiry)--expiry[cache expiry duration]:duration: ' ) fi operation_args=( # Task names completion (can be specified multiple times) '(operation)*: :__task_list' # Operational args completion (mutually exclusive) + '(operation)' '(*)'{-l,--list}'[list describable tasks]' '(*)'{-a,--list-all}'[list all tasks]' '(*)'{-i,--init}'[create new Taskfile.yml]' '(- *)'{-h,--help}'[show help]' '(- *)--version[show version and exit]' ) # Experimental operations (dynamically added based on enabled experiments) if __task_is_experiment_enabled "REMOTE_TASKFILES"; then standard_args+=( '(--offline --clear-cache)--download[download remote Taskfile]' ) operation_args+=( '(* --download)--clear-cache[clear remote Taskfile cache]' ) fi _arguments -S $standard_args $operation_args } # don't run the completion function when being source-ed or eval-ed if [ "$funcstack[1]" = "_task" ]; then _task "$@" fi