diff --git a/.travis.yml b/.travis.yml index e243a87..b562bc8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ --- language: scala -script: "sbt coveralls test" +script: "sbt coveralls" jdk: - oraclejdk7 - openjdk7 diff --git a/README.md b/README.md index 7129d74..509c9e1 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ seq(ScctPlugin.instrumentSettings : _*) 1) Add the following to you `travis.yml` - script: "sbt coveralls test" + script: "sbt coveralls" 2) Job done! Commit these changes to `travis.yml` to kick off your Travis build and you should see coverage reports appear on http://coveralls.io @@ -60,9 +60,11 @@ For example output [click here](https://coveralls.io/builds/6727) # Custom Encoding -By default `xsbt-coveralls-plugin` uses `UTF-8` encoding. To use a different encoding run the command +By default `xsbt-coveralls-plugin` uses `UTF-8` encoding. To use a different encoding, add the following to your `build.sbt` - coveralls test enc=ISO-8859-1 + import com.github.theon.coveralls.CoverallsPlugin.CoverallsKeys._ + + encoding := "ISO-8859-1" # SNAPSHOT Builds diff --git a/project/build.sbt b/project/build.sbt index ae3d4f6..9ffda16 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -7,4 +7,4 @@ resolvers ++= Seq( addSbtPlugin("reaktor" %% "sbt-scct" % "0.2-SNAPSHOT") -addSbtPlugin("com.github.theon" %% "xsbt-coveralls-plugin-meta" % "0.0.1-SNAPSHOT") \ No newline at end of file +addSbtPlugin("com.github.theon" %% "xsbt-coveralls-plugin-meta" % "0.0.3-SNAPSHOT") \ No newline at end of file diff --git a/src/main/scala/com/github/theon/coveralls/CoverallsPlugin.scala b/src/main/scala/com/github/theon/coveralls/CoverallsPlugin.scala index 85b1c02..99f5e64 100644 --- a/src/main/scala/com/github/theon/coveralls/CoverallsPlugin.scala +++ b/src/main/scala/com/github/theon/coveralls/CoverallsPlugin.scala @@ -5,49 +5,46 @@ import sbt._ import scala.io.{Codec, Source} import tools.nsc.Global import annotation.tailrec +import scala.Some +import scala.Some +import com.github.theon.coveralls.CoverallsPlugin.CoverallsKeys /** * Date: 10/03/2013 * Time: 17:01 */ -object CoverallsPlugin extends AbstractCoverallsPlugin { - def coberturaFile(state:State) = findCoberturaFile("target/", state).head - def coverallsFile(state:State) = baseDir(state) + "target/coveralls.json" +object CoverallsPlugin extends Plugin with AbstractCoverallsPlugin { + + import CoverallsKeys._ + def apiHttpClient = new ScalaJHttpClient - def baseDir(state:State) = state.configuration.baseDirectory.getAbsolutePath + "/" def travisJobIdent = sys.env.get("TRAVIS_JOB_ID") def userRepoToken = sys.env.get("COVERALLS_REPO_TOKEN").orElse(userRepoTokenFromFile) - //TODO: Get rid of this awful method. I make myself sick. - def findCoberturaFile(path:String, state:State):Set[String] = { - val f = new File(path) - val children = Option[Array[File]](f.listFiles()) - if(f.name == "cobertura.xml") Set(f.getAbsolutePath) - else if(children.isEmpty) Set.empty - else children.get.foldLeft(Set[String]())((set, file) => set ++ findCoberturaFile(file.getAbsolutePath, state)) + object CoverallsKeys { + val coverallsTask = TaskKey[Unit]("coveralls", "Generate coveralls reports") + val encoding = SettingKey[String]("encoding") } -} -trait AbstractCoverallsPlugin extends Plugin { - override lazy val settings = Seq(commands += Command.args("coveralls", "test")(coverallsCommand)) + override lazy val settings = Seq ( + encoding := "UTF-8", + coverallsTask <<= (state, baseDirectory, crossTarget, encoding) map { + (state, baseDirectory, crossTarget, encoding) => { + val coberturaFile = crossTarget.getAbsolutePath + "/coverage-report/cobertura.xml" + val coverallsFile = crossTarget.getAbsolutePath + "/coveralls.json" + val projectDirectory = baseDirectory.getAbsoluteFile + "/" + coverallsCommand(state, projectDirectory, coberturaFile, coverallsFile, encoding) + } + } + ) +} - def coberturaFile(state:State):String - def coverallsFile(state:State):String - def baseDir(state:State):String +trait AbstractCoverallsPlugin { def apiHttpClient:HttpClient - def scctConfig = config("scct-test") - - val encPrefix = "enc=" - - def coverallsCommand = (state:State, args:Seq[String]) => { - - val encoding = args. - find(_.startsWith(encPrefix)). - map(e => Codec(e.replace(encPrefix, ""))). - getOrElse(Codec("UTF-8")) + def coverallsCommand(state: State, projectDirectory: String, coberturaFile: String, coverallsFile: String, encoding: String) = { if(travisJobIdent.isEmpty && userRepoToken.isEmpty) { state.log.error("Could not find coveralls repo token or determine travis job id") @@ -55,16 +52,17 @@ trait AbstractCoverallsPlugin extends Plugin { state.log.error(" - Otherwise, make sure the COVERALLS_REPO_TOKEN env variable is set or that the repo token is written inside " + userRepoTokenFilePath) state.fail } else { + //Run the scct plugin to generate code coverage Command.process("scct:test", state) val reader = new CoberturaReader { - def file = coberturaFile(state) + def file = coberturaFile } val writer = new CoverallPayloadWriter { def repoToken = userRepoToken - def file = coverallsFile(state) + def file = coverallsFile def travisJobId = travisJobIdent val gitClient = new GitClient {} } @@ -76,13 +74,13 @@ trait AbstractCoverallsPlugin extends Plugin { writer.start(state.log) sourceFiles.foreach(sourceFile => { - val sourceReport = reader.reportForSource(baseDir(state), sourceFile) + val sourceReport = reader.reportForSource(projectDirectory, sourceFile) writer.addSourceFile(sourceReport) }) writer.end() - val res = coverallsClient.postFile(coverallsFile(state), encoding) + val res = coverallsClient.postFile(coverallsFile, Codec(encoding)) if(res.error) { state.log.error("Uploading to coveralls.io failed: " + res.message) if(res.message.contains("Build processing error")) { @@ -93,7 +91,6 @@ trait AbstractCoverallsPlugin extends Plugin { state.log.info("Uploading to coveralls.io succeeded: " + res.message) state.log.info(res.url) state.log.info("(results may not appear immediately)") - state } } } diff --git a/src/test/scala/com/github/theon/coveralls/PluginIntegrationTest.scala b/src/test/scala/com/github/theon/coveralls/PluginIntegrationTest.scala index 01bc025..5d19049 100644 --- a/src/test/scala/com/github/theon/coveralls/PluginIntegrationTest.scala +++ b/src/test/scala/com/github/theon/coveralls/PluginIntegrationTest.scala @@ -10,29 +10,25 @@ import java.io.File * Time: 15:19 */ class PluginIntegrationTest extends WordSpec with BeforeAndAfterAll with ShouldMatchers { + + val projectRoot = new File("").getAbsolutePath + "/" + val coberturaFile = projectRoot + "src/test/resources/test_cobertura.xml" + val coverallsFile = "/tmp/xsbt-coveralls-plugin/coveralls.json" + object SuccessTestCoverallsPlugin extends AbstractCoverallsPlugin { - def coberturaFile(state:State) = new File("").getAbsolutePath + "/src/test/resources/test_cobertura.xml" - def coverallsFile(state:State) = "/tmp/xsbt-coveralls-plugin/coveralls.json" def apiHttpClient = new TestSuccessHttpClient() - def baseDir(state:State) = "" def userRepoToken = Some("test-repo-token") def travisJobIdent = None } object FailureTestCoverallsPlugin extends AbstractCoverallsPlugin { - def coberturaFile(state:State) = new File("").getAbsolutePath + "/src/test/resources/test_cobertura.xml" - def coverallsFile(state:State) = "/tmp/xsbt-coveralls-plugin/coveralls.json" def apiHttpClient = new TestFailureHttpClient() - def baseDir(state:State) = "" def userRepoToken = Some("test-repo-token") def travisJobIdent = None } object NoRepoTokenOfTravisJobIdTestCoverallsPlugin extends AbstractCoverallsPlugin { - def coberturaFile(state:State) = new File("").getAbsolutePath + "/src/test/resources/test_cobertura.xml" - def coverallsFile(state:State) = "/tmp/xsbt-coveralls-plugin/coveralls.json" def apiHttpClient = new TestFailureHttpClient() - def baseDir(state:State) = "" def userRepoToken = None def travisJobIdent = None } @@ -44,7 +40,7 @@ class PluginIntegrationTest extends WordSpec with BeforeAndAfterAll with ShouldM val logger = new TestLogger() val state = State(null, Seq(), Set(), None, Seq(), null, null, new GlobalLogging(logger, null, null), null) - SuccessTestCoverallsPlugin.coverallsCommand.apply(state, Nil) + SuccessTestCoverallsPlugin.coverallsCommand(state, projectRoot, coberturaFile, coverallsFile, "UTF-8") logger.messages(Level.Info) should contain("Uploading to coveralls.io succeeded: test message") logger.messages(Level.Info) should contain("https://github.com/theon/xsbt-coveralls-plugin") @@ -56,7 +52,7 @@ class PluginIntegrationTest extends WordSpec with BeforeAndAfterAll with ShouldM val logger = new TestLogger() val state = State(null, Seq(), Set(), None, Seq(), null, null, new GlobalLogging(logger, null, null), null) - FailureTestCoverallsPlugin.coverallsCommand.apply(state, Nil) + FailureTestCoverallsPlugin.coverallsCommand(state, projectRoot, coberturaFile, coverallsFile, "UTF-8") logger.messages(Level.Error) should contain("Uploading to coveralls.io failed: test error message when there was an error") } @@ -67,7 +63,7 @@ class PluginIntegrationTest extends WordSpec with BeforeAndAfterAll with ShouldM val logger = new TestLogger() val state = State(null, Seq(), Set(), None, Seq(), null, null, new GlobalLogging(logger, null, null), null) - NoRepoTokenOfTravisJobIdTestCoverallsPlugin.coverallsCommand.apply(state, Nil) + NoRepoTokenOfTravisJobIdTestCoverallsPlugin.coverallsCommand(state, projectRoot, coberturaFile, coverallsFile, "UTF-8") logger.messages(Level.Error) should contain("Could not find coveralls repo token or determine travis job id") }