pbyrne84.github.io

Scala Sbt Lib Resolver Cli

Source code and more documentation can be found at https://github.com/pbyrne84/scala-sbt-lib-resolver-cli.

A native commandline tool to resolve the latest versions of you favourite libraries. After building the command line tool no jvm is required on a target machines. This is written using Scala, ZIO 2, STTP, Decline, Circe and Docker.

I built this as I always forget to add plugins etc. Some libraries do not search that easily.

Example output

scala-sbt-lib-resolver-cli-linux --config internal --hotlist zio-app --debug --version 3

Will produce

"dev.zio" %% "zio" % "2.0.8"
"dev.zio" %% "zio-config-typesafe" % "3.0.7"
"dev.zio" %% "zio-logging-slf4j" % "2.1.9"
"io.circe" %% "circe-core" % "0.14.4"
"io.circe" %% "circe-generic" % "0.14.4"
"io.circe" %% "circe-parser" % "0.14.4"
"dev.zio" %% "zio-test" % "2.0.8" % Test
"dev.zio" %% "zio-test-sbt" % "2.0.8" % Test
"ch.qos.logback" % "logback-classic" % "1.4.5"
"net.logstash.logback" % "logstash-logback-encoder" % "7.2"
"com.github.tomakehurst" % "wiremock" % "2.27.2" % Test
addSbtPlugin( "com.timushev.sbt" % "sbt-rewarn" % "0.1.3" )
addSbtPlugin( "org.scalameta" % "sbt-scalafmt" % "2.4.6" )
addSbtPlugin( "org.scoverage" % "sbt-scoverage" % "2.0.5" )
addCompilerPlugin( "com.olegpy" % "better-monadic-for" % "0.3.1" )

And have debug logging enabled and limit to Scala 3, the default is scala 2.13.

The –config internal command says use the internal from in the resources. This is not of great use except as an example and also demo purposes. –config config.json will try and load the config from the same root as the executable, not the current command line position. This allows having the executable on the path easily.

Installing GRAALVM and building a native image

src/main/resources/META-INF/native-image configurations

These are generated by running tests

fork := true
Test / javaOptions += "-agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image"

Linux/OSX

This can be done via SDKMAN.

sdk install java 22.3.r11-grl
sdk install sbt
gu install native-image

Windows

For Windows Chocolatey can be used.

This will install 22.3.1 and needs to be run in administrator mode.

choco install graalvm-java11
gu install native-image

Build native image

Linux/OSX

native-image  --no-server \
  --no-fallback \
  --allow-incomplete-classpath \
  --report-unsupported-elements-at-runtime \
  --static \
  --initialize-at-build-time=scala.runtime.Statics \
  -H:ConfigurationFileDirectories=src/main/resources/META-INF/native-image \
  -H:+ReportExceptionStackTraces \
  -H:TraceClassInitialization=true \
  -jar binaries/scala-sbt-lib-resolver-cli.jar

Windows

rem vcvars64.bat needs to be run, avira also blocks things as viruses so need to be turned off for a while
rem also run in cmd and not powershell
native-image  --no-server ^
  --no-fallback ^
  --allow-incomplete-classpath ^
  --report-unsupported-elements-at-runtime ^
  --static ^
  --initialize-at-build-time=scala.runtime.Statics ^
  -H:ConfigurationFileDirectories=src/main/resources/META-INF/native-image ^
  -H:+ReportExceptionStackTraces ^
  -H:TraceClassInitialization=true ^
  -jar target/scala-2.13/scala-sbt-lib-resolver-cli.jar

You will need the MS Build tools installed for vcvars64.bat https://visualstudio.microsoft.com/downloads/?q=build+tools. Antivirus can also get a bit too aggressive and can cause weird issues.

Example config

Internal config.json

{
  "defaults": {
    "productionVersionRegex": "([\\d\\.]+)",
    "hotList": "zio-app"
  },
  "maximumPagesToPaginate": 2,
  "retryCount": 6,
  "hotLists": [
    {
      "name": "zio-app",
      "refs": [
        "circe",
        "logback",
        "logstash-logback",
        "zio",
        "wiremock",
        "scoverage",
        "scalafmt",
        "sbt-rewarn",
        "better-monadic-for"
      ]
    },
    {
      "name": "test-single",
      "refs": [
        "scoverage"
      ]
    }
  ],
  "groups": [
    {
      "name": "circe",
      "org": "io.circe",
      "modules": [
        {
          "name": "circe-core"
        },
        {
          "name": "circe-parser"
        },
        {
          "name": "circe-generic"
        }
      ]
    },
    {
      "name": "logback",
      "org": "ch.qos.logback",
      "modules": [
        {
          "name": "logback-classic",
          "moduleType": "java"
        }
      ]
    },
    {
      "name": "logstash-logback",
      "org": "net.logstash.logback",
      "modules": [
        {
          "name": "logstash-logback-encoder",
          "moduleType": "java"
        }
      ]
    },
    {
      "name": "zio",
      "org": "dev.zio",
      "modules": [
        {
          "name": "zio-logging-slf4j"
        },
        {
          "name": "zio-config-typesafe"
        },
        {
          "name": "zio"
        },
        {
          "name": "zio-test",
          "moduleType": "scala-test"
        },
        {
          "name": "zio-test-sbt",
          "moduleType": "scala-test"
        }
      ]
    },
    {
      "name": "scoverage",
      "org": "org.scoverage",
      "modules": [
        {
          "name": "sbt-scoverage",
          "moduleType": "plugin"
        }
      ]
    },
    {
      "name": "scalafmt",
      "org": "org.scalameta",
      "modules": [
        {
          "name": "sbt-scalafmt",
          "moduleType": "plugin"
        }
      ]
    },
    {
      "name": "nativeimage",
      "org": "org.scalameta",
      "modules": [
        {
          "name": "sbt-native-image",
          "moduleType": "plugin"
        }
      ]
    },
    {
      "name": "assembly",
      "org": "com.eed3si9n",
      "modules": [
        {
          "name": "sbt-assembly",
          "moduleType": "plugin"
        }
      ]
    },
    {
      "name": "sbt-rewarn",
      "org": "com.timushev.sbt",
      "modules": [
        {
          "name": "sbt-rewarn",
          "moduleType": "plugin"
        }
      ]
    },
    {
      "name": "wiremock",
      "org": "com.github.tomakehurst",
      "modules": [
        {
          "name": "wiremock",
          "moduleType": "java-test"
        }
      ]
    },
    {
      "name": "better-monadic-for",
      "org": "com.olegpy",
      "modules": [
        {
          "name": "better-monadic-for",
          "moduleType": "compiler-plugin"
        }
      ]
    }
  ]
}