log a textual representation
This commit is contained in:
parent
4864a12151
commit
7b131d8b6b
27
src/graph.rs
27
src/graph.rs
@ -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
|
||||||
|
}
|
||||||
|
54
src/main.rs
54
src/main.rs
@ -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
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user