From 05a480fa1590b438f94096c1917657fd5d4294a4 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 1 Mar 2022 19:40:43 +0000 Subject: [PATCH 1/5] fix(runfiles): use normalized paths when guarding runfiles root and node_modules on Windows (#3331) * fix(runfiles): use normalized paths when guarding runfiles root and node_modules on Windows * refactor(builtin): run new code path only on Windows --- internal/node/launcher.sh | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/internal/node/launcher.sh b/internal/node/launcher.sh index fd832d0203..64820f48e9 100644 --- a/internal/node/launcher.sh +++ b/internal/node/launcher.sh @@ -13,6 +13,32 @@ # See the License for the specific language governing permissions and # limitations under the License. +# It helps to determine if we are running on a Windows environment (excludes WSL as it acts like Unix) +function isWindows { + case "$(uname -s)" in + CYGWIN*) local IS_WINDOWS=1 ;; + MINGW*) local IS_WINDOWS=1 ;; + MSYS_NT*) local IS_WINDOWS=1 ;; + *) local IS_WINDOWS=0 ;; + esac + + echo $IS_WINDOWS + return +} + +# It helps to normalizes paths when running on Windows. +# +# Example: +# C:/Users/XUser/_bazel_XUser/7q7kkv32/execroot/A/b/C -> /c/users/xuser/_bazel_xuser/7q7kkv32/execroot/a/b/c +function normalizeWindowsPath { + # Apply the followings paths transformations to normalize paths on Windows + # -process driver letter + # -convert path separator + # -lowercase everything + echo $(sed -e 's#^\(.\):#/\L\1#' -e 's#\\#/#g' -e 's/[A-Z]/\L&/g' <<< "$1") + return +} + # --- begin runfiles.bash initialization v2 --- # Copy-pasted from the Bazel Bash runfiles library v2. set -uo pipefail; f=build_bazel_rules_nodejs/third_party/github.com/bazelbuild/bazel/tools/bash/runfiles/runfiles.bash @@ -49,7 +75,13 @@ source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ # Case 6a is handled like case 3. if [[ -n "${RUNFILES_MANIFEST_ONLY:-}" ]]; then # Windows only has a manifest file instead of symlinks. - RUNFILES=${RUNFILES_MANIFEST_FILE%/MANIFEST} + if [[ $(isWindows) -eq "1" ]]; then + # If Windows normalizing the path and case insensitive removing the `/MANIFEST` part of the path + NORMALIZED_RUNFILES_MANIFEST_FILE_PATH=$(normalizeWindowsPath $RUNFILES_MANIFEST_FILE) + RUNFILES=$(sed 's|\/MANIFEST$||i' <<< $NORMALIZED_RUNFILES_MANIFEST_FILE_PATH) + else + RUNFILES=${RUNFILES_MANIFEST_FILE%/MANIFEST} + fi elif [[ -n "${TEST_SRCDIR:-}" ]]; then # Case 4, bazel has identified runfiles for us. RUNFILES="${TEST_SRCDIR:-}" From 8790485a71c3ceabc4f02fb29182a11eaaa69dab Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 14 Apr 2022 00:40:47 +0100 Subject: [PATCH 2/5] chore(builtin): test ci --- internal/node/launcher.sh | 65 ++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/internal/node/launcher.sh b/internal/node/launcher.sh index 64820f48e9..1175bc826c 100644 --- a/internal/node/launcher.sh +++ b/internal/node/launcher.sh @@ -13,31 +13,31 @@ # See the License for the specific language governing permissions and # limitations under the License. -# It helps to determine if we are running on a Windows environment (excludes WSL as it acts like Unix) -function isWindows { - case "$(uname -s)" in - CYGWIN*) local IS_WINDOWS=1 ;; - MINGW*) local IS_WINDOWS=1 ;; - MSYS_NT*) local IS_WINDOWS=1 ;; - *) local IS_WINDOWS=0 ;; - esac - - echo $IS_WINDOWS - return -} - -# It helps to normalizes paths when running on Windows. -# -# Example: -# C:/Users/XUser/_bazel_XUser/7q7kkv32/execroot/A/b/C -> /c/users/xuser/_bazel_xuser/7q7kkv32/execroot/a/b/c -function normalizeWindowsPath { - # Apply the followings paths transformations to normalize paths on Windows - # -process driver letter - # -convert path separator - # -lowercase everything - echo $(sed -e 's#^\(.\):#/\L\1#' -e 's#\\#/#g' -e 's/[A-Z]/\L&/g' <<< "$1") - return -} +# # It helps to determine if we are running on a Windows environment (excludes WSL as it acts like Unix) +# function isWindows { +# case "$(uname -s)" in +# CYGWIN*) local IS_WINDOWS=1 ;; +# MINGW*) local IS_WINDOWS=1 ;; +# MSYS_NT*) local IS_WINDOWS=1 ;; +# *) local IS_WINDOWS=0 ;; +# esac + +# echo $IS_WINDOWS +# return +# } + +# # It helps to normalizes paths when running on Windows. +# # +# # Example: +# # C:/Users/XUser/_bazel_XUser/7q7kkv32/execroot/A/b/C -> /c/users/xuser/_bazel_xuser/7q7kkv32/execroot/a/b/c +# function normalizeWindowsPath { +# # Apply the followings paths transformations to normalize paths on Windows +# # -process driver letter +# # -convert path separator +# # -lowercase everything +# echo $(sed -e 's#^\(.\):#/\L\1#' -e 's#\\#/#g' -e 's/[A-Z]/\L&/g' <<< "$1") +# return +# } # --- begin runfiles.bash initialization v2 --- # Copy-pasted from the Bazel Bash runfiles library v2. @@ -75,13 +75,14 @@ source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ # Case 6a is handled like case 3. if [[ -n "${RUNFILES_MANIFEST_ONLY:-}" ]]; then # Windows only has a manifest file instead of symlinks. - if [[ $(isWindows) -eq "1" ]]; then - # If Windows normalizing the path and case insensitive removing the `/MANIFEST` part of the path - NORMALIZED_RUNFILES_MANIFEST_FILE_PATH=$(normalizeWindowsPath $RUNFILES_MANIFEST_FILE) - RUNFILES=$(sed 's|\/MANIFEST$||i' <<< $NORMALIZED_RUNFILES_MANIFEST_FILE_PATH) - else - RUNFILES=${RUNFILES_MANIFEST_FILE%/MANIFEST} - fi + # if [[ $(isWindows) -eq "1" ]]; then + # # If Windows normalizing the path and case insensitive removing the `/MANIFEST` part of the path + # NORMALIZED_RUNFILES_MANIFEST_FILE_PATH=$(normalizeWindowsPath $RUNFILES_MANIFEST_FILE) + # RUNFILES=$(sed 's|\/MANIFEST$||i' <<< $NORMALIZED_RUNFILES_MANIFEST_FILE_PATH) + # else + # RUNFILES=${RUNFILES_MANIFEST_FILE%/MANIFEST} + # fi + RUNFILES=${RUNFILES_MANIFEST_FILE%/MANIFEST} elif [[ -n "${TEST_SRCDIR:-}" ]]; then # Case 4, bazel has identified runfiles for us. RUNFILES="${TEST_SRCDIR:-}" From 7fa864c7b60025d707e4a46cf267f5a4277312a6 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 14 Apr 2022 00:54:49 +0100 Subject: [PATCH 3/5] Revert "chore(builtin): test ci" This reverts commit 8790485a71c3ceabc4f02fb29182a11eaaa69dab. --- internal/node/launcher.sh | 65 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/internal/node/launcher.sh b/internal/node/launcher.sh index 1175bc826c..64820f48e9 100644 --- a/internal/node/launcher.sh +++ b/internal/node/launcher.sh @@ -13,31 +13,31 @@ # See the License for the specific language governing permissions and # limitations under the License. -# # It helps to determine if we are running on a Windows environment (excludes WSL as it acts like Unix) -# function isWindows { -# case "$(uname -s)" in -# CYGWIN*) local IS_WINDOWS=1 ;; -# MINGW*) local IS_WINDOWS=1 ;; -# MSYS_NT*) local IS_WINDOWS=1 ;; -# *) local IS_WINDOWS=0 ;; -# esac - -# echo $IS_WINDOWS -# return -# } - -# # It helps to normalizes paths when running on Windows. -# # -# # Example: -# # C:/Users/XUser/_bazel_XUser/7q7kkv32/execroot/A/b/C -> /c/users/xuser/_bazel_xuser/7q7kkv32/execroot/a/b/c -# function normalizeWindowsPath { -# # Apply the followings paths transformations to normalize paths on Windows -# # -process driver letter -# # -convert path separator -# # -lowercase everything -# echo $(sed -e 's#^\(.\):#/\L\1#' -e 's#\\#/#g' -e 's/[A-Z]/\L&/g' <<< "$1") -# return -# } +# It helps to determine if we are running on a Windows environment (excludes WSL as it acts like Unix) +function isWindows { + case "$(uname -s)" in + CYGWIN*) local IS_WINDOWS=1 ;; + MINGW*) local IS_WINDOWS=1 ;; + MSYS_NT*) local IS_WINDOWS=1 ;; + *) local IS_WINDOWS=0 ;; + esac + + echo $IS_WINDOWS + return +} + +# It helps to normalizes paths when running on Windows. +# +# Example: +# C:/Users/XUser/_bazel_XUser/7q7kkv32/execroot/A/b/C -> /c/users/xuser/_bazel_xuser/7q7kkv32/execroot/a/b/c +function normalizeWindowsPath { + # Apply the followings paths transformations to normalize paths on Windows + # -process driver letter + # -convert path separator + # -lowercase everything + echo $(sed -e 's#^\(.\):#/\L\1#' -e 's#\\#/#g' -e 's/[A-Z]/\L&/g' <<< "$1") + return +} # --- begin runfiles.bash initialization v2 --- # Copy-pasted from the Bazel Bash runfiles library v2. @@ -75,14 +75,13 @@ source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ # Case 6a is handled like case 3. if [[ -n "${RUNFILES_MANIFEST_ONLY:-}" ]]; then # Windows only has a manifest file instead of symlinks. - # if [[ $(isWindows) -eq "1" ]]; then - # # If Windows normalizing the path and case insensitive removing the `/MANIFEST` part of the path - # NORMALIZED_RUNFILES_MANIFEST_FILE_PATH=$(normalizeWindowsPath $RUNFILES_MANIFEST_FILE) - # RUNFILES=$(sed 's|\/MANIFEST$||i' <<< $NORMALIZED_RUNFILES_MANIFEST_FILE_PATH) - # else - # RUNFILES=${RUNFILES_MANIFEST_FILE%/MANIFEST} - # fi - RUNFILES=${RUNFILES_MANIFEST_FILE%/MANIFEST} + if [[ $(isWindows) -eq "1" ]]; then + # If Windows normalizing the path and case insensitive removing the `/MANIFEST` part of the path + NORMALIZED_RUNFILES_MANIFEST_FILE_PATH=$(normalizeWindowsPath $RUNFILES_MANIFEST_FILE) + RUNFILES=$(sed 's|\/MANIFEST$||i' <<< $NORMALIZED_RUNFILES_MANIFEST_FILE_PATH) + else + RUNFILES=${RUNFILES_MANIFEST_FILE%/MANIFEST} + fi elif [[ -n "${TEST_SRCDIR:-}" ]]; then # Case 4, bazel has identified runfiles for us. RUNFILES="${TEST_SRCDIR:-}" From 5891039befa1741d98964b1e36495f32c01adfe0 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Tue, 8 Mar 2022 18:54:48 +0100 Subject: [PATCH 4/5] chore(builtin): cherry-pick 8606c50 --- docs/TypeScript.md | 2 +- internal/node/test/env.spec.js | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/TypeScript.md b/docs/TypeScript.md index 788628e71d..995b32f4d1 100755 --- a/docs/TypeScript.md +++ b/docs/TypeScript.md @@ -502,7 +502,7 @@ for more details about the trade-offs between the two rules. Some TypeScript options affect which files are emitted, and Bazel wants to know these ahead-of-time. So several options from the tsconfig file must be mirrored as attributes to ts_project. -See https://www.typescriptlang.org/v2/en/tsconfig for a listing of the TypeScript options. +See https://www.typescriptlang.org/tsconfig for a listing of the TypeScript options. Any code that works with `tsc` should work with `ts_project` with a few caveats: diff --git a/internal/node/test/env.spec.js b/internal/node/test/env.spec.js index 8a5a410654..a978e7e379 100644 --- a/internal/node/test/env.spec.js +++ b/internal/node/test/env.spec.js @@ -44,27 +44,30 @@ describe('launcher.sh environment', function() { expectPathsToMatch(process.env['BAZEL_WORKSPACE'], 'build_bazel_rules_nodejs'); expectPathsToMatch(process.env['BAZEL_TARGET'], '//internal/node/test:env_test'); expectPathsToMatch(process.cwd(), `${process.env['RUNFILES_DIR']}/build_bazel_rules_nodejs`); - expectPathsToMatch(process.env['PWD'], `${process.env['RUNFILES_DIR']}/build_bazel_rules_nodejs`); + expectPathsToMatch( + process.env['PWD'], + `${process.env['RUNFILES_DIR']}/build_bazel_rules_nodejs` + ); expectPathsToMatch(process.env['BAZEL_NODE_MODULES_ROOTS'], ':npm'); const expectedRoots = [ `${execroot}`, `${execroot}/node_modules`, `${runfilesRoot}`, `${runfilesRoot}/build_bazel_rules_nodejs/node_modules`, - ] + ]; if (isWindows) { expectedRoots.push( process.env['RUNFILES'], - `${process.env['RUNFILES']}/build_bazel_rules_nodejs/node_modules`, - ) + `${process.env['RUNFILES']}/build_bazel_rules_nodejs/node_modules` + ); } expectPathsToMatch(process.env['BAZEL_PATCH_ROOTS'].split(','), expectedRoots); }); - + it('should setup correct bazel environment variables when in execroot with no third party deps', function() { const env = require(runfiles.resolvePackageRelative('dump_build_env.json')); // On Windows, the RUNFILES path ends in a /MANIFEST segment in this context - const runfilesRoot = normPath(isWindows ? path.dirname(env['RUNFILES']) : env['RUNFILES']); + const runfilesRoot = normPath(env['RUNFILES']); const match = runfilesRoot.match(/\/bazel-out\//); expect(!!match).toBe(true); const execroot = runfilesRoot.slice(0, match.index); @@ -83,11 +86,11 @@ describe('launcher.sh environment', function() { ]; expectPathsToMatch(env['BAZEL_PATCH_ROOTS'].split(','), expectedRoots); }); - + it('should setup correct bazel environment variables when in execroot with third party deps', function() { const env = require(runfiles.resolvePackageRelative('dump_build_env_alt.json')); // On Windows, the RUNFILES path ends in a /MANIFEST segment in this context - const runfilesRoot = normPath(isWindows ? path.dirname(env['RUNFILES']) : env['RUNFILES']); + const runfilesRoot = normPath(env['RUNFILES']); const match = runfilesRoot.match(/\/bazel-out\//); expect(!!match).toBe(true); const execroot = runfilesRoot.slice(0, match.index); @@ -104,7 +107,7 @@ describe('launcher.sh environment', function() { ]; expectPathsToMatch(env['BAZEL_PATCH_ROOTS'].split(','), expectedRoots); }); - + it('should setup correct bazel environment variables from env attr', function() { const env = require(runfiles.resolvePackageRelative('dump_build_env_attr.json')); expect(env['FOO']).toBe('BAR'); From a86962626c42dc8ad9294718bffedce3b59f75ac Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 20 Apr 2022 17:40:23 +0100 Subject: [PATCH 5/5] docs(builtin): do not change unnecessary docs for this PR purpose --- docs/TypeScript.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/TypeScript.md b/docs/TypeScript.md index 995b32f4d1..788628e71d 100755 --- a/docs/TypeScript.md +++ b/docs/TypeScript.md @@ -502,7 +502,7 @@ for more details about the trade-offs between the two rules. Some TypeScript options affect which files are emitted, and Bazel wants to know these ahead-of-time. So several options from the tsconfig file must be mirrored as attributes to ts_project. -See https://www.typescriptlang.org/tsconfig for a listing of the TypeScript options. +See https://www.typescriptlang.org/v2/en/tsconfig for a listing of the TypeScript options. Any code that works with `tsc` should work with `ts_project` with a few caveats: