Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CompileTime Plugin is not usable with Scala 3 #1239

Closed
pmeheut opened this issue Jan 6, 2022 · 16 comments
Closed

CompileTime Plugin is not usable with Scala 3 #1239

pmeheut opened this issue Jan 6, 2022 · 16 comments
Labels
tools Issue related to Caliban tools like code generation or schema comparison

Comments

@pmeheut
Copy link
Contributor

pmeheut commented Jan 6, 2022

Hi,
I have a simple Scala 3.1.0 cross Scala.js application based on https://github.com/adpi2/scala3-full-stack-example
I tried to replace the REST api by GraphQL but it has proved to be a minefield.

I need to use Scala 3 versions of Circe, Caliban to derive codecs and schema of my code. This works fine.
But as soon as I tried to use the akka-http-adapter, I got a lof of conflicts with 2.13 versions of libraries.

So I switched to ZHttp as this a Scala 3 http server. I made it work.

But then, I wanted to write the client code so I used caliban-codegen-sbt but of course, back to 2.13 libraries dependencies and nothing works.
I've tried to exclude dependencies, to write subprojects in 2.13 but each time, I find another problem.
I even look to the sbt plugin source code to see if it could be easily recompiled in Scala 3. No luck because of the macros of course.

It should not be this hard. So back to my title question: is there a way to write a full stack scala 3 jvm/scala 3.js application with Caliban and automatic schema generation, etc?

@ghostdogpr
Copy link
Owner

Akka HTTP doesn't provide artifacts for Scala 3 yet (some other parts of Akka like Akka Actors do, but not Akka HTTP yet). They say it works with 2.13 artifacts but I haven't tried it. For native scala 3 support, zio http and http4s are recommended.

Sbt plugins can only be compiled with Scala 2.12 (sbt only supports that), but you can use it regardless of your Scala version. The code generated should work with any Scala version. Is that not the case?

@ghostdogpr
Copy link
Owner

I've just tested it in a small Scala 3 project, it generates client code well.

@pmeheut
Copy link
Contributor Author

pmeheut commented Jan 7, 2022

I'm trying to reproduce the issue. Maybe I missed something. I'll let you know.
Regards.

@pmeheut
Copy link
Contributor Author

pmeheut commented Jan 7, 2022

I've tried with a very simple project. It works fine in 2.13.7. When I change scalaVersion to 3.1.0, I cannot resolve com.github.ghostdogpr:caliban-tools_3:1.3.1.
I do not use it explicitly and the message occurs as soon as I activate the CompileTimeCalibanServerPlugin.
I've tried to force it with CrossVersion.for3Use2_13 but it changes nothing.

@ghostdogpr
Copy link
Owner

I only tried CalibanPlugin, let me try the compile time one.

@ghostdogpr
Copy link
Owner

Right, this is not working with Scala 3 as it requires caliban-tools. caliban-tools is not published for Scala 3 because it requires scalafmt-core and scalafmt-dynamic and those don't have Scala 3 artifacts. I will see if I can make it work in 2.13 compatibility mode.

In the meantime, you have to use the regular CalibanPlugin (generate from a schema file or an URL).

@ghostdogpr ghostdogpr changed the title Is Caliban really usable with Scala 3? CompileTime Plugin is not usable with Scala 3 Jan 7, 2022
@pmeheut
Copy link
Contributor Author

pmeheut commented Jan 7, 2022

In the meantime, you have to use the regular CalibanPlugin (generate from a schema file or an URL).

Yes, this was my conclusion but this defeats my purpose of coding everything once in Scala and use it both in the server and the browser without having to write boilerplate code such as a schema file.
In the meantime, I'll stick with Scala 2.13 but this is kind of sad because I like Scala 3 a lot (extensions, inline, map with automatic pattern matching, etc).

@ghostdogpr
Copy link
Owner

What I did before the compile time plugin existed was to start my server locally, and run the client generation on-demand pointing on my local server URL. Not as nice of course because you have to do it each time you modify the schema, but it's just a command line to run.

@ghostdogpr
Copy link
Owner

Compatibility mode doesn't seem to work, so we will need scalameta/scalafmt#3035

@ghostdogpr ghostdogpr added the tools Issue related to Caliban tools like code generation or schema comparison label Jan 7, 2022
@pmeheut
Copy link
Contributor Author

pmeheut commented Jan 8, 2022

I saw scalameta/scalafmt#3035. I know how to use Coursier to load the jar dynamically but I'm not sure how this would be easy to integrate into Caliban.

Anyhow, I managed to compile caliban-tools in Scala 3. I had to

  • remove references and calls to scalafmt for the time being waiting for a better solution (as it is optional, this is not a problem)
  • change the imports in Options.scala to use the new zio.config.magnolia unified API
  • change the private constructors to private[SchemaLoader] in SchemaLoader
  • replace calls such as map(TypeAdded) where TypeAdded is a case class to map(TypeAdded.apply) to avoid warnings

And it works. I would like to go further and implement scalafm-dynamic Coursier loading but I need help.

@ghostdogpr
Copy link
Owner

Which part do you need help with? The only call to scalafmt is here but I think you found it already since you disabled it. As I understand, Coursier can be used via its API. However, it doesn't seem to support Scala 3 either (https://mvnrepository.com/artifact/io.get-coursier/coursier) but maybe it works in 2.13 compat mode 🤔

@pmeheut
Copy link
Contributor Author

pmeheut commented Jan 9, 2022

I did not need help: just remember some basic Java. The existing code was already using scalafmt-interfaces but not fully. I made the necessary changes and everything now works in Scala 3 and compiles in 2.12 and 2.13 as well.

You can see the changes here: https://github.com/pmeheut/caliban, branch tools_scala3.

There are two things I'm not sure of before I can generate a pull request:

  1. my branch uses zhttp RC21 as this is the one described by their documentation (!! instead of Root for instance)
  2. In Formatter.scala, scalafmt-dynamic version is hard coded. It would be better to get it from the sbt-project but I'm not sure about the best way to do it.

@ghostdogpr
Copy link
Owner

Sounds great! You can open a PR.

Using zhttp RC21 won't work because we need a release from Tapir. This work in ongoing in #1216. It's better not to mix it up with this PR.

@pmeheut
Copy link
Contributor Author

pmeheut commented Jan 9, 2022

It works fine with Tapir 0.20.0-M4: I run my Rest & Graphql server like this.
But I'll remove it from the PR.

@pmeheut
Copy link
Contributor Author

pmeheut commented Jan 10, 2022

Ok, I generated the PR. This is my first one ever so let me know if I did something wrong.

@ghostdogpr
Copy link
Owner

Closed by #1415

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tools Issue related to Caliban tools like code generation or schema comparison
Projects
None yet
Development

No branches or pull requests

2 participants