Configuring SBT JSLint With TeamCity Build

In this post I will shortly describe configuration process of JSLint SBT plugin and then TeamCity build config that reacts on errors/warnings raised by this plugin.

Problem

In my current project we are working with rather non-standard technologies for a decent Java developer. Our backend runs on Scala and Scalatra and serves pure JSON to the frontend written in JavaScript and AngularJS. And as we are far from being seasoned JS developers, we want to have quality our JS codebase guarded by some automatic tool.

Toolbox

After some research it appeared that JSLint is for JS the same as FindBugs for Java so we decided to try it out in our project. Luckily there is a JSLint SBT plugin so we weren’t forced to carve our own solution.

Configuration

SBT-JSLint plugin

According to the documentation to configure plugin we have to perform two following steps:

  1. Add plugin declaration to Plugins.scala file
1
2
3
4
5
6
7
8
object Plugins extends Build {
  lazy val plugins = Project(
    "plugins",
    file("."),
    settings = Defaults.defaultSettings ++
      Seq(addSbtPlugin("com.github.philcali" % "sbt-jslint" % "0.1.3"))
  )
}
  1. Include plugin settings in Build.scala:
1
2
3
4
5
6
7
8
9
import sbtjslint.Plugin._
import sbtjslint.Plugin.LintKeys._

// ...
  lazy val ui: Project = Project(
    "bootstrap-ui",
    file("bootstrap-ui"),
    settings = buildSettings ++ lintSettings
  )

But as usual these steps are not enough. First of all, when we run sbt jslint we will see that it scans some default directory looking for JS files to analyse. And of course our JavaScript lies in a completely different place. Secondly, we want to add jslint step to build process so it is executed every time. So simply, we need lintCustomSettings with declared custom JS location and jslint step process added to test step in our build:

1
2
3
4
5
6
7
8
9
10
  val lintCustomSettings = lintSettings ++ inConfig(Test)(Seq(
    sourceDirectory in jslint <<= (baseDirectory)(_ / "src/main/webapp/app"),
    compile in Test <<= (compile in Test) dependsOn (jslint)
  ))

  lazy val ui: Project = Project(
    "bootstrap-ui",
    file("bootstrap-ui"),
    settings = buildSettings ++ lintCustomSettings
  )

Now after running sbt test we will see that JavaScript code is checked and report is printed to the console and also written in target/jslint/results.xml file.

When you analyse report.xml you might be overwhelmed by the number of warnings raised by the plugin. Some of them are quite useful, but some might be ignored or, even better, disabled by custom flags. In our project we use something like:

1
  flags in jslint ++= Seq("undef", "vars", "browser")

added to lintCustomSettings. For more flags and their descriptions please visit plugin documentation.

Team City config

Now, as we have our plugin running and generating report.xml, we could configure TeamCity build to react on JS errors and warnings.

Simply go to Edit Configuration Settings of your build and then choose “Build Step: Command Line”:

tc-step1

And in the section Additional Build Features click “Add build feature”, choose “XML report processing”, then “JSLint” and specify path to the report.xml file. Personally I also check “Verbose output” to see more details in the build log.

tc-step2

After saving we can go next build step named “Build failure conditions” and define two new rules there so we end up with something similar to screen presented below:

tc-step3

And finally our build is fully configured to report and react on problems in JavaScript files:

tc-step4

Reference commits from my current project:


How-to, JavaScript, Scala

Comments