get the tree data structure working (finally)
This commit is contained in:
parent
cccab03886
commit
2371324cf3
17
Cargo.lock
generated
17
Cargo.lock
generated
@ -79,6 +79,12 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@ -227,6 +233,7 @@ name = "gh-stack"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"petgraph",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"tokio",
|
||||
@ -575,6 +582,16 @@ version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "0.4.17"
|
||||
|
@ -11,3 +11,4 @@ reqwest = { version = "0.10.6", features = ["json"] }
|
||||
tokio = { version = "0.2", features = ["full"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
futures = "0.3.5"
|
||||
petgraph = "0.5"
|
||||
|
@ -2,26 +2,28 @@ use futures::future::join_all;
|
||||
use serde::Deserialize;
|
||||
use std::error::Error;
|
||||
|
||||
use crate::{api, Credentials};
|
||||
use crate::{api, markdown, Credentials};
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
pub struct SearchItem {
|
||||
url: String,
|
||||
title: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
pub struct PullRequestRef {
|
||||
label: String,
|
||||
r#ref: String,
|
||||
sha: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
pub struct PullRequest {
|
||||
id: usize,
|
||||
number: usize,
|
||||
head: PullRequestRef,
|
||||
base: PullRequestRef,
|
||||
merges_into: Option<Box<PullRequest>>,
|
||||
title: String,
|
||||
}
|
||||
|
||||
@ -33,8 +35,22 @@ impl PullRequest {
|
||||
pub fn base(&self) -> &str {
|
||||
&self.base.label
|
||||
}
|
||||
|
||||
pub fn set_merges_into(&mut self, into: PullRequest) {
|
||||
// `clone` here to avoid an explosion of lifetime specifiers
|
||||
self.merges_into = Some(Box::new(into))
|
||||
}
|
||||
}
|
||||
|
||||
// impl markdown::AsMarkdown for PullRequest {
|
||||
// fn as_markdown_table_row(&self) -> String {
|
||||
// match self.merges_into {
|
||||
// Some(into) => format!("|#{}|{}|#{}|", self.number, self.title, into.number),
|
||||
// None => format!("|#{}|{}|`develop`/feature branch|", self.number, self.title),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct SearchResponse {
|
||||
items: Vec<SearchItem>,
|
||||
|
41
src/graph.rs
41
src/graph.rs
@ -1,34 +1,23 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use petgraph::visit::IntoNodeReferences;
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use petgraph::Graph;
|
||||
|
||||
use crate::api::search::PullRequest;
|
||||
|
||||
pub fn build(prs: &[PullRequest]) {
|
||||
let mut heads = HashSet::new();
|
||||
let mut prs_by_base = HashMap::new();
|
||||
pub fn build(prs: Vec<Rc<PullRequest>>) -> Graph<Rc<PullRequest>, usize> {
|
||||
let mut tree = Graph::<Rc<PullRequest>, usize>::new();
|
||||
let heads = prs.iter().map(|pr| pr.head());
|
||||
let handles: Vec<_> = prs.iter().map(|pr| tree.add_node(pr.clone())).collect();
|
||||
let handles_by_head: HashMap<_, _> = heads.zip(handles.iter()).collect();
|
||||
|
||||
for pr in prs.iter() {
|
||||
heads.insert(pr.head());
|
||||
let entry = prs_by_base.entry(pr.base()).or_insert(Vec::new());
|
||||
entry.push(pr);
|
||||
for (i, pr) in prs.iter().enumerate() {
|
||||
let head_handle = handles[i];
|
||||
if let Some(&base_handle) = handles_by_head.get(pr.base()) {
|
||||
tree.add_edge(head_handle, *base_handle, 1);
|
||||
}
|
||||
}
|
||||
|
||||
let roots: Vec<&PullRequest> = prs.iter().filter(|pr| !heads.contains(pr.base())).collect();
|
||||
let results = resolve(&roots, &prs_by_base);
|
||||
}
|
||||
|
||||
fn resolve<'a>(
|
||||
roots: &Vec<&'a PullRequest>,
|
||||
prs_by_base: &'a HashMap<&str, Vec<&PullRequest>>
|
||||
) -> Vec<&'a PullRequest> {
|
||||
let mut results = Vec::new();
|
||||
|
||||
for &root in roots.iter() {
|
||||
results.push(root);
|
||||
if let Some(children) = prs_by_base.get(root.head()) {
|
||||
let mut children = resolve(children, prs_by_base);
|
||||
results.append(&mut children);
|
||||
}
|
||||
}
|
||||
|
||||
results
|
||||
tree
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
pub mod api;
|
||||
pub mod graph;
|
||||
pub mod markdown;
|
||||
|
||||
pub struct Credentials {
|
||||
// Personal access token
|
||||
|
@ -1,10 +1,12 @@
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::process;
|
||||
|
||||
use gh_stack::api;
|
||||
use gh_stack::graph;
|
||||
use gh_stack::markdown;
|
||||
use gh_stack::Credentials;
|
||||
|
||||
#[tokio::main]
|
||||
@ -25,7 +27,11 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let credentials = Credentials::new(token);
|
||||
|
||||
let prs = api::search::fetch_pull_requests_matching(&pattern, &credentials).await?;
|
||||
graph::build(&prs);
|
||||
let prs = prs.into_iter().map(|pr| Rc::new(pr)).collect();
|
||||
let tree = graph::build(prs);
|
||||
println!("{:?}", tree);
|
||||
|
||||
// markdown::build_table(&graph[..]);
|
||||
|
||||
Ok(())
|
||||
/*
|
||||
|
8
src/markdown.rs
Normal file
8
src/markdown.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use crate::api::search::PullRequest;
|
||||
use std::fmt::Display;
|
||||
|
||||
pub trait AsMarkdown {
|
||||
fn as_markdown_table_row(&self) -> String;
|
||||
}
|
||||
|
||||
pub fn build_table<T: Display>(graph: &[T]) {}
|
Loading…
Reference in New Issue
Block a user