diff options
author | dana <dana@dana.is> | 2017-07-25 21:14:26 -0500 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2017-07-26 09:30:14 -0400 |
commit | 9283dd122ede03f9e6a8ba77ecf8a33088fe3502 (patch) | |
tree | c795d574a684a1e0b0e5a5e4e3894ab49b78f0d9 /ci | |
parent | 4c41e9225b8326988575b34e72d5d7e92518a65d (diff) |
Update test_complete to source completion function for more reliable options parsing
Diffstat (limited to 'ci')
-rwxr-xr-x | ci/test_complete.sh | 161 |
1 files changed, 82 insertions, 79 deletions
diff --git a/ci/test_complete.sh b/ci/test_complete.sh index 9b7f91fe..100c0859 100755 --- a/ci/test_complete.sh +++ b/ci/test_complete.sh @@ -1,91 +1,94 @@ -#!/bin/sh +#!/usr/bin/env zsh ## # Compares options in `rg --help` output to options in zsh completion function -# -# @todo If we could rely on zsh being installed we could change all of this to -# simply source the completion-function file and pull the rg_args array out... -set -e +emulate -R zsh +setopt extended_glob +setopt no_function_argzero +setopt no_unset + +get_comp_args() { + setopt local_options unset + + # Our completion function recognises a special variable which tells it to + # dump the _arguments specs and then just return. But do this in a sub-shell + # anyway to avoid any weirdness + ( _RG_COMPLETE_LIST_ARGS=1 source $1 ) + return $? +} main() { - local rg="target/${TARGET}/release/rg" - local _rg='complete/_rg' - local ret='0' - local helpTemp="$( mktemp )" - local compTemp="$( mktemp )" local diff + local rg="${${0:a}:h}/../target/${TARGET:-}/release/rg" + local _rg="${${0:a}:h}/../complete/_rg" + local -a help_args comp_args + + [[ -e $rg ]] || rg=${rg/%\/release\/rg/\/debug\/rg} + + [[ -e $rg ]] || { + printf >&2 'File not found: %s\n' $rg + return 1 + } + [[ -e $_rg ]] || { + printf >&2 'File not found: %s\n' $_rg + return 1 + } + + printf 'Comparing options:\n-%s\n+%s\n' $rg $_rg - [ -e "${rg}" ] || rg="target/${TARGET}/debug/rg" - - if [ ! -e "${rg}" ]; then - printf 'File not found: %s\n' "${rg}" >&2 - ret='1' - elif [ ! -e "${_rg}" ]; then - printf 'File not found: %s\n' "${_rg}" >&2 - ret='1' - else - # 'Parse' options out of the `--help` output. To prevent false positives - # we only look at lines where the first non-white-space character is `-` - "${rg}" --help | - "${rg}" -- '^\s*-' | - "${rg}" -io -- '[\t ,](-[a-z0-9]|--[a-z0-9-]+)\b' | + # 'Parse' options out of the `--help` output. To prevent false positives we + # only look at lines where the first non-white-space character is `-` + help_args=( ${(f)"$( + $rg --help | + $rg -- '^\s*-' | + $rg -io -- '[\t ,](-[a-z0-9]|--[a-z0-9-]+)\b' | tr -d '\t ,' | - sort -u > "${helpTemp}" - - # 'Parse' options out of the completion-function file. To prevent false - # negatives, we: - # - # * Exclude lines that don't start with punctuation expected of option - # definitions - # * Exclude lines that don't appear to have a bracketed description - # suitable for `_arguments` - # * Exclude those bracketed descriptions so we don't match options - # which might be referenced in them - # * Exclude parenthetical lists of exclusive options so we don't match - # those - # - # This does of course make the following assumptions: - # - # * Each option definition is on its own (single) line - # * Each option definition has a description - # * Option names are static — i.e., they aren't constructed from - # variables or command substitutions. Brace expansion is OK as long as - # each component of the expression is a complete option flag — in - # other words, `{--foo,--bar}` is valid, but `--{foo,bar}` is not - # * Bracketed descriptions must contain at least two characters and must - # not begin with `!`, `@`, or `^` (in order to avoid confusion with - # shell syntax) - "${rg}" -- "^\s*[\"':({*-]" "${_rg}" | - "${rg}" --replace '$1' -- '^.*?(?:\(.+?\).*?)?(-.+)\[[^!@^].+\].*' | - tr -d "\t (){}*=+:'\"" | - tr ',' '\n' | - sort -u > "${compTemp}" - - diff="$( - if diff --help 2>&1 | grep -qF -- '--label'; then - diff -U2 \ - --label '`rg --help`' \ - --label "${_rg}" \ - "${helpTemp}" "${compTemp}" || true - else - diff -U2 \ - -L '`rg --help`' \ - -L "${_rg}" \ - "${helpTemp}" "${compTemp}" || true - fi - )" - - [ -n "${diff}" ] && { - printf '%s\n' 'zsh completion options differ from `--help` options:' >&2 - printf '%s\n' "${diff}" >&2 - ret='1' - } - fi - - rm -f "${helpTemp}" "${compTemp}" - - return "${ret}" + sort -u + )"} ) + + # 'Parse' options out of the completion function + comp_args=( ${(f)"$( get_comp_args $_rg )"} ) + + comp_args=( ${comp_args#\(*\)} ) # Strip excluded options + comp_args=( ${comp_args#\*} ) # Strip repetition indicator + comp_args=( ${comp_args%%-[:[]*} ) # Strip everything after -optname- + comp_args=( ${comp_args%%[:+=[]*} ) # Strip everything after other optspecs + comp_args=( ${comp_args##[^-]*} ) # Remove non-options + + # This probably isn't necessary, but we should ensure the same order + comp_args=( ${(f)"$( printf '%s\n' $comp_args | sort -u )"} ) + + (( $#help_args )) || { + printf >&2 'Failed to get help_args\n' + return 1 + } + (( $#comp_args )) || { + printf >&2 'Failed to get comp_args\n' + return 1 + } + + diff="$( + if diff --help 2>&1 | grep -qF -- '--label'; then + diff -U2 \ + --label '`rg --help`' \ + --label '`_rg`' \ + =( printf '%s\n' $help_args ) =( printf '%s\n' $comp_args ) + else + diff -U2 \ + -L '`rg --help`' \ + -L '`_rg`' \ + =( printf '%s\n' $help_args ) =( printf '%s\n' $comp_args ) + fi + )" + + (( $#diff )) && { + printf >&2 '%s\n' 'zsh completion options differ from `--help` options:' + printf >&2 '%s\n' $diff + return 1 + } + printf 'OK\n' + return 0 } main "${@}" |