Skip to content

Commit

Permalink
feat(runfiles): add support for spaces and newlines in runfiles paths (
Browse files Browse the repository at this point in the history
…#2456)

Bazel 7.4.0 introduced support for all characters in runfile source and
target paths: bazelbuild/bazel#23912

This is a backwards-compatible change, based on a similar change in
rules_go: bazel-contrib/rules_go#4136
  • Loading branch information
dizzy57 authored Nov 28, 2024
1 parent be704e2 commit ae953da
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ Other changes:
* (providers) Added {obj}`py_runtime_info.site_init_template` and
{obj}`PyRuntimeInfo.site_init_template` for specifying the template to use to
initialize the interpreter via venv startup hooks.
* (runfiles) (Bazel 7.4+) Added support for spaces and newlines in runfiles paths

{#v0-0-0-removed}
### Removed
Expand Down
25 changes: 18 additions & 7 deletions python/runfiles/runfiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,24 @@ def _LoadRunfiles(path: str) -> Dict[str, str]:
result = {}
with open(path, "r") as f:
for line in f:
line = line.strip()
if line:
tokens = line.split(" ", 1)
if len(tokens) == 1:
result[line] = line
else:
result[tokens[0]] = tokens[1]
line = line.rstrip("\n")
if line.startswith(" "):
# In lines that start with a space, spaces, newlines, and backslashes are escaped as \s, \n, and \b in
# link and newlines and backslashes are escaped in target.
escaped_link, escaped_target = line[1:].split(" ", maxsplit=1)
link = (
escaped_link.replace(r"\s", " ")
.replace(r"\n", "\n")
.replace(r"\b", "\\")
)
target = escaped_target.replace(r"\n", "\n").replace(r"\b", "\\")
else:
link, target = line.split(" ", maxsplit=1)

if target:
result[link] = target
else:
result[link] = link
return result

def _GetRunfilesDir(self) -> str:
Expand Down
7 changes: 6 additions & 1 deletion tests/runfiles/runfiles_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,11 @@ def testFailsToCreateAnyRunfilesBecauseEnvvarsAreNotDefined(self) -> None:
def testManifestBasedRlocation(self) -> None:
with _MockFile(
contents=[
"Foo/runfile1",
"Foo/runfile1 ", # A trailing whitespace is always present in single entry lines.
"Foo/runfile2 C:/Actual Path\\runfile2",
"Foo/Bar/runfile3 D:\\the path\\run file 3.txt",
"Foo/Bar/Dir E:\\Actual Path\\Directory",
" Foo\\sBar\\bDir\\nNewline/runfile5 F:\\bActual Path\\bwith\\nnewline/runfile5",
]
) as mf:
r = runfiles.CreateManifestBased(mf.Path())
Expand All @@ -205,6 +206,10 @@ def testManifestBasedRlocation(self) -> None:
r.Rlocation("Foo/Bar/Dir/Deeply/Nested/runfile4"),
"E:\\Actual Path\\Directory/Deeply/Nested/runfile4",
)
self.assertEqual(
r.Rlocation("Foo Bar\\Dir\nNewline/runfile5"),
"F:\\Actual Path\\with\nnewline/runfile5",
)
self.assertIsNone(r.Rlocation("unknown"))
if RunfilesTest.IsWindows():
self.assertEqual(r.Rlocation("c:/foo"), "c:/foo")
Expand Down

0 comments on commit ae953da

Please sign in to comment.