aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/shell-completions/bash/meson441
-rw-r--r--data/shell-completions/zsh/_meson18
-rw-r--r--mesonbuild/mesonmain.py2
-rw-r--r--mesonbuild/mtest.py4
4 files changed, 461 insertions, 4 deletions
diff --git a/data/shell-completions/bash/meson b/data/shell-completions/bash/meson
new file mode 100644
index 0000000..d757e96
--- /dev/null
+++ b/data/shell-completions/bash/meson
@@ -0,0 +1,441 @@
+_meson() {
+ command="${COMP_WORDS[1]}"
+ case "$command" in
+ setup |\
+ configure |\
+ install |\
+ introspect |\
+ init |\
+ test |\
+ wrap |\
+ subprojects |\
+ help)
+ _meson-$command "${COMP_WORDS[@]:1}"
+ ;;
+ *)
+ _meson-setup "${COMP_WORDS[@]}"
+ ;;
+ esac
+} &&
+complete -F _meson meson
+
+_meson_complete_option() {
+ option_string=$1
+
+ if [[ $# -eq 2 ]] && ! [[ "$option_string" == *=* ]]; then
+ option_string="$option_string=$2"
+ fi
+
+ if [[ "$option_string" == *=* ]]; then
+ _meson_complete_option_value "$option_string"
+ else
+ _meson_complete_option_name "$option_string"
+ fi
+}
+
+_meson_complete_option_name() {
+ option=$1
+ options=($(python3 -c 'import sys, json
+for option in json.load(sys.stdin):
+ print(option["name"])
+' <<< "$(_meson_get_options)"))
+ compopt -o nospace
+ COMPREPLY=($(compgen -W '${options[@]}' -S= -- "$option"))
+}
+
+_meson_complete_option_value() {
+ cur=$1
+ option_name=${cur%%=*}
+ option_value=${cur#*=}
+
+ if _meson_complete_filedir "$option_name" "$option_value"; then
+ return
+ fi
+
+# TODO: support all the option types
+ options=($(python3 -c 'import sys, json
+for option in json.load(sys.stdin):
+ if option["name"] != "'$option_name'":
+ continue
+ choices = []
+ if option["type"] == "boolean":
+ choices.append("true")
+ choices.append("false")
+ elif option["type"] == "combo":
+ for choice in option["choices"]:
+ choices.append(choice)
+ for choice in choices:
+ if choice.startswith("'$cur'"):
+ print(choice)
+' <<< "$(_meson_get_options)"))
+ COMPREPLY=("${options[@]}")
+}
+
+_meson_get_options() {
+ local options
+ for builddir in "${COMP_WORDS[@]}"; do
+ if [ -d "$builddir" ]; then
+ break
+ fi
+ builddir=.
+ done
+ options=$(meson introspect "$builddir" --buildoptions 2>/dev/null) &&
+ echo "$options" ||
+ echo '[]'
+}
+
+_meson_complete_filedir() {
+ _filedir_in() {
+ pushd "$1" &>/dev/null
+ local COMPREPLY=()
+ _filedir
+ echo "${COMPREPLY[@]}"
+ popd &>/dev/null
+ }
+
+ option=$1
+ cur=$2
+ case $option in
+ prefix |\
+ libdir |\
+ libexecdir |\
+ bindir |\
+ sbindir |\
+ includedir |\
+ datadir |\
+ mandir |\
+ infodir |\
+ localedir |\
+ sysconfdir |\
+ localstatedir |\
+ sharedstatedir)
+ _filedir -d
+ ;;
+ cross-file)
+ _filedir
+ COMPREPLY+=($(_filedir_in "$XDG_DATA_DIRS"/meson/cross))
+ COMPREPLY+=($(_filedir_in /usr/local/share/meson/cross))
+ COMPREPLY+=($(_filedir_in /usr/share/meson/cross))
+ COMPREPLY+=($(_filedir_in "$XDG_DATA_HOME"/meson/cross))
+ COMPREPLY+=($(_filedir_in ~/.local/share/meson/cross))
+ ;;
+ *)
+ return 1;;
+ esac
+ return 0
+}
+
+_meson-setup() {
+
+ shortopts=(
+ h
+ D
+ v
+ )
+
+ longopts=(
+ help
+ prefix
+ libdir
+ libexecdir
+ bindir
+ sbindir
+ includedir
+ datadir
+ mandir
+ infodir
+ localedir
+ sysconfdir
+ localstatedir
+ sharedstatedir
+ backend
+ buildtype
+ strip
+ unity
+ werror
+ layout
+ default-library
+ warnlevel
+ stdsplit
+ errorlogs
+ cross-file
+ version
+ wrap-mode
+ )
+
+ local cur prev
+ if _get_comp_words_by_ref cur prev &>/dev/null &&
+ [ "${prev:0:2}" = '--' ] && _meson_complete_option "${prev:2}" "$cur"; then
+ return
+ elif _get_comp_words_by_ref cur prev &>/dev/null &&
+ [ "${prev:0:1}" = '-' ] && [ "${prev:1:2}" != '-' ] && _meson_complete_option "${prev:1}"; then
+ return
+ elif _get_comp_words_by_ref -n '=' cur prev &>/dev/null; then
+ if [ $prev == -D ]; then
+ _meson_complete_option "$cur"
+ return
+ fi
+ else
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ fi
+
+ if [[ "$cur" == "--"* ]]; then
+ COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}"))
+ elif [[ "$cur" == "-"* ]]; then
+ COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}"))
+ COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}' -- "${cur:1}"))
+ else
+ _filedir -d
+ if [ -z "$cur" ]; then
+ COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}'))
+ COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}'))
+ fi
+
+ if [ $COMP_CWORD -eq 1 ]; then
+ COMPREPLY+=($(compgen -W 'setup configure test introspect' -- "$cur"))
+ fi
+ fi
+}
+
+_meson-configure() {
+
+ shortopts=(
+ h
+ D
+ )
+
+ longopts=(
+ help
+ clearcache
+ )
+
+ local cur prev
+ if _get_comp_words_by_ref -n '=' cur prev &>/dev/null; then
+ if [ $prev == -D ]; then
+ _meson_complete_option "$cur"
+ return
+ fi
+ else
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ fi
+
+ if [[ "$cur" == "--"* ]]; then
+ COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}"))
+ elif [[ "$cur" == "-"* ]]; then
+ COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}"))
+ COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}' -- "${cur:1}"))
+ else
+ for dir in "${COMP_WORDS[@]}"; do
+ if [ -d "$dir" ]; then
+ break
+ fi
+ dir=.
+ done
+ if [ ! -d "$dir/meson-private" ]; then
+ _filedir -d
+ fi
+
+ if [ -z "$cur" ]; then
+ COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}'))
+ COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}'))
+ fi
+ fi
+}
+
+_meson-test() {
+ shortopts=(
+ q
+ v
+ t
+ C
+ )
+
+ longopts=(
+ quiet
+ verbose
+ timeout-multiplier
+ repeat
+ no-rebuild
+ gdb
+ list
+ wrapper --wrap
+ no-suite
+ suite
+ no-stdsplit
+ print-errorlogs
+ benchmark
+ logbase
+ num-processes
+ setup
+ test-args
+ )
+
+ local cur prev
+ if _get_comp_words_by_ref -n ':' cur prev &>/dev/null; then
+ case $prev in
+ --repeat)
+ # number, can't be completed
+ return
+ ;;
+ --wrapper)
+ _command_offset $COMP_CWORD
+ return
+ ;;
+ -C)
+ _filedir -d
+ return
+ ;;
+ --suite | --no-suite)
+ for i in "${!COMP_WORDS[@]}"; do
+ opt="${COMP_WORDS[i]}"
+ dir="${COMP_WORDS[i+1]}"
+ case "$opt" in
+ -C)
+ break
+ ;;
+ esac
+ dir=.
+ done
+ suites=($(python3 -c 'import sys, json;
+for test in json.load(sys.stdin):
+ for suite in test["suite"]:
+ print(suite)
+ ' <<< "$(meson introspect "$dir" --tests)"))
+# TODO
+ COMPREPLY+=($(compgen -W "${suites[*]}" -- "$cur"))
+ return
+ ;;
+ --logbase)
+ # free string, can't be completed
+ return
+ ;;
+ --num-processes)
+ # number, can't be completed
+ return
+ ;;
+ -t | --timeout-multiplier)
+ # number, can't be completed
+ return
+ ;;
+ --setup)
+ # TODO
+ return
+ ;;
+ --test-args)
+ return
+ ;;
+ esac
+ else
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ fi
+
+ if [[ "$cur" == "--"* ]]; then
+ COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}"))
+ elif [[ "$cur" == "-"* && ${#cur} -gt 1 ]]; then
+ COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}' -- "${cur:1}"))
+ else
+ for dir in "${COMP_WORDS[@]}"; do
+ if [ -d "$dir" ]; then
+ break
+ fi
+ dir=.
+ done
+ if [ ! -d "$dir/meson-private" ]; then
+ _filedir -d
+ fi
+
+ for i in "${!COMP_WORDS[@]}"; do
+ opt="${COMP_WORDS[i]}"
+ dir="${COMP_WORDS[i+1]}"
+ case "$opt" in
+ -C)
+ break
+ ;;
+ esac
+ dir=.
+ done
+ tests=($(python3 -c 'import sys, json;
+for test in json.load(sys.stdin):
+ print(test["name"])
+' <<< "$(meson introspect "$dir" --tests)"))
+ COMPREPLY+=($(compgen -W "${tests[*]}" -- "$cur"))
+
+ if [ -z "$cur" ]; then
+ COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}"))
+ COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}' -- "${cur:1}"))
+ fi
+ fi
+}
+
+_meson-introspect() {
+ shortopts=(
+ h
+ )
+
+ longopts=(
+ targets
+ installed
+ target-files
+ buildsystem-files
+ buildoptions
+ tests
+ benchmarks
+ dependencies
+ projectinfo
+ )
+
+ local cur prev
+ if _get_comp_words_by_ref cur prev &>/dev/null; then
+ case $prev in
+ --target-files)
+ for i in "${!COMP_WORDS[@]}"; do
+ opt="${COMP_WORDS[i]}"
+ dir="${COMP_WORDS[i+1]}"
+ case "$opt" in
+ -C)
+ break
+ ;;
+ esac
+ dir=.
+ done
+ tests_json=$(meson introspect "$dir" --targets)
+ if [ $? -eq 0 ]; then
+ tests=$(python3 -c 'import sys, json
+for target in json.load(sys.stdin):
+ print(target["id"])
+' <<< "$tests_json")
+ COMPREPLY=($(compgen -W '$tests' -- "$cur"))
+ fi
+ return
+ ;;
+ esac
+ else
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ fi
+
+ if [[ "$cur" == "--"* ]]; then
+ COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}"))
+ elif [[ "$cur" == "-"* ]]; then
+ COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}"))
+ COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}' -- "${cur:1}"))
+ else
+ for dir in "${COMP_WORDS[@]}"; do
+ if [ -d "$dir" ]; then
+ break
+ fi
+ dir=.
+ done
+ if [ ! -d "$dir/meson-private" ]; then
+ _filedir -d
+ fi
+
+ if [ -z "$cur" ]; then
+ COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}'))
+ COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}'))
+ fi
+ fi
+}
+
+_meson-wrap() {
+ : TODO
+}
diff --git a/data/shell-completions/zsh/_meson b/data/shell-completions/zsh/_meson
index 481d04c..b48b0f8 100644
--- a/data/shell-completions/zsh/_meson
+++ b/data/shell-completions/zsh/_meson
@@ -49,8 +49,22 @@ local -a meson_commands=(
# TODO: implement build option completion
(( $+functions[__meson_build_options] )) || __meson_build_options() {}
-# TODO: implement target name completion
-(( $+functions[__meson_targets] )) || __meson_targets() {}
+
+(( $+functions[__meson_targets] )) || __meson_targets() {
+ local tests_json
+ # TODO: get builddir out of the cmdline and pass it here
+ if tests_json="$(_call_program meson meson introspect --targets)";
+ then
+ local -a tests_ids=$(_call_program python3 python3 -c 'import sys, json;
+for target in json.load(sys.stdin):
+ print(target["id"])
+' <<< "$tests_json")
+ _describe -t "tests" "Meson tests IDs" tests_ids
+ else
+ _message -r "current working directory is not a build directory"
+ fi
+}
+
# `meson introspect` currently can provide that information in JSON.
# We can:
# 1) pipe its output to python3 -m json.tool | grep "$alovelyregex" | cut <...>
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
index 822a943..91a52b1 100644
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -28,6 +28,8 @@ from .environment import detect_msys2_arch
from .wrap import wraptool
+# Note: when adding arguments, please also add them to the completion
+# scripts in $MESONSRC/data/shell-completions/
class CommandLineParser:
def __init__(self):
self.term_width = shutil.get_terminal_size().columns
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index 02b728e..77a0f82 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -943,6 +943,7 @@ def list_tests(th):
tests = th.get_tests()
for t in tests:
print(th.get_pretty_suite(t))
+ return not tests
def rebuild_all(wd):
if not os.path.isfile(os.path.join(wd, 'build.ninja')):
@@ -996,8 +997,7 @@ def run(options):
try:
th = TestHarness(options)
if options.list:
- list_tests(th)
- return 0
+ return list_tests(th)
if not options.args:
return th.doit()
return th.run_special()