| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * license agreements; and to You under the Apache License, version 2.0: |
| * |
| * https://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * This file is part of the Apache Pekko project, derived from Akka. |
| */ |
| |
| import com.github.pjfanning.pekkobuild._ |
| import com.github.sbt.JavaFormatterPlugin.autoImport.javafmtSortImports |
| import net.bzzt.reproduciblebuilds.ReproducibleBuildsPlugin.reproducibleBuildsCheckResolver |
| import org.apache.pekko.grpc.{ Dependencies, NoPublish, PekkoCoreDependency, PekkoHttpDependency } |
| import org.apache.pekko.grpc.Dependencies.Versions.{ scala212, scala213 } |
| import org.apache.pekko.grpc.ProjectExtensions._ |
| import org.apache.pekko.grpc.build.ReflectiveCodeGen |
| import com.typesafe.tools.mima.core._ |
| import sbt.Keys.scalaVersion |
| |
| sourceDistName := "apache-pekko-grpc" |
| sourceDistIncubating := false |
| ThisBuild / versionScheme := Some(VersionScheme.SemVerSpec) |
| |
| commands := commands.value.filterNot { command => |
| command.nameOption.exists { name => |
| name.contains("sonatypeRelease") || name.contains("sonatypeBundleRelease") |
| } |
| } |
| |
| ThisBuild / reproducibleBuildsCheckResolver := Resolver.ApacheMavenStagingRepo |
| |
| // So that gRPC is properly styled |
| ThisBuild / apacheSonatypeArtifactNameProcessor := apacheSonatypeArtifactNameProcessor.value.andThen { |
| _.replaceAll("Grpc", "gRPC") |
| } |
| |
| val pekkoPrefix = "pekko-grpc" |
| val pekkoGrpcRuntimeName = s"$pekkoPrefix-runtime" |
| |
| lazy val mkBatAssemblyTask = taskKey[File]("Create a Windows bat assembly") |
| |
| // gradle plugin compatibility (avoid `+` in snapshot versions) |
| (ThisBuild / dynverSeparator) := "-" |
| |
| ThisBuild / javafmtFormatterCompatibleJavaVersion := 17 |
| |
| addCommandAlias("checkCodeStyle", "scalafmtCheckAll; scalafmtSbtCheck; javafmtCheckAll; +headerCheckAll") |
| addCommandAlias("applyCodeStyle", "+headerCreateAll; scalafmtAll; scalafmtSbt; javafmtAll") |
| |
| val pekkoGrpcCodegenId = s"$pekkoPrefix-codegen" |
| lazy val codegen = Project(id = "codegen", base = file("codegen")) |
| .enablePlugins(SbtTwirl, BuildInfoPlugin) |
| .enablePlugins(ReproducibleBuildsPlugin) |
| .disablePlugins(MimaPlugin) |
| .settings(Dependencies.codegen) |
| .settings(resolvers += Resolver.sbtPluginRepo("releases")) |
| .settings(MetaInfLicenseNoticeCopy.assemblySettings) |
| .settings( |
| name := s"$pekkoPrefix-codegen", |
| mkBatAssemblyTask := { |
| val file = assembly.value |
| Assemblies.mkBatAssembly(file) |
| }, |
| buildInfoKeys ++= Seq[BuildInfoKey](organization, name, version, scalaVersion, sbtVersion), |
| buildInfoKeys += "runtimeArtifactName" -> pekkoGrpcRuntimeName, |
| buildInfoKeys += "pekkoVersion" -> Dependencies.Versions.pekko, |
| buildInfoKeys += "pekkoHttpVersion" -> Dependencies.Versions.pekkoHttp, |
| buildInfoKeys += "grpcVersion" -> Dependencies.Versions.grpc, |
| buildInfoKeys += "googleProtocVersion" -> Dependencies.Versions.googleProtoc, |
| buildInfoKeys += "googleProtobufJavaVersion" -> Dependencies.Versions.googleProtobufJava, |
| buildInfoPackage := "org.apache.pekko.grpc.gen", |
| (Compile / assembly / artifact) := { |
| val art = (Compile / assembly / artifact).value |
| art.withClassifier(Some("assembly")) |
| }, |
| (assembly / mainClass) := Some("org.apache.pekko.grpc.gen.Main"), |
| (assembly / assemblyOption) := (assembly / assemblyOption).value.withPrependShellScript( |
| Some(sbtassembly.AssemblyPlugin.defaultUniversalScript(shebang = true))), |
| (assembly / assemblyMergeStrategy) := { |
| case PathList("META-INF", "LICENSE") => MergeStrategy.discard |
| case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard |
| case PathList("META-INF", "versions", _, "module-info.class") => MergeStrategy.discard |
| case "LICENSE" | "LICENSE.txt" | "NOTICE" => MergeStrategy.discard |
| case _ => MergeStrategy.deduplicate |
| }, |
| crossScalaVersions := Dependencies.Versions.CrossScalaForPlugin, |
| scalaVersion := Dependencies.Versions.CrossScalaForPlugin.head) |
| .settings(addArtifact(Compile / assembly / artifact, assembly)) |
| .settings(addArtifact(sbt.Artifact(pekkoGrpcCodegenId, "bat", "bat", "bat"), mkBatAssemblyTask)) |
| |
| val mimaCompareVersion = "1.0.2" |
| |
| lazy val runtime = Project(id = "runtime", base = file("runtime")) |
| .addPekkoModuleDependency("pekko-stream", "", PekkoCoreDependency.default) |
| .addPekkoModuleDependency("pekko-http-core", "", PekkoHttpDependency.default) |
| .addPekkoModuleDependency("pekko-http", "", PekkoHttpDependency.default) |
| .addPekkoModuleDependency("pekko-discovery", "", PekkoCoreDependency.default) |
| .addPekkoModuleDependency("pekko-http-cors", "", PekkoHttpDependency.default) |
| .addPekkoModuleDependency("pekko-testkit", "test", PekkoCoreDependency.default) |
| .addPekkoModuleDependency("pekko-stream-testkit", "test", PekkoCoreDependency.default) |
| .settings(Dependencies.runtime) |
| .settings(VersionGenerator.settings) |
| .settings(MetaInfLicenseNoticeCopy.runtimeSettings) |
| .settings( |
| crossScalaVersions := Dependencies.Versions.CrossScalaForLib, |
| scalaVersion := Dependencies.Versions.CrossScalaForLib.head) |
| .settings( |
| name := pekkoGrpcRuntimeName, |
| mimaFailOnNoPrevious := true, |
| mimaPreviousArtifacts := Set( |
| organization.value %% "pekko-grpc-runtime" % mimaCompareVersion), |
| AutomaticModuleName.settings("pekko.grpc.runtime"), |
| ReflectiveCodeGen.generatedLanguages := Seq("Scala"), |
| ReflectiveCodeGen.extraGenerators := Seq("ScalaMarshallersCodeGenerator"), |
| PB.protocVersion := Dependencies.Versions.googleProtoc, |
| Test / PB.targets += (scalapb.gen() -> (Test / sourceManaged).value)) |
| .enablePlugins(org.apache.pekko.grpc.build.ReflectiveCodeGen) |
| .enablePlugins(ReproducibleBuildsPlugin) |
| |
| /** This could be an independent project - or does upstream provide this already? didn't find it.. */ |
| val pekkoGrpcProtocPluginId = s"$pekkoPrefix-scalapb-protoc-plugin" |
| lazy val scalapbProtocPlugin = Project(id = "scalapb-protoc-plugin", base = file("scalapb-protoc-plugin")) |
| .disablePlugins(MimaPlugin) |
| .settings(MetaInfLicenseNoticeCopy.assemblySettings) |
| .settings( |
| name := s"$pekkoPrefix-scalapb-protoc-plugin", |
| libraryDependencies += { |
| Dependencies.Compile.scalapbCompilerPlugin |
| }, |
| mkBatAssemblyTask := { |
| val file = assembly.value |
| Assemblies.mkBatAssembly(file) |
| }, |
| (Compile / assembly / artifact) := { |
| val art = (Compile / assembly / artifact).value |
| art.withClassifier(Some("assembly")) |
| }, |
| (assembly / mainClass) := Some("org.apache.pekko.grpc.scalapb.Main"), |
| (assembly / assemblyOption) := (assembly / assemblyOption).value.withPrependShellScript( |
| Some(sbtassembly.AssemblyPlugin.defaultUniversalScript(shebang = true))), |
| (assembly / assemblyMergeStrategy) := { |
| case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard |
| case PathList("META-INF", "versions", _, "module-info.class") => MergeStrategy.discard |
| case "LICENSE" | "LICENSE.txt" | "NOTICE" => MergeStrategy.discard |
| case _ => MergeStrategy.deduplicate |
| }) |
| .settings( |
| crossScalaVersions := Dependencies.Versions.CrossScalaAll, |
| scalaVersion := Dependencies.Versions.CrossScalaAll.head) |
| .settings(addArtifact(Compile / assembly / artifact, assembly)) |
| .settings(addArtifact(sbt.Artifact(pekkoGrpcProtocPluginId, "bat", "bat", "bat"), mkBatAssemblyTask)) |
| .enablePlugins(ReproducibleBuildsPlugin) |
| |
| lazy val mavenPlugin = Project(id = "maven-plugin", base = file("maven-plugin")) |
| .enablePlugins(org.apache.pekko.grpc.SbtMavenPlugin) |
| .enablePlugins(ReproducibleBuildsPlugin) |
| .disablePlugins(MimaPlugin) |
| .settings(Dependencies.mavenPlugin) |
| .settings( |
| name := s"$pekkoPrefix-maven-plugin", |
| crossPaths := false, |
| crossScalaVersions := Dependencies.Versions.CrossScalaForPlugin, |
| scalaVersion := Dependencies.Versions.CrossScalaForPlugin.head) |
| .dependsOn(codegen) |
| |
| lazy val sbtPlugin = Project(id = "sbt-plugin", base = file("sbt-plugin")) |
| .enablePlugins(SbtPlugin) |
| .enablePlugins(ReproducibleBuildsPlugin) |
| .disablePlugins(MimaPlugin) |
| .settings(Dependencies.sbtPlugin) |
| .settings( |
| name := s"$pekkoPrefix-sbt-plugin", |
| pluginCrossBuild / sbtVersion := { |
| scalaBinaryVersion.value match { |
| case "2.12" => "1.12.11" |
| case _ => "2.0.0-RC13" |
| } |
| }, |
| /** And for scripted tests: */ |
| scriptedSbt := (pluginCrossBuild / sbtVersion).value, |
| scriptedLaunchOpts += ("-Dproject.version=" + version.value), |
| scriptedLaunchOpts ++= sys.props.collect { case (k @ "sbt.ivy.home", v) => s"-D$k=$v" }.toSeq, |
| scriptedDependencies := { |
| val p1 = publishLocal.value |
| val p2 = (codegen / publishLocal).value |
| val p3 = (runtime / publishLocal).value |
| val p4 = (interopTests / publishLocal).value |
| }, |
| scriptedBufferLog := false, |
| scalacOptions ++= { |
| scalaBinaryVersion.value match { |
| case "2.12" => Seq("-Xsource:3") |
| case _ => Seq.empty |
| } |
| }) |
| .settings( |
| crossScalaVersions := Dependencies.Versions.CrossScalaForPlugin, |
| scalaVersion := Dependencies.Versions.CrossScalaForPlugin.head) |
| .dependsOn(codegen) |
| |
| lazy val interopTests = Project(id = "interop-tests", base = file("interop-tests")) |
| .disablePlugins(MimaPlugin) |
| .addPekkoModuleDependency("pekko-http", "", PekkoHttpDependency.default) |
| .addPekkoModuleDependency("pekko-slf4j", "", PekkoCoreDependency.default) |
| .addPekkoModuleDependency("pekko-testkit", "test", PekkoCoreDependency.default) |
| .addPekkoModuleDependency("pekko-stream-testkit", "test", PekkoCoreDependency.default) |
| .settings(Dependencies.interopTests) |
| .settings( |
| crossScalaVersions := Dependencies.Versions.CrossScalaForLib, |
| scalaVersion := Dependencies.Versions.CrossScalaForLib.head) |
| .pluginTestingSettings |
| .settings( |
| name := s"$pekkoPrefix-interop-tests", |
| javafmtSortImports := false, |
| // All io.grpc servers want to bind to port :8080 |
| parallelExecution := false, |
| ReflectiveCodeGen.generatedLanguages := Seq("Scala", "Java"), |
| ReflectiveCodeGen.extraGenerators := Seq("ScalaMarshallersCodeGenerator"), |
| ReflectiveCodeGen.codeGeneratorSettings ++= Seq("server_power_apis"), |
| // grpc 1.54.2 brings in extra unnecessary proto files that cause build issues |
| PB.generate / excludeFilter := new SimpleFileFilter(f => f.getAbsolutePath().contains("envoy")), |
| PB.protocVersion := Dependencies.Versions.googleProtoc, |
| // We need to be able to publish locally in order for sbt interopt tests to work |
| // however this sbt project should not be published to an actual repository |
| publishLocal / skip := false, |
| // the following is needed to exclude the gRPC generated sources for protobuf-java from the sources, |
| // they cause tests to fail - https://github.com/apache/pekko-grpc/pull/610 |
| Compile / sources := (Compile / sources).value.filterNot { f => |
| f.getPath.replace('\\', '/').contains("/src_managed/main/com/google/protobuf") |
| }, |
| Compile / doc := (Compile / doc / target).value) |
| .settings(inConfig(Test)(Seq( |
| reStart / mainClass := (Test / run / mainClass).value, { |
| import spray.revolver.Actions._ |
| reStart := |
| Def |
| .inputTask { |
| restartApp( |
| streams.value, |
| reLogTag.value, |
| thisProjectRef.value, |
| reForkOptions.value, |
| (reStart / mainClass).value, |
| (reStart / fullClasspath).value, |
| reStartArgs.value, |
| startArgsParser.parsed) |
| } |
| .dependsOn(Compile / products) |
| .evaluated |
| }))).enablePlugins(NoPublish) |
| |
| lazy val benchmarks = Project(id = "benchmarks", base = file("benchmarks")) |
| .dependsOn(runtime) |
| .dependsOn(pluginTesterScala) |
| .enablePlugins(JmhPlugin) |
| .disablePlugins(MimaPlugin) |
| .settings( |
| name := s"$pekkoPrefix-benchmarks", |
| crossScalaVersions := Dependencies.Versions.CrossScalaForLib, |
| scalaVersion := Dependencies.Versions.CrossScalaForLib.head) |
| .enablePlugins(NoPublish) |
| |
| lazy val docs = Project(id = "docs", base = file("docs")) |
| // Make sure code generation is run: |
| .dependsOn(pluginTesterScala) |
| .dependsOn(pluginTesterJava) |
| .enablePlugins(PekkoParadoxPlugin, ParadoxSitePlugin, PreprocessPlugin) |
| .disablePlugins(MimaPlugin) |
| .settings( |
| name := s"$pekkoPrefix-docs", |
| makeSite := makeSite.dependsOn(LocalRootProject / ScalaUnidoc / doc).value, |
| pekkoParadoxGithub := Some("https://github.com/apache/pekko-grpc"), |
| previewPath := (Paradox / siteSubdirName).value, |
| Global / excludeLintKeys += previewPath, |
| Preprocess / siteSubdirName := s"api/pekko-grpc/${projectInfoVersion.value}", |
| Preprocess / sourceDirectory := (LocalRootProject / ScalaUnidoc / unidoc / target).value, |
| Paradox / siteSubdirName := s"docs/pekko-grpc/${projectInfoVersion.value}", |
| // Make sure code generation is run before paradox: |
| (Compile / paradox) := (Compile / paradox).dependsOn(Compile / compile).value, |
| paradoxGroups := Map("Language" -> Seq("Java", "Scala"), "Buildtool" -> Seq("sbt", "Gradle", "Maven")), |
| Global / pekkoParadoxIncubatorNotice := None, |
| Compile / paradoxProperties ++= Map( |
| "pekko.version" -> Dependencies.Versions.pekko, |
| "pekko-http.version" -> Dependencies.Versions.pekkoHttp, |
| "grpc.version" -> Dependencies.Versions.grpc, |
| "project.url" -> "https://pekko.apache.org/docs/pekko-grpc/current/", |
| "canonical.base_url" -> "https://pekko.apache.org/docs/pekko-grpc/current", |
| "scaladoc.scala.base_url" -> "https://www.scala-lang.org/api/current/", |
| // Apache Pekko |
| "extref.pekko.base_url" -> s"https://pekko.apache.org/docs/pekko/${Dependencies.Versions.pekkoBinary}/%s", |
| "scaladoc.org.apache.pekko.base_url" -> |
| s"https://pekko.apache.org/api/pekko/${Dependencies.Versions.pekkoBinary}/", |
| "javadoc.org.apache.pekko.base_url" -> |
| s"https://pekko.apache.org/japi/pekko/${Dependencies.Versions.pekkoBinary}/", |
| // Apache Pekko HTTP |
| "extref.pekko-http.base_url" -> |
| s"https://pekko.apache.org/docs/pekko-http/${Dependencies.Versions.pekkoHttpBinary}/%s", |
| "scaladoc.org.apache.pekko.http.base_url" -> |
| s"https://pekko.apache.org/api/pekko-http/${Dependencies.Versions.pekkoHttpBinary}/", |
| "javadoc.org.apache.pekko.http.base_url" -> |
| s"https://pekko.apache.org/japi/pekko-http/${Dependencies.Versions.pekkoHttpBinary}/", |
| // Apache Pekko gRPC |
| "scaladoc.org.apache.pekko.grpc.base_url" -> s"/${(Preprocess / siteSubdirName).value}/", |
| "javadoc.org.apache.pekko.grpc.base_url" -> "" // @apidoc links to Scaladoc |
| ), |
| apidocRootPackage := "org.apache.pekko", |
| Compile / paradoxMarkdownToHtml / sourceGenerators += Def.taskDyn { |
| val targetFile = (Compile / paradox / sourceManaged).value / "license-report.md" |
| |
| (LocalRootProject / dumpLicenseReportAggregate).map { dir => |
| IO.copy(List(dir / "pekko-grpc-root-licenses.md" -> targetFile)).toList |
| } |
| }.taskValue) |
| .settings( |
| crossScalaVersions := Dependencies.Versions.CrossScalaForLib, |
| scalaVersion := Dependencies.Versions.CrossScalaForLib.head) |
| .enablePlugins(NoPublish) |
| |
| lazy val pluginTesterScala = Project(id = "plugin-tester-scala", base = file("plugin-tester-scala")) |
| .disablePlugins(MimaPlugin) |
| .addPekkoModuleDependency("pekko-http-cors", "", PekkoHttpDependency.default) |
| .addPekkoModuleDependency("pekko-http", "", PekkoHttpDependency.default) |
| .addPekkoModuleDependency("pekko-pki", "", PekkoCoreDependency.default) |
| .addPekkoModuleDependency("pekko-actor-typed", "", PekkoCoreDependency.default) |
| .addPekkoModuleDependency("pekko-actor-testkit-typed", "test", PekkoCoreDependency.default) |
| .settings(Dependencies.pluginTester) |
| .settings( |
| name := s"$pekkoPrefix-plugin-tester-scala", |
| fork := true, |
| PB.protocVersion := Dependencies.Versions.googleProtoc, |
| crossScalaVersions := Dependencies.Versions.CrossScalaForLib, |
| scalaVersion := Dependencies.Versions.CrossScalaForLib.head, |
| ReflectiveCodeGen.codeGeneratorSettings ++= Seq("flat_package", "server_power_apis"), |
| // the following is needed to exclude the gRPC generated sources for protobuf-java from the sources, |
| // they cause tests to fail - https://github.com/apache/pekko-grpc/pull/610 |
| Compile / sources := (Compile / sources).value.filterNot { f => |
| f.getPath.replace('\\', '/').contains("/src_managed/main/com/google/protobuf") |
| }) |
| .pluginTestingSettings |
| .enablePlugins(NoPublish) |
| |
| lazy val pluginTesterJava = Project(id = "plugin-tester-java", base = file("plugin-tester-java")) |
| .disablePlugins(MimaPlugin) |
| .addPekkoModuleDependency("pekko-pki", "", PekkoCoreDependency.default) |
| .addPekkoModuleDependency("pekko-actor-typed", "", PekkoCoreDependency.default) |
| .settings(Dependencies.pluginTester) |
| .settings( |
| name := s"$pekkoPrefix-plugin-tester-java", |
| javafmtSortImports := false, |
| fork := true, |
| PB.protocVersion := Dependencies.Versions.googleProtoc, |
| ReflectiveCodeGen.generatedLanguages := Seq("Java"), |
| crossScalaVersions := Dependencies.Versions.CrossScalaForLib, |
| scalaVersion := Dependencies.Versions.CrossScalaForLib.head, |
| ReflectiveCodeGen.codeGeneratorSettings ++= Seq("server_power_apis")) |
| .pluginTestingSettings |
| .enablePlugins(NoPublish) |
| |
| lazy val root = Project(id = "pekko-grpc", base = file(".")) |
| .enablePlugins(ScalaUnidocPlugin) |
| .disablePlugins(SitePlugin, MimaPlugin) |
| .aggregate( |
| runtime, |
| codegen, |
| mavenPlugin, |
| sbtPlugin, |
| scalapbProtocPlugin, |
| interopTests, |
| pluginTesterScala, |
| pluginTesterJava, |
| benchmarks, |
| docs) |
| .settings( |
| name := s"$pekkoPrefix-root", |
| (Compile / headerCreate / unmanagedSources) := (baseDirectory.value / "project").**("*.scala").get, |
| // unidoc combines sources and jars from all subprojects and that |
| // might include some incompatible ones. Depending on the |
| // classpath order that might lead to scaladoc compilation errors. |
| // the scalapb compilerplugin has a scalapb/package$.class that conflicts |
| // with the one from the scalapb runtime, so for that reason we don't produce |
| // unidoc for the codegen projects: |
| ScalaUnidoc / unidoc / unidocProjectFilter := inProjects(runtime), |
| // https://github.com/sbt/sbt/issues/3465 |
| // Libs and plugins must share a version. The root project must use that |
| // version (and set the crossScalaVersions as empty list) so each sub-project |
| // can then decide which scalaVersion and crossScalaVersions they use. |
| crossScalaVersions := Nil, |
| scalaVersion := Dependencies.Versions.CrossScalaForLib.head) |
| .enablePlugins(NoPublish) |
| |
| Global / onLoad := (Global / onLoad).value.andThen { s => |
| val v = version.value |
| val log = sLog.value |
| log.info( |
| s"Building Pekko gRPC $v against Pekko ${Dependencies.Versions.pekko} and Pekko HTTP ${Dependencies.Versions.pekkoHttp}") |
| s |
| } |