Skip to content

Commit

Permalink
separate twirl-specific data from play #SCL-22065
Browse files Browse the repository at this point in the history
Twirl sbt plugin can be used independently of Play plugin
  • Loading branch information
unkarjedy committed Aug 15, 2024
1 parent fff8dcd commit 8670403
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 32 deletions.
5 changes: 1 addition & 4 deletions extractor/src/main/scala/org/jetbrains/sbt/CreateTasks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import org.jetbrains.sbt.extractors._
import sbt._
import sbt.jetbrains.apiAdapter._

/**
* @author Nikolay Obedin
*/

object CreateTasks extends (State => State) with SbtStateOps {

lazy val globalSettings: Seq[Setting[_]] = Seq[Setting[_]](
Expand Down Expand Up @@ -35,6 +31,7 @@ object CreateTasks extends (State => State) with SbtStateOps {
StructureKeys.sourceConfigurations := UtilityTasks.sourceConfigurations.value,

StructureKeys.extractPlay2 := Play2Extractor.taskDef.value,
StructureKeys.extractTwirl := TwirlTemplatesDataExtractor.taskDef.value,
StructureKeys.extractBuild := BuildExtractor.taskDef.value,
StructureKeys.extractDependencies := DependenciesExtractor.taskDef.value,
StructureKeys.extractProject := ProjectExtractor.taskDef.value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ object StructureKeys {
val acceptedProjects: TaskKey[Seq[ProjectRef]] = TaskKey("ssAcceptedProjects", rank = Invisible)

val extractPlay2: TaskKey[Option[Play2Data]] = TaskKey("ssExtractPlay2", rank = Invisible)
val extractTwirl: TaskKey[Option[TwirlData]] = TaskKey("ssExtractTwirl", rank = Invisible)
val extractBuild: TaskKey[BuildData] = TaskKey("ssExtractBuild", rank = Invisible)
val extractBuilds: TaskKey[Seq[BuildData]] = TaskKey("ssExtractBuilds", rank = Invisible)
val extractDependencies: TaskKey[DependencyData] = TaskKey("ssExtractDependencies", rank = Invisible)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import org.jetbrains.sbt.{SbtStateOps, TaskOps}
import org.jetbrains.sbt.structure._
import sbt._

/**
* @author Dmitry Naydanov
* @author Nikolay Obedin
*/
object Play2Extractor extends SbtStateOps with TaskOps {

def taskDef: Def.Initialize[Task[Option[Play2Data]]] = Def.task {
Expand All @@ -21,30 +17,26 @@ object Play2Extractor extends SbtStateOps with TaskOps {
} yield {
val playVersion =
Keys.playVersion.in(projectRef).find(state)
val templateImports =
Keys.templateImports.in(projectRef).getOrElse(state, Seq.empty)
val routesImports =
Keys.routesImports.in(projectRef).find(state)
.orElse(Keys.routesImports_prior_to_2_4_0.in(projectRef).find(state))
.getOrElse(Seq.empty)
val confDirectory =
Keys.confDirectory.in(projectRef).find(state)

Play2Data(playVersion, fixTemplateImports(templateImports),
routesImports, confDirectory, sourceDirectory)
Play2Data(
playVersion,
routesImports,
confDirectory,
sourceDirectory
)
}
}

private def fixTemplateImports(imports: Seq[String]): Seq[String] = imports.map {
case "views.%format%._" => "views.xml._"
case value => value
}

private object Keys {
val playPlugin_prior_to_2_4_0: SettingKey[Boolean] = SettingKey[Boolean]("play-plugin")
val playPlugin: SettingKey[Boolean] = SettingKey[Boolean]("playPlugin")
val playVersion: SettingKey[String] = SettingKey[String]("play-version")
val templateImports: SettingKey[Seq[String]] = SettingKey[Seq[String]]("twirl-template-imports")
val routesImports_prior_to_2_4_0: SettingKey[Seq[String]] = SettingKey[Seq[String]]("play-routes-imports")
val routesImports: SettingKey[Seq[String]] = SettingKey[Seq[String]]("playRoutesImports")
val confDirectory: SettingKey[File] = SettingKey[File]("play-conf")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ import scala.util.{Failure, Success, Try}
// don't remove this import: sbt.jetbrains.apiAdapter._ -- it shadows some symbols for sbt 1.0 compatibility
import sbt.jetbrains.apiAdapter._

/**
* @author Nikolay Obedin
* @since 4/10/15.
*/
class ProjectExtractor(
projectRef: ProjectRef,
name: String,
Expand Down Expand Up @@ -43,6 +39,7 @@ class ProjectExtractor(
testConfigurations: Seq[sbt.Configuration],
dependencies: DependencyData,
play2: Option[Play2Data],
twirl: Option[TwirlData],
settingData: Seq[SettingData],
taskData: Seq[TaskData],
commandData: Seq[CommandData],
Expand Down Expand Up @@ -97,6 +94,7 @@ class ProjectExtractor(
dependencies,
resolvers,
play2,
twirl,
settingData,
taskData,
commandData,
Expand Down Expand Up @@ -401,6 +399,7 @@ object ProjectExtractor extends SbtStateOps with TaskOps {
StructureKeys.testConfigurations.value,
StructureKeys.extractDependencies.value,
StructureKeys.extractPlay2.value,
StructureKeys.extractTwirl.value,
StructureKeys.settingData.value,
StructureKeys.taskData.value,
StructureKeys.commandData.value.distinct,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.jetbrains.sbt.extractors

import org.jetbrains.sbt.structure._
import org.jetbrains.sbt.{SbtStateOps, TaskOps}
import sbt._

object TwirlTemplatesDataExtractor extends SbtStateOps with TaskOps {

def taskDef: Def.Initialize[Task[Option[TwirlData]]] = Def.task {
val state = sbt.Keys.state.value
val projectRef = sbt.Keys.thisProjectRef.value

for {
templateImports <- Keys.templateImports.in(projectRef).find(state)
} yield {
val templateImportsFixed = fixTemplateImports(templateImports)
TwirlData(templateImportsFixed)
}
}

private def fixTemplateImports(imports: Seq[String]): Seq[String] = imports.map {
case "views.%format%._" => "views.xml._"
case value => value
}

private object Keys {
// should match play.twirl.sbt.Import.TwirlKeys#templateImports
// (see https://github.com/playframework/twirl/blob/main/sbt-twirl/src/main/scala/play/twirl/sbt/SbtTwirl.scala)
val templateImports: SettingKey[Seq[String]] = SettingKey[Seq[String]]("twirl-template-imports")
}
}
9 changes: 8 additions & 1 deletion shared/src/main/scala/org/jetbrains/sbt/structure/data.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ case class ProjectData(
dependencies: DependencyData,
resolvers: Set[ResolverData],
play2: Option[Play2Data],
twirl: Option[TwirlData],
settings: Seq[SettingData],
tasks: Seq[TaskData],
commands: Seq[CommandData],
Expand Down Expand Up @@ -228,7 +229,13 @@ case class ResolverData(name: String, root: String)
* List of parameters specific to Play projects
*/
case class Play2Data(playVersion: Option[String],
templatesImports: Seq[String],
routesImports: Seq[String],
confDirectory: Option[File],
sourceDirectory: File)

/**
* List of parameters specific to projects which have twirl templates set-up (even without the Play framework)
*/
case class TwirlData(
templatesImports: Seq[String]
)
Original file line number Diff line number Diff line change
Expand Up @@ -448,23 +448,33 @@ trait DataSerializers {
override def serialize(what: Play2Data): Elem =
<play2>
{what.playVersion.toSeq.map(ver => <version>{ver}</version> )}
<templatesImports>
{what.templatesImports.map(imp => <import>{imp}</import>)}
</templatesImports>
<routesImports>
{what.routesImports.map(imp => <import>{imp}</import>)}
</routesImports>
{what.confDirectory.toSeq.map(dir => <confDirectory>{dir.path}</confDirectory>)}
<sourceDirectory>{what.sourceDirectory.path}</sourceDirectory>
</play2>

override def deserialize(what: Node): Either[Throwable,Play2Data] = {
override def deserialize(what: Node): Either[Throwable, Play2Data] = {
val playVersion = (what \ "version").map(_.text).headOption
val templatesImports = (what \ "templatesImports" \ "import").map(_.text)
val routesImports = (what \ "routesImports" \ "import").map(_.text)
val confDirectory = (what \ "confDirectory").map(_.text).headOption
val sourceDirectory = (what ! "sourceDirectory").text
Right(Play2Data(playVersion, templatesImports, routesImports, confDirectory.map(_.file), sourceDirectory.file))
Right(Play2Data(playVersion, routesImports, confDirectory.map(_.file), sourceDirectory.file))
}
}

implicit val twirlTemplateDataSerializer: XmlSerializer[TwirlData] = new XmlSerializer[TwirlData] {
override def serialize(what: TwirlData): Elem =
<twirl>
<templatesImports>
{what.templatesImports.map(imp => <import>{imp}</import>)}
</templatesImports>
</twirl>

override def deserialize(what: Node): Either[Throwable, TwirlData] = {
val templatesImports = (what \ "templatesImports" \ "import").map(_.text)
Right(TwirlData(templatesImports))
}
}

Expand All @@ -487,6 +497,7 @@ trait DataSerializers {
{what.dependencies.serialize}
{what.resolvers.map(_.serialize).toSeq}
{what.play2.map(_.serialize).toSeq}
{what.twirl.map(_.serialize).toSeq}
{what.settings.map(_.serialize)}
{what.tasks.map(_.serialize)}
{what.commands.map(_.serialize)}
Expand All @@ -513,16 +524,37 @@ trait DataSerializers {
val compileOrder = (what \ "compileOrder").text
val resolvers = (what \ "resolver").deserialize[ResolverData].toSet
val play2 = (what \ "play2").deserialize[Play2Data].headOption
val twirl = (what \ "twirl").deserialize[TwirlData].headOption

val settings = (what \ "setting").deserialize[SettingData]
val tasks = (what \ "task").deserialize[TaskData]
val commands = (what \ "command").deserialize[CommandData]

val tryDeps = (what \ "dependencies").deserializeOne[DependencyData]
tryDeps.right.map { dependencies =>
ProjectData(id, buildURI, name, organization, version, base, packagePrefix, basePackages,
target, configurations, java, scala, compileOrder,
dependencies, resolvers, play2, settings, tasks, commands, mainSourceDirectories, testSourceDirectories)
ProjectData(
id,
buildURI,
name,
organization,
version,
base,
packagePrefix,
basePackages,
target,
configurations,
java,
scala,
compileOrder,
dependencies,
resolvers,
play2,
twirl,
settings,
tasks,
commands,
mainSourceDirectories,
testSourceDirectories)
}

}
Expand Down

0 comments on commit 8670403

Please sign in to comment.