From 055c93d11ab20cc4479539b24bbdfa5cab78a342 Mon Sep 17 00:00:00 2001 From: Yuval Date: Tue, 16 Mar 2021 02:18:53 -0700 Subject: [PATCH] Switch to path autocompletion after -- for bazel run commands. Closes #11292. Closes #12957. PiperOrigin-RevId: 363136663 --- scripts/bash_completion_test.sh | 39 ++++++++++-- scripts/bazel-complete-template.bash | 89 +++++++++++++++++----------- 2 files changed, 88 insertions(+), 40 deletions(-) diff --git a/scripts/bash_completion_test.sh b/scripts/bash_completion_test.sh index 7029137a376fa6..ca66c42e8899c5 100755 --- a/scripts/bash_completion_test.sh +++ b/scripts/bash_completion_test.sh @@ -171,7 +171,7 @@ assert_expansion_function() { local ws=${PWD} local function="$1" displacement="$2" type="$3" expected="$4" current="$5" disable_errexit - local actual_result=$(eval "_bazel__${function} \"${ws}\" \"${displacement}\" \"${current}\" \"${type}\"") + local actual_result=$(eval "_bazel__${function} \"${ws}\" \"${displacement}\" \"${current}\" \"${type}\"" | sort) enable_errexit assert_equals "$(echo -ne "${expected}")" "${actual_result}" } @@ -196,7 +196,7 @@ test_expand_rules_in_package() { # label should match test and non-test rules assert_expansion_function "expand_rules_in_package" "" label \ - 'token_bucket_test \ntoken_bucket_binary ' \ + 'token_bucket_binary \ntoken_bucket_test ' \ 'video/streamer2:token_bucket_' assert_expansion_function "expand_rules_in_package" "" label \ 'stuff ' 'video/streamer2/stuff:s' @@ -234,7 +234,7 @@ test_expand_rules_in_package() { # with BAZEL_COMPLETION_ALLOW_TESTS_FOR_RUN set. BAZEL_COMPLETION_ALLOW_TESTS_FOR_RUN=true \ assert_expansion_function "expand_rules_in_package" "" label-bin \ - 'token_bucket_test \ntoken_bucket_binary ' 'video/streamer2:to' + 'token_bucket_binary \ntoken_bucket_test ' 'video/streamer2:to' # Test the label-bin expands for test rules, with # BAZEL_COMPLETION_ALLOW_TESTS_FOR_RUN set. @@ -303,7 +303,7 @@ test_expand_package_name() { # label-package assert_expansion_function "expand_package_name" "" "label-package" \ - "//video/streamer2/stuff/\n//video/streamer2/stuff " \ + "//video/streamer2/stuff \n//video/streamer2/stuff/" \ "//video/streamer2/stu" assert_expansion_function "expand_package_name" "" "label-package" \ "//video/notapackage/" \ @@ -357,7 +357,7 @@ test_complete_pattern() { "//video/streamer2/stu" assert_expansion_function "complete_pattern" "" label-package \ - "//video/streamer2/stuff/\n//video/streamer2/stuff " \ + "//video/streamer2/stuff \n//video/streamer2/stuff/" \ "//video/streamer2/stu" assert_expansion_function "complete_pattern" "" command \ @@ -392,6 +392,19 @@ test_complete_pattern() { '' 'video/streamer2:ta' assert_expansion_function "complete_pattern" "video/" label \ 'with_special+_,=-.@~chars ' 'streamer2:with_s' + + # Path expansion + if [[ -z $PACKAGE_PATH_PREFIX ]]; then + assert_expansion_function "complete_pattern" "" path \ + "video/streamer2/BUILD \nvideo/streamer2/names/\nvideo/streamer2/stuff/\nvideo/streamer2/testing/" \ + "video/streamer2/" + else + # When $PACKAGE_PATH_PREFIX is set, the "stuff" directory will not be in + # the same directory as the others, so we have to omit it. + assert_expansion_function "complete_pattern" "" path \ + "video/streamer2/BUILD \nvideo/streamer2/names/\nvideo/streamer2/testing/" \ + "video/streamer2/" + fi } #### TESTS ############################################################# @@ -707,6 +720,22 @@ test_target_expansion_in_package() { 'build :s' } +test_filename_expansion_after_double_dash() { + make_packages + assert_expansion 'run :target -- vid' \ + 'run :target -- video/' + assert_expansion 'run :target -- video/st' \ + 'run :target -- video/streamer2/' + assert_expansion 'run :target -- video/streamer2/B' \ + 'run :target -- video/streamer2/BUILD ' + assert_expansion 'run :target -- video/streamer2/n' \ + 'run :target -- video/streamer2/names/' + + # Autocomplete arguments as well. + assert_expansion 'run :target -- --arg=video/streamer2/n' \ + 'run :target -- --arg=video/streamer2/names/' +} + test_help() { # "Test that bazel help expands subcommand names" assert_expansion 'help qu' \ diff --git a/scripts/bazel-complete-template.bash b/scripts/bazel-complete-template.bash index 8a918a30e0ef3d..ed870c2cd15d31 100644 --- a/scripts/bazel-complete-template.bash +++ b/scripts/bazel-complete-template.bash @@ -350,7 +350,13 @@ _bazel__complete_pattern() { compgen -S " " -W "${commands}" -- "$current" ;; path) - compgen -f -- "$current" + for file in $(compgen -f -- "$current"); do + if [[ -d "$file" ]]; then + echo "$file/" + else + echo "$file " + fi + done ;; *) compgen -S " " -W "$type" -- "$current" @@ -571,6 +577,15 @@ _bazel__expand_config() { compgen -S " " -W "$all_configs" -- "$cur" } +_bazel__is_after_doubledash() { + for word in "${COMP_WORDS[@]:1:COMP_CWORD-1}"; do + if [[ "$word" == "--" ]]; then + return 0 + fi + done + return 1 +} + _bazel__complete_stdout() { local cur=$(_bazel__get_cword) word command displacement workspace @@ -580,41 +595,45 @@ _bazel__complete_stdout() { workspace="$(_bazel__get_workspace_path)" displacement="$(_bazel__get_displacement ${workspace})" - case "$command" in - "") # Expand startup-options or commands - local commands=$(echo "${BAZEL_COMMAND_LIST}" \ - | tr " " "\n" | "grep" -v "^${BAZEL_IGNORED_COMMAND_REGEX}$") - _bazel__expand_options "$workspace" "$displacement" "$cur" \ - "${commands}\ - ${BAZEL_STARTUP_OPTIONS}" - ;; + if _bazel__is_after_doubledash && [[ "$command" == "run" ]]; then + _bazel__complete_pattern "$workspace" "$displacement" "${cur#*=}" "path" + else + case "$command" in + "") # Expand startup-options or commands + local commands=$(echo "${BAZEL_COMMAND_LIST}" \ + | tr " " "\n" | "grep" -v "^${BAZEL_IGNORED_COMMAND_REGEX}$") + _bazel__expand_options "$workspace" "$displacement" "$cur" \ + "${commands}\ + ${BAZEL_STARTUP_OPTIONS}" + ;; - *) - case "$cur" in - --config=*) # Expand options: - _bazel__expand_config "$workspace" "$command" "${cur#"--config="}" - ;; - -*) # Expand options: - _bazel__expand_options "$workspace" "$displacement" "$cur" \ - "$(_bazel__options_for $command)" - ;; - *) # Expand target pattern - expansion_pattern="$(_bazel__expansion_for $command)" - NON_QUOTE_REGEX="^[\"']" - if [[ $command = query && $cur =~ $NON_QUOTE_REGEX ]]; then - : # Ideally we would expand query expressions---it's not - # that hard, conceptually---but readline is just too - # damn complex when it comes to quotation. Instead, - # for query, we just expand target patterns, unless - # the first char is a quote. - elif [ -n "$expansion_pattern" ]; then - _bazel__complete_pattern \ - "$workspace" "$displacement" "$cur" "$expansion_pattern" - fi - ;; - esac - ;; - esac + *) + case "$cur" in + --config=*) # Expand options: + _bazel__expand_config "$workspace" "$command" "${cur#"--config="}" + ;; + -*) # Expand options: + _bazel__expand_options "$workspace" "$displacement" "$cur" \ + "$(_bazel__options_for $command)" + ;; + *) # Expand target pattern + expansion_pattern="$(_bazel__expansion_for $command)" + NON_QUOTE_REGEX="^[\"']" + if [[ $command = query && $cur =~ $NON_QUOTE_REGEX ]]; then + : # Ideally we would expand query expressions---it's not + # that hard, conceptually---but readline is just too + # damn complex when it comes to quotation. Instead, + # for query, we just expand target patterns, unless + # the first char is a quote. + elif [ -n "$expansion_pattern" ]; then + _bazel__complete_pattern \ + "$workspace" "$displacement" "$cur" "$expansion_pattern" + fi + ;; + esac + ;; + esac + fi } _bazel__to_compreply() {