Created
November 8, 2016 21:13
-
-
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)
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
#!/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