scalac-options icon indicating copy to clipboard operation
scalac-options copied to clipboard

Random idea: take inspiration from http4s `Headers`?

Open armanbilge opened this issue 3 years ago • 3 comments

Just a random idea I've been brewing, feel free to tell me I'm being dumb

It seems to me a lot of the trickiness with scalacOptions is that in userland we want to operate (add/remove) with a higher-level DSL (which is what this library provides) but the underlying representation is a raw Seq[String].

I assume this has motivated the approach in sbt-tpolecat where tpolecatScalacOptions is defined in terms of the DSL and it is intended that all operations are done on that setting, and the plugin then writes it into scalacOptions. Unfortunately this has shortcomings as well e.g. https://github.com/typelevel/sbt-tpolecat/issues/60 or https://github.com/typelevel/sbt-tpolecat/issues/102.

While reviewing an http4s PR I realized that the Headers model is super similar to maybe what we want here. Notably, Headers is represented as a raw sequence of CIString -> String tuples but users are able to interact with it elegantly using the various model classes. I wonder if we could adopt a similar design pattern here.

I haven't fully worked out how it would actually work in sbt, but the rough idea would be that all interactions should be done by applying DSL-based operations directly to the scalacOptions setting. I think this would get us the wins while avoiding the traps.

Thoughts?

armanbilge avatar Aug 19 '22 20:08 armanbilge

This sounds really interesting - sounds like I need to read up about http4s Headers. typelevel/sbt-tpolecat#102 is driving me absolutely nuts so any improvement on the status quo would be extremely helpful. 😆

DavidGregory084 avatar Aug 20 '22 12:08 DavidGregory084

Had some time to have a look at the Headers DSL in http4s and I'm having some trouble understanding what you are proposing on this one @armanbilge - can you elaborate on this part?

all interactions should be done by applying DSL-based operations directly to the scalacOptions setting

I think that we would lose the ability to manipulate different keys in different scopes by doing this (which admittedly doesn't work very well at the moment).

DavidGregory084 avatar Sep 27 '22 11:09 DavidGregory084

@DavidGregory084 heh, sorry if I wasn't so clear.

Besides the fact that in sbt scalacOptions is represented as a Seq[String], let's forget about sbt for a minute.

My observation is essentially that in http4s Headers is just a fancy wrapper for a List[(String, String)]. So even though there is a fancy DSL for working with modeled headers, they are fundamentally represented in their raw form and not as e.g. List[Header]. The raw form is the single, canonical representation.

Circling back to sbt and sbt-tpolecat, IIUC the way you are doing things now is:

  1. Introducing a setting Seq[ScalacOption], and claiming this is the canonical way of interacting with your options.
  2. Users happily manipulate the Seq[ScalacOption] with the DSL, in every scope.
  3. sbt-tpolecat attempts to load the contents of Seq[ScalacOption] into the raw Seq[String] correctly per-scope, which is when bad things are happening.

Instead I am proposing this:

  1. Users happily manipulate the raw Seq[String] with the DSL, in every scope.

Let me know if that makes more sense 😅

armanbilge avatar Sep 27 '22 13:09 armanbilge