-
-
Save alexcrichton/cfa1c2db32e00673a832 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(macro_rules)] | |
extern crate curl; | |
extern crate libc; | |
extern crate serialize; | |
use std::io::process::{Command, InheritFd}; | |
use std::io::{stdio, File, BufReader}; | |
use std::os; | |
use curl::http; | |
use serialize::json; | |
fn number(json: Option<json::Json>) -> u64 { | |
json.unwrap().as_u64().expect("not a number") | |
} | |
fn string(json: Option<json::Json>) -> String { | |
match json { | |
Some(json::String(s)) => s, | |
_ => fail!("not a string"), | |
} | |
} | |
fn object(json: Option<json::Json>) -> json::JsonObject { | |
match json { | |
Some(json::Object(l)) => l, | |
_ => fail!("not an object"), | |
} | |
} | |
fn list(json: Option<json::Json>) -> json::JsonList { | |
match json { | |
Some(json::List(l)) => l, | |
_ => fail!("not a list"), | |
} | |
} | |
fn fetch() -> json::Json { | |
let url = "https://api.github.com/repos/rust-lang/rust/pulls?direction=asc"; | |
let mut url = url.to_string(); | |
let mut ret = Vec::new(); | |
'outer: loop { | |
println!("fetching -- {}", url); | |
let response = http::handle() | |
.get(url.as_slice()) | |
.header("User-Agent", "fun-times") | |
.exec() | |
.unwrap(); | |
let mut rdr = BufReader::new(response.get_body()); | |
let l = list(Some(serialize::json::from_reader(&mut rdr).unwrap())); | |
ret.extend(l.into_iter()); | |
for header in response.get_header("link").iter() { | |
for part in header.as_slice().split(',') { | |
let part = part.trim(); | |
if !part.ends_with("; rel=\"next\"") { continue } | |
url = header.as_slice() | |
.slice(1, header.as_slice().find_str(">").unwrap()) | |
.to_string(); | |
continue 'outer | |
} | |
} | |
break | |
} | |
return json::List(ret); | |
} | |
fn main() { | |
let mut input = stdio::stdin(); | |
let args = os::args(); | |
let json = if args.len() > 1 { | |
let mut file = File::open(&Path::new(args[1].as_slice())).unwrap(); | |
serialize::json::from_reader(&mut file).unwrap() | |
} else { | |
let json = fetch(); | |
File::create(&Path::new("github.json")) | |
.write(json.to_string().as_bytes()) | |
.unwrap(); | |
json | |
}; | |
// let mut message = File::open_mode(&Path::new("commit-message"), | |
// io::Append, io::Write); | |
let min = os::getenv("PR").and_then(|s| { | |
from_str::<uint>(s.as_slice()) | |
}); | |
for opr in list(Some(json)).into_iter() { | |
let mut pr = object(Some(opr)); | |
let number = number(pr.pop(&"number".to_string())); | |
if Some(number as uint) < min { continue } | |
let title = string(pr.pop(&"title".to_string())); | |
print!("merge {} {}? [y/N]: ", number, title); | |
let line = input.read_line().unwrap(); | |
let line = line.as_slice(); | |
if line.starts_with("q") { break } | |
if !line.starts_with("y") { continue } | |
let mut head = object(pr.pop(&"head".to_string())); | |
let mut user = object(pr.pop(&"user".to_string())); | |
let mut repo = object(head.pop(&"repo".to_string())); | |
let login = string(user.pop(&"login".to_string())); | |
let git_ref = string(head.pop(&"ref".to_string())); | |
let sha = string(head.pop(&"sha".to_string())); | |
let url = string(repo.pop(&"git_url".to_string())); | |
let msg = format!("rollup merge of #{} : {}/{}", number, login, git_ref); | |
macro_rules! git( ($($a:expr),*) => ({ | |
let mut cmd = Command::new("git"); | |
$(cmd.arg($a);)* | |
println!("\x1b[38;5;106m$ {}\x1b[0m", cmd); | |
cmd.stdout(InheritFd(libc::STDOUT_FILENO)); | |
cmd.stderr(InheritFd(libc::STDERR_FILENO)); | |
cmd.status().unwrap().success() | |
}) ) | |
let _ = git!("remote", "rm", login.as_slice()); | |
assert!(git!("remote", "add", login.as_slice(), url)); | |
assert!(git!("fetch", login.as_slice(), git_ref)); | |
if !git!("merge", "--no-ff", "-m", msg, sha) { | |
println!("\x1b[38;5;160m{}\x1b[0m", | |
"couldn't merge"); | |
assert!(git!("merge", "--abort")); | |
} | |
// assert!(git!("branch", "-D", "rollup-merge")); | |
// assert!(git!("checkout", "-b", "rollup-merge", sha)); | |
// if git!("rebase", "rollup") { | |
// assert!(git!("checkout", "rollup")); | |
// assert!(git!("reset", "--hard", "rollup-merge")); | |
// | |
// (writeln!(&mut message, "Closes #{} ({})", number, title)).unwrap(); | |
// } else { | |
// println!("\x1b[38;5;160m{}\x1b[0m", | |
// "couldn't merge"); | |
// assert!(git!("rebase", "--abort")); | |
// assert!(git!("reset", "--hard")); | |
// assert!(git!("checkout", "rollup")); | |
// } | |
// assert!(git!("branch", "-D", "rollup-merge")); | |
assert!(git!("remote", "rm", login.as_slice())); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment