diff --git a/internal/common/test/BUILD.bazel b/internal/common/test/BUILD.bazel index 2d174325b8..f9e585f0d8 100644 --- a/internal/common/test/BUILD.bazel +++ b/internal/common/test/BUILD.bazel @@ -1,4 +1,4 @@ -load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_test") +load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary", "nodejs_test") load("//internal/common:copy_to_bin.bzl", "copy_to_bin") load("//internal/common:params_file.bzl", "params_file") @@ -48,3 +48,18 @@ nodejs_test( entry_point = ":check_params_file.js", templated_args = ["$(location :params_file.out)"], ) + +nodejs_binary( + name = "print_cmd_args", + entry_point = ":print_cmd_args.js", +) + +sh_test( + name = "test_pass_cmd_args", + srcs = ["test_pass_cmd_args.sh"], + data = [ + ":print_cmd_args", + "//third_party/github.com/bazelbuild/bazel-skylib:tests/unittest.bash", + ], + deps = ["@bazel_tools//tools/bash/runfiles"], +) diff --git a/internal/common/test/print_cmd_args.js b/internal/common/test/print_cmd_args.js new file mode 100644 index 0000000000..bc285bc20d --- /dev/null +++ b/internal/common/test/print_cmd_args.js @@ -0,0 +1,20 @@ +/** + * @license + * Copyright 2017 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +for (var i=2; i < process.argv.length; i += 1) { + console.log("arg" + i + "=(" + process.argv[i] + ")"); +} diff --git a/internal/common/test/test_pass_cmd_args.sh b/internal/common/test/test_pass_cmd_args.sh new file mode 100755 index 0000000000..7fed151fda --- /dev/null +++ b/internal/common/test/test_pass_cmd_args.sh @@ -0,0 +1,64 @@ +# Copyright 2019 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# --- begin runfiles.bash initialization v2 --- +# Copy-pasted from the Bazel Bash runfiles library v2. +set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v2 --- + +source "$(rlocation build_bazel_rules_nodejs/third_party/github.com/bazelbuild/bazel-skylib/tests/unittest.bash)" \ + || { echo "Could not source build_bazel_rules_nodejs/third_party/github.com/bazelbuild/bazel-skylib/tests/unittest.bash" >&2; exit 1; } + +case "$(uname -s | tr [:upper:] [:lower:])" in +msys*|mingw*|cygwin*) + declare -r is_windows=true + ;; +*) + declare -r is_windows=false + ;; +esac + +if "$is_windows"; then + export MSYS_NO_PATHCONV=1 + export MSYS2_ARG_CONV_EXCL="*" +fi + +function test_pass_cmd_args() { + if "$is_windows"; then + script=build_bazel_rules_nodejs/internal/common/test/print_cmd_args.bat + else + script=build_bazel_rules_nodejs/internal/common/test/print_cmd_args.sh + fi + + "$(rlocation ${script})" '/foo bar' "\\foo \\bar" "/foo bar/" \foo\bar /foo/bar \\foo\\bar "\foo\bar" "\\foo\\bar" '\foo\bar' '\\foo\\bar' >"$TEST_log" + + expect_log 'arg2=(/foo bar)' + expect_log 'arg3=(\\foo \\bar)' + expect_log 'arg4=(/foo bar/)' + expect_log 'arg5=(foobar)' + expect_log 'arg6=(/foo/bar)' + expect_log 'arg7=(\\foo\\bar)' + expect_log 'arg8=(\\foo\\bar)' + expect_log 'arg9=(\\foo\\bar)' + expect_log 'arg10=(\\foo\\bar)' + expect_log 'arg11=(\\\\foo\\\\bar)' +} + +run_suite "test_pass_cmd_args test suite" diff --git a/internal/common/windows_utils.bzl b/internal/common/windows_utils.bzl index d41467b5ef..1ae88c2021 100644 --- a/internal/common/windows_utils.bzl +++ b/internal/common/windows_utils.bzl @@ -96,7 +96,13 @@ set RUNFILES_MANIFEST_ONLY=1 call :rlocation "{sh_script}" run_script for %%a in ("{bash_bin}") do set "bash_bin_dir=%%~dpa" set PATH=%bash_bin_dir%;%PATH% -"{bash_bin}" -c "!run_script! %*" +set args=%* +rem Escape \ and * in args before passsing it with double quote +if defined args ( + set args=!args:\=\\\\! + set args=!args:"=\"! +) +"{bash_bin}" -c "!run_script! !args!" """.format( bash_bin = ctx.toolchains["@bazel_tools//tools/sh:toolchain_type"].path, sh_script = _to_manifest_path(ctx, shell_script),