Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/rorschach.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Rebert <code@rebertia.com>2014-10-10 05:45:54 +0400
committerChris Rebert <code@rebertia.com>2014-10-10 05:48:16 +0400
commitae4710d99f95fe0d5920a5adc942679bba5b7f27 (patch)
treeafff8461164d7aaeba7e84b96fd892d4e5d79785 /src
parenta6fd8eaedbbc5d8ace8bb7a32c093e9be643ba8b (diff)
have Rorschach try to close bad PRs
Diffstat (limited to 'src')
-rw-r--r--src/main/resources/application.conf27
-rw-r--r--src/main/scala/com/getbootstrap/rorschach/github/GitHubIssueCommenter.scala40
-rw-r--r--src/main/scala/com/getbootstrap/rorschach/github/GitHubPullRequestCommenter.scala61
-rw-r--r--src/main/scala/com/getbootstrap/rorschach/github/IssueNumber.scala15
-rw-r--r--src/main/scala/com/getbootstrap/rorschach/github/PullRequestFeedback.scala2
-rw-r--r--src/main/scala/com/getbootstrap/rorschach/github/PullRequestNumber.scala15
-rw-r--r--src/main/scala/com/getbootstrap/rorschach/github/PullRequestStatus.scala20
-rw-r--r--src/main/scala/com/getbootstrap/rorschach/github/util/package.scala23
-rw-r--r--src/main/scala/com/getbootstrap/rorschach/server/Boot.scala31
-rw-r--r--src/main/scala/com/getbootstrap/rorschach/server/PullRequestEventHandler.scala20
-rw-r--r--src/main/scala/com/getbootstrap/rorschach/server/Settings.scala1
11 files changed, 170 insertions, 85 deletions
diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf
new file mode 100644
index 0000000..bcc55f0
--- /dev/null
+++ b/src/main/resources/application.conf
@@ -0,0 +1,27 @@
+akka {
+ loglevel = INFO
+}
+
+spray.can {
+ server {
+ request-timeout = 5 s
+ }
+
+ client {
+ user-agent-header = "Rorschach/0.1 (https://github.com/cvrebert/rorschach)"
+ request-timeout = 20 s
+ idle-timeout = 15 s
+ }
+ host-connector {
+ max-connections = 5
+ max-retries = 3
+ max-redirects = 3
+ }
+}
+
+rorschach {
+ default-port = 9090
+ username = throwaway9475947
+ password = XXXXXXXX
+ web-hook-secret-key = abcdefg
+}
diff --git a/src/main/scala/com/getbootstrap/rorschach/github/GitHubIssueCommenter.scala b/src/main/scala/com/getbootstrap/rorschach/github/GitHubIssueCommenter.scala
deleted file mode 100644
index 368c96a..0000000
--- a/src/main/scala/com/getbootstrap/rorschach/github/GitHubIssueCommenter.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.getbootstrap.rorschach.github
-
-import scala.util.{Try,Failure,Success}
-import org.eclipse.egit.github.core.service.IssueService
-import org.eclipse.egit.github.core.RepositoryId
-import com.getbootstrap.rorschach.server.Settings
-
-
-class GitHubIssueCommenter extends GitHubActorWithLogging {
- // val settings = Settings(context.system)
-
- private def tryToCommentOn(repo: RepositoryId, issue: IssueNumber, commentMarkdown: String) = {
- val issueService = new IssueService(gitHubClient)
- Try { issueService.createComment(repo, issue.number, commentMarkdown) }
- }
-
- override def receive = {
- case PullRequestFeedback(prNum, requester, messages) => {
- val username = requester.getLogin
- val messagesMarkdown = messages.map{ "* " + _ }.mkString("\n")
- val commentMarkdown = s"""
- |Hi @${username}!
- |
- |Thanks for wanting to contribute to Bootstrap by sending this pull request.
- |Unfortunately, your pull request seems to have some problems:
- |${messagesMarkdown}
- |
- |You'll need to **fix these mistakes** and revise your pull request before we can proceed further.
- |Thanks!
- |
- |(*Please note that this is a fully automated comment.*)
- """.stripMargin
-
- tryToCommentOn(BootstrapRepoId, prNum, commentMarkdown) match {
- case Success(comment) => log.info(s"Successfully posted comment ${comment.getUrl} for ${prNum}")
- case Failure(exc) => log.error(exc, s"Error posting comment for ${prNum}")
- }
- }
- }
-}
diff --git a/src/main/scala/com/getbootstrap/rorschach/github/GitHubPullRequestCommenter.scala b/src/main/scala/com/getbootstrap/rorschach/github/GitHubPullRequestCommenter.scala
new file mode 100644
index 0000000..77171c2
--- /dev/null
+++ b/src/main/scala/com/getbootstrap/rorschach/github/GitHubPullRequestCommenter.scala
@@ -0,0 +1,61 @@
+package com.getbootstrap.rorschach.github
+
+import scala.util.{Try,Failure,Success}
+import org.eclipse.egit.github.core.service.{PullRequestService, IssueService}
+import org.eclipse.egit.github.core.RepositoryId
+import com.getbootstrap.rorschach.github.util.RichPullRequest
+import com.getbootstrap.rorschach.server.Settings
+
+
+class GitHubPullRequestCommenter extends GitHubActorWithLogging {
+ // val settings = Settings(context.system)
+
+ private def tryToCommentOn(repo: RepositoryId, prNum: PullRequestNumber, commentMarkdown: String) = {
+ val issueService = new IssueService(gitHubClient)
+ Try { issueService.createComment(repo, prNum.number, commentMarkdown) }
+ }
+
+ private def tryToClose(repo: RepositoryId, prNum: PullRequestNumber): Try[None.type] = {
+ val prService = new PullRequestService(gitHubClient)
+ val prTry = Try { prService.getPullRequest(repo, prNum.number) } match {
+ case fetchFail@Failure(exc) => {
+ log.error(exc, s"Error fetching pull request ${prNum} in order to close it")
+ fetchFail
+ }
+ case Success(pr) => {
+ pr.status = Closed
+ Try { prService.editPullRequest(repo, pr) }
+ }
+ }
+ prTry.map{ x => None }
+ }
+
+ override def receive = {
+ case PullRequestFeedback(prNum, requester, messages) => {
+ val username = requester.getLogin
+ val messagesMarkdown = messages.map{ "* " + _ }.mkString("\n")
+ val commentMarkdown = s"""
+ |Hi @${username}!
+ |
+ |Thanks for wanting to contribute to Bootstrap by sending this pull request.
+ |Unfortunately, your pull request seems to have some problems:
+ |${messagesMarkdown}
+ |
+ |You'll need to **fix these mistakes** and revise your pull request before we can proceed further.
+ |Thanks!
+ |
+ |(*Please note that this is a [fully automated](https://github.com/cvrebert/rorschach) comment.*)
+ """.stripMargin
+
+ tryToCommentOn(BootstrapRepoId, prNum, commentMarkdown) match {
+ case Success(comment) => log.info(s"Successfully posted comment ${comment.getUrl} for ${prNum}")
+ case Failure(exc) => log.error(exc, s"Error posting comment for ${prNum}")
+ }
+
+ tryToClose(BootstrapRepoId, prNum) match {
+ case Success(_) => log.info(s"Successfully closed ${prNum} due to failed audit(s)")
+ case Failure(exc) => log.error(exc, s"Error closing ${prNum}")
+ }
+ }
+ }
+}
diff --git a/src/main/scala/com/getbootstrap/rorschach/github/IssueNumber.scala b/src/main/scala/com/getbootstrap/rorschach/github/IssueNumber.scala
deleted file mode 100644
index 86e7a80..0000000
--- a/src/main/scala/com/getbootstrap/rorschach/github/IssueNumber.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.getbootstrap.rorschach.github
-
-object IssueNumber {
- def apply(number: Int): Option[IssueNumber] = {
- if (number > 0) {
- Some(new IssueNumber(number))
- }
- else {
- None
- }
- }
-}
-class IssueNumber private(val number: Int) extends AnyVal {
- override def toString = s"IssueNumber(${number})"
-}
diff --git a/src/main/scala/com/getbootstrap/rorschach/github/PullRequestFeedback.scala b/src/main/scala/com/getbootstrap/rorschach/github/PullRequestFeedback.scala
index a5dc57e..511fe48 100644
--- a/src/main/scala/com/getbootstrap/rorschach/github/PullRequestFeedback.scala
+++ b/src/main/scala/com/getbootstrap/rorschach/github/PullRequestFeedback.scala
@@ -3,7 +3,7 @@ package com.getbootstrap.rorschach.github
import org.eclipse.egit.github.core.User
case class PullRequestFeedback(
- prNum: IssueNumber,
+ prNum: PullRequestNumber,
requester: User,
messages: Seq[String]
)
diff --git a/src/main/scala/com/getbootstrap/rorschach/github/PullRequestNumber.scala b/src/main/scala/com/getbootstrap/rorschach/github/PullRequestNumber.scala
new file mode 100644
index 0000000..e05c996
--- /dev/null
+++ b/src/main/scala/com/getbootstrap/rorschach/github/PullRequestNumber.scala
@@ -0,0 +1,15 @@
+package com.getbootstrap.rorschach.github
+
+object PullRequestNumber {
+ def apply(number: Int): Option[PullRequestNumber] = {
+ if (number > 0) {
+ Some(new PullRequestNumber(number))
+ }
+ else {
+ None
+ }
+ }
+}
+class PullRequestNumber private(val number: Int) extends AnyVal {
+ override def toString = s"IssueNumber(${number})"
+}
diff --git a/src/main/scala/com/getbootstrap/rorschach/github/PullRequestStatus.scala b/src/main/scala/com/getbootstrap/rorschach/github/PullRequestStatus.scala
new file mode 100644
index 0000000..e136f32
--- /dev/null
+++ b/src/main/scala/com/getbootstrap/rorschach/github/PullRequestStatus.scala
@@ -0,0 +1,20 @@
+package com.getbootstrap.rorschach.github
+
+object PullRequestStatus {
+ def apply(value: String): PullRequestStatus = {
+ value match {
+ case Open.Value => Open
+ case Closed.Value => Closed
+ case _ => throw new IllegalArgumentException(s"Invalid pull request status string: ${value}")
+ }
+ }
+}
+sealed trait PullRequestStatus {
+ val Value: String
+}
+object Open extends PullRequestStatus {
+ override val Value = "open"
+}
+object Closed extends PullRequestStatus {
+ override val Value = "closed"
+}
diff --git a/src/main/scala/com/getbootstrap/rorschach/github/util/package.scala b/src/main/scala/com/getbootstrap/rorschach/github/util/package.scala
new file mode 100644
index 0000000..9a2aa6e
--- /dev/null
+++ b/src/main/scala/com/getbootstrap/rorschach/github/util/package.scala
@@ -0,0 +1,23 @@
+package com.getbootstrap.rorschach.github
+
+import org.eclipse.egit.github.core._
+
+package object util {
+ implicit class RichRepository(repo: Repository) {
+ def repositoryId: RepositoryId = new RepositoryId(repo.getOwner.getLogin, repo.getName)
+ }
+ implicit class RichPullRequestMarker(marker: PullRequestMarker) {
+ def commitSha: CommitSha = new CommitSha(marker.getSha)
+ }
+ implicit class RichCommitFile(file: CommitFile) {
+ def status: CommitFileStatus = CommitFileStatus(file.getStatus)
+ }
+ implicit class RichPullRequest(pr: PullRequest) {
+ def number: PullRequestNumber = PullRequestNumber(pr.getNumber).get
+
+ def status_= (value: PullRequestStatus) {
+ pr.setState(value.Value)
+ }
+ def status = PullRequestStatus(pr.getState)
+ }
+}
diff --git a/src/main/scala/com/getbootstrap/rorschach/server/Boot.scala b/src/main/scala/com/getbootstrap/rorschach/server/Boot.scala
index 36923f8..a1ccbeb 100644
--- a/src/main/scala/com/getbootstrap/rorschach/server/Boot.scala
+++ b/src/main/scala/com/getbootstrap/rorschach/server/Boot.scala
@@ -1,5 +1,6 @@
package com.getbootstrap.rorschach.server
+import scala.util.{Success,Failure}
import scala.concurrent.duration._
import scala.util.Try
import akka.actor.{ActorSystem, Props}
@@ -8,34 +9,36 @@ import spray.can.Http
import akka.pattern.ask
import akka.routing.SmallestMailboxPool
import akka.util.Timeout
-import com.getbootstrap.rorschach.github.GitHubIssueCommenter
+import com.getbootstrap.rorschach.github.GitHubPullRequestCommenter
object Boot extends App {
val arguments = args.toSeq
- val maybePort = arguments match {
+ val argsPort = arguments match {
case Seq(portStr: String) => {
- Try{ portStr.toInt }.toOption
- }
- case _ => None
- }
- maybePort match {
- case Some(port) => run(port)
- case _ => {
- System.err.println("USAGE: rorschach <port-number>")
- System.exit(1)
+ Try{ portStr.toInt } match {
+ case Failure(_) => {
+ System.err.println("USAGE: lmvtfy <port-number>")
+ System.exit(1)
+ None // dead code
+ }
+ case Success(portNum) => Some(portNum)
+ }
}
+ case Seq() => None
}
- def run(port: Int) {
+ run(argsPort)
+
+ def run(port: Option[Int]) {
implicit val system = ActorSystem("on-spray-can")
// import actorSystem.dispatcher
- val commenter = system.actorOf(SmallestMailboxPool(3).props(Props(classOf[GitHubIssueCommenter])), "gh-pr-commenter")
+ val commenter = system.actorOf(SmallestMailboxPool(3).props(Props(classOf[GitHubPullRequestCommenter])), "gh-pr-commenter")
val prAuditorPool = system.actorOf(SmallestMailboxPool(5).props(Props(classOf[PullRequestEventHandler], commenter)), "pr-auditor-pool")
val webService = system.actorOf(Props(classOf[RorschachActor], prAuditorPool), "rorschach-service")
implicit val timeout = Timeout(15.seconds)
- IO(Http) ? Http.Bind(webService, interface = "0.0.0.0", port = port)
+ IO(Http) ? Http.Bind(webService, interface = "0.0.0.0", port = port.getOrElse(settings.DefaultPort))
}
}
diff --git a/src/main/scala/com/getbootstrap/rorschach/server/PullRequestEventHandler.scala b/src/main/scala/com/getbootstrap/rorschach/server/PullRequestEventHandler.scala
index 0d2ebed..b2ed228 100644
--- a/src/main/scala/com/getbootstrap/rorschach/server/PullRequestEventHandler.scala
+++ b/src/main/scala/com/getbootstrap/rorschach/server/PullRequestEventHandler.scala
@@ -5,23 +5,13 @@ import com.getbootstrap.rorschach.auditing.{BaseAndHeadBranchesAuditor, Modified
import scala.collection.JavaConverters._
import scala.util.{Try,Success,Failure}
import akka.actor.ActorRef
-import com.getbootstrap.rorschach.github._
-import org.eclipse.egit.github.core.service.CommitService
import org.eclipse.egit.github.core._
+import org.eclipse.egit.github.core.service.CommitService
+import com.getbootstrap.rorschach.github._
+import com.getbootstrap.rorschach.github.util._
class PullRequestEventHandler(commenter: ActorRef) extends GitHubActorWithLogging {
- implicit class RichRepository(repo: Repository) {
- def repositoryId: RepositoryId = new RepositoryId(repo.getOwner.getLogin, repo.getName)
- }
- implicit class RichPullRequestMarker(marker: PullRequestMarker) {
- def commitSha: CommitSha = new CommitSha(marker.getSha)
- }
- implicit class RichCommitFile(file: CommitFile) {
- def status: CommitFileStatus = CommitFileStatus(file.getStatus)
- }
- implicit class RichPullRequest(pr: PullRequest) {
- def issueNumber: IssueNumber = IssueNumber(pr.getNumber).get
- }
+
private def modifiedFilesFor(repoId: RepositoryId, base: CommitSha, head: CommitSha) = {
val commitService = new CommitService(gitHubClient)
@@ -54,7 +44,7 @@ class PullRequestEventHandler(commenter: ActorRef) extends GitHubActorWithLoggin
val allMessages = fileMessages ++ branchMessages
if (allMessages.nonEmpty) {
- commenter ! PullRequestFeedback(pr.issueNumber, pr.getUser, allMessages)
+ commenter ! PullRequestFeedback(pr.number, pr.getUser, allMessages)
}
}
case otherRepo => log.error(s"Received event from GitHub about irrelevant repository: ${otherRepo}")
diff --git a/src/main/scala/com/getbootstrap/rorschach/server/Settings.scala b/src/main/scala/com/getbootstrap/rorschach/server/Settings.scala
index 1b47482..20788d8 100644
--- a/src/main/scala/com/getbootstrap/rorschach/server/Settings.scala
+++ b/src/main/scala/com/getbootstrap/rorschach/server/Settings.scala
@@ -13,6 +13,7 @@ class SettingsImpl(config: Config) extends Extension {
val BotUsername: String = config.getString("rorschach.username")
val BotPassword: String = config.getString("rorschach.password")
val WebHookSecretKey: ByteString = ByteString(config.getString("rorschach.web-hook-secret-key").utf8Bytes)
+ val DefaultPort: Int = config.getInt("rorschach.default-port")
}
object Settings extends ExtensionId[SettingsImpl] with ExtensionIdProvider {
override def lookup() = Settings