Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 55 additions & 2 deletions rust/runfiles/runfiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,26 @@ impl Runfiles {
let path_mapping = manifest_content
.lines()
.flat_map(|line| {
let pair = line
let raw_pair = line
.strip_prefix(' ')
.unwrap_or(line)
.split_once(' ')
.ok_or(RunfilesError::RunfilesManifestInvalidFormat)?;
Ok::<(PathBuf, PathBuf), RunfilesError>((pair.0.into(), pair.1.into()))
let pair = if line.starts_with(' ') {
// Unescape according to src/main/java/com/google/devtools/build/lib/analysis/SourceManifestAction.java.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you leave a link with a commit hash in it so the context isn't invalidated by upstream changes when folks go to look this up?

Suggested change
// Unescape according to src/main/java/com/google/devtools/build/lib/analysis/SourceManifestAction.java.
// Unescape according to SourceManifestAction.java
// https://github.com/bazelbuild/bazel/blob/5b3e143adf7ccf40b05f73b0711f60f1ceade180/src/main/java/com/google/devtools/build/lib/analysis/SourceManifestAction.java

(
raw_pair
.0
.replace("\\s", " ")
.replace("\\n", "\n")
.replace("\\b", "\\")
.into(),
raw_pair.1.replace("\\n", "\n").replace("\\b", "\\").into(),
)
} else {
(raw_pair.0.into(), raw_pair.1.into())
};
Ok::<(PathBuf, PathBuf), RunfilesError>(pair)
})
.collect::<HashMap<_, _>>();
Ok(Mode::ManifestBased(path_mapping))
Expand Down Expand Up @@ -633,6 +649,43 @@ mod test {
);
}

#[test]
fn test_manifest_parsing() {
let temp_dir = PathBuf::from(std::env::var("TEST_TMPDIR").unwrap());
std::fs::create_dir_all(&temp_dir).unwrap();

let manifest_file = temp_dir.join("test_manifest_parsing.manifest");
std::fs::write(
&manifest_file,
[
"a/b c/d\n",
" a\\sb/c\\nd\\be f g/h\\ni\\bj\n",
"empty-file \n",
]
.join("\n"),
)
.unwrap();

with_mock_env(
[
(MANIFEST_FILE_ENV_VAR, Some(manifest_file.to_str().unwrap())),
(RUNFILES_DIR_ENV_VAR, None::<&str>),
(TEST_SRCDIR_ENV_VAR, None::<&str>),
],
|| {
let r = Runfiles::create().unwrap();
assert_eq!(r.rlocation("a/b"), Some(PathBuf::from("c/d")));
// Note that the `\s` is not escaped in the link, so not testing for it.
assert_eq!(
r.rlocation("a b/c\nd\\e"),
Some(PathBuf::from("f g/h\ni\\j"))
);
assert_eq!(r.rlocation("empty-file"), Some(PathBuf::from("")));
assert_eq!(r.rlocation("does/not/exist"), None);
},
);
}

#[test]
fn test_manifest_based_can_read_data_from_runfiles() {
let mut path_mapping = HashMap::new();
Expand Down