From e102b0f02cbecba6022b80a5d3fa5a0ba6053f6e Mon Sep 17 00:00:00 2001 From: OlegYch Date: Sun, 14 Jul 2024 16:50:41 +0200 Subject: [PATCH] Allow modifying generated sources (eg to hook up scalafmt), some general cleanup --- README.md | 4 ++ build.sbt | 7 ++- .../main/scala/AbstractCodegenPlugin.scala | 38 ++++++++-------- .../src/main/scala/GuardrailAnalysis.scala | 21 --------- modules/core/src/main/scala/Tasks.scala | 4 -- project/build.properties | 2 +- .../java-codegen-app/project/build.properties | 2 +- .../sbt-guardrail/java-codegen-app/test | 6 +-- .../project/build.properties | 2 +- .../scala-client-codegen-app/test | 10 ++--- .../sbt-guardrail/scalafmt/.scalafmt.conf | 1 + src/sbt-test/sbt-guardrail/scalafmt/build.sbt | 16 +++++++ .../scalafmt/project/build.properties | 1 + .../scalafmt/project/plugins.sbt | 12 ++++++ .../main/openapi/com/example/petstore.json | 43 +++++++++++++++++++ src/sbt-test/sbt-guardrail/scalafmt/test | 10 +++++ 16 files changed, 121 insertions(+), 58 deletions(-) delete mode 100644 modules/core/src/main/scala/GuardrailAnalysis.scala create mode 100644 src/sbt-test/sbt-guardrail/scalafmt/.scalafmt.conf create mode 100644 src/sbt-test/sbt-guardrail/scalafmt/build.sbt create mode 100644 src/sbt-test/sbt-guardrail/scalafmt/project/build.properties create mode 100644 src/sbt-test/sbt-guardrail/scalafmt/project/plugins.sbt create mode 100644 src/sbt-test/sbt-guardrail/scalafmt/src/main/openapi/com/example/petstore.json create mode 100644 src/sbt-test/sbt-guardrail/scalafmt/test diff --git a/README.md b/README.md index fef602c..d8ff12b 100644 --- a/README.md +++ b/README.md @@ -48,3 +48,7 @@ Compile / guardrailTasks := (Compile / guardrailDiscoveredOpenApiFiles).value.fl ) } ``` +Formatting generated sources with scalafmt: +``` +Compile / scalafmt / unmanagedSources ++= (Compile / guardrail).value +``` \ No newline at end of file diff --git a/build.sbt b/build.sbt index 64368dd..af595f8 100644 --- a/build.sbt +++ b/build.sbt @@ -22,7 +22,8 @@ ThisBuild / developers := List( ) ) -ThisBuild / scalaVersion := "2.12.18" +ThisBuild / scalacOptions := Seq("-target:jvm-1.8") +//ThisBuild / pluginCrossBuild / sbtVersion := "1.5.0" //breaks on windows https://github.com/sbt/sbt/issues/7082 ThisBuild / scalacOptions ++= List("-feature", "-Xexperimental") libraryDependencies ++= Seq( @@ -44,7 +45,7 @@ git.gitDescribedVersion := git.gitDescribedVersion(v => { git.gitUncommittedChanges := git.gitCurrentTags.value.isEmpty -val commonSettings = Seq( +val commonSettings: SettingsDefinition = Seq( // Release publishMavenStyle := true, sonatypeCredentialHost := "s01.oss.sonatype.org", @@ -52,6 +53,8 @@ val commonSettings = Seq( ) +scriptedBufferLog := false + scriptedLaunchOpts := { scriptedLaunchOpts.value ++ Seq("-Xmx1024M", "-Dplugin.version=" + version.value) } diff --git a/modules/core/src/main/scala/AbstractCodegenPlugin.scala b/modules/core/src/main/scala/AbstractCodegenPlugin.scala index bbf4a1a..3bb0124 100644 --- a/modules/core/src/main/scala/AbstractCodegenPlugin.scala +++ b/modules/core/src/main/scala/AbstractCodegenPlugin.scala @@ -3,6 +3,7 @@ package sbt import _root_.sbt.{Keys => SbtKeys, Types => _, _} import _root_.sbt.plugins.JvmPlugin +import _root_.sbt.nio.{Keys => SbtNioKeys} import dev.guardrail.runner.GuardrailRunner import dev.guardrail.terms.protocol.PropertyRequirement import dev.guardrail.{ @@ -187,36 +188,33 @@ trait AbstractGuardrailPlugin { self: AutoPlugin => lazy val GuardrailHelpers = _root_.dev.guardrail.sbt.GuardrailHelpers } - private def cachedGuardrailTask(projectName: String, scope: String, scalaBinaryVersion: String)(kind: String, streams: _root_.sbt.Keys.TaskStreams)(tasks: List[(String, Args)], sources: Seq[java.io.File]) = { - val inputFiles = tasks.flatMap(_._2.specPath).map(file(_)).toSet - val cacheDir = streams.cacheDirectory / "guardrail" / scalaBinaryVersion / kind - - val cachedFn = _root_.sbt.util.FileFunction - .cached(cacheDir, inStyle = FilesInfo.hash, outStyle = FilesInfo.hash) { - _ => - GuardrailAnalysis( - BuildInfo.version, - Tasks.guardrailTask(runner.guardrailRunner)(tasks, sources.head) - ).products - } - - cachedFn(inputFiles).toSeq - } - - def scopedSettings(name: String, scope: Configuration) = { + def scopedSettings(scope: Configuration): SettingsDefinition = { import _root_.sbt.Keys.{resourceDirectory, sourceDirectory, unmanagedResourceDirectories, unmanagedSourceDirectories} Seq( scope / unmanagedSourceDirectories += (scope / sourceDirectory).value / "openapi", scope / unmanagedResourceDirectories += (scope / resourceDirectory).value / "openapi", scope / Keys.guardrailDiscoveredOpenApiFiles := GuardrailHelpers.discoverOpenApiFiles((scope / sourceDirectory).value / "openapi"), scope / Keys.guardrailTasks := List.empty, - scope / Keys.guardrail := cachedGuardrailTask(SbtKeys.name.value, scope.name, SbtKeys.scalaBinaryVersion.value)(name, _root_.sbt.Keys.streams.value)((scope / Keys.guardrailTasks).value, (scope / SbtKeys.managedSourceDirectories).value), + + scope / Keys.guardrail / SbtNioKeys.fileInputs := (scope / Keys.guardrailTasks).value.flatMap(_._2.specPath).map( p => Glob(file(p).getAbsoluteFile)), + scope / Keys.guardrail / SbtKeys.sourceManaged := (scope / SbtKeys.sourceManaged).value / "guardrail", + scope / Keys.guardrail := { + val tasks = (scope / Keys.guardrailTasks).value + val csf = (scope / Keys.guardrail / SbtKeys.streams).value.cacheStoreFactory + .sub(SbtKeys.scalaBinaryVersion.value) + .sub(BuildInfo.version) + .sub(Hash.toHex(Hash(tasks.toString))) + val output = (scope / Keys.guardrail / SbtKeys.sourceManaged).value + val cached = FileFunction.cached(csf, inStyle = FileInfo.hash, outStyle = FileInfo.exists) { (_, _) => + Tasks.guardrailTask(runner.guardrailRunner)(tasks, output) + } + cached((scope / Keys.guardrail / SbtNioKeys.allInputFiles).value.map(_.toFile).toSet).toSeq + }, scope / SbtKeys.sourceGenerators += (scope / Keys.guardrail).taskValue, - scope / SbtKeys.watchSources ++= Tasks.watchSources((scope / Keys.guardrailTasks).value), ) } override lazy val projectSettings = { - scopedSettings("compile", Compile) ++ scopedSettings("test", Test) + scopedSettings(Compile) ++ scopedSettings(Test) } } diff --git a/modules/core/src/main/scala/GuardrailAnalysis.scala b/modules/core/src/main/scala/GuardrailAnalysis.scala deleted file mode 100644 index 3bb1130..0000000 --- a/modules/core/src/main/scala/GuardrailAnalysis.scala +++ /dev/null @@ -1,21 +0,0 @@ -package dev.guardrail -package sbt - -import _root_.sbt._ -import _root_.sbt.util.CacheImplicits._ -import sjsonnew.{ :*:, LList, LNil} - -case class GuardrailAnalysis(guardrailVersion: String, products: Set[java.io.File]) { - def ++(that: GuardrailAnalysis): GuardrailAnalysis = - GuardrailAnalysis(guardrailVersion, products ++ that.products) -} -object GuardrailAnalysis { - - private val from: (String :*: Set[java.io.File] :*: LNil) => GuardrailAnalysis = { - case ((_, version) :*: (_, in) :*: LNil) => GuardrailAnalysis(version, in) - } - - implicit val analysisIso = LList.iso( - { a: GuardrailAnalysis => ("guardrailVersion", a.guardrailVersion) :*: ("products", a.products) :*: LNil }, - { from }) -} diff --git a/modules/core/src/main/scala/Tasks.scala b/modules/core/src/main/scala/Tasks.scala index 9c7d2cb..ac57e95 100644 --- a/modules/core/src/main/scala/Tasks.scala +++ b/modules/core/src/main/scala/Tasks.scala @@ -89,8 +89,4 @@ object Tasks { paths.map(_.toFile).toSet } finally Thread.currentThread().setContextClassLoader(oldClassLoader) } - - def watchSources(tasks: List[Types.Args]): Seq[WatchSource] = { - tasks.flatMap(_._2.specPath.map(new File(_)).map(WatchSource(_))).toSeq - } } diff --git a/project/build.properties b/project/build.properties index abbbce5..ee4c672 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.8 +sbt.version=1.10.1 diff --git a/src/sbt-test/sbt-guardrail/java-codegen-app/project/build.properties b/src/sbt-test/sbt-guardrail/java-codegen-app/project/build.properties index abbbce5..e67343a 100644 --- a/src/sbt-test/sbt-guardrail/java-codegen-app/project/build.properties +++ b/src/sbt-test/sbt-guardrail/java-codegen-app/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.8 +sbt.version=1.5.0 diff --git a/src/sbt-test/sbt-guardrail/java-codegen-app/test b/src/sbt-test/sbt-guardrail/java-codegen-app/test index 5d8e657..e65a314 100644 --- a/src/sbt-test/sbt-guardrail/java-codegen-app/test +++ b/src/sbt-test/sbt-guardrail/java-codegen-app/test @@ -1,10 +1,10 @@ > clean -$ absent target/scala-2.12/src_managed/main/com/example/clients/petstore/user/UserClient.java +$ absent target/scala-2.12/src_managed/main/guardrail/com/example/clients/petstore/user/UserClient.java $ absent target/scala-2.12/classes/com/example/clients/petstore/user/UserClient.class > compile -$ exists target/scala-2.12/src_managed/main/com/example/clients/petstore/user/UserClient.java +$ exists target/scala-2.12/src_managed/main/guardrail/com/example/clients/petstore/user/UserClient.java $ exists target/scala-2.12/classes/com/example/clients/petstore/user/UserClient.class > compile -$ exists target/scala-2.12/src_managed/main/com/example/clients/petstore/user/UserClient.java +$ exists target/scala-2.12/src_managed/main/guardrail/com/example/clients/petstore/user/UserClient.java $ exists target/scala-2.12/classes/com/example/clients/petstore/user/UserClient.class > test diff --git a/src/sbt-test/sbt-guardrail/scala-client-codegen-app/project/build.properties b/src/sbt-test/sbt-guardrail/scala-client-codegen-app/project/build.properties index abbbce5..e67343a 100644 --- a/src/sbt-test/sbt-guardrail/scala-client-codegen-app/project/build.properties +++ b/src/sbt-test/sbt-guardrail/scala-client-codegen-app/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.8 +sbt.version=1.5.0 diff --git a/src/sbt-test/sbt-guardrail/scala-client-codegen-app/test b/src/sbt-test/sbt-guardrail/scala-client-codegen-app/test index de89a4f..321f28c 100644 --- a/src/sbt-test/sbt-guardrail/scala-client-codegen-app/test +++ b/src/sbt-test/sbt-guardrail/scala-client-codegen-app/test @@ -1,14 +1,14 @@ > clean -$ absent target/scala-2.12/src_managed/main/com/example/petstore/client/user/UserClient.scala +$ absent target/scala-2.12/src_managed/main/guardrail/com/example/petstore/client/user/UserClient.scala $ absent target/scala-2.12/classes/com/example/petstore/client/user/UserClient.class > compile -$ exists target/scala-2.12/src_managed/main/com/example/petstore/client/user/UserClient.scala +$ exists target/scala-2.12/src_managed/main/guardrail/com/example/petstore/client/user/UserClient.scala $ exists target/scala-2.12/classes/com/example/petstore/client/user/UserClient.class -$ exists target/scala-2.12/src_managed/main/com/example/petstore/server/user/Routes.scala +$ exists target/scala-2.12/src_managed/main/guardrail/com/example/petstore/server/user/Routes.scala $ exists target/scala-2.12/classes/com/example/petstore/server/user/UserHandler.class > compile -$ exists target/scala-2.12/src_managed/main/com/example/petstore/client/user/UserClient.scala +$ exists target/scala-2.12/src_managed/main/guardrail/com/example/petstore/client/user/UserClient.scala $ exists target/scala-2.12/classes/com/example/petstore/client/user/UserClient.class -$ exists target/scala-2.12/src_managed/main/com/example/petstore/server/user/Routes.scala +$ exists target/scala-2.12/src_managed/main/guardrail/com/example/petstore/server/user/Routes.scala $ exists target/scala-2.12/classes/com/example/petstore/server/user/UserHandler.class > test diff --git a/src/sbt-test/sbt-guardrail/scalafmt/.scalafmt.conf b/src/sbt-test/sbt-guardrail/scalafmt/.scalafmt.conf new file mode 100644 index 0000000..dd18323 --- /dev/null +++ b/src/sbt-test/sbt-guardrail/scalafmt/.scalafmt.conf @@ -0,0 +1 @@ +version = 2.5.2 diff --git a/src/sbt-test/sbt-guardrail/scalafmt/build.sbt b/src/sbt-test/sbt-guardrail/scalafmt/build.sbt new file mode 100644 index 0000000..38c63f5 --- /dev/null +++ b/src/sbt-test/sbt-guardrail/scalafmt/build.sbt @@ -0,0 +1,16 @@ + +name := "sbt-guardrail-scala-client-test-app" + +version := "1.0." + System.currentTimeMillis + +scalaVersion := "2.12.18" + +scalacOptions += "-Xexperimental" + +Compile / guardrailTasks := GuardrailHelpers.createGuardrailTasks((Compile / sourceDirectory).value / "openapi") { openApiFile => + List( + ScalaClient(openApiFile.file), + ) +} + +Compile / scalafmt / unmanagedSources ++= (Compile / guardrail).value \ No newline at end of file diff --git a/src/sbt-test/sbt-guardrail/scalafmt/project/build.properties b/src/sbt-test/sbt-guardrail/scalafmt/project/build.properties new file mode 100644 index 0000000..e67343a --- /dev/null +++ b/src/sbt-test/sbt-guardrail/scalafmt/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.5.0 diff --git a/src/sbt-test/sbt-guardrail/scalafmt/project/plugins.sbt b/src/sbt-test/sbt-guardrail/scalafmt/project/plugins.sbt new file mode 100644 index 0000000..269436c --- /dev/null +++ b/src/sbt-test/sbt-guardrail/scalafmt/project/plugins.sbt @@ -0,0 +1,12 @@ +{ + val pluginVersion = System.getProperty("plugin.version") + if(pluginVersion == null) + throw new RuntimeException("""|The system property 'plugin.version' is not defined. + |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) + else addSbtPlugin("dev.guardrail" % "sbt-guardrail" % pluginVersion) +} + +libraryDependencies += "dev.guardrail" %% "guardrail-scala-support" % "1.0.0-M1" +libraryDependencies += "dev.guardrail" %% "guardrail-scala-akka-http" % "1.0.0-M1" + +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") diff --git a/src/sbt-test/sbt-guardrail/scalafmt/src/main/openapi/com/example/petstore.json b/src/sbt-test/sbt-guardrail/scalafmt/src/main/openapi/com/example/petstore.json new file mode 100644 index 0000000..32fd56f --- /dev/null +++ b/src/sbt-test/sbt-guardrail/scalafmt/src/main/openapi/com/example/petstore.json @@ -0,0 +1,43 @@ +{ + "swagger": "2.0", + "host": "petstore.swagger.io", + "basePath": "/v2", + "schemes": [ + "http" + ], + "definitions": { + "Order": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "petId": { + "type": "integer", + "format": "int64" + }, + "quantity": { + "type": "integer", + "format": "int32" + }, + "shipDate": { + "type": "string", + "format": "date-time" + }, + "status": { + "type": "string", + "description": "Order Status", + "x-scala-type": "OrderStatus" + }, + "complete": { + "type": "boolean", + "default": false + } + }, + "xml": { + "name": "Order" + } + } + } +} diff --git a/src/sbt-test/sbt-guardrail/scalafmt/test b/src/sbt-test/sbt-guardrail/scalafmt/test new file mode 100644 index 0000000..809cc86 --- /dev/null +++ b/src/sbt-test/sbt-guardrail/scalafmt/test @@ -0,0 +1,10 @@ +> clean +$ absent target/scala-2.12/src_managed/main/guardrail/swagger/definitions/Order.scala +> Compile / guardrail +$ exists target/scala-2.12/src_managed/main/guardrail/swagger/definitions/Order.scala +$ copy-file target/scala-2.12/src_managed/main/guardrail/swagger/definitions/Order.scala created +> Compile / scalafmt +$ newer target/scala-2.12/src_managed/main/guardrail/swagger/definitions/Order.scala created +$ copy-file target/scala-2.12/src_managed/main/guardrail/swagger/definitions/Order.scala formatted +> Compile / guardrail +-$ newer target/scala-2.12/src_managed/main/guardrail/swagger/definitions/Order.scala formatted