Skip to content
Snippets Groups Projects
Commit ae11f523 authored by Arsenij Solovjev's avatar Arsenij Solovjev
Browse files

[BUILD] change config framework p.2

Instead of plain XML use Typesafe's config library.
Leaner configuration for better maintainability.
parent d2d53a04
No related branches found
No related tags found
No related merge requests found
...@@ -30,7 +30,7 @@ libraryDependencies += "org.agse" % "gitclient_2.10" % "0.0.1" ...@@ -30,7 +30,7 @@ libraryDependencies += "org.agse" % "gitclient_2.10" % "0.0.1"
libraryDependencies += "com.typesafe" % "config" % "1.2.1" libraryDependencies += "com.typesafe" % "config" % "1.2.1"
libraryDependencies += "org.specs2" % "specs2_2.10" % "2.4.16" libraryDependencies += "org.specs2" % "specs2_2.10" % "2.4.16" % "test"
resolvers ++= Seq( resolvers ++= Seq(
"Scalaz Bintray Repo" at "http://dl.bintray.com/scalaz/releases", "Scalaz Bintray Repo" at "http://dl.bintray.com/scalaz/releases",
......
...@@ -13,15 +13,16 @@ import duration._ ...@@ -13,15 +13,16 @@ import duration._
import scala.xml._ import scala.xml._
import scala.util.{ Success, Failure } import scala.util.{ Success, Failure }
object GerritRestClient extends LazyLogging { import com.typesafe.config.Config
class GerritRestClient(conf: Config) extends LazyLogging {
private val conf = XML.load("conf.xml")
//required //required
private val defaultHost = (conf \ "host").text private val defaultHost = conf.getString("gerrit.host")
private val defaultUser = (conf \ "user").text private val defaultUser = conf.getString("gerrit.user")
private val defaultPass = (conf \ "pass").text private val defaultPass = conf.getString("gerrit.pass")
//optional //optional
private val defaultPort = (conf \ "port").text private val defaultPort = if (conf.hasPath("gerrit.port")) conf.getString("gerrit.port") else ""
def setReview(changeId: String, patchsetRevision: String, def setReview(changeId: String, patchsetRevision: String,
comments: String, host: String = defaultHost, comments: String, host: String = defaultHost,
......
...@@ -4,6 +4,7 @@ import com.typesafe.scalalogging.slf4j._ ...@@ -4,6 +4,7 @@ import com.typesafe.scalalogging.slf4j._
import net.liftweb.json._ import net.liftweb.json._
import JsonDSL._ import JsonDSL._
import scala.xml._ import scala.xml._
import com.typesafe.config.Config
/** /**
* Parses Sonar Issues Reports. * Parses Sonar Issues Reports.
...@@ -11,7 +12,7 @@ import scala.xml._ ...@@ -11,7 +12,7 @@ import scala.xml._
* https://github.com/SonarCommunity/sonar-issues-report/blob/1b38791/src/main/resources/org/sonar/issuesreport/printer/html/issuesreport.ftl * https://github.com/SonarCommunity/sonar-issues-report/blob/1b38791/src/main/resources/org/sonar/issuesreport/printer/html/issuesreport.ftl
*/ */
class IssuesParser(repo: GitRepo) extends LazyLogging { class IssuesParser(repo: GitRepo, config: Config) extends LazyLogging {
// this particular parser can parse "tag-soup" document, which old html is // this particular parser can parse "tag-soup" document, which old html is
val xml = XML.withSAXParser(new org.ccil.cowan.tagsoup.jaxp.SAXFactoryImpl().newSAXParser()) val xml = XML.withSAXParser(new org.ccil.cowan.tagsoup.jaxp.SAXFactoryImpl().newSAXParser())
...@@ -24,17 +25,17 @@ class IssuesParser(repo: GitRepo) extends LazyLogging { ...@@ -24,17 +25,17 @@ class IssuesParser(repo: GitRepo) extends LazyLogging {
def isMerge = repo.lastCommit.isMerge def isMerge = repo.lastCommit.isMerge
logger.debug(s"Last commit is a merge commit? $isMerge") logger.debug(s"Last commit is a merge commit? $isMerge")
def parse(pathToReportsDir: String, changeId: String): String = def parse(changeId: String): String =
pretty( pretty(
render( render(
merged( merged(
projects map (parseProject(pathToReportsDir, changeId, _))))) projects map (parseProject(changeId, _)))))
def parse(pathToReportsDir: String, changeId: String, project: String): String = def parse(changeId: String, project: String): String =
if (!isMerge) if (!isMerge)
pretty( pretty(
render( render(
parseProject(pathToReportsDir, changeId, project))) parseProject(changeId, project)))
else else
pretty( pretty(
render( render(
...@@ -42,9 +43,12 @@ class IssuesParser(repo: GitRepo) extends LazyLogging { ...@@ -42,9 +43,12 @@ class IssuesParser(repo: GitRepo) extends LazyLogging {
val mergeCommitReply = ("message" -> "Nothing to analyze, since this is a merge commit.") val mergeCommitReply = ("message" -> "Nothing to analyze, since this is a merge commit.")
private def parseProject(pathToReportsDir: String, changeId: String, project: String): JValue = { private def parseProject(changeId: String, project: String): JValue = {
val pathToReport = pathToReportsDir + "/" + changeId + "/" + project + "/issues-report-light.html" val pathToReport = config.getString(s"projects.$project.issueReports") +
changeId + "/" +
project +
"/issues-report-light.html"
val issuesReport = xml.load(pathToReport) val issuesReport = xml.load(pathToReport)
// this element is always there // this element is always there
val summaryPerFile = (issuesReport \\ "div") find { x => (x \ "@id").text == "summary-per-file" } val summaryPerFile = (issuesReport \\ "div") find { x => (x \ "@id").text == "summary-per-file" }
...@@ -61,8 +65,6 @@ class IssuesParser(repo: GitRepo) extends LazyLogging { ...@@ -61,8 +65,6 @@ class IssuesParser(repo: GitRepo) extends LazyLogging {
("comments" -> comments) ("comments" -> comments)
} }
val forProject = (project: String) => "for project ${project}"
private def commentsPerResource(resourceReport: Node): JValue = { private def commentsPerResource(resourceReport: Node): JValue = {
val sources = (resourceReport \\ "table") find val sources = (resourceReport \\ "table") find
{ x => (x \ "@class").text == "sources" } { x => (x \ "@class").text == "sources" }
......
...@@ -3,6 +3,7 @@ import org.rogach.scallop._ ...@@ -3,6 +3,7 @@ import org.rogach.scallop._
import scala.xml._ import scala.xml._
import org.agse.gitclient.{ GitRepo } import org.agse.gitclient.{ GitRepo }
import com.typesafe.config._ import com.typesafe.config._
import java.io.File
object sonarReview { object sonarReview {
...@@ -12,16 +13,24 @@ object sonarReview { ...@@ -12,16 +13,24 @@ object sonarReview {
banner("""Usage: sonarreview.jar --change|c GERRIT_CHANGE_NUMBER --revision|-r GERRIT_PATCHSET_NUMBER --project|-p PROJECT [--debug|-d] banner("""Usage: sonarreview.jar --change|c GERRIT_CHANGE_NUMBER --revision|-r GERRIT_PATCHSET_NUMBER --project|-p PROJECT [--debug|-d]
| |
|sonarReview uses a configuration file which must lie in the same directory from where it is being called |sonarReview uses a configuration file which must lie in the same directory from where it is being called
|and it must be named "conf.xml". It must contain the following (${port} being optional) |and it must be named "application.conf". It must contain the following (${port} being optional)
|<conf>
| <host>gerrit.host.com</host>
| <user>user</user>
| <pass>pass</pass>
| <port>app_server_port</port>
| <issuesReportDir>/issues/reports/dir/</issuesReportDir>
|</conf>
| |
|It will look for issues reports under ${issuesReportDir}/GERRIT_CHANGE_NUMBER, parse them and post |gerrit {
| host = the server on which gerrit is hosted
| user = the username, as which you want to post the review
| pass = the password for the username above
| port = the port on which to post to the gerrit server, omitting this defaults to port 80
|}
|
|gitRepoLocation = absolute path to the location of the .git folder of your current project
|
|projects{
| projectFolder {
| projectTitle = the human-readable version of the project title
| issueReports = absolute path to the location of the folder where issue reports should be found
| }
|}
|It will look for issues reports under ${issueReports}/GERRIT_CHANGE_NUMBER, parse them and post
|the issues found therein as comments to ${host}:${port}/gerrit as the user identified by ${user} and |the issues found therein as comments to ${host}:${port}/gerrit as the user identified by ${user} and
|${pass} for the patchset revision GERRIT_PATCHSET_NUMBER. |${pass} for the patchset revision GERRIT_PATCHSET_NUMBER.
| |
...@@ -48,20 +57,21 @@ object sonarReview { ...@@ -48,20 +57,21 @@ object sonarReview {
else else
root.setLevel(Level.INFO) root.setLevel(Level.INFO)
val conf = XML.load("conf.xml") val config = ConfigFactory.parseFile(new File("application.conf"))
val pathToIssuesReport = (conf \ "issuesReportDir").text
val issuesParser = new IssuesParser(new GitRepo((XML.load("conf.xml") \ "gitRepoLocation").text)) val git = new GitRepo(config.getString("gitRepoLocation"))
val comments = P.project.get match { val issuesParser = new IssuesParser(git, config)
val comments = P.project.get match {
case Some(project) => case Some(project) =>
issuesParser.parse(pathToIssuesReport, P.changeNumber.apply, project) issuesParser.parse(P.changeNumber.apply, project)
case None => case None =>
issuesParser.parse(pathToIssuesReport, P.changeNumber.apply) issuesParser.parse(P.changeNumber.apply)
} }
GerritRestClient.setReview(P.changeNumber.apply, P.patchsetNumber.apply, comments) val gerrit = new GerritRestClient(config)
gerrit.setReview(P.changeNumber.apply, P.patchsetNumber.apply, comments)
System.exit(0) System.exit(0)
} }
......
...@@ -4,6 +4,7 @@ import org.agse.gitclient.GitRepo ...@@ -4,6 +4,7 @@ import org.agse.gitclient.GitRepo
import net.liftweb.json._ import net.liftweb.json._
import org.specs2.mutable._ import org.specs2.mutable._
import org.specs2.mock.Mockito import org.specs2.mock.Mockito
import com.typesafe.config._
object ParserTest extends Specification with Mockito { object ParserTest extends Specification with Mockito {
sequential sequential
...@@ -32,34 +33,37 @@ object ParserTest extends Specification with Mockito { ...@@ -32,34 +33,37 @@ object ParserTest extends Specification with Mockito {
val changeId = "sampleReport" val changeId = "sampleReport"
val project = "de.fu_berlin.inf.dpp.core" val project = "de.fu_berlin.inf.dpp.core"
val issuesParser = new IssuesParser(mockRepo) val mockConfig = mock[Config]
mockConfig.getString(s"projects.$project.issueReports") returns pathToReports
val issuesParser = new IssuesParser(mockRepo, mockConfig)
"IssuesParser" should { "IssuesParser" should {
"not analyze merge commits" in { "not analyze merge commits" in {
val review = issuesParser.parse(pathToReports, changeId, project) val review = issuesParser.parse(changeId, project)
compact(render(parse(review) \ "message")) mustEqual "\"Nothing to analyze, since this is a merge commit.\"" compact(render(parse(review) \ "message")) mustEqual "\"Nothing to analyze, since this is a merge commit.\""
} }
"produce a confirmatory review message when no issues are found" in { "produce a confirmatory review message when no issues are found" in {
val review = issuesParser.parse(pathToReports, changeId, project) val review = issuesParser.parse(changeId, project)
compact(render(parse(review) \ "message")) mustEqual "\"Congratulations, QA found no issues whatsoever!\"" compact(render(parse(review) \ "message")) mustEqual "\"Congratulations, QA found no issues whatsoever!\""
} }
"produce a review message that prompts to review the issues found" in { "produce a review message that prompts to review the issues found" in {
val review = issuesParser.parse(pathToReports, changeId, project) val review = issuesParser.parse(changeId, project)
compact(render(parse(review) \ "message")) mustEqual "\"Please review your QA analysis results\"" compact(render(parse(review) \ "message")) mustEqual "\"Please review your QA analysis results\""
} }
"produce a comment for each line with an issue" in { "produce a comment for each line with an issue" in {
val numberOfIssues = 12 val numberOfIssues = 12
val review = issuesParser.parse(pathToReports, changeId, project) val review = issuesParser.parse(changeId, project)
(parse(review) \\ "line").children.length mustEqual numberOfIssues (parse(review) \\ "line").children.length mustEqual numberOfIssues
((parse(review) \\ "message").children.length - 1) mustEqual numberOfIssues ((parse(review) \\ "message").children.length - 1) mustEqual numberOfIssues
} }
"produce comments when issues are found" in { "produce comments when issues are found" in {
val lengthOfReview = 1942 val lengthOfReview = 1942
val review = issuesParser.parse(pathToReports, changeId, project) val review = issuesParser.parse(changeId, project)
compact(render(parse(review))).length mustEqual lengthOfReview compact(render(parse(review))).length mustEqual lengthOfReview
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment