diff --git a/build.sbt b/build.sbt index edb04bd15..e890990b2 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.14" @@ -216,7 +218,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) @@ -267,18 +286,25 @@ lazy val codegenSbt = project .settings( scriptedLaunchOpts := { scriptedLaunchOpts.value ++ - Seq("-Xmx1024M", "-Xss4M", "-Dplugin.version=" + version.value) + Seq( + "-Xmx1024M", + "-Xss4M", + "-Dplugin.version=" + version.value, + 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 a800a3573..7105d0528 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.20 +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 cbfa21bba..2b8ab5cb5 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,19 +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.9.8", "com.softwaremill.sttp.client3" %% "zio" % "3.9.8" ) -lazy val zioTest = Seq("dev.zio" %% "zio-test" % "2.1.9" % Test) +lazy val zioTest = Seq( + "dev.zio" %% "zio-test" % "2.1.9" % Test, + "dev.zio" %% "zio-test-sbt" % "2.1.9" % Test +) // ### App Modules ### /** @@ -106,6 +107,7 @@ lazy val posts = ) .settings(libraryDependencies ++= calibanLib ++ zioTest) + lazy val potatoes = project .in(file("modules/potatoes")) 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 index 4d688e333..c6bc4f849 100644 --- 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 @@ -1,24 +1,24 @@ import poc.caliban.posts.GraphQLApi import scala.io.Source -import java.io.File -import java.nio.file.{Files, Paths} import zio.test.Assertion._ import zio.test._ +import caliban.tools._ +import java.nio.file.Path -class ValidateGraphQlSpec extends ZIOSpecDefault { +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 filename = "postservice.graphql" - val expectedGraphQL: String = Source.fromResource(filename).getLines().mkString("\n") val gqlApi = GraphQLApi.api val renderContent: String = s"${gqlApi.render}" - //Files.writeString(Paths.get(File(s"/tmp/$filename").toURI), renderContent) - - assertTrue(expectedGraphQL == renderContent) + 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 000000000..d2c7cd4b1 --- /dev/null +++ b/codegen-sbt/src/sbt-test/compiletime-codegen/test-compile/project/Version.scala @@ -0,0 +1,8 @@ +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) + } +} diff --git a/tools/src/test/scala/caliban/tools/SnapshotTest.scala b/tools/src/test/scala/caliban/tools/SnapshotTest.scala index aa88ed8b6..99d974570 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)