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.
2.11.8
, here you can find an example project, just needs to be compiled. – TheobaldRoutes.scala
file but the compiler points directly to theroutes
file and I'm not sure why or if it matters. Regarding the formatter, scalariform doesn't support import optimization, maybe can be set in Intellij. Regarding scalac I don't even know were to start, googling didn't help either. – Theobaldwarn-unused-import
. Did you ever find a solution to this? – Cooper