Skip to content

Commit

Permalink
Scala Native (#381)
Browse files Browse the repository at this point in the history
  • Loading branch information
kubukoz authored Sep 27, 2022
1 parent 7ff54a3 commit 30b9b48
Show file tree
Hide file tree
Showing 38 changed files with 228 additions and 78 deletions.
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
36 changes: 18 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,21 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
scala: [3.1.2]
java: [graal_21.3.0@11]
scala: [3.2.0]
java: [temurin@11]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout current branch (full)
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Setup GraalVM (graal_21.3.0@11)
if: matrix.java == 'graal_21.3.0@11'
uses: DeLaGuardo/setup-[email protected]
- name: Setup Java (temurin@11)
if: matrix.java == 'temurin@11'
uses: actions/setup-java@v2
with:
graalvm: 21.3.0
java: java11
distribution: temurin
java-version: 11

- name: Cache sbt
uses: actions/cache@v2
Expand All @@ -62,7 +62,7 @@ jobs:
run: sbt ++${{ matrix.scala }} test

- name: Compress target directories
run: tar cf targets.tar target project/target
run: tar cf targets.tar target app/.jvm/target app/.native/target project/target

- name: Upload target directories
uses: actions/upload-artifact@v2
Expand All @@ -77,21 +77,21 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
scala: [3.1.2]
java: [graal_21.3.0@11]
scala: [3.2.0]
java: [temurin@11]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout current branch (full)
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Setup GraalVM (graal_21.3.0@11)
if: matrix.java == 'graal_21.3.0@11'
uses: DeLaGuardo/setup-[email protected]
- name: Setup Java (temurin@11)
if: matrix.java == 'temurin@11'
uses: actions/setup-java@v2
with:
graalvm: 21.3.0
java: java11
distribution: temurin
java-version: 11

- name: Cache sbt
uses: actions/cache@v2
Expand All @@ -105,12 +105,12 @@ jobs:
~/Library/Caches/Coursier/v1
key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}

- name: Download target directories (3.1.2)
- name: Download target directories (3.2.0)
uses: actions/download-artifact@v2
with:
name: target-${{ matrix.os }}-3.1.2-${{ matrix.java }}
name: target-${{ matrix.os }}-3.2.0-${{ matrix.java }}

- name: Inflate target directories (3.1.2)
- name: Inflate target directories (3.2.0)
run: |
tar xf targets.tar
rm targets.tar
Expand Down
1 change: 1 addition & 0 deletions .sbtopts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-J-Xmx8G
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.kubukoz.next

import cats.effect.unsafe.IORuntime

object RuntimePlatform {
val default: IORuntime = IORuntime.global
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.kubukoz.next

import epollcat.unsafe.EpollRuntime
import cats.effect.unsafe.IORuntime

object RuntimePlatform {
val default: IORuntime = EpollRuntime.global
}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import cats.effect.implicits.*
import java.io.EOFException
import LoginProcess.given
import org.typelevel.log4cats.Logger
import org.typelevel.log4cats.slf4j.Slf4jLogger
// import org.typelevel.log4cats.slf4j.Slf4jLogger
import org.typelevel.log4cats.noop.NoOpLogger
import cats.effect.unsafe.IORuntime

enum Choice {
case Login
Expand Down Expand Up @@ -57,19 +59,19 @@ object Choice {

object Main extends CommandIOApp(name = "spotify-next", header = "spotify-next: Gather great music.", version = BuildInfo.version) {

override protected def runtime: IORuntime = RuntimePlatform.default

import Program.*
given Logger[IO] = Slf4jLogger.getLogger[IO]
given Logger[IO] = NoOpLogger[IO]
// given Logger[IO] = Slf4jLogger.getLogger[IO]

def makeProgram[F[_]: Async: Console: Logger]: Resource[F, Runner[F]] = {
given UserOutput[F] = UserOutput.toConsole(sonos.baseUri)

val dummy = Async[F].unit.toResource

for {
given ConfigLoader[F] <- makeLoader[F].toResource
rawClient <- makeBasicClient[F]
given Config.Ask[F] = ConfigLoader[F].configAsk
_ <- dummy
// obviously quite a lot of duplication here...
spotifyLogin = Login.ember[F](OAuth.fromKernel[F](rawClient, OAuth.spotify))
spotifyLoginProcess = LoginProcess
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,19 @@ object OAuth {
private val baseUri = uri"https://accounts.spotify.com"

def refreshToken(token: RefreshToken): F[Token] =
client
.fetchAs[RefreshedTokenResponse](kernel.refreshToken(token))
kernel
.refreshToken(token)
.flatMap(
client
.fetchAs[RefreshedTokenResponse](_)
)
.map(_.access_token)
.map(Token(_))

def getTokens(code: Code): F[Tokens] =
client
.expect[TokenResponse](kernel.getTokens(code))
kernel
.getTokens(code)
.flatMap(client.expect[TokenResponse](_))
.map { response =>
Tokens(Token(response.access_token), RefreshToken(response.refresh_token))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,15 @@ object Program {
def sonosMiddlewares[F[_]: MonadCancelThrow]: Client[F] => Client[F] =
middlewares.defaultContentType(`Content-Type`(MediaType.application.json, Charset.`UTF-8`))

def makeSpotify[F[_]: UserOutput: ConfigLoader: Concurrent](spotifyClient: Client[F], sonosClient: Client[F]): F[Spotify[F]] =
def makeSpotify[F[_]: UserOutput: ConfigLoader: Concurrent](spotifyClient: Client[F], sonosClient: Client[F]): F[Spotify[F]] = {
val spotifyBaseUri = com.kubukoz.next.api.spotify.baseUri

for {
given SpotifyApi[F] <- SimpleRestJsonBuilder(SpotifyApiGen).client[F](spotifyClient, com.kubukoz.next.api.spotify.baseUri).liftTo[F]
given SonosApi[F] <- SimpleRestJsonBuilder(SonosApiGen).client[F](sonosClient, sonos.baseUri).liftTo[F]
given SpotifyApi[F] <- SimpleRestJsonBuilder(SpotifyApiGen).client[F](spotifyClient).uri(spotifyBaseUri).use.liftTo[F]
given SonosApi[F] <- SimpleRestJsonBuilder(SonosApiGen).client[F](sonosClient).uri(sonos.baseUri).use.liftTo[F]
result <- makeSpotifyInternal[F]
} yield result
}

def makeSpotifyInternal[F[_]: UserOutput: SpotifyApi: SonosApi: ConfigLoader: Concurrent]: F[Spotify[F]] = {
given Spotify.DeviceInfo[F] = Spotify.DeviceInfo.instance
Expand Down
47 changes: 47 additions & 0 deletions app/src/main/scala/monocle/Lens.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package monocle

import cats.Functor

type Lens[S, A] = PLens[S, S, A, A]

object Lens {

def apply[S, A](_get: S => A)(_set: A => S => S): Lens[S, A] = new Lens[S, A] {

def get(s: S): A = _get(s)

def set(s: S, a: A): S = _set(a)(s)
}

}

trait PLens[S, T, A, B] {
def get(s: S): A
def set(s: S, b: B): T
def replace(b: B): S => T = set(_, b)

def asGetter: Getter[S, A] = get(_)

def modifyF[F[_]: Functor](f: A => F[B])(s: S): F[T] = Functor[F].map(f(get(s)))(set(s, _))
}

object PLens {

def apply[S, T, A, B](_get: S => A)(_set: B => S => T): PLens[S, T, A, B] = new PLens[S, T, A, B] {

def get(s: S): A = _get(s)

def set(s: S, b: B): T = _set(b)(s)

}

}

trait Getter[S, A] {
def get(s: S): A
def map[B](f: A => B): Getter[S, B] = s => f(get(s))
}

object syntax {
object all {}
}
File renamed without changes.
File renamed without changes.
73 changes: 46 additions & 27 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ inThisBuild(
)
Global / onChangedBuildSource := ReloadOnSourceChanges

(ThisBuild / scalaVersion) := "3.1.2"
ThisBuild / scalaVersion := "3.2.0"

ThisBuild / githubWorkflowJavaVersions := Seq(JavaSpec.graalvm("21.3.0", "11"))
ThisBuild / githubWorkflowTargetTags := Seq("v*")
ThisBuild / githubWorkflowPublishTargetBranches := List(RefPredicate.StartsWith(Ref.Tag("v")), RefPredicate.Equals(Ref.Branch("main")))

Expand Down Expand Up @@ -65,8 +64,8 @@ val commonSettings = Seq(
),
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-effect" % "3.3.14",
"org.scalameta" %%% "munit" % "0.7.29" % Test,
"org.typelevel" %% "munit-cats-effect-3" % "1.0.7" % Test
"org.scalameta" %%% "munit" % "1.0.0-M6" % Test,
"org.typelevel" %%% "munit-cats-effect" % "2.0.0-M3" % Test
),
addCompilerPlugins,
Compile / doc / sources := Nil
Expand Down Expand Up @@ -118,29 +117,49 @@ val front = project
.dependsOn(core)
*/

val app = crossProject(JVMPlatform, NativePlatform)
.crossType(CrossType.Pure)
.settings(commonSettings)
.settings(
libraryDependencies ++= Seq(
"com.disneystreaming.smithy4s" %%% "smithy4s-http4s" % smithy4sVersion.value,
"org.typelevel" %%% "cats-mtl" % "1.3.0",
"com.monovore" %%% "decline-effect" % "2.3.1",
"org.http4s" %%% "http4s-dsl" % "0.23.16",
"org.http4s" %%% "http4s-ember-server" % "0.23.16",
"org.http4s" %%% "http4s-ember-client" % "0.23.16",
"org.http4s" %%% "http4s-circe" % "0.23.16",
"io.circe" %%% "circe-parser" % "0.14.3",
"org.typelevel" %%% "log4cats-noop" % "2.5.0"
// waiting
// "dev.optics" %%% "monocle-core" % "3.1.0"
),
buildInfoKeys := Seq[BuildInfoKey](version),
buildInfoPackage := "com.kubukoz.next"
)
.settings(name := "spotify-next")
.enablePlugins(BuildInfoPlugin)
.settings(
Compile / smithy4sInputDir := (ThisBuild / baseDirectory).value / "app" / "src" / "main" / "smithy"
)
.enablePlugins(Smithy4sCodegenPlugin)
.jvmConfigure(
_.settings(
libraryDependencies ++= Seq(
"ch.qos.logback" % "logback-classic" % "1.2.11"
)
).enablePlugins(JavaAppPackaging)
)
.nativeConfigure(
_.settings(
libraryDependencies ++= Seq(
"com.armanbilge" %%% "epollcat" % "0.1.1"
)
)
)

val root =
project
.in(file("."))
.settings(commonSettings)
.settings(
libraryDependencies ++= Seq(
"com.disneystreaming.smithy4s" %% "smithy4s-http4s" % smithy4sVersion.value,
"org.typelevel" %% "cats-mtl" % "1.3.0",
"com.monovore" %% "decline-effect" % "2.3.0",
"org.http4s" %% "http4s-dsl" % "0.23.13",
"org.http4s" %% "http4s-ember-server" % "0.23.12",
"org.http4s" %% "http4s-ember-client" % "0.23.12",
"org.http4s" %% "http4s-circe" % "0.23.13",
"ch.qos.logback" % "logback-classic" % "1.2.11",
"io.circe" %% "circe-parser" % "0.14.2",
"dev.optics" %% "monocle-core" % "3.1.0"
),
buildInfoKeys := Seq[BuildInfoKey](version),
buildInfoPackage := "com.kubukoz.next"
)
.settings(name := "spotify-next")
.enablePlugins(BuildInfoPlugin)
.enablePlugins(JavaAppPackaging)
.enablePlugins(Smithy4sCodegenPlugin)
// .dependsOn(core)
// .aggregate(core /* , front */ )
.enablePlugins(NoPublishPlugin)
.aggregate(app.componentProjects.map(p => p: ProjectReference): _*)
5 changes: 0 additions & 5 deletions core/src/main/scala/com/kubukoz/next/Model.scala

This file was deleted.

42 changes: 42 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
inputs.nixpkgs.url = "github:nixos/nixpkgs";
inputs.flake-utils.url = "github:numtide/flake-utils";

outputs = { self, nixpkgs, flake-utils, ... }@inputs:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs { inherit system; };
in
{
devShells.default = pkgs.mkShell {
nativeBuildInputs = [ pkgs.s2n-tls ];
};
}
);
}
4 changes: 0 additions & 4 deletions pkgs.nix

This file was deleted.

Loading

0 comments on commit 30b9b48

Please sign in to comment.