Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

-Ywarn-unused-import triggering on play routes file

I want to be able to use -Xfatal-warnings and -Ywarn-unused-import, the problem is that the compiler is triggering an error on the file which contains the play routes for my application:

[error] /path/to/app/conf/routes: Unused import [error] /path/to/app/conf/routes: Unused import [error] /path/to/app/conf/routes:1: Unused import [error] GET        /document/:id        my.app.controllers.MyController.getById(id: Int) 

same goes for other routes.

Is it possible maybe to tell scalac to ignore a file?

Scala version is 2.11.8.

like image 207
Ende Neu Avatar asked May 24 '16 12:05

Ende Neu


2 Answers

I just encountered the same problem with Scala 2.12 and Play 2.6 (which you're probably now using).

A Scala compiler plugin called Silencer sorts it out: https://github.com/ghik/silencer

Add the following dependency into build.sbt:

val silencerVersion = "1.2.1"  libraryDependencies ++= Seq(     compilerPlugin("com.github.ghik" %% "silencer-plugin" % silencerVersion),     "com.github.ghik" %% "silencer-lib" % silencerVersion % Provided ) 

Then add (also in build.sbt):

scalacOptions += "-P:silencer:globalFilters=Unused import" 

The text after the globalFilters= is a list of regex matches for compiler warnings to silence, can be comma-separated. You might need to tweak the regex for your own case, but I found the above example worked fine.

It does mean that it silences any "Unused import" warnings, but if you're in the habit of auto-formatting your code (ctrl+alt+L in Intellij), including tidying up unused imports, then it shouldn't cause a problem.

like image 164
Matt Stephens Avatar answered Sep 30 '22 22:09

Matt Stephens


A horrible "solution" could be to remove those unused imports after the routes are generated but before the compile task runs. Here's a sketch:

lazy val optimizeRoutesImports = taskKey[Unit]("Remove unused imports from generated routes sources.")  optimizeRoutesImports := {    def removeUnusedImports(targetFiles: (File) => PathFinder, linesToRemove: Set[String], linesToReplace: Map[String, String]) = {     val files = targetFiles(crossTarget.value).get     files foreach { file =>       val lines = sbt.IO.readLines(file)       val updatedLines = lines map { line =>         linesToReplace.getOrElse(line, line)       } filterNot { line =>         linesToRemove.contains(line.trim)       }       sbt.IO.writeLines(file, updatedLines, append = false)     }   }    removeUnusedImports(     _ / "routes" / "main" / "controllers" / "ReverseRoutes.scala",     Set("import ReverseRouteContext.empty"),     Map(       "import play.api.mvc.{ QueryStringBindable, PathBindable, Call, JavascriptLiteral }" ->         "import play.api.mvc.{ QueryStringBindable, PathBindable, Call }",       "import play.core.routing.{ HandlerDef, ReverseRouteContext, queryString, dynamicString }" ->         "import play.core.routing.{ ReverseRouteContext, queryString, dynamicString }"     )   )    removeUnusedImports(     _ / "routes" / "main" / "controllers" / "javascript" / "JavaScriptReverseRoutes.scala",     Set(       "import play.core.routing.{ HandlerDef, ReverseRouteContext, queryString, dynamicString }",       "import ReverseRouteContext.empty"     ),     Map(       "import play.api.mvc.{ QueryStringBindable, PathBindable, Call, JavascriptLiteral }" ->         "import play.api.mvc.{ QueryStringBindable, PathBindable }"     )   )    removeUnusedImports(     _ / "routes" / "main" / "router" / "Routes.scala",     Set("import play.core.j._"),     Map()) } 

You'll then want to sort out the task dependencies:

// Our optimize routes imports task depends on the routes task. optimizeRoutesImports := (optimizeRoutesImports dependsOn (play.sbt.routes.RoutesKeys.routes in Compile)).value  // And compilation depends on the unused routes having been removed. compile := ((compile in Compile) dependsOn optimizeRoutesImports).value 

You'll also likely need to set TwirlKeys.templateImports to a conservative list before enabling -Ywarn-unused-import. Something like this, depending on what types are used in your views:

TwirlKeys.templateImports := Seq("play.api.mvc._", "play.api.i18n.Messages", "controllers.routes") 

I also had to knock unused TemplateMagic imports out of Twirl templates (YMMV):

  removeUnusedImports(     _ / "twirl" ** "*.template.scala",     Set("import play.twirl.api.TemplateMagic._"),     Map()) 

If you do that, make sure the task dependencies are set up appropriately.

This works for me. Scala 2.11.8, Play 2.5.10, both -Xfatal-warnings and -Ywarn-unused-import enabled. It's hideous, but it works.

like image 45
danielnixon Avatar answered Sep 30 '22 23:09

danielnixon