summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWyatt Calandro <64923869+wcalandro@users.noreply.github.com>2022-06-10 14:51:09 -0700
committerGitHub <noreply@github.com>2022-06-10 14:51:09 -0700
commit48b4edf36193ffe9f1b8d5263c54e6e2d058f6e4 (patch)
tree3c73d3112cdb83a1a8c20ef1a15ed5fee84c3fb2
parent40808f97d474b2e6a609b585974311c4b8d32892 (diff)
downloadkythe-48b4edf36193ffe9f1b8d5263c54e6e2d058f6e4.tar.gz
fix(rust_extractor): find the analysis file based on crate name (#5306)
-rw-r--r--kythe/rust/extractor/src/bin/extractor.rs68
1 files changed, 40 insertions, 28 deletions
diff --git a/kythe/rust/extractor/src/bin/extractor.rs b/kythe/rust/extractor/src/bin/extractor.rs
index 86198ee0e..547313e71 100644
--- a/kythe/rust/extractor/src/bin/extractor.rs
+++ b/kythe/rust/extractor/src/bin/extractor.rs
@@ -23,10 +23,10 @@ use extra_actions_base_rust_proto::*;
use kythe_rust_extractor::vname_util::VNameRule;
use protobuf::Message;
use sha2::{Digest, Sha256};
-use std::env;
use std::fs::File;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
+use std::{env, fs};
use tempdir::TempDir;
use zip::{write::FileOptions, ZipWriter};
@@ -82,13 +82,30 @@ fn main() -> Result<()> {
}
// Grab the build target's output path
- let build_output_path: &String = spawn_info
+ let build_output_path = spawn_info
.get_output_file()
.get(0)
.ok_or_else(|| anyhow!("Failed to get output file from spawn info"))?;
+ // Infer the crate name from the compiler args, falling back to the output file
+ // name if necessary
+ let crate_name = {
+ let crate_name_matches: Vec<_> =
+ build_target_arguments.iter().filter(|arg| arg.starts_with("--crate-name=")).collect();
+ if !crate_name_matches.is_empty() {
+ crate_name_matches.get(0).unwrap().replace("--crate-name=", "")
+ } else {
+ PathBuf::from(build_output_path)
+ .file_name()
+ .unwrap()
+ .to_str()
+ .ok_or_else(|| anyhow!("Failed to convert build output path file name to string"))?
+ .to_string()
+ }
+ };
+
// Add save analysis to kzip
- let save_analysis_path: String = analysis_path_string(build_output_path, tmp_dir.path())?;
+ let save_analysis_path: String = analysis_path_string(&crate_name, tmp_dir.path())?;
let save_analysis_vname: VName =
create_vname(&mut vname_rules, &save_analysis_path, &default_corpus);
kzip_add_required_input(
@@ -246,33 +263,28 @@ fn kzip_add_file(
Ok(())
}
-/// Generate the string path of the save_analysis file using the build target's
-/// output path and the temporary base directory
-fn analysis_path_string(build_output_path: &str, temp_dir_path: &Path) -> Result<String> {
- // Take the build output path and change the extension to .json
- let analysis_file_name = Path::new(build_output_path).with_extension("json");
- // Extract the file name from the path and convert to a string
- let analysis_file_str = analysis_file_name
- .file_name()
- .unwrap()
- .to_str()
- .ok_or_else(|| anyhow!("Failed to convert path to string"))?;
-
- // Join the temp_dir_path with "save-analysis/${analysis_file_str}" to get the
- // full path of the save_analysis JSON file
- let mut path = temp_dir_path.join("save-analysis").join(analysis_file_str);
-
- // The path should almost always exist. However, if the target name had
- // hyphens, then the final save_analysis file has underscores. We can't
- // always replace the hyphens with underscores because the save_analysis
- // files for libraries have hyphens in them.
- if !path.exists() {
- path = temp_dir_path.join("save-analysis").join(analysis_file_str.replace('-', "_"));
+/// Find the path of the save_analysis file using the build target's
+/// crate name and the temporary base directory
+fn analysis_path_string(crate_name: &str, temp_dir_path: &Path) -> Result<String> {
+ let entries = fs::read_dir(temp_dir_path.join("save-analysis")).with_context(|| {
+ format!("Failed to read the save_analysis temporary directory: {:?}", temp_dir_path)
+ })?;
+
+ for entry in entries {
+ let entry = entry.with_context(|| "Failed to get information about directory entry")?;
+ let metadata = entry.metadata().with_context(|| "Failed to get entry metadata")?;
+ let path = entry.path();
+ let path_string = path
+ .to_str()
+ .ok_or_else(|| anyhow!("save_analysis file path is not valid UTF-8"))
+ .map(|path_str| path_str.to_string())?;
+ if metadata.is_file() && path_string.contains(crate_name) && path_string.ends_with(".json")
+ {
+ return Ok(path_string);
+ }
}
- path.to_str()
- .ok_or_else(|| anyhow!("save_analysis file path is not valid UTF-8"))
- .map(|path_str| path_str.to_string())
+ Err(anyhow!("Failed to find save-analysis file in {:?}", temp_dir_path))
}
fn create_vname(rules: &mut [VNameRule], path: &str, default_corpus: &str) -> VName {