Skip to content

Instantly share code, notes, and snippets.

@dportabella
Created November 8, 2016 21:13
Show Gist options
  • Save dportabella/3dbd22333012682210b6d6ee2e50118d to your computer and use it in GitHub Desktop.
Save dportabella/3dbd22333012682210b6d6ee2e50118d to your computer and use it in GitHub Desktop.
An example Scala script that runs a test on all github projects with a given name and their forks and branches (you need to install ammonite: brew install ammonite-repl)
#!/usr/bin/env amm
/* To run this script:
* $ chmod +x ./RunTestOnMultipleGithubRepos
* $ ./RunTestOnMultipleGithubRepos
*/
import ammonite.ops._
import scalaj.http._
import $ivy.`org.eclipse.jgit:org.eclipse.jgit:4.5.0.201609210915-r`, org.eclipse.jgit.api.Git
import org.eclipse.jgit.api.ListBranchCommand.ListMode
import org.eclipse.jgit.storage.file.FileRepositoryBuilder
import scala.collection.JavaConverters._
@main
def main() = {
// get all repos with this name, and all their forks
val repos = getGithubReposAndForks(nameQuery("jdeserialize"))
// test: run `ant` to build the project, and then run it with my test case
def testFn(dir: Path): String = {
val wd = dir/'jdeserialize
%('ant)(wd)
val res = %%('java, "-jar", "jdeserialize.jar", "/tmp/file.ser")(wd)
println(res.out); println(res.err)
if (res.err.string.isEmpty) "OK" else "ERROR"
}
// run the test on all the branches of all the repos
runTest(repos, testFn)
}
def runTest(repos: Seq[String], testFn: (Path) => String) {
val tmpDir: Path = tmp()
println(s"tmpDir: $tmpDir")
repos.foreach(repo => {
println(s"clone: $repo")
cloneRepo(repo, tmpDir)
val branches = getRemoteBranches(tmpDir)
println(s"branches: $branches")
branches.foreach(branch => {
println(s"clone: $repo branch: $branch")
cloneRepo(repo, tmpDir)
checkoutRemoteBranch(tmpDir, branch)
val res =
try testFn(tmpDir)
catch { case e: Throwable => "ERROR: " + e.toString }
val text = s"+++ $repo:$branch +++ $res"
println(text)
})
})
}
def nameQuery(name: String) =
Http("https://api.github.com/search/repositories?sort=stars&order=desc").param("q", name + " in:name")
def getGithubReposIds(httpRequest: HttpRequest): List[String] = {
val json = upickle.json.read(httpRequest.asString.body)
println("incomplete_results: " + json.obj("incomplete_results"))
(for { item <- json.obj("items").arr } yield item.obj("full_name").str).toList
}
def getGithubCloneUrl(repoId: String) = s"https://github.com/$repoId.git"
def getGithubForks(repoId: String): List[String] = {
val queryUrl = s"https://api.github.com/repos/$repoId/forks"
val json = upickle.json.read(Http(queryUrl).asString.body)
(for { item <- json.arr } yield item.obj("full_name").str).toList
}
def getGithubReposAndForks(httpRequest: HttpRequest): List[String] = {
val repos = getGithubReposIds(httpRequest)
.flatMap(r => r :: getGithubForks(r))
.distinct
.map(getGithubCloneUrl)
repos.foreach(println)
repos
}
def cloneRepo(cloneUrl: String, tmpDir: Path) {
createDir(tmpDir)
val cloneCommand = Git.cloneRepository()
cloneCommand.setURI(cloneUrl)
cloneCommand.setDirectory(tmpDir.toIO)
val git = cloneCommand.call()
}
def getGit(dir: Path): Git = {
val builder = new FileRepositoryBuilder()
val repository = builder.setGitDir(new java.io.File(dir.toIO, ".git"))
.readEnvironment().findGitDir().build()
new Git(repository)
}
def getRemoteBranches(dir: Path): List[String] = {
val git = getGit(dir)
val branchListCommand = git.branchList()
branchListCommand.setListMode(ListMode.REMOTE)
branchListCommand.call().asScala.toList
.map(_.getName)
}
def checkoutRemoteBranch(dir: Path, name: String) {
val git = getGit(dir)
val checkoutCommand = git.checkout()
checkoutCommand.setName("test")
checkoutCommand.setCreateBranch(true)
checkoutCommand.setStartPoint(name)
checkoutCommand.call()
}
val r = "refs/remotes/origin/(.*)".r
def getLocalName(name: String): String = name match {
case r(localName) => localName
}
def createDir(path: Path) {
rm! path
mkdir! path
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment