diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac71ddbc9..10adabc07 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,12 +91,6 @@ jobs: - name: Build project run: sbt '++ ${{ matrix.scala }}' test - - uses: coursier/setup-action@v1 - - - name: Test sbt plugin - if: ${{ github.event_name == 'pull_request' }} && matrix.scala == '2.12.19' - run: sbt ++2.12.19 zioHttpGenSbt/scripted - - uses: coursier/setup-action@v1 with: apps: sbt @@ -112,7 +106,7 @@ jobs: run: sbt '++ ${{ matrix.scala }}' zioHttpShadedTests/test - name: Compress target directories - run: tar cf targets.tar sbt-zio-http-grpc/target zio-http-gen-sbt-plugin/target zio-http-cli/target target zio-http/jvm/target zio-http-docs/target sbt-zio-http-grpc-tests/target zio-http-gen/target zio-http-benchmarks/target zio-http-tools/target zio-http-example/target zio-http-testkit/target zio-http/js/target zio-http-htmx/target project/target + run: tar cf targets.tar sbt-zio-http-grpc/target zio-http-cli/target target zio-http/jvm/target zio-http-docs/target sbt-zio-http-grpc-tests/target zio-http-gen/target zio-http-benchmarks/target zio-http-tools/target zio-http-example/target zio-http-testkit/target zio-http/js/target zio-http-htmx/target project/target - name: Upload target directories uses: actions/upload-artifact@v4 diff --git a/build.sbt b/build.sbt index 28eefe636..a19027bdb 100644 --- a/build.sbt +++ b/build.sbt @@ -94,22 +94,6 @@ ThisBuild / githubWorkflowBuildPreamble := Seq( ), ) -ThisBuild / githubWorkflowBuild := { - (ThisBuild / githubWorkflowBuild).value ++ WorkflowJob( - "testSbtPlugin", - "Test sbt plugin", - List( - WorkflowStep.Use(UseRef.Public("coursier", "setup-action", "v1")), - WorkflowStep.Run( - name = Some(s"Test sbt plugin"), - commands = List(s"sbt ++${Scala212} zioHttpGenSbt/scripted"), - cond = Some(s"$${{ github.event_name == 'pull_request' }} && matrix.scala == '$Scala212'"), - ), - ), - scalas = List(Scala212), - ).steps -} - ThisBuild / githubWorkflowBuildPostamble := WorkflowJob( "checkDocGeneration", @@ -367,26 +351,6 @@ lazy val zioHttpGen = (project in file("zio-http-gen")) ) .dependsOn(zioHttpJVM) -lazy val zioHttpGenSbt = (project in file("zio-http-gen-sbt-plugin")) - .enablePlugins(SbtPlugin) - .settings(publishSetting(true)) - .settings( - name := "zio-http-sbt-codegen", - sbtPlugin := true, - scalaVersion := Scala212, - semanticdbEnabled := true, - semanticdbVersion := scalafixSemanticdb.revision, - scalacOptions ++= stdOptions ++ extraOptions(scalaVersion.value), - sbtTestDirectory := sourceDirectory.value / "sbt-test", - scriptedLaunchOpts += ("-Dplugin.version=" + version.value), - scriptedBufferLog := false, - libraryDependencies ++= Seq( - `zio-json-yaml`, - `zio-test`, - `zio-test-sbt`, - ) - ).dependsOn(LocalProject("zioHttpGen")) - lazy val sbtZioHttpGrpc = (project in file("sbt-zio-http-grpc")) .settings(stdSettings("sbt-zio-http-grpc")) .settings(publishSetting(true)) diff --git a/project/BuildHelper.scala b/project/BuildHelper.scala index 62b15549b..44e6243a8 100644 --- a/project/BuildHelper.scala +++ b/project/BuildHelper.scala @@ -12,7 +12,7 @@ object BuildHelper extends ScalaSettings { val ScoverageVersion = "2.0.12" val JmhVersion = "0.4.7" - val stdOptions = Seq( + private val stdOptions = Seq( "-deprecation", "-encoding", "UTF-8", diff --git a/project/build.properties b/project/build.properties index e88a0d817..081fdbbc7 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.6 +sbt.version=1.10.0 diff --git a/zio-http-gen-sbt-plugin/src/main/scala/zio/http/gen/sbt/Format.scala b/zio-http-gen-sbt-plugin/src/main/scala/zio/http/gen/sbt/Format.scala deleted file mode 100644 index 66268483a..000000000 --- a/zio-http-gen-sbt-plugin/src/main/scala/zio/http/gen/sbt/Format.scala +++ /dev/null @@ -1,11 +0,0 @@ -package zio.http.gen.sbt - -sealed trait Format -object Format { - case object YAML extends Format - case object JSON extends Format - def fromFileName(fileName: String): Format = - if (fileName.endsWith("yml") || fileName.endsWith("yaml")) YAML - else if (fileName.endsWith("json")) JSON - else throw new Exception(s"Unknown format for file $fileName") -} diff --git a/zio-http-gen-sbt-plugin/src/main/scala/zio/http/gen/sbt/ZioHttpCodegen.scala b/zio-http-gen-sbt-plugin/src/main/scala/zio/http/gen/sbt/ZioHttpCodegen.scala deleted file mode 100644 index d2de9ec11..000000000 --- a/zio-http-gen-sbt-plugin/src/main/scala/zio/http/gen/sbt/ZioHttpCodegen.scala +++ /dev/null @@ -1,146 +0,0 @@ -package zio.http.gen.sbt - -import java.io.File -import java.nio.charset.StandardCharsets -import java.nio.file.StandardOpenOption.{CREATE, TRUNCATE_EXISTING} -import java.nio.file.{Files, Path} - -import scala.io.Source - -import zio.json.yaml._ - -import zio.schema.codec.JsonCodec - -import zio.http.endpoint.openapi.OpenAPI -import zio.http.gen.openapi.{Config, EndpointGen} -import zio.http.gen.scala.CodeGen - -import sbt.Defaults.configSrcSub -import sbt.Keys._ -import sbt._ -import sbt.util.FileInfo - -object ZioHttpCodegen extends AutoPlugin { - - object autoImport { - - val ZIOpenApi = config("oapi") extend Compile - - val zioHttpCodegenMake = taskKey[Seq[File]]("Generate ADTs & endpoints from OpenAPI spec files") - val zioHttpCodegenConf = settingKey[Config]("Configuration for codegen") - val zioHttpCodegenSources = settingKey[File]("Source dir. analoguous to e.g: scalaSource or javaSource") - } - - import autoImport._ - - override lazy val projectSettings: Seq[Setting[_]] = inConfig(ZIOpenApi)( - Seq[Setting[_]]( - zioHttpCodegenSources := (Compile / sourceDirectory).value / "oapi", - sourceGenerators := Nil, - sourceManaged := configSrcSub(sourceManaged).value, - sourceDirectories := List(zioHttpCodegenSources.value, sourceManaged.value), - sources := { - val generatedFiles = Defaults.generate(sourceGenerators).value - streams.value.log.info(s"Generated ${generatedFiles.length} OpenAPI spec files") - sourceDirectories.value.flatMap(listFilesRec) - }, - zioHttpCodegenConf := Config.default, - zioHttpCodegenMake := Def.taskDyn { - - val maybeCached = (ZIOpenApi / zioHttpCodegenMake).previous - val s = streams.value - - val cachedCodegen = Tracked.inputChanged[ - FilesInfo[FileInfo.full.F], - Def.Initialize[Task[Seq[File]]], - ](s.cacheStoreFactory.make("zioapigen")) { (changed, in) => - maybeCached match { - case Some(cached) if !changed => - Def.task { - s.log.info("OpenAPI spec unchanged, skipping codegen and using cached files") - cached - } - case _ => - Def.task { - s.log.info("OpenAPI spec changed, or nothing in cache: regenerating code") - zioHttpCodegenMakeTask.value - } - } - } - - cachedCodegen(FileInfo.full((ZIOpenApi / sources).value.toSet)) - }.value, - ), - ) ++ Seq( - Compile / sourceGenerators += (ZIOpenApi / zioHttpCodegenMake).taskValue, - Compile / watchSources ++= (ZIOpenApi / sources).value, - ) - - lazy val zioHttpCodegenMakeTask = Def.task { - val openApiFiles: Seq[File] = (ZIOpenApi / sources).value - val openApiRootDirs: Seq[File] = (ZIOpenApi / sourceDirectories).value - val baseDir = baseDirectory.value - val targetDir: File = (Compile / sourceManaged).value - val config: Config = (ZIOpenApi / zioHttpCodegenConf).value - - openApiFiles.flatMap { openApiFile => - val content = fileContentAsString(openApiFile) - val format = Format.fromFileName(openApiFile.getName) - val openApiRootDir = openApiRootDirs.foldLeft(baseDir) { case (bestSoFar, currentDir) => - val currentPath = currentDir.getAbsolutePath - val isAncestor = openApiFile.getAbsolutePath.startsWith(currentPath) - val isMoreSpecific = currentPath.length >= bestSoFar.getAbsolutePath.length - if (isAncestor && isMoreSpecific) currentDir - else bestSoFar - } - val parsedOrError = format match { - case Format.YAML => content.fromYaml[OpenAPI](JsonCodec.jsonDecoder(OpenAPI.schema)) - case Format.JSON => OpenAPI.fromJson(content) - } - - parsedOrError match { - case Left(error) => throw new Exception(s"Failed to parse OpenAPI from $format: $error") - case Right(openapi) => - val codegenEndpoints = EndpointGen.fromOpenAPI(openapi, config) - val basePackageParts = dirDiffToPackage(openApiRootDir, openApiFile) - val currentTargetDir = basePackageParts.foldLeft(targetDir)(_ / _) - val currentTargetPat = Path.of(currentTargetDir.toURI()) - - CodeGen - .renderedFiles(codegenEndpoints, basePackageParts.mkString(".")) - .map { case (path, content) => - val filePath = currentTargetPat.resolve(path) - Files.createDirectories(filePath.getParent) - Files.write(filePath, content.getBytes(StandardCharsets.UTF_8), CREATE, TRUNCATE_EXISTING) - filePath.toFile - } - .toSeq - - } - } - } - - private def listFilesRec(dir: File): List[File] = { - def inner(dir: File, acc: List[File]): List[File] = - sbt.io.IO.listFiles(dir).foldRight(acc) { case (f, tail) => - if (f.isDirectory) inner(f, tail) - else f :: tail - } - - inner(dir, Nil) - } - - private def fileContentAsString(file: File): String = { - val s = Source.fromFile(file) - val r = s.mkString - s.close() - r - } - - private def dirDiffToPackage(dir: File, file: File): List[String] = { - val dirPath = dir.toPath - val filePath = file.toPath - val relativePath = dirPath.relativize(filePath.getParent) - relativePath.toString.split(File.separatorChar).toList - } -} diff --git a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/dynamic/build.sbt b/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/dynamic/build.sbt deleted file mode 100644 index dcab84689..000000000 --- a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/dynamic/build.sbt +++ /dev/null @@ -1,44 +0,0 @@ -import gigahorse.support.apachehttp.Gigahorse -import zio.json.ast.Json -import zio.json.ast.JsonCursor -import scala.concurrent.{Await, ExecutionContext} -import scala.concurrent.duration.DurationInt -import scala.util.{Failure, Try} - -lazy val root = (project in file(".")) - .enablePlugins(ZioHttpCodegen) - .settings( - name := "uspto-sdk", - organization := "com.example", - scalaVersion := "2.13.15", - libraryDependencies +="dev.zio" %% "zio-http" % "3.0.1", - ZIOpenApi / sourceGenerators += Def.task[Seq[File]] { - - val outFile = (ZIOpenApi / sourceManaged).value / "gov" / "uspto" / "ibd" / "api.json" - val http = Gigahorse.http(Gigahorse.config) - val request = Gigahorse.url("https://developer.uspto.gov/ibd-api/v3/api-docs") - val response = http.run(request, Gigahorse.asString) - - Await.result(response.transform(_.flatMap { content => - - // TODO: this is a temporary workaround - // current zio-http-gen module has many gaps not yet implemented, - // so we need to clean the API just so we can use it here. - // in the future, once the module had matured enough, - // we should remove this part, and perhaps take a more comprehensive example like: - // https://petstore3.swagger.io - val either = for { - decodedJsObj <- Json.Obj.decoder.decodeJson(content) - noInlined404 <- decodedJsObj.delete(JsonCursor.field("paths").isObject.field("/v1/weeklyarchivedata/searchWeeklyArchiveData").isObject.field("get").isObject.field("responses").isObject.field("404")) - noInlinedAPI <- noInlined404.delete(JsonCursor.field("paths").isObject.field("/v1/weeklyarchivedata/apistatus")) - } yield noInlinedAPI - - either.fold[Try[Seq[File]]]( - failure => Failure(new Exception(failure)), - cleaned => Try { - IO.write(outFile, cleaned.toJsonPretty) - Seq(outFile) - }) - })(ExecutionContext.global), 1.minute) - } - ) \ No newline at end of file diff --git a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/dynamic/project/plugins.sbt b/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/dynamic/project/plugins.sbt deleted file mode 100644 index feecfbcc7..000000000 --- a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/dynamic/project/plugins.sbt +++ /dev/null @@ -1,5 +0,0 @@ -sys.props.get("plugin.version") match { - case Some(ver) => addSbtPlugin("dev.zio" % "zio-http-sbt-codegen" % ver) - case None => sys.error("""|The system property 'plugin.version' is not defined. - |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) -} \ No newline at end of file diff --git a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/dynamic/test b/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/dynamic/test deleted file mode 100644 index f36a96ad0..000000000 --- a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/dynamic/test +++ /dev/null @@ -1,7 +0,0 @@ -# compile should depend on generated sources, -# thus we'll check it triggers codegen by inspecting expected .class files -# compiled from expected generated sources -> compile -$ exists target/scala-2.13/src_managed/oapi/gov/uspto/ibd/api.json -$ exists target/scala-2.13/classes/gov/uspto/ibd/v1/weeklyarchivedata/SearchWeeklyArchiveData.class -$ exists target/scala-2.13/classes/gov/uspto/ibd/component/ArchiveDataRecord.class diff --git a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/build.sbt b/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/build.sbt deleted file mode 100644 index 1233d113f..000000000 --- a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/build.sbt +++ /dev/null @@ -1,8 +0,0 @@ -lazy val root = (project in file(".")) - .enablePlugins(ZioHttpCodegen) - .settings( - name := "zoo-sdk", - organization := "dev.zoo", - scalaVersion := "2.13.15", - libraryDependencies +="dev.zio" %% "zio-http" % "3.0.1" - ) \ No newline at end of file diff --git a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/project/plugins.sbt b/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/project/plugins.sbt deleted file mode 100644 index feecfbcc7..000000000 --- a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/project/plugins.sbt +++ /dev/null @@ -1,5 +0,0 @@ -sys.props.get("plugin.version") match { - case Some(ver) => addSbtPlugin("dev.zio" % "zio-http-sbt-codegen" % ver) - case None => sys.error("""|The system property 'plugin.version' is not defined. - |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) -} \ No newline at end of file diff --git a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/src/main/oapi/dev/zoo/service/openapi.yaml b/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/src/main/oapi/dev/zoo/service/openapi.yaml deleted file mode 100644 index 600b44f8d..000000000 --- a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/src/main/oapi/dev/zoo/service/openapi.yaml +++ /dev/null @@ -1,69 +0,0 @@ -info: - title: Animals Service - version: 0.0.1 -tags: - - name: Animals_API -paths: - /api/v1/zoo/{animal}: - get: - operationId: get_animal - parameters: - - in: path - name: animal - schema: - type: string - required: true - tags: - - Animals_API - description: Get animals by species name - responses: - "200": - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Animal' -openapi: 3.0.3 -components: - schemas: - Animal: - oneOf: - - $ref: '#/components/schemas/Alligator' - - $ref: '#/components/schemas/Zebra' - AnimalSharedFields: - type: object - required: - - age - - weight - properties: - age: - type: integer - format: int32 - minimum: 0 - weight: - type: number - format: double - minimum: 0 - Alligator: - allOf: - - $ref: '#/components/schemas/AnimalSharedFields' - - type: object - required: - - num_teeth - properties: - num_teeth: - type: integer - format: int32 - minimum: 0 - Zebra: - allOf: - - $ref: '#/components/schemas/AnimalSharedFields' - - type: object - required: - - num_stripes - properties: - num_stripes: - type: integer - format: int32 - minimum: 0 diff --git a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/test b/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/test deleted file mode 100644 index 83c430a03..000000000 --- a/zio-http-gen-sbt-plugin/src/sbt-test/zio-http-sbt-codegen/simple/test +++ /dev/null @@ -1,6 +0,0 @@ -# compile should depend on generated sources, -# thus we'll check it triggers codegen by inspecting expected .class files -# compiled from expected generated sources -> compile -$ exists target/scala-2.13/classes/dev/zoo/service/api/v1/zoo/Animal.class -$ exists target/scala-2.13/classes/dev/zoo/service/component/Animal.class \ No newline at end of file diff --git a/zio-http/jvm/src/test/scala/zio/http/ClientHttpsSpec.scala b/zio-http/jvm/src/test/scala/zio/http/ClientHttpsSpec.scala index 3e466bb4d..fcdb1842e 100644 --- a/zio-http/jvm/src/test/scala/zio/http/ClientHttpsSpec.scala +++ b/zio-http/jvm/src/test/scala/zio/http/ClientHttpsSpec.scala @@ -18,7 +18,7 @@ package zio.http import zio._ import zio.test.Assertion._ -import zio.test.TestAspect.{flaky, ignore, nonFlaky} +import zio.test.TestAspect.nonFlaky import zio.test.{TestAspect, assertZIO} import zio.http.netty.NettyConfig @@ -53,16 +53,7 @@ abstract class ClientHttpsSpecBase extends ZIOHttpSpec { test("should respond as Bad Request") { val actual = Client.batched(Request.get(badRequest)).map(_.status) assertZIO(actual)(equalTo(Status.BadRequest)) - } @@ ignore /* started getting 503 consistently, - flaky does not help, nor exponential retries. - Either we're being throttled, or the service is under high load. - Regardless, we should not depend on an external service like that. - Luckily, httpbin is available via docker. - So once we make sure to: - - $ docker run -p 80:80 kennethreitz/httpbin - - before invoking tests, we can un-ignore this test. */, + }, test("should throw DecoderException for handshake failure") { val actual = Client.batched(Request.get(untrusted)).exit assertZIO(actual)( diff --git a/zio-http/jvm/src/test/scala/zio/http/endpoint/AuthSpec.scala b/zio-http/jvm/src/test/scala/zio/http/endpoint/AuthSpec.scala index e912e7f41..8e89510c8 100644 --- a/zio-http/jvm/src/test/scala/zio/http/endpoint/AuthSpec.scala +++ b/zio-http/jvm/src/test/scala/zio/http/endpoint/AuthSpec.scala @@ -1,7 +1,6 @@ package zio.http.endpoint import zio.Config.Secret -import zio.test.TestAspect.flaky import zio.test._ import zio.{Scope, ZIO, durationInt} @@ -152,7 +151,7 @@ object AuthSpec extends ZIOSpecDefault { .catchAllCause(c => ZIO.logInfoCause(c)) <* ZIO.sleep(1.seconds) response <- response } yield assertTrue(response == "admin") - } @@ flaky, + }, test("Auth basic or bearer with context and endpoint client") { val endpoint = Endpoint(Method.GET / "multiAuth")