Skip to content

Instantly share code, notes, and snippets.

@cholick
Created March 21, 2012 05:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cholick/2144619 to your computer and use it in GitHub Desktop.
Save cholick/2144619 to your computer and use it in GitHub Desktop.
Script to export issues with comments for a github project
/**
*
* This script pulls all the issues from github for the project in the working directory
* and tosses them onto standard out
* Prerequisites: configure git with a username:
* $ git config --global github.user username
*
* @author Matt Cholick
*
* todo: Deal with rate limiting
*/
@Grab(group = 'org.codehaus.groovy.modules.http-builder', module = 'http-builder', version = '0.5.2')
// specifying explicit groovy version due to problem with grab and dependency range
// see http://groovy.329449.n5.nabble.com/Grab-is-Unusably-Slow-td371278.html
@Grab(group = "org.codehaus.groovy", module = "groovy", version = "1.8.6")
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.JSON
import static groovyx.net.http.Method.GET
import groovy.json.JsonOutput
//harvest username and repository information to connect with
String user = 'git config --get github.user'.execute().text.trim()
assert user
String origin = 'git remote show origin'.execute().text.trim()
assert origin
def repo = (origin =~ (/.*github.com:(\w*)\/(\w*).*/))
String repoUser = repo[0][1]
assert repoUser
String repoName = repo[0][2]
assert repoName
String password = null
System.in.withReader { reader ->
//print password prompt to error (so script output can be tossed into a file)
System.err.print "Password: "
password = reader.readLine().trim()
}
assert (password)
//perform a request to github's api and execute the callback on the returned json
def githubRequest = { url, callback ->
def github = new HTTPBuilder(url)
github.request(GET, JSON) { req ->
headers.'Accept' = 'application/vnd.github.VERSION.raw+json'
String encoded = "${user}:${password}".toString().bytes.encodeBase64().toString()
headers.'Authorization' = "Basic ${encoded}"
response.success = { resp, json ->
callback(json)
}
response.failure = { resp ->
println "Failure: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}"
}
}
}
//base repo url, pulled from project the script is run under
String baseUrl = "https://api.github.com/repos/${repoUser}/${repoName}/issues"
//get both opened and closed issues
["${baseUrl}?state=closed", "${baseUrl}?state=open"].each { issueUrl ->
githubRequest(issueUrl, { issuesJson ->
//pull just the numbers for each issue to iterate over
issuesJson.number.reverse().each { number ->
//get the full issue and output
githubRequest("${baseUrl}/${number}", { issueJson ->
//println JsonOutput.prettyPrint(issueJson.toString())
String header = "${number}: ${issueJson.title} by ${issueJson.user.login}, ${issueJson.state} (${issueJson.created_at})"
println "<h3>${header}</h3>"
if (issueJson.body) {
println "<p>${issueJson.body}</p>"
}
})
//get the list of comments and output
githubRequest("${baseUrl}/${number}/comments", { commentJson ->
//println JsonOutput.prettyPrint(commentJson.toString())
Integer commentCount = 1
//commentJson is an array of comments, loop over each and print
commentJson.each { commentJsonElement ->
println "<div style='margin-left: 2em'>"
//JsonOutput.prettyPrint(commentJsonElement.toString())
String header = "Comment ${commentCount++} of ${commentJson.size()} by ${commentJsonElement.user.login} (${commentJsonElement.created_at})"
println "<h4>${header}</h4>"
println "<hr/>"
println "<p>${commentJsonElement.body}</p>"
println "</div>"
}
})
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment