1use git2::{Object, Oid, Repository};
2use serde::Deserialize;
3use std::path::{Path, PathBuf};
4use std::{env, fs};
5
6#[derive(Deserialize, Clone)]
7struct QueryMatches {
8 query: String,
9 matches: Vec<String>,
10}
11
12#[derive(Deserialize, Clone)]
13struct RepoEval {
14 repo: String,
15 commit: String,
16 assertions: Vec<QueryMatches>,
17}
18
19const TMP_REPO_PATH: &str = "./target/eval_repos";
20
21fn parse_eval() -> anyhow::Result<Vec<RepoEval>> {
22 let eval_folder = env::current_dir()?
23 .as_path()
24 .parent()
25 .unwrap()
26 .join("crates/semantic_index/eval");
27
28 let mut repo_evals: Vec<RepoEval> = Vec::new();
29 for entry in fs::read_dir(eval_folder)? {
30 let file_path = entry.unwrap().path();
31 if let Some(extension) = file_path.extension() {
32 if extension == "json" {
33 if let Ok(file) = fs::read_to_string(file_path) {
34 let repo_eval = serde_json::from_str(file.as_str());
35
36 match repo_eval {
37 Ok(repo_eval) => {
38 repo_evals.push(repo_eval);
39 }
40 Err(err) => {
41 println!("Err: {:?}", err);
42 }
43 }
44 }
45 }
46 }
47 }
48
49 Ok(repo_evals)
50}
51
52fn clone_repo(repo_eval: RepoEval) -> anyhow::Result<PathBuf> {
53 let repo_name = Path::new(repo_eval.repo.as_str())
54 .file_name()
55 .unwrap()
56 .to_str()
57 .unwrap()
58 .to_owned()
59 .replace(".git", "");
60 let clone_path = Path::new(TMP_REPO_PATH).join(&repo_name).to_path_buf();
61
62 // Delete Clone Path if already exists
63 let _ = fs::remove_dir_all(&clone_path);
64
65 // Clone in Repo
66 git2::build::RepoBuilder::new()
67 // .branch(repo_eval.sha.as_str())
68 .clone(repo_eval.repo.as_str(), clone_path.as_path())?;
69
70 let repo: Repository = Repository::open(clone_path.clone())?;
71 let obj: Object = repo
72 .find_commit(Oid::from_str(repo_eval.commit.as_str())?)?
73 .into_object();
74 repo.checkout_tree(&obj, None)?;
75 repo.set_head_detached(obj.id())?;
76
77 Ok(clone_path)
78}
79
80fn main() {
81 if let Ok(repo_evals) = parse_eval() {
82 for repo in repo_evals {
83 let cloned = clone_repo(repo.clone());
84 match cloned {
85 Ok(clone_path) => {
86 println!(
87 "Cloned {:?} @ {:?} into {:?}",
88 repo.repo, repo.commit, clone_path
89 );
90 }
91 Err(err) => {
92 println!("Error Cloning: {:?}", err);
93 }
94 }
95 }
96 }
97}