|  | #compdef fx | 
|  |  | 
|  | __fx_nodename() { | 
|  | # TODO: allow configuration of node names with zstyle | 
|  | local -a nodenames=( $(${fuchsia_dir}/${fuchsia_build_dir}.zircon/tools/netls | awk '/device/ { print $2; }') ) | 
|  | _describe 'nodename' nodenames | 
|  | } | 
|  |  | 
|  | __fx_amber_package() { | 
|  | # packages are directories in the build dir under amber-files/repository/targets | 
|  | _values $(cd ${fuchsia_dir}/${fuchsia_build_dir}/amber-files/repository/targets >/dev/null 2>&1 && echo *(/)) | 
|  | } | 
|  |  | 
|  | __fx_build_dir() { | 
|  | # build dirs are directories under out/ with an args.gn | 
|  | compadd $(cd ${fuchsia_dir} >/dev/null 2>&1; echo out/^*.zircon/args.gn(N:h)) | 
|  | } | 
|  |  | 
|  | __fx_gn_target() { | 
|  | # use a cache of "gn ls" that's updated when build.ninja changes. | 
|  | local -r absolute_build_dir="${fuchsia_dir}/${fuchsia_build_dir}" | 
|  | local -r targets_file="${absolute_build_dir}/.gn_ls" | 
|  | local -r ninja_file="${absolute_build_dir}/build.ninja" | 
|  | if [ ! -e "${targets_file}" -o ${ninja_file} -nt ${targets_file} ]; then | 
|  | local -r tmp_targets_file="$(mktemp -p "${absolute_build_dir}")" | 
|  | "${fuchsia_dir}/prebuilt/third_party/gn/${prebuilt_os}/gn" ls "${absolute_build_dir}" > "${tmp_targets_file}" | 
|  | mv "${tmp_targets_file}" "${targets_file}" | 
|  | fi | 
|  | _values $(cat ${absolute_build_dir}/.gn_ls) | 
|  | } | 
|  |  | 
|  | _fx() { | 
|  | typeset -A opt_args | 
|  |  | 
|  | local fuchsia_dir="${FUCHSIA_DIR}" | 
|  | if [[ -z "${fuchsia_dir}" ]]; then | 
|  | fuchsia_dir="$(pwd)" | 
|  | while [[ ! -d "${fuchsia_dir}/.jiri_root" ]]; do | 
|  | fuchsia_dir="$(dirname "${fuchsia_dir}")" | 
|  | if [[ "${fuchsia_dir}" == "/" ]]; then | 
|  | _message -r "Cannot find Platform Source Tree containing $(pwd)" | 
|  | return | 
|  | fi | 
|  | done | 
|  | fi | 
|  |  | 
|  | # list of commands based on //tools/devshell/ | 
|  | # each file is read to find the description line (starts with "### "). | 
|  | local -a commands lines | 
|  | local -a command_dirs=( | 
|  | "${fuchsia_dir}/tools/devshell" | 
|  | "${fuchsia_dir}/tools/devshell/contrib" | 
|  | ${fuchsia_dir}/vendor/*/scripts/devshell(/N) | 
|  | ) | 
|  | local desc command dir | 
|  | for dir in ${command_dirs[*]}; do | 
|  | for command in ${dir}/*(*); do | 
|  | lines=("${(f)$(<${command})}") | 
|  | desc=${${lines[${lines[(i)\#\#\# *]}]}#????} | 
|  | commands+=("${command#*${dir}/}:${desc}") | 
|  | done | 
|  | done | 
|  | commands+=("gn:invoke the gn command") | 
|  | commands+=("ninja:invoke the ninja command") | 
|  |  | 
|  | _arguments \ | 
|  | "--dir[build directory]:directory:__fx_build_dir" \ | 
|  | "-d[target device]:device:__fx_nodename" \ | 
|  | "-i[iterative mode]" \ | 
|  | "-x[print commands]" \ | 
|  | "1: :{_describe 'command' commands}" \ | 
|  | "*:: :->args" | 
|  |  | 
|  | if [[ $state != "args" ]]; then | 
|  | return | 
|  | fi | 
|  |  | 
|  | # get the config file location from --dir or ${fuchsia_dir}/.fx-build-dir | 
|  | typeset -l fuchsia_build_dir="${opt_args[--dir]}" | 
|  | if [[ -z "$fuchsia_build_dir" && -f "${fuchsia_dir}/.fx-build-dir" ]]; then | 
|  | fuchsia_build_dir="$(<"${fuchsia_dir}/.fx-build-dir")" | 
|  | fi | 
|  |  | 
|  | # the host os id for prebuilts | 
|  | case "$(uname -s)" in | 
|  | Linux) | 
|  | local prebuilt_os=linux-x64 | 
|  | ;; | 
|  | Darwin) | 
|  | local prebuilt_os=mac-x64 | 
|  | ;; | 
|  | *) | 
|  | # Unknown OS, don't complete | 
|  | exit | 
|  | ;; | 
|  | esac | 
|  |  | 
|  | # look for a completion function | 
|  | local f | 
|  | f=_fx_$words[1] | 
|  | if [[ -e ${fuchsia_dir}/scripts/zsh-completion/$f ]]; then | 
|  | autoload $f; $f | 
|  | else | 
|  | _normal | 
|  | fi | 
|  | } | 
|  |  | 
|  | _fx |