Skip to content

Instantly share code, notes, and snippets.

@alexcrichton
Created November 15, 2014 19:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save alexcrichton/cfa1c2db32e00673a832 to your computer and use it in GitHub Desktop.
Save alexcrichton/cfa1c2db32e00673a832 to your computer and use it in GitHub Desktop.
#![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