1+ "Windows Batch snippets for js rules"
2+
3+ # TODO: Instead of setting a new RUNFILES env; just set RUNFILES_DIR if it is not set;
4+ # needs testing to know if RUNFILES_DIR is set always set to the same value as RUNFILES
5+ # when it is set.
6+ # Batch snippet to initialize the RUNFILES environment variable.
7+ # Depends on there being a logf_fatal function defined.
8+ # NB: If this can be generalized fully in the future and not depend on logf_fatal
9+ # then it could be hoisted to bazel-lib where we have other batch snippets.
10+ BAT_INITIALIZE_RUNFILES = r"""
11+ rem Initialize RUNFILES environment variable for Windows batch
12+ rem This is the Windows batch equivalent of the bash runfiles initialization
13+
14+ :init_runfiles
15+ rem Set a RUNFILES environment variable to the root of the runfiles tree
16+ rem since RUNFILES_DIR is not set by Bazel in all contexts.
17+ rem For example, `RUNFILES=C:\path\to\my_js_binary.bat.runfiles`.
18+ rem
19+ rem Call this program X. X was generated by a genrule and may be invoked
20+ rem in many ways:
21+ rem 1a) directly by a user, with %0 in the output tree
22+ rem 1b) via 'bazel run' (similar to case 1a)
23+ rem 2) directly by a user, with %0 in X's runfiles
24+ rem 3) by another program Y which has a data dependency on X, with %0 in Y's
25+ rem runfiles
26+ rem 4a) via 'bazel test'
27+ rem 4b) case 3 in the context of a test
28+ rem 5a) by a genrule cmd, with %0 in the output tree
29+ rem 6a) case 3 in the context of a genrule
30+ rem
31+ rem For case 1, %0 will be a regular file, and the runfiles will be
32+ rem at %0.runfiles.
33+ rem For case 2 or 3, %0 will be a symlink to the file seen in case 1.
34+ rem For case 4, %TEST_SRCDIR% should already be set to the runfiles by
35+ rem bazel.
36+ rem Case 5a is handled like case 1.
37+ rem Case 6a is handled like case 3.
38+
39+ if defined TEST_SRCDIR (
40+ rem Case 4, bazel has identified runfiles for us.
41+ set "RUNFILES=%TEST_SRCDIR%"
42+ rem Convert forward slashes to backslashes
43+ set "RUNFILES=!RUNFILES:/=\!"
44+ ) else if defined RUNFILES_MANIFEST_FILE (
45+ set "RUNFILES=%RUNFILES_MANIFEST_FILE%"
46+ rem Convert forward slashes to backslashes
47+ set "RUNFILES=!RUNFILES:/=\!"
48+ rem Check if RUNFILES ends with .runfiles_manifest
49+ if "!RUNFILES:~-17!"==".runfiles_manifest" (
50+ rem Newer versions of Bazel put the manifest besides the runfiles with the suffix .runfiles_manifest.
51+ rem For example, the runfiles directory is named my_binary.runfiles then the manifest is beside the
52+ rem runfiles directory and named my_binary.runfiles_manifest
53+ set "RUNFILES=!RUNFILES:~0,-17!"
54+ ) else (
55+ rem Check if RUNFILES ends with \MANIFEST
56+ echo !RUNFILES! | findstr /c:"\MANIFEST" >nul
57+ if !errorlevel! equ 0 (
58+ rem Older versions of Bazel put the manifest file named MANIFEST in the runfiles directory
59+ set "RUNFILES=!RUNFILES:\MANIFEST=!"
60+ ) else (
61+ call :logf_fatal "Unexpected RUNFILES_MANIFEST_FILE value %RUNFILES_MANIFEST_FILE%"
62+ exit /b 1
63+ )
64+ )
65+ ) else (
66+ rem Determine the full path of the current script
67+ set "self=%~f0"
68+
69+ :resolve_runfiles_loop
70+ rem Check if .runfiles directory exists next to the script
71+ if exist "!self!.runfiles" (
72+ set "RUNFILES=!self!.runfiles"
73+ goto :runfiles_found
74+ )
75+
76+ rem Check if we're inside a .runfiles directory
77+ echo !self! | findstr /c:".runfiles\" >nul
78+ if !errorlevel! equ 0 (
79+ rem Extract the runfiles directory path
80+ for /f "tokens=1 delims=" %%a in ('echo !self! ^| findstr /o /c:".runfiles\"') do set "pos_info=%%a"
81+ for /f "tokens=1 delims=:" %%b in ("!pos_info!") do set "pos=%%b"
82+ set /a "end_pos=!pos!+9"
83+ for /f %%c in ('echo !self! ^| findstr /c:".runfiles\"') do (
84+ for /f "tokens=1 delims=\" %%d in ("%%c") do (
85+ set "base_part=%%d"
86+ )
87+ )
88+ rem Find the .runfiles directory by going back from current position
89+ for /f "delims=" %%e in ('echo !self!') do (
90+ set "temp_path=%%e"
91+ for /f "tokens=1,* delims=\" %%f in ("!temp_path!") do (
92+ if "%%g"=="" (
93+ if exist "%%f.runfiles" set "RUNFILES=%%f.runfiles"
94+ ) else (
95+ call :extract_runfiles_path "%%e"
96+ )
97+ )
98+ )
99+ rem This is a last resort for case 6b - don't exit the loop yet
100+ )
101+
102+ rem For Windows, we don't need to resolve symlinks like in bash since
103+ rem Windows batch files don't typically use symlinks in the same way
104+ rem If we reach here and haven't found runfiles, we'll fail below
105+
106+ :runfiles_found
107+ if not defined RUNFILES (
108+ call :logf_fatal "RUNFILES environment variable is not set"
109+ exit /b 1
110+ )
111+
112+ rem Convert forward slashes to backslashes
113+ set "RUNFILES=!RUNFILES:/=\!"
114+ )
115+
116+ rem Ensure RUNFILES is an absolute path
117+ echo !RUNFILES! | findstr "^[A-Za-z]:" >nul
118+ if !errorlevel! neq 0 (
119+ rem RUNFILES is not absolute, make it relative to current directory
120+ set "RUNFILES=%CD%\!RUNFILES!"
121+ )
122+
123+ goto :runfiles_init_done
124+
125+ :extract_runfiles_path
126+ set "input_path=%~1"
127+ rem Simple approach to find .runfiles directory in path
128+ for /f "tokens=*" %%a in ('echo %input_path% ^| findstr /c:".runfiles"') do (
129+ set "temp=%%a"
130+ for /f "tokens=1 delims=\" %%b in ('echo !temp! ^| findstr /o /c:".runfiles"') do (
131+ set "match_info=%%b"
132+ for /f "tokens=1 delims=:" %%c in ("!match_info!") do (
133+ set "match_pos=%%c"
134+ set /a "runfiles_end=!match_pos!+8"
135+ set "RUNFILES=!input_path:~0,%runfiles_end%!"
136+ )
137+ )
138+ )
139+ exit /b 0
140+
141+ :runfiles_init_done
142+ """
0 commit comments