wip: pr file diffing
This commit is contained in:
153
build.rs
153
build.rs
@@ -133,9 +133,13 @@ fn render_assets(
|
||||
fn render_github_fixtures(fixture_root: &Path) -> String {
|
||||
let user_fetch = read_json_fixture(&fixture_root.join("user.fetch.json"));
|
||||
let repo_list = read_json_fixture(&fixture_root.join("repo.list.json"));
|
||||
let repo_file_content_root = fixture_root.join("repo.file_content");
|
||||
|
||||
let mut issue_fixtures = BTreeMap::<(String, u32), String>::new();
|
||||
let mut pull_request_fixtures = BTreeMap::<String, String>::new();
|
||||
let mut pull_request_file_tree_fixtures = BTreeMap::<String, String>::new();
|
||||
let mut repo_file_content_fixtures =
|
||||
BTreeMap::<(String, String, String, Option<String>), String>::new();
|
||||
let mut pull_request_timeline_fixtures =
|
||||
BTreeMap::<String, BTreeMap<u32, TimelineFixturePage>>::new();
|
||||
let mut entries = fs::read_dir(fixture_root)
|
||||
@@ -144,6 +148,14 @@ fn render_github_fixtures(fixture_root: &Path) -> String {
|
||||
.collect::<Vec<_>>();
|
||||
entries.sort_by_key(|entry| entry.file_name());
|
||||
|
||||
if repo_file_content_root.exists() {
|
||||
collect_repo_file_content_fixtures(
|
||||
&repo_file_content_root,
|
||||
&repo_file_content_root,
|
||||
&mut repo_file_content_fixtures,
|
||||
);
|
||||
}
|
||||
|
||||
for entry in entries {
|
||||
let file_name = entry
|
||||
.file_name()
|
||||
@@ -161,6 +173,13 @@ fn render_github_fixtures(fixture_root: &Path) -> String {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(id) = parse_pull_request_file_tree_fixture_name(&file_name) {
|
||||
let value = read_fixture_value(&entry.path());
|
||||
pull_request_file_tree_fixtures
|
||||
.insert(id, read_pull_request_file_tree_fixture(&value, &entry.path()));
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some((id, page)) = parse_pull_request_timeline_fixture_name(&file_name) {
|
||||
let value = read_fixture_value(&entry.path());
|
||||
pull_request_timeline_fixtures
|
||||
@@ -199,6 +218,35 @@ fn render_github_fixtures(fixture_root: &Path) -> String {
|
||||
output.push_str(" }\n");
|
||||
output.push_str("}\n");
|
||||
|
||||
output.push_str("\n");
|
||||
output.push_str(
|
||||
"pub fn repo_file_content(owner: &str, repo: &str, path: &str, reff: Option<&str>) -> Option<&'static str> {\n",
|
||||
);
|
||||
output.push_str(" match (owner, repo, path, reff) {\n");
|
||||
for ((owner, repo, path, reff), content) in repo_file_content_fixtures {
|
||||
output.push_str(" (");
|
||||
output.push_str(&string_literal(&owner));
|
||||
output.push_str(", ");
|
||||
output.push_str(&string_literal(&repo));
|
||||
output.push_str(", ");
|
||||
output.push_str(&string_literal(&path));
|
||||
output.push_str(", ");
|
||||
match reff {
|
||||
| Some(reff) => {
|
||||
output.push_str("Some(");
|
||||
output.push_str(&string_literal(&reff));
|
||||
output.push(')');
|
||||
}
|
||||
| None => output.push_str("None"),
|
||||
}
|
||||
output.push_str(") => Some(");
|
||||
output.push_str(&string_literal(&content));
|
||||
output.push_str("),\n");
|
||||
}
|
||||
output.push_str(" _ => None,\n");
|
||||
output.push_str(" }\n");
|
||||
output.push_str("}\n");
|
||||
|
||||
output.push_str("\n");
|
||||
output.push_str("pub fn issues_pull_request(id: &str) -> Option<&'static str> {\n");
|
||||
output.push_str(" match id {\n");
|
||||
@@ -213,6 +261,20 @@ fn render_github_fixtures(fixture_root: &Path) -> String {
|
||||
output.push_str(" }\n");
|
||||
output.push_str("}\n");
|
||||
|
||||
output.push_str("\n");
|
||||
output.push_str("pub fn issues_pull_request_file_tree(id: &str) -> Option<&'static str> {\n");
|
||||
output.push_str(" match id {\n");
|
||||
for (id, json) in pull_request_file_tree_fixtures {
|
||||
output.push_str(" ");
|
||||
output.push_str(&string_literal(&id));
|
||||
output.push_str(" => Some(");
|
||||
output.push_str(&string_literal(&json));
|
||||
output.push_str("),\n");
|
||||
}
|
||||
output.push_str(" _ => None,\n");
|
||||
output.push_str(" }\n");
|
||||
output.push_str("}\n");
|
||||
|
||||
output.push_str("\n");
|
||||
output.push_str("pub fn issues_pull_request_timeline(id: &str, after: Option<&str>) -> Option<&'static str> {\n");
|
||||
output.push_str(" match (id, after) {\n");
|
||||
@@ -322,6 +384,28 @@ fn read_timeline_fixture(value: &serde_json::Value, path: &Path) -> TimelineFixt
|
||||
TimelineFixturePage { json, end_cursor }
|
||||
}
|
||||
|
||||
fn read_pull_request_file_tree_fixture(value: &serde_json::Value, path: &Path) -> String {
|
||||
if !matches!(
|
||||
value
|
||||
.get("node")
|
||||
.and_then(|node| node.get("files"))
|
||||
.and_then(|files| files.get("edges")),
|
||||
Some(serde_json::Value::Array(_))
|
||||
) {
|
||||
panic!(
|
||||
"pull request file tree fixture {} must include node.files.edges",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
|
||||
serde_json::to_string(value).unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"failed to serialize pull request file tree fixture {}: {err}",
|
||||
path.display()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn map_issue_fixture(issue: &serde_json::Value) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"id": issue_fixture_graphql_id(issue),
|
||||
@@ -371,6 +455,69 @@ fn required_string<'a>(value: &'a serde_json::Value, path: &[&str]) -> &'a str {
|
||||
.unwrap_or_else(|| panic!("expected string at {} in fixture", path.join(".")))
|
||||
}
|
||||
|
||||
fn collect_repo_file_content_fixtures(
|
||||
root: &Path,
|
||||
dir: &Path,
|
||||
fixtures: &mut BTreeMap<(String, String, String, Option<String>), String>,
|
||||
) {
|
||||
let mut entries = fs::read_dir(dir)
|
||||
.unwrap_or_else(|err| panic!("failed to read {}: {err}", dir.display()))
|
||||
.map(|entry| entry.expect("failed to read repo file content fixture entry"))
|
||||
.collect::<Vec<_>>();
|
||||
entries.sort_by_key(|entry| entry.file_name());
|
||||
|
||||
for entry in entries {
|
||||
let path = entry.path();
|
||||
if path.is_dir() {
|
||||
collect_repo_file_content_fixtures(root, &path, fixtures);
|
||||
continue;
|
||||
}
|
||||
|
||||
if !path.is_file() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let relative = path.strip_prefix(root).unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"failed to compute repo file content fixture path {}: {err}",
|
||||
path.display()
|
||||
)
|
||||
});
|
||||
let parts = relative
|
||||
.components()
|
||||
.map(|component| component.as_os_str().to_string_lossy().into_owned())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if parts.len() < 4 {
|
||||
panic!(
|
||||
"repo file content fixture {} must be nested as owner/repo/ref/path",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
|
||||
let owner = parts[0].clone();
|
||||
let repo = parts[1].clone();
|
||||
let reff = match parts[2].as_str() {
|
||||
| "@default" => None,
|
||||
| value => Some(value.to_owned()),
|
||||
};
|
||||
let virtual_path = parts[3..].join("/");
|
||||
let content = fs::read_to_string(&path).unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"failed to read repo file content fixture {}: {err}",
|
||||
path.display()
|
||||
)
|
||||
});
|
||||
|
||||
if fixtures
|
||||
.insert((owner, repo, virtual_path, reff), content)
|
||||
.is_some()
|
||||
{
|
||||
panic!("duplicate repo file content fixture for {}", path.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_issue_fixture_name(file_name: &str) -> Option<(String, u32)> {
|
||||
let name = file_name.strip_suffix(".json")?;
|
||||
let rest = name.strip_prefix("issues.pull_requests.")?;
|
||||
@@ -392,6 +539,12 @@ fn parse_pull_request_timeline_fixture_name(file_name: &str) -> Option<(String,
|
||||
Some((id.to_owned(), page))
|
||||
}
|
||||
|
||||
fn parse_pull_request_file_tree_fixture_name(file_name: &str) -> Option<String> {
|
||||
let name = file_name.strip_suffix(".json")?;
|
||||
name.strip_prefix("issues.pull_request_file_tree.")
|
||||
.map(str::to_owned)
|
||||
}
|
||||
|
||||
fn string_literal(value: &str) -> String {
|
||||
format!("{value:?}")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user