diff --git a/build.sbt b/build.sbt index 214382c355..ef6a1d7c3d 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,8 @@ import com.typesafe.tools.mima.core.* import org.scalajs.linker.interface.ModuleSplitStyle import sbtcrossproject.CrossPlugin.autoImport.{ crossProject, CrossType } +import sbt.* +import Keys.* val scala212 = "2.12.20" val scala213 = "2.13.15" @@ -215,7 +217,24 @@ lazy val tools = project "dev.zio" %% "zio-test" % zioVersion % Test, "dev.zio" %% "zio-test-sbt" % zioVersion % Test, "dev.zio" %% "zio-json" % zioJsonVersion % Test - ) + ), + Test / publishArtifact := true, + + // Include test artifact for publishLocal + publishLocalConfiguration := { + val config = publishLocalConfiguration.value + val testArtifacts = (Test / packagedArtifacts).value + config.withArtifacts(config.artifacts ++ testArtifacts).withOverwrite(true) + }, + // Exclude test artifact from publish + publishConfiguration := { + val config = publishConfiguration.value + config + .withArtifacts(config.artifacts.filterNot { case (artifact, _) => + artifact.configurations.exists(_.name == "test") + }) + .withOverwrite(true) + } ) .dependsOn(core, clientJVM, quickAdapter % Test) @@ -266,18 +285,27 @@ lazy val codegenSbt = project .settings( scriptedLaunchOpts := { scriptedLaunchOpts.value ++ - Seq("-Xmx1024M", "-Xss4M", "-Dplugin.version=" + version.value) + Seq( + "-Xmx1024M", + "-Xss4M", + "-Dplugin.version=" + version.value, + "-Dzio.test.version=" + ScriptedDependency.Version.zioTest, + "-Dsttp.version=" + ScriptedDependency.Version.sttp, + s"-Dproject.dir=${baseDirectory.value.getAbsolutePath}" + ) }, scriptedBufferLog := false, - scriptedDependencies := { - (macros / publishLocal).value - (core / publishLocal).value - (clientJVM / publishLocal).value - (tools / publishLocal).value - publishLocal.value - } + scriptedDependencies := scriptedDependencies + .dependsOn( + macros / publishLocal, + core / publishLocal, + clientJVM / publishLocal, + tools / publishLocal, + publishLocal + ) + .value ) - .dependsOn(tools) + .dependsOn(tools % "compile->compile;test->test") lazy val catsInterop = project .in(file("interop/cats")) diff --git a/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/README.md b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/README.md index a800a35731..b1629c1e88 100644 --- a/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/README.md +++ b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/README.md @@ -1,3 +1,14 @@ # Test doc -This test project has been copied from: https://github.com/guizmaii/poc_compile_time_caliban_client_generation \ No newline at end of file +This test project has been copied from: +https://github.com/guizmaii/poc_compile_time_caliban_client_generation + +### Running locally +You can run these tests using following sbt commandos: + +```sbt +project codegenSbt +++2.12 +update +scripted compiletime-codegen/test-compile +``` diff --git a/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/build.sbt b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/build.sbt index 3b4146911a..fadfa95a64 100644 --- a/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/build.sbt +++ b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/build.sbt @@ -26,18 +26,20 @@ ThisBuild / crossScalaVersions := allScala // ### Dependencies ### -lazy val calibanLib: Seq[ModuleID] = - sys.props.get("plugin.version") match { - case Some(x) => Seq("com.github.ghostdogpr" %% "caliban" % x) - case _ => sys.error("""|The system property 'plugin.version' is not defined. - |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) - } +lazy val calibanLib = Seq( + "com.github.ghostdogpr" %% "caliban" % Version.pluginVersion, + "com.github.ghostdogpr" %% "caliban-tools" % Version.pluginVersion % "compile->compile;test->test" +) lazy val sttp = Seq( - "com.softwaremill.sttp.client3" %% "core" % "3.10.1", - "com.softwaremill.sttp.client3" %% "zio" % "3.10.1" + "com.softwaremill.sttp.client3" %% "core" % Version.sttpVersion, + "com.softwaremill.sttp.client3" %% "zio" % Version.sttpVersion ) +lazy val zioTest = Seq( + "dev.zio" %% "zio-test" % Version.zioTestVersion % Test, + "dev.zio" %% "zio-test-sbt" % Version.zioTestVersion % Test +) // ### App Modules ### /** @@ -103,7 +105,7 @@ lazy val posts = ) ) ) - .settings(libraryDependencies ++= calibanLib) + .settings(libraryDependencies ++= calibanLib ++ zioTest) lazy val potatoes = project diff --git a/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/modules/posts/src/test/resources/postservice.graphql b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/modules/posts/src/test/resources/postservice.graphql new file mode 100644 index 0000000000..71122441c4 --- /dev/null +++ b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/modules/posts/src/test/resources/postservice.graphql @@ -0,0 +1,54 @@ +schema { + query: Query + mutation: Mutation + subscription: Subscription +} +scalar Unit + +input AuthorNameInput { + name: String! +} + +input PostContentInput { + content: String! +} + +input PostTitleInput { + title: String! +} + +type AuthorName { + name: String! +} + +type Mutation { + createPost(authorName: AuthorNameInput!, title: PostTitleInput!, content: PostContentInput!): Post + deletePost(id: ID!): Unit +} + +type Post { + id: PostId! + author: AuthorName! + title: PostTitle! + content: PostContent! +} + +type PostContent { + content: String! +} + +type PostId { + id: ID! +} + +type PostTitle { + title: String! +} + +type Query { + postById(id: ID!): Post +} + +type Subscription { + allPostsByAuthor(name: String!): Post +} \ No newline at end of file diff --git a/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/modules/posts/src/test/scala/ValidateGraphQlSpec.scala b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/modules/posts/src/test/scala/ValidateGraphQlSpec.scala new file mode 100644 index 0000000000..c6bc4f8492 --- /dev/null +++ b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/modules/posts/src/test/scala/ValidateGraphQlSpec.scala @@ -0,0 +1,24 @@ +import poc.caliban.posts.GraphQLApi + +import scala.io.Source +import zio.test.Assertion._ +import zio.test._ +import caliban.tools._ +import java.nio.file.Path + +object ValidateGraphQlSpec extends SnapshotTest { + override val testName: String = "ValidateGraphQlSpec" + + val graphqlFile= "src/sbt-test/compiletime-codegen/test-compile/modules/posts/src/test/resources/postservice.graphql" + val projectDir = sys.props.get("project.dir").getOrElse("") + + override def spec = + suite("Validate Postservice")( + test("Render postservice as earlier") { + val gqlApi = GraphQLApi.api + val renderContent: String = s"${gqlApi.render}" + + writeAndCompare(Path.of(projectDir).resolve(graphqlFile), renderContent, "Render postservice") + } + ) +} \ No newline at end of file diff --git a/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/project/Version.scala b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/project/Version.scala new file mode 100644 index 0000000000..64d3c3eccd --- /dev/null +++ b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/project/Version.scala @@ -0,0 +1,20 @@ +object Version { + def pluginVersion: String = + sys.props.get("plugin.version") match { + case Some(x) => x + case _ => sys.error("""|The system property 'plugin.version' is not defined. + |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) + } + def zioTestVersion: String = + sys.props.get("zio.test.version") match { + case Some(x) => x + case _ => sys.error("""|The system property 'zio.test.version' is not defined. + |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) + } + def sttpVersion: String = + sys.props.get("sttp.version") match { + case Some(x) => x + case _ => sys.error("""|The system property 'sttp.version' is not defined. + |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) + } +} diff --git a/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/test b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/test index e063c05659..1ad20505c5 100644 --- a/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/test +++ b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/test @@ -201,3 +201,5 @@ $ exists modules/potatoes-clients/src/main/scala/poc/caliban/client/generated/po -$ newer modules/posts/target/ctCalibanServer/touch modules/posts/target/ctCalibanServer/touch_old # TODO: This should be newer, sadly I don't find how to make it work. -$ newer modules/posts-clients/target/scala-2.12/src_managed/main/poc/caliban/client/generated/posts/CalibanClient.scala modules/posts-clients/tmp/CalibanClient.scala.old + +> reload; test \ No newline at end of file diff --git a/project/ScriptedDependency.scala b/project/ScriptedDependency.scala new file mode 100644 index 0000000000..9baf7bd930 --- /dev/null +++ b/project/ScriptedDependency.scala @@ -0,0 +1,20 @@ +import sbt.* + +//noinspection TypeAnnotation +object ScriptedDependency { + // scala steward should understand these version in context of dependencies described here + object Version { + val sttp = "3.10.1" + val zioTest = "2.1.9" + } + + lazy val sttp = Seq( + "com.softwaremill.sttp.client3" %% "core" % Version.sttp, + "com.softwaremill.sttp.client3" %% "zio" % Version.sttp + ) + + lazy val zioTest = Seq( + "dev.zio" %% "zio-test" % Version.zioTest % Test, + "dev.zio" %% "zio-test-sbt" % Version.zioTest % Test + ) +} diff --git a/tools/src/test/scala/caliban/tools/SnapshotTest.scala b/tools/src/test/scala/caliban/tools/SnapshotTest.scala index aa88ed8b64..99d9745706 100644 --- a/tools/src/test/scala/caliban/tools/SnapshotTest.scala +++ b/tools/src/test/scala/caliban/tools/SnapshotTest.scala @@ -2,7 +2,9 @@ package caliban.tools import caliban.tools.SnapshotTest.GitLock import zio.internal.stacktracer.SourceLocation -import zio.test.{ assert, assertTrue, Assertion, Spec, TestResult, ZIOSpecDefault } +import zio.prelude._ +import zio.test.Assertion.equalTo +import zio.test.{ assert, assertNever, assertTrue, Assertion, Spec, TestResult, ZIOSpecDefault } import zio.{ Task, Trace } import java.nio.file.{ Files, Path } @@ -16,51 +18,64 @@ trait SnapshotTest extends ZIOSpecDefault { )(str: Task[String])(implicit sourceLocation: SourceLocation, trace: Trace): Spec[Any, Throwable] = { val label = label0.replace('/', '_').replace("'", "") zio.test.test[Task[TestResult]](label) { - str.map { str => - val isCi = SnapshotTest.isCi + str.map { content => val path = SnapshotTest.projectRoot.resolve(s"tools/src/test/resources/snapshots/$testName/${label + ".scala"}") + writeAndCompare(path, content, label) + } + } + } - def write(): TestResult = { - Files.createDirectories(path.getParent) - Files.writeString(path, str) - import scala.sys.process._ - // at least don't take the git lock multiple times from same process. this can still fail if concurrent processes try to take it. - GitLock.synchronized { - // allow failing external command, but complain to stderr - try s"git add '$path'".! - catch { - case th: Throwable => - System.err.println(s"Could not add snapshot file '$path' to git: ${th.getMessage}") - } - } - assert(())(Assertion.anything) - } + private def write(path: Path, str: String): TestResult = { + Files.createDirectories(path.getParent) + Files.writeString(path, str) + import scala.sys.process._ - Try(Files.readString(path)) match { - case Success(existing) if isCi => - assertTrue(str == existing).label( - s"generated result for test '$label' did not match snapshot contents in file '$path. Rerun with environment `CI` not set to 'true' to update and then check in the file" - ) - case Success(_) => - write() - case Failure(_) if isCi => - assertTrue(false).label( - s"Could not read snapshot file '$path'. Rerun with environment `CI` not set to 'true' to create and then check in the file" - ) - case Failure(_) => - write() + var exitCode = 0 + // at least don't take the git lock multiple times from same process. this can still fail if concurrent processes try to take it. + GitLock.synchronized { + // allow failing external command, but complain to stderr + exitCode = + try + s"git add '$path'".! + catch { + case th: Throwable => + System.err.println(s"Could not add snapshot file '$path' to git: ${th.getMessage}") + -1 } - } + } + + if (exitCode == 0) { + assert(())(Assertion.anything) + } else { + assertNever(s"Failed to add file '$path' to git. Exit code: $exitCode") } } + def writeAndCompare(path: Path, content: String, label: String): TestResult = + Try(Files.readString(path)) match { + case Success(existing) if SnapshotTest.isCi => + assertTrue(content == existing).label( + s"generated result for test '$label' did not match snapshot contents in file '$path. Rerun with environment `CI` not set to 'true' to update and then check in the file" + ) + case Success(existing) if existing.equals(content) => + assert(())(Assertion.anything) + case Success(_) => + write(path, content) + case Failure(_) if SnapshotTest.isCi => + assertTrue(false).label( + s"Could not read snapshot file '$path'. Rerun with environment `CI` not set to 'true' to create and then check in the file" + ) + case Failure(_) => + write(path, content) + } + } object SnapshotTest { val `.git`: Path = Path.of(".git") val cwd: Path = Path.of(sys.props("user.dir")) - val projectRoot: Path = { + lazy val projectRoot: Path = { def lookUpwards(p: Path): Option[Path] = if (Files.list(p).anyMatch(p => p.getFileName == `.git`)) Some(p) else Option(p.getParent).flatMap(lookUpwards)