diff --git a/scripts/format.sh b/scripts/format.sh index 7dcd629..8d59d75 100755 --- a/scripts/format.sh +++ b/scripts/format.sh @@ -2,6 +2,13 @@ set -euo pipefail +if [ "$#" -eq 0 ] || [ "$1" != check ]; then + bazel build $(bazel query 'kind("scala_format_test", //...)') + bazel query 'kind("scala_format_test", //...)' --output package | while read package; do bazel-bin/"$package"/*-format .; done +else + bazel query 'kind("scala_format_test", //...)' | xargs bazel test +fi + if [ "$#" -eq 0 ] || [ "$1" != check ]; then bazel run //dev:buildifier else diff --git a/twirl-compiler-cli/BUILD.bazel b/twirl-compiler-cli/BUILD.bazel index 0e0e40e..2b9c504 100644 --- a/twirl-compiler-cli/BUILD.bazel +++ b/twirl-compiler-cli/BUILD.bazel @@ -1,6 +1,12 @@ +load("@rules_scala_annex//rules:scalafmt.bzl", "scala_format_test") load(":twirl-compiler-cli.bzl", "generate_twirl_compiler_targets") # Check twirl-compiler-cli.bzl for the actual build definitions generate_twirl_compiler_targets(scala_version = "3") generate_twirl_compiler_targets(scala_version = "2.13") + +scala_format_test( + name = "format", + srcs = glob(["*.scala"]), +) diff --git a/twirl-compiler-cli/CommandLineTwirlTemplateCompiler.scala b/twirl-compiler-cli/CommandLineTwirlTemplateCompiler.scala index 79faac9..50f8c96 100644 --- a/twirl-compiler-cli/CommandLineTwirlTemplateCompiler.scala +++ b/twirl-compiler-cli/CommandLineTwirlTemplateCompiler.scala @@ -3,11 +3,14 @@ package rulestwirl.twirl import higherkindness.rules_scala.common.error.AnnexWorkerError import higherkindness.rules_scala.common.interrupt.InterruptUtil import higherkindness.rules_scala.common.sandbox.SandboxUtil -import higherkindness.rules_scala.common.worker.{WorkerMain, WorkTask} +import higherkindness.rules_scala.common.worker.{WorkTask, WorkerMain} import play.twirl.compiler.TwirlCompiler +import play.twirl.parser.TwirlIO import java.io.{File, PrintStream} import java.nio.file.{Files, Path, Paths} +import scala.io.Codec import scala.jdk.CollectionConverters._ +import scala.util.Properties import scopt.OptionParser // @@ -32,30 +35,48 @@ object CommandLineTwirlTemplateCompiler extends WorkerMain[Unit] { // Do not exit as it causes problems for Bazel workers override def terminate(exitState: Either[String, Unit]): Unit = () - arg[Path]("").required().action { (value, config) => - config.output = SandboxUtil.getSandboxPath(workDir, value) - config - }.text("output file") - - arg[Path]("").required().action { (value, config) => - config.sourceDirectory = SandboxUtil.getSandboxPath(workDir, value) - config - }.text("root source directory") - - arg[Path]("").unbounded().required().action { (value, config) => - config.source = SandboxUtil.getSandboxPath(workDir, value) - config - }.text("source file") - - opt[String]('i', "additionalImport").valueName("").unbounded().action { (value, config) => - config.additionalImports = config.additionalImports ++ List(value) - config - }.text("additional imports to add to the compiled templates") - - opt[(String, String)]('t', "templateFormat").unbounded().action({ case ((key, value), config) => - config.templateFormats = config.templateFormats + (key -> value) - config - }).keyValueName("format", "formatterType").text("additional template formats to use when compiling templates") + arg[Path]("") + .required() + .action { (value, config) => + config.output = SandboxUtil.getSandboxPath(workDir, value) + config + } + .text("output file") + + arg[Path]("") + .required() + .action { (value, config) => + config.sourceDirectory = SandboxUtil.getSandboxPath(workDir, value) + config + } + .text("root source directory") + + arg[Path]("") + .unbounded() + .required() + .action { (value, config) => + config.source = SandboxUtil.getSandboxPath(workDir, value) + config + } + .text("source file") + + opt[String]('i', "additionalImport") + .valueName("") + .unbounded() + .action { (value, config) => + config.additionalImports = config.additionalImports ++ List(value) + config + } + .text("additional imports to add to the compiled templates") + + opt[(String, String)]('t', "templateFormat") + .unbounded() + .action { case ((key, value), config) => + config.templateFormats = config.templateFormats + (key -> value) + config + } + .keyValueName("format", "formatterType") + .text("additional template formats to use when compiling templates") } def compileTwirl(config: Config, isCancelled: Function0[Boolean]): Unit = { @@ -67,15 +88,19 @@ object CommandLineTwirlTemplateCompiler extends WorkerMain[Unit] { content = new String(Files.readAllBytes(config.source)), source = config.source.toFile(), sourceDirectory = config.sourceDirectory.toFile(), + resultType = s"${formatterType}.Appendable", formatterType = formatterType, + scalaVersion = Some(scalaVersion), additionalImports = config.additionalImports.map(_.replace("%format%", extension)), + constructorAnnotations = scala.collection.Seq.empty, + codec = Codec(Properties.sourceEncoding), // Equivalent to `TwirlIO.defaultCodec` inclusiveDot = false, - resultType = s"${formatterType}.Appendable" ) InterruptUtil.throwIfInterrupted(isCancelled) // TwirlCompiler.compileVirtual generates a footer comment that contains non-reproducible metatdata; remove it - val sansMetadata = result.content.split("\n").span(s => !s.contains("-- GENERATED --"))._1.dropRight(1).mkString("\n") + val sansMetadata = + result.content.split("\n").span(s => !s.contains("-- GENERATED --"))._1.dropRight(1).mkString("\n") Files.write(config.output, sansMetadata.getBytes) } @@ -84,22 +109,25 @@ object CommandLineTwirlTemplateCompiler extends WorkerMain[Unit] { protected def work(task: WorkTask[Unit]): Unit = { val finalArgs = task.args.toList.flatMap { case arg if arg.startsWith("@") => Files.readAllLines(Paths.get(arg.tail)).asScala - case arg => Array(arg) + case arg => Array(arg) } InterruptUtil.throwIfInterrupted(task.isCancelled) - parser(task.workDir, task.output).parse(finalArgs, Config()).map { config => - InterruptUtil.throwIfInterrupted(task.isCancelled) - compileTwirl(config, task.isCancelled) - }.getOrElse { - throw new AnnexWorkerError(3) - } + parser(task.workDir, task.output) + .parse(finalArgs, Config()) + .map { config => + InterruptUtil.throwIfInterrupted(task.isCancelled) + compileTwirl(config, task.isCancelled) + } + .getOrElse { + throw new AnnexWorkerError(3) + } } def defaultFormats = Map( "html" -> "play.twirl.api.HtmlFormat", "txt" -> "play.twirl.api.TxtFormat", "xml" -> "play.twirl.api.XmlFormat", - "js" -> "play.twirl.api.JavaScriptFormat" + "js" -> "play.twirl.api.JavaScriptFormat", ) -} \ No newline at end of file +} diff --git a/twirl-compiler-cli/package2.scala b/twirl-compiler-cli/package2.scala new file mode 100644 index 0000000..cf50b62 --- /dev/null +++ b/twirl-compiler-cli/package2.scala @@ -0,0 +1,5 @@ +package rulestwirl + +package object twirl { + private[twirl] val scalaVersion: String = "2" +} diff --git a/twirl-compiler-cli/package3.scala b/twirl-compiler-cli/package3.scala new file mode 100644 index 0000000..0fc96ec --- /dev/null +++ b/twirl-compiler-cli/package3.scala @@ -0,0 +1,5 @@ +package rulestwirl + +package object twirl { + private[twirl] val scalaVersion: String = "3.x" +} diff --git a/twirl-compiler-cli/twirl-compiler-cli.bzl b/twirl-compiler-cli/twirl-compiler-cli.bzl index e9ab44c..8245a83 100644 --- a/twirl-compiler-cli/twirl-compiler-cli.bzl +++ b/twirl-compiler-cli/twirl-compiler-cli.bzl @@ -9,14 +9,19 @@ def generate_twirl_compiler_targets(scala_version): scala_version_dash = scala_version.replace(".", "-") if scala_version.startswith("3"): scala_library_target = "@twirl_compiler_cli_{}//:org_scala_lang_scala3_library_3".format(scala_version_underscore) + version_specific_srcs = ["package3.scala"] else: scala_library_target = "@twirl_compiler_cli_{}//:org_scala_lang_scala_library".format(scala_version_underscore) + version_specific_srcs = ["package2.scala"] main_class = "rulestwirl.twirl.CommandLineTwirlTemplateCompiler" scala_library( name = "twirl-compiler-lib-{}".format(scala_version_dash), - srcs = native.glob(["*.scala"]), + srcs = native.glob( + ["*.scala"], + exclude = ["package*.scala"], + ) + version_specific_srcs, scalacopts = ["-Xfatal-warnings"], visibility = ["//visibility:public"], deps_used_whitelist = [ @@ -27,6 +32,7 @@ def generate_twirl_compiler_targets(scala_version): scala_library_target, "@twirl_compiler_cli_{}//:com_github_scopt_scopt_{}".format(scala_version_underscore, scala_version_underscore), "@twirl_compiler_cli_{}//:org_playframework_twirl_twirl_compiler_{}".format(scala_version_underscore, scala_version_underscore), + "@twirl_compiler_cli_{}//:org_playframework_twirl_twirl_parser_{}".format(scala_version_underscore, scala_version_underscore), "@twirl_compiler_cli_{}//:com_google_protobuf_protobuf_java".format(scala_version_underscore), "@rules_scala_annex//src/main/scala/higherkindness/rules_scala/common/error", "@rules_scala_annex//src/main/scala/higherkindness/rules_scala/common/interrupt",