log a textual representation

This commit is contained in:
Timothy Andrew 2020-06-04 16:42:57 +05:30
parent 4864a12151
commit 7b131d8b6b
No known key found for this signature in database
GPG Key ID: ABD64509E977B249
3 changed files with 63 additions and 19 deletions

View File

@ -1,6 +1,8 @@
use petgraph::Graph; use petgraph::visit::Bfs;
use std::collections::HashMap; use petgraph::visit::EdgeRef;
use petgraph::{Direction, Graph};
use std::rc::Rc; use std::rc::Rc;
use std::collections::HashMap;
use crate::api::search::PullRequest; use crate::api::search::PullRequest;
@ -19,3 +21,24 @@ pub fn build(prs: &Vec<Rc<PullRequest>>) -> Graph<Rc<PullRequest>, usize> {
tree tree
} }
/// Return a flattened list of graph nodes as tuples; each tuple is `(node, node's parent [if exists])`.
pub fn log(graph: &Graph<Rc<PullRequest>, usize>) -> Vec<(Rc<PullRequest>, Option<Rc<PullRequest>>)> {
let roots: Vec<_> = graph.externals(Direction::Incoming).collect();
let mut out = Vec::new();
for root in roots {
let mut bfs = Bfs::new(&graph, root);
while let Some(node) = bfs.next(&graph) {
let parent = graph.edges_directed(node, Direction::Incoming).next();
let node: Rc<PullRequest> = graph[node].clone();
match parent {
Some(parent) => out.push((node, Some(graph[parent.source()].clone()))),
None => out.push((node, None)),
}
}
}
out
}

View File

@ -35,13 +35,14 @@ async fn main() -> Result<(), Box<dyn Error>> {
let env: HashMap<String, String> = env::vars().collect(); let env: HashMap<String, String> = env::vars().collect();
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
if args.len() > 3 { if args.len() > 4 {
println!("usage: gh-stack <pattern> <prelude_filename>"); println!("usage: gh-stack <command=save|log> <pattern> <prelude_filename?>");
process::exit(1); process::exit(1);
} }
let pattern = &args[1]; let command = &args[1][..];
let prelude = args.get(2); let pattern = &args[2];
let prelude = args.get(3);
let token = env let token = env
.get("GHSTACK_OAUTH_TOKEN") .get("GHSTACK_OAUTH_TOKEN")
@ -52,22 +53,40 @@ async fn main() -> Result<(), Box<dyn Error>> {
let prs = api::search::fetch_pull_requests_matching(&pattern, &credentials).await?; let prs = api::search::fetch_pull_requests_matching(&pattern, &credentials).await?;
let prs = prs.into_iter().map(|pr| Rc::new(pr)).collect(); let prs = prs.into_iter().map(|pr| Rc::new(pr)).collect();
let tree = graph::build(&prs); let tree = graph::build(&prs);
let table = markdown::build_table(tree, pattern);
let output = match prelude { match command {
Some(prelude) => build_final_output(prelude, &table), "github" => {
None => table let table = markdown::build_table(tree, pattern);
let output = match prelude {
Some(prelude) => build_final_output(prelude, &table),
None => table
};
for pr in prs.iter() {
println!("{}: {}", pr.number(), pr.title());
}
let response = read_cli_input("Going to update these PRs ☝️ (y/n): ");
match &response[..] {
"y" => persist::persist(&prs, &output, &credentials).await?,
_ => std::process::exit(1),
}
}
"log" => {
let log = graph::log(&tree);
for (pr, maybe_parent) in log {
match maybe_parent {
Some(parent) => println!("{}{}", pr.head(), parent.head()),
None => println!("{} → N/A", pr.head())
}
}
}
_ => { panic!("Invalid command!") }
}; };
for pr in prs.iter() {
println!("{}: {}", pr.number(), pr.title());
}
let response = read_cli_input("Going to update these PRs ☝️ (y/n): ");
match &response[..] {
"y" => persist::persist(&prs, &output, &credentials).await?,
_ => std::process::exit(1),
}
println!("Done!"); println!("Done!");
@ -80,6 +99,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
- [x] Create markdown table - [x] Create markdown table
- [x] Persist table back to Github - [x] Persist table back to Github
- [x] Accept a prelude via STDIN - [x] Accept a prelude via STDIN
- [x] Log a textual representation of the graph
- [ ] Panic on non-200s - [ ] Panic on non-200s
*/ */
} }

View File

@ -18,6 +18,7 @@ pub fn build_table(graph: Graph<Rc<PullRequest>, usize>, title: &str) -> String
out.push_str("| PR | Title | Merges Into |\n"); out.push_str("| PR | Title | Merges Into |\n");
out.push_str("|:--:|:------|:-------------:|\n"); out.push_str("|:--:|:------|:-------------:|\n");
// TODO: Use graph::log to simplify this
let roots: Vec<_> = graph.externals(Direction::Incoming).collect(); let roots: Vec<_> = graph.externals(Direction::Incoming).collect();
for root in roots { for root in roots {