-
-
Notifications
You must be signed in to change notification settings - Fork 5
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
Separate Generated and Non-Generated Source Files in SBT Build #3
base: master
Are you sure you want to change the base?
Separate Generated and Non-Generated Source Files in SBT Build #3
Conversation
- Modified `build.sbt` to use `Compile / sourceManaged` for the output directory of autogenerated sources. - Modified `ShoelaceGenerator.scala` to return a `List[File]` of generated sources.
Heyo, sorry I didn't have time to respond to Mark's related comments before you started working on this. The generated files in all of my projects are committed to git, and that's very much by design. The main reasons for this are:
Can we keep the generated files where they are, but still add If you want to separate the generated code from non-generated code in the source, please note that I want to keep the generated code where it is, because it's all user-facing, and I want to let users easily import everything they need with just a single |
@raquo thanks, I think we understand the requirements and reasons. We were looking at the build first as a way to get familiar with project and hopefully fix a broken window or two along the way. Thank you for your patience and help while we get familiar. I believe @YakimaProgrammer is already started working on your "#nc" comments in Regarding this PR... I do think there might be a way to solve "all the issues", where those issues are:
I think this can be achieved with something simple like: // build.sbt
val generatedDir = settingKey[File]("Directory in which to generate sources")
// settings
...
.settings(
generatedDir := (Compile / scalaSource).value / "com" / "raquo" / "laminar" / "shoelace" / "sl" / "generated",
generateShoelace := new ShoelaceGenerator(
onlineSourceRoot = "https://github.com/raquo/laminar-shoelace-components/blob/master",
customElementsJsonPath = "node_modules/@shoelace-style/shoelace/dist/custom-elements.json",
baseOutputDirectoryPath = "src/main/scala/com/raquo/laminar/shoelace/sl",
baseOutputDirectoryPath = generatedDir.value, // <- this is now in source control
baseOutputPackagePath = "com.raquo.laminar.shoelace.sl" // <- this stays the same
).generate(),
// Now to make sure we trash generated files on clean:
(Compile / clean) := {
(Compile / clean).value // make sure run regular clean (like super.clean)
val dir = generatedDir.value
IO.delete(dir.listFiles().toList)
} I think this would work and not require adding an |
@markschaake Indeed those would be good bullet points to fix! I don't think we can do the In Airstream, I do have some code in a In this project, we can't do this, because we want a simple and pretty import path, and easy references to e.g. These constraints don't leave us with a lot of options. One of them is the Personally I think Personally, when I'm working on this shoelace project, my biggest gripe is that I need to remember to run |
Thank you for sharing your perspective. I understand the structure and vision for this project a lot better now. I'm looking forward to the road ahead as we work on this project! |
Sorry for maybe raising the dead. My understanding is that we have: Two kinds of projects:
There are three types of code here:
There are two types of users
Proposed solutionSeparate the parts into different sbt modules.
The generator would output code into the When all code is in the ui-lib module, it can be built and published to maven and so on. Other than this I would keep the glue code in a separate package, like
this is not strictly needed, but makes the life of tooling devs easier. |
@PerWiklander That seems like a good assessment of use cases. I don't really understand the value of creating multiple projects for I may be forgetting some nuance that we've previously talked about, but I think this should satisfy the tooling developers as well. We would just need to wire an sbt task that would delete all If you meant this as a way to support multiple ui-libs – then yes, we'd need something like that. In that case, I think each ui-lib should exist in a separate repo – separate both from each other and from the tooling, and the This way, commits to these separate ui-lib repos with updated generated code would generally attribute the changes not to a specific commit in the generator project, but to a specific release of it, similarly to how we attribute changes in Laminar's DOM definitions to a specific release of Scala DOM Types. I feel like this generally provides enough granularity, as the updates in generated code are generally trivial, and the generator releases are small in scope, usually just adding support for more props. However, the multi-lib setup is more of a long term plan. We haven't yet decoupled the Shoelace generator from Laminar, it needs to be made more configurable to support outputting code for other UI libraries. |
This: "If you meant this as a way to support multiple ui-libs – then yes, we'd need something like that. In that case, I think each ui-lib should exist in a separate repo". I just didn't want to suggest that at first, since it's more work to get it going. I also see a need to generate e.g. Scala tags versions for server side rendering. It would be nice to have the same API for the components regardless of the intended output. Or is there a server side story for Laminar these days? |
I plan to eventually implement ScalaTags-like rendering functionality for Laminar on the backend. It won't directly support reactive stuff (anything with Airstream or anything with |
Would it be possible to have the same API though, but just make any reactive stuff a noop? |
I don't know, I went down that rabbit hole a while ago, and my general conclusion was that it may be possible, but it's not trivial, and I don't know if the outcome would actually be desirable. If we're going down that path, we could even implement the parts of the DOM that Laminar needs internally (basically implement a small subset of the I think that trying to fake a JS/browser environment on the JVM, and inevitably leaving exposed rough edges one way or another, is not as rewarding of a destination as it may appear. The issue I linked offers a much simpler alternative that is admittedly less ergonomic to use for cross-compiled components, but it would give users a safe, honest and easy to understand, if slightly cumbersome to use, approach to writing cross compiled components. Other Scala.js UI libraries may face less of an issue running on the JVM as they use platform-agnostic virtual DOM abstractions, and use reactive systems that were designed for the backend, but Laminar and Airstream take different tradeoffs, optimizing for ergonomics of frontend SPA development, so the cross compiling support will inevitably have more friction. |
Hello!
This is our (myself and @markschaake) first pull request and we were getting our feet wet with this project. We were taking a look at the build and had a couple of ideas for teasing apart generated and nongenerated sources. We'd love if you took a look and shared your thoughts!
These changes have a couple of tradeoffs: