diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 5c6a502..0000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "image": "mcr.microsoft.com/devcontainers/universal:2", - "features": { - "ghcr.io/devcontainers-extra/features/sbt-sdkman:2": {} - }, - "postCreateCommand": "sdk install sbt" -} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9208c3f..1a53cd4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,14 +13,13 @@ jobs: steps: - uses: actions/checkout@v5 - uses: coursier/cache-action@v6 - - uses: VirtusLab/scala-cli-setup@main + - uses: actions/setup-java@v4 with: - jvm: temurin:21 - apps: sbt - power: true + java-version: 25 + distribution: temurin - name: Start up emulators - run: docker compose up -d - - run: sbt buildCliBinary test + run: docker compose up -d + - run: ./mill tests.__.test publish: runs-on: ubuntu-latest name: Publish Artifacts @@ -29,17 +28,16 @@ jobs: steps: - uses: actions/checkout@v5 - uses: coursier/cache-action@v6 - - uses: VirtusLab/scala-cli-setup@main + - uses: actions/setup-java@v4 with: - jvm: temurin:21 - apps: sbt + java-version: 25 + distribution: temurin - name: Import signing key if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE == '' env: PGP_SECRET: ${{ secrets.PGP_SECRET }} PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} run: echo $PGP_SECRET | base64 -d -i - | gpg --import - - name: Import signing key and strip passphrase if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE != '' env: @@ -53,4 +51,8 @@ jobs: env: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - run: sbt publishSigned sonaRelease + PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} + run: | + ./mill core.jvm.publish + ./mill core.native.publish + ./mill cli.publish diff --git a/.mill-version b/.mill-version new file mode 100644 index 0000000..0664a8f --- /dev/null +++ b/.mill-version @@ -0,0 +1 @@ +1.1.6 diff --git a/README.md b/README.md index 0487752..2bf491b 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ See output in `example/out`. ##### Jsoniter Json type and codec example Jsoniter doesn't ship with a type that can represent raw Json values to be used for mapping of `any` / `object` types, but it provides methods to read / write raw values as bytes (related [issue](https://github.com/plokhotnyuk/jsoniter-scala/issues/1257)). -Given that we can create a custom type with a codec which can look for example like [that](modules/example-jsoniter-json/shared/src/main/scala/json.scala): +Given that we can create a custom type with a codec which can look for example like [that](modules/example-jsoniter-json/src/main/scala/json.scala): ```scala package example.jsoniter import com.github.plokhotnyuk.jsoniter_scala.core.* diff --git a/build.mill b/build.mill new file mode 100644 index 0000000..4ab4c3c --- /dev/null +++ b/build.mill @@ -0,0 +1,222 @@ +package build + +import mill.* +import mill.scalalib.* +import mill.scalanativelib.* +import mill.scalanativelib.api.* +import mill.scalalib.publish.* +import mill.util.VcsVersionModule +import mill.api.Task.Simple +import mill.api.TaskCtx +import os.Path + +val scalaVer = "3.8.3" + +val scalaNativeVer = "0.5.12" + +val sttpClient4Ver = "4.0.23" + +val zioVer = "2.1.26" + +val zioJsonVer = "0.9.1" + +val jsoniterVer = "2.38.12" + +val munitVer = "1.3.0" + +val upickleVer = "4.4.3" + +/** Build the Scala Native CLI binary */ +def buildCliBinary: T[PathRef] = Task { + val linked = cli.nativeLink() + val dest = Task.dest / "cli" + os.makeDir.all(dest / os.up) + os.copy.over(linked.path, dest) + PathRef(dest) +} + +trait Publishable extends PublishModule with VcsVersionModule { + def pomSettings = PomSettings( + description = "Google Cloud client code generator", + organization = "dev.rolang", + url = "https://github.com/rolang/google-rest-api-codegen", + licenses = Seq(License.MIT), + versionControl = VersionControl.github("rolang", "google-rest-api-codegen"), + developers = Seq( + Developer(id = "rolang", name = "Roman Langolf", url = "https://rolang.dev", email = "rolang@pm.me") + ) + ) +} + +// --------------------------------------------------------------------------- +// core: published as gcp-codegen, JVM + Scala Native +// --------------------------------------------------------------------------- + +object core extends Module { + // jvm and native share src via SbtModule's parent-dir convention: + // /jvm/../src/main/scala == /src/main/scala + + trait CoreModule extends ScalaModule with SbtModule with Publishable { + override def moduleDir: Path = super.moduleDir / ".." / ".." / "modules" / "core" + + def scalaVersion = scalaVer + override def artifactName = Task { "gcp-codegen" } + override def mvnDeps = Task { Seq(mvn"com.lihaoyi::upickle::$upickleVer") } + } + + object jvm extends CoreModule + + object native extends CoreModule with ScalaNativeModule { + def scalaNativeVersion = scalaNativeVer + override def nativeMultithreading: T[Option[Boolean]] = Task { Some(false) } + } +} + +// --------------------------------------------------------------------------- +// cli: published as gcp-codegen-cli, Scala Native binary +// --------------------------------------------------------------------------- + +object cli extends ScalaNativeModule with Publishable with SbtModule { + override def moduleDir: Path = super.moduleDir / ".." / "modules" / "cli" + def scalaVersion = scalaVer + def scalaNativeVersion = scalaNativeVer + override def moduleDeps = Seq(core.native) + override def artifactName = Task { "gcp-codegen-cli" } + override def nativeMultithreading: T[Option[Boolean]] = Task { Some(false) } + override def releaseMode: T[ReleaseMode] = Task { ReleaseMode.ReleaseFast } +} + +// --------------------------------------------------------------------------- +// example-jsoniter-json: not published, JVM + Scala Native +// --------------------------------------------------------------------------- + +object exampleJsoniterJson extends Module { + trait ExampleModule extends ScalaModule with SbtModule { + override def moduleDir: Path = super.moduleDir / ".." / ".." / "modules" / "example-jsoniter-json" + def scalaVersion = scalaVer + override def mvnDeps = Task { Seq(mvn"com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-core:$jsoniterVer") } + override def compileMvnDeps = Task { + Seq(mvn"com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-macros:$jsoniterVer") + } + } + + object jvm extends ExampleModule + + object native extends ExampleModule with ScalaNativeModule { + def scalaNativeVersion = scalaNativeVer + } +} + +// --------------------------------------------------------------------------- +// testLocal: local dev helper, not published +// --------------------------------------------------------------------------- + +object testLocal extends ScalaModule { + override def sources = Task.Sources(moduleDir / "src" / "main" / "scala") + def scalaVersion = scalaVer + override def moduleDeps = Seq(exampleJsoniterJson.jvm) + override def mvnDeps = Task { + Seq( + mvn"com.softwaremill.sttp.client4::core:$sttpClient4Ver", + mvn"com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-core:$jsoniterVer", + mvn"dev.zio::zio-json:$zioJsonVer", + mvn"dev.zio::zio:$zioVer" + ) + } + override def compileMvnDeps = Task { + Seq(mvn"com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-macros:$jsoniterVer") + } +} + +// --------------------------------------------------------------------------- +// Test modules: one per (api, version, httpSource, jsonCodec, arrayType) combo +// --------------------------------------------------------------------------- + +type TestKey = (String, String, String, String, String) + +val testCombos: Seq[TestKey] = for { + (apiName, apiVersion) <- Seq( + "pubsub" -> "v1", + "storage" -> "v1", + "aiplatform" -> "v1", + "iamcredentials" -> "v1", + "redis" -> "v1", + "sheets" -> "v4" + ) + httpSource <- Seq("Sttp4") + jsonCodec <- Seq("ZioJson", "Jsoniter") + arrayType <- Seq("ZioChunk", "List") +} yield (apiName, apiVersion, httpSource, jsonCodec, arrayType) + +object tests extends Cross[TestModule](testCombos) +trait TestModule extends Cross.Module5[String, String, String, String, String] with ScalaModule { + val apiName = crossValue + val apiVersion = crossValue2 + val httpSource = crossValue3 + val jsonCodec = crossValue4 + val arrayType = crossValue5 + + def scalaVersion = scalaVer + + override def scalacOptions: T[Seq[String]] = + Task { super.scalacOptions() ++ Seq("-Xmax-inlines:64") } + + override def sources: T[Seq[PathRef]] = Task { Seq.empty[PathRef] } + + override def moduleDeps: Seq[JavaModule] = + if (jsonCodec == "Jsoniter") Seq(exampleJsoniterJson.jvm) else Seq() + + override def mvnDeps: T[Seq[Dep]] = Task { + Seq(mvn"com.softwaremill.sttp.client4::core:$sttpClient4Ver") ++ + (jsonCodec match { + case "Jsoniter" => + Seq(mvn"com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-core:$jsoniterVer") + case "ZioJson" => Seq(mvn"dev.zio::zio-json:$zioJsonVer") + case other => sys.error(s"Unknown jsonCodec: $other") + }) ++ + (arrayType match { + case "ZioChunk" => Seq(mvn"dev.zio::zio:$zioVer") + case _ => Seq.empty + }) + } + + override def compileMvnDeps: T[Seq[Dep]] = Task { + if (jsonCodec == "Jsoniter") + Seq(mvn"com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-macros:$jsoniterVer") + else Seq.empty + } + + override def generatedSources: T[Seq[PathRef]] = Task { + val dest = Task.dest + val basePkg = s"gcp.$apiName.$apiVersion.${httpSource}_${jsonCodec}_${arrayType}".toLowerCase() + val outSrcDir = dest / "scala" + val ws = implicitly[TaskCtx].workspace + val specFile = + ws / "modules" / "test-resources" / "src" / "main" / "resources" / s"${apiName}_${apiVersion}.json" + + val cliBin = buildCliBinary() + + os.makeDir.all(outSrcDir) + os.proc( + cliBin.path, + s"-specs=$specFile", + s"-out-dir=$outSrcDir", + s"-out-pkg=$basePkg", + s"-http-source=$httpSource", + s"-json-codec=$jsonCodec", + s"-array-type=$arrayType", + s"-jsoniter-json-type=_root_.example.jsoniter.Json" + ).call(cwd = ws) + Seq(PathRef(dest)) + } + + object test extends ScalaTests { + override def mvnDeps: T[Seq[Dep]] = Task { + Seq( + mvn"org.scalameta::munit:$munitVer", + mvn"com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-macros:$jsoniterVer" + ) + } + def testFramework = "munit.Framework" + } +} diff --git a/mill b/mill new file mode 100755 index 0000000..5268dce --- /dev/null +++ b/mill @@ -0,0 +1,199 @@ +#!/usr/bin/env sh + +set -e + +if [ -z "${DEFAULT_MILL_VERSION}" ] ; then DEFAULT_MILL_VERSION="1.1.6"; fi + +if [ -z "${GITHUB_RELEASE_CDN}" ] ; then GITHUB_RELEASE_CDN=""; fi + +if [ -z "$MILL_MAIN_CLI" ] ; then MILL_MAIN_CLI="${0}"; fi + +MILL_REPO_URL="https://github.com/com-lihaoyi/mill" + +MILL_BUILD_SCRIPT="" + +if [ -f "build.mill" ] ; then + MILL_BUILD_SCRIPT="build.mill" +elif [ -f "build.mill.scala" ] ; then + MILL_BUILD_SCRIPT="build.mill.scala" +elif [ -f "build.sc" ] ; then + MILL_BUILD_SCRIPT="build.sc" +fi + +# `s/.*://`: +# This is a greedy match that removes everything from the beginning of the line up to (and including) the last +# colon (:). This effectively isolates the value part of the declaration. +# +# `s/#.*//`: +# This removes any comments at the end of the line. +# +# `s/['\"]//g`: +# This removes all single and double quotes from the string, wherever they appear (g is for "global"). +# +# `s/^[[:space:]]*//; s/[[:space:]]*$//`: +# These two expressions trim any leading or trailing whitespace ([[:space:]] matches spaces and tabs). +TRIM_VALUE_SED="s/.*://; s/#.*//; s/['\"]//g; s/^[[:space:]]*//; s/[[:space:]]*$//" + +if [ -z "${MILL_VERSION}" ] ; then + if [ -f ".mill-version" ] ; then + MILL_VERSION="$(tr '\r' '\n' < .mill-version | head -n 1 2> /dev/null)" + elif [ -f ".config/mill-version" ] ; then + MILL_VERSION="$(tr '\r' '\n' < .config/mill-version | head -n 1 2> /dev/null)" + elif [ -f "build.mill.yaml" ] ; then + MILL_VERSION="$(grep -E "mill-version:" "build.mill.yaml" | sed -E "$TRIM_VALUE_SED")" + elif [ -n "${MILL_BUILD_SCRIPT}" ] ; then + MILL_VERSION="$(grep -E "//\|.*mill-version" "${MILL_BUILD_SCRIPT}" | sed -E "$TRIM_VALUE_SED")" + fi +fi + +if [ -z "${MILL_VERSION}" ] ; then MILL_VERSION="${DEFAULT_MILL_VERSION}"; fi + +MILL_USER_CACHE_DIR="${XDG_CACHE_HOME:-${HOME}/.cache}/mill" + +if [ -z "${MILL_FINAL_DOWNLOAD_FOLDER}" ] ; then MILL_FINAL_DOWNLOAD_FOLDER="${MILL_USER_CACHE_DIR}/download"; fi + +MILL_NATIVE_SUFFIX="-native" +MILL_JVM_SUFFIX="-jvm" +ARTIFACT_SUFFIX="" + +# Check if GLIBC version is at least the required version +# Returns 0 (true) if GLIBC >= required version, 1 (false) otherwise +check_glibc_version() { + required_version="2.39" + required_major=$(echo "$required_version" | cut -d. -f1) + required_minor=$(echo "$required_version" | cut -d. -f2) + # Get GLIBC version from ldd --version (first line contains version like "ldd (GNU libc) 2.31") + glibc_version=$(ldd --version 2>/dev/null | head -n 1 | grep -oE '[0-9]+\.[0-9]+$' || echo "") + if [ -z "$glibc_version" ]; then + # If we can't determine GLIBC version, assume it's too old + return 1 + fi + glibc_major=$(echo "$glibc_version" | cut -d. -f1) + glibc_minor=$(echo "$glibc_version" | cut -d. -f2) + if [ "$glibc_major" -gt "$required_major" ]; then + return 0 + elif [ "$glibc_major" -eq "$required_major" ] && [ "$glibc_minor" -ge "$required_minor" ]; then + return 0 + else + return 1 + fi +} + +set_artifact_suffix() { + if [ "$(uname -s 2>/dev/null | cut -c 1-5)" = "Linux" ]; then + # Native binaries require new enough GLIBC; fall back to JVM launcher if older + if ! check_glibc_version; then + return + fi + if [ "$(uname -m)" = "aarch64" ]; then ARTIFACT_SUFFIX="-native-linux-aarch64" + else ARTIFACT_SUFFIX="-native-linux-amd64"; fi + elif [ "$(uname)" = "Darwin" ]; then + if [ "$(uname -m)" = "arm64" ]; then ARTIFACT_SUFFIX="-native-mac-aarch64" + else ARTIFACT_SUFFIX="-native-mac-amd64"; fi + else + echo "This native mill launcher supports only Linux and macOS." 1>&2 + exit 1 + fi +} + +case "$MILL_VERSION" in + *"$MILL_NATIVE_SUFFIX") + MILL_VERSION=${MILL_VERSION%"$MILL_NATIVE_SUFFIX"} + set_artifact_suffix + ;; + + *"$MILL_JVM_SUFFIX") + MILL_VERSION=${MILL_VERSION%"$MILL_JVM_SUFFIX"} + ;; + + *) + case "$MILL_VERSION" in + 0.1.* | 0.2.* | 0.3.* | 0.4.* | 0.5.* | 0.6.* | 0.7.* | 0.8.* | 0.9.* | 0.10.* | 0.11.* | 0.12.*) + ;; + *) + set_artifact_suffix + ;; + esac + ;; +esac + +MILL="${MILL_FINAL_DOWNLOAD_FOLDER}/$MILL_VERSION$ARTIFACT_SUFFIX" + +# If not already downloaded, download it +if [ ! -s "${MILL}" ] || [ "$MILL_TEST_DRY_RUN_LAUNCHER_SCRIPT" = "1" ] ; then + case $MILL_VERSION in + 0.0.* | 0.1.* | 0.2.* | 0.3.* | 0.4.*) + MILL_DOWNLOAD_SUFFIX="" + MILL_DOWNLOAD_FROM_MAVEN=0 + ;; + 0.5.* | 0.6.* | 0.7.* | 0.8.* | 0.9.* | 0.10.* | 0.11.0-M*) + MILL_DOWNLOAD_SUFFIX="-assembly" + MILL_DOWNLOAD_FROM_MAVEN=0 + ;; + *) + MILL_DOWNLOAD_SUFFIX="-assembly" + MILL_DOWNLOAD_FROM_MAVEN=1 + ;; + esac + case $MILL_VERSION in + 0.12.0 | 0.12.1 | 0.12.2 | 0.12.3 | 0.12.4 | 0.12.5 | 0.12.6 | 0.12.7 | 0.12.8 | 0.12.9 | 0.12.10 | 0.12.11) + MILL_DOWNLOAD_EXT="jar" + ;; + 0.12.*) + MILL_DOWNLOAD_EXT="exe" + ;; + 0.*) + MILL_DOWNLOAD_EXT="jar" + ;; + *) + MILL_DOWNLOAD_EXT="exe" + ;; + esac + + MILL_TEMP_DOWNLOAD_FILE="${MILL_OUTPUT_DIR:-out}/mill-temp-download" + mkdir -p "$(dirname "${MILL_TEMP_DOWNLOAD_FILE}")" + + if [ "$MILL_DOWNLOAD_FROM_MAVEN" = "1" ] ; then + MILL_DOWNLOAD_URL="https://repo1.maven.org/maven2/com/lihaoyi/mill-dist${ARTIFACT_SUFFIX}/${MILL_VERSION}/mill-dist${ARTIFACT_SUFFIX}-${MILL_VERSION}.${MILL_DOWNLOAD_EXT}" + else + MILL_VERSION_TAG=$(echo "$MILL_VERSION" | sed -E 's/([^-]+)(-M[0-9]+)?(-.*)?/\1\2/') + MILL_DOWNLOAD_URL="${GITHUB_RELEASE_CDN}${MILL_REPO_URL}/releases/download/${MILL_VERSION_TAG}/${MILL_VERSION}${MILL_DOWNLOAD_SUFFIX}" + unset MILL_VERSION_TAG + fi + + + if [ "$MILL_TEST_DRY_RUN_LAUNCHER_SCRIPT" = "1" ] ; then + echo "$MILL_DOWNLOAD_URL" + echo "$MILL" + exit 0 + fi + + echo "Downloading mill ${MILL_VERSION} from ${MILL_DOWNLOAD_URL} ..." 1>&2 + curl -f -L -o "${MILL_TEMP_DOWNLOAD_FILE}" "${MILL_DOWNLOAD_URL}" + + chmod +x "${MILL_TEMP_DOWNLOAD_FILE}" + + mkdir -p "${MILL_FINAL_DOWNLOAD_FOLDER}" + mv "${MILL_TEMP_DOWNLOAD_FILE}" "${MILL}" + + unset MILL_TEMP_DOWNLOAD_FILE + unset MILL_DOWNLOAD_SUFFIX +fi + +MILL_FIRST_ARG="" +if [ "$1" = "--bsp" ] || [ "${1#"-i"}" != "$1" ] || [ "$1" = "--interactive" ] || [ "$1" = "--no-server" ] || [ "$1" = "--no-daemon" ] || [ "$1" = "--help" ] ; then + # Need to preserve the first position of those listed options + MILL_FIRST_ARG=$1 + shift +fi + +unset MILL_FINAL_DOWNLOAD_FOLDER +unset MILL_OLD_DOWNLOAD_PATH +unset OLD_MILL +unset MILL_VERSION +unset MILL_REPO_URL + +# -D mill.main.cli is for compatibility with Mill 0.10.9 - 0.13.0-M2 +# We don't quote MILL_FIRST_ARG on purpose, so we can expand the empty value without quotes +# shellcheck disable=SC2086 +exec "${MILL}" $MILL_FIRST_ARG -D "mill.main.cli=${MILL_MAIN_CLI}" "$@" diff --git a/modules/cli/src/main/scala/cli.scala b/modules/cli/src/main/scala/main.scala similarity index 97% rename from modules/cli/src/main/scala/cli.scala rename to modules/cli/src/main/scala/main.scala index dd20351..c81be95 100644 --- a/modules/cli/src/main/scala/cli.scala +++ b/modules/cli/src/main/scala/main.scala @@ -1,7 +1,7 @@ // for test runs using scala-cli //> using jvm system -//> using scala 3.8.2 -//> using file ../../../../core/shared/src/main/scala/codegen.scala +//> using scala 3.8.3 +//> using file ../../../../core/src/main/scala/codegen.scala //> using dep com.lihaoyi::upickle:4.4.3 package gcp.codegen.cli diff --git a/modules/core/shared/src/main/scala/codegen.scala b/modules/core/src/main/scala/codegen.scala similarity index 100% rename from modules/core/shared/src/main/scala/codegen.scala rename to modules/core/src/main/scala/codegen.scala diff --git a/modules/example-jsoniter-json/shared/src/main/scala/json.scala b/modules/example-jsoniter-json/src/main/scala/json.scala similarity index 100% rename from modules/example-jsoniter-json/shared/src/main/scala/json.scala rename to modules/example-jsoniter-json/src/main/scala/json.scala diff --git a/project/build.properties b/project/build.properties deleted file mode 100644 index dabdb15..0000000 --- a/project/build.properties +++ /dev/null @@ -1 +0,0 @@ -sbt.version=1.12.11 diff --git a/build.sbt b/sbt_backup/build_sbt.bak similarity index 86% rename from build.sbt rename to sbt_backup/build_sbt.bak index 3427c82..5705c47 100644 --- a/build.sbt +++ b/sbt_backup/build_sbt.bak @@ -40,34 +40,30 @@ lazy val noPublish = Seq( publish / skip := true ) -val sttpClient4Version = "4.0.13" +val sttpClient4Version = "4.0.23" -val zioVersion = "2.1.23" +val zioVersion = "2.1.26" -val zioJsonVersion = "0.8.0" +val zioJsonVersion = "0.9.1" val jsoniterVersion = "2.38.12" -val munitVersion = "1.2.1" +val munitVersion = "1.3.0" val upickleVersion = "4.4.3" -addCommandAlias("fmt", "all scalafmtSbt scalafmt test:scalafmt") +addCommandAlias("fmt", "all scalafmtSbt scalafmt Test/scalafmt") lazy val root = (project in file(".")) .aggregate( - core.native, - core.jvm, - exampleJsoniterJson.native, - exampleJsoniterJson.jvm, - cli + (core.projectRefs ++ exampleJsoniterJson.projectRefs ++ Seq(LocalProject("cli")) ++ testProjects.componentProjects + .map(p => LocalProject(p.id))) * ) - .aggregate(testProjects.componentProjects.map(p => LocalProject(p.id)) *) .settings(noPublish) // for supporting code inspection / testing of generated code via test_gen.sh script lazy val testLocal = (project in file("test-local")) - .dependsOn(exampleJsoniterJson.jvm) + .dependsOn(LocalProject("exampleJsoniterJson")) .settings( libraryDependencies ++= Seq( "com.softwaremill.sttp.client4" %% "core" % sttpClient4Version, @@ -79,8 +75,7 @@ lazy val testLocal = (project in file("test-local")) ) .settings(noPublish) -lazy val core = crossProject(JVMPlatform, NativePlatform) - .in(file("modules/core")) +lazy val core = (projectMatrix in file("modules/core")) .settings(publishSettings) .settings( name := "gcp-codegen", @@ -88,24 +83,25 @@ lazy val core = crossProject(JVMPlatform, NativePlatform) ) .settings( libraryDependencies ++= Seq( - "com.lihaoyi" %%% "upickle" % upickleVersion + "com.lihaoyi" %% "upickle" % upickleVersion ) ) + .jvmPlatform(scalaVersions = Seq("3.8.3")) + .nativePlatform(scalaVersions = Seq("3.8.3")) lazy val cli = project .in(file("modules/cli")) - .aggregate(core.native) - .dependsOn(core.native) + .aggregate(LocalProject("coreNative")) + .dependsOn(LocalProject("coreNative")) .enablePlugins(ScalaNativePlugin) .settings(publishSettings) .settings( name := "gcp-codegen-cli", moduleName := "gcp-codegen-cli", - nativeConfig := nativeConfig.value.withMultithreading(false) + nativeConfig ~= { _.withMultithreading(false) } ) -lazy val exampleJsoniterJson = crossProject(JVMPlatform, NativePlatform) - .in(file("modules/example-jsoniter-json")) +lazy val exampleJsoniterJson = (projectMatrix in file("modules/example-jsoniter-json")) .settings(noPublish) .settings( name := "example-jsoniter-json", @@ -117,6 +113,8 @@ lazy val exampleJsoniterJson = crossProject(JVMPlatform, NativePlatform) "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % jsoniterVersion % "compile-internal" ) ) + .jvmPlatform(scalaVersions = Seq("3.8.3")) + .nativePlatform(scalaVersions = Seq("3.8.3")) def dependencyByConfig(httpSource: String, jsonCodec: String, arrayType: String): Seq[ModuleID] = { (httpSource match { @@ -182,7 +180,7 @@ lazy val testProjects: CompositeProject = new CompositeProject { } lazy val cliBinFile: File = { - val cliTarget = new File("modules/cli/target/bin") + val cliTarget = new File("target/bin") def normalise(s: String) = s.toLowerCase.replaceAll("[^a-z0-9]+", "") val props = sys.props.toMap @@ -208,8 +206,8 @@ lazy val cliBinFile: File = { } lazy val buildCliBinary = taskKey[File]("") -buildCliBinary := { - val built = (cli / Compile / nativeLinkReleaseFast).value +buildCliBinary := Def.uncached { + val built = java.io.File((cli / Compile / nativeLinkReleaseFast).value.toString.replace(s"$${OUT}", "target/out")) IO.copyFile(built, cliBinFile) cliBinFile } @@ -231,11 +229,11 @@ def codegenTask( val outSrcDir = outDir / "scala" @scala.annotation.tailrec - def listFilesRec(dir: List[File], res: List[File]): List[File] = + def listFilesRec(dir: List[File], res: Seq[File]): Seq[File] = dir match { case x :: xs => val (dirs, files) = IO.listFiles(x).toList.partition(_.isDirectory()) - listFilesRec(dirs ::: xs, files ::: res) + listFilesRec(dirs ::: xs, files ++ res) case Nil => res } @@ -267,6 +265,6 @@ def codegenTask( val files = listFilesRec(List(outDir), Nil) IO.delete(outDir / ".scala-build") - files + files.toSeq } } diff --git a/sbt_backup/project/build_properties.bak b/sbt_backup/project/build_properties.bak new file mode 100644 index 0000000..ab6f7c0 --- /dev/null +++ b/sbt_backup/project/build_properties.bak @@ -0,0 +1 @@ +sbt.version=2.0.0-RC12 diff --git a/project/plugins.sbt b/sbt_backup/project/plugins_sbt.bak similarity index 74% rename from project/plugins.sbt rename to sbt_backup/project/plugins_sbt.bak index 0895661..eb56196 100644 --- a/project/plugins.sbt +++ b/sbt_backup/project/plugins_sbt.bak @@ -2,8 +2,6 @@ addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.12") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.6") -addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.3.2") - addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.1.1") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1")