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

Consider publishing an SBT Plugin? #103

Open
markschaake opened this issue Jun 22, 2024 · 7 comments
Open

Consider publishing an SBT Plugin? #103

markschaake opened this issue Jun 22, 2024 · 7 comments

Comments

@markschaake
Copy link

Hi! My understanding (correct me if I'm wrong) is that scala-dom-types is now really a build tool - whose purpose is to be used at build / compile time to generate code. If that's accurate, then it seems to me the elegant way to provide build tool functionality is via SBT AutoPlugin. Has this been considered? If you are open to the idea, I would be happy to whip together a pull request adding an sbt-scala-domtypes subproject for this. (I already have the start of the code locally in my fork).

I have quite a bit of experience with SBT plugins and would be happy to contribute to this project in this way, unless of course there is a reason to avoid SBT plugins?

@raquo
Copy link
Owner

raquo commented Jun 22, 2024

Heyo, it's true that we're using SDT somewhat as a build tool – at compile time as a code generator – however keep in mind that this is not the only use case, so core functionality must remain sbt-free. For example, some users may want to use mill instead of sbt, others may want to load SDT as a runtime dependency, e.g. to make some interactive website with the data contained in SDT.

I haven't made it an sbt plugin mainly because I'm trying to minimize dependencies, including dependencies on specialized knowledge and concepts.

My lack of sbt skill is a big part of not having any fancy integration with it. I'm not even sure, what exactly could AutoPlugin give us? If you look at how Laminar uses SDT, then what can we get by making an AutoPlugin? Can it save our users (libraries like Laminar) some boilerplate under /project? That would be nice I think.

@markschaake
Copy link
Author

If you look at how Laminar uses SDT, then what can we get by making an AutoPlugin? Can it save our users (libraries like Laminar) some boilerplate under /project? That would be nice I think.

Yes, exactly. A plugin would / could eliminate the need to have the boilerplate code in /project for those client SBT projects using SDT as a build tool. It also would not impact non-SBT and runtime-dependent client projects which would just continue to depend on the library itself. We could add an SBT plugin fairly simply. I think having a plugin would also simplify the use of SDT by future web component binding generator projects (such as laminar-shoelace-components).

In case I haven't been clear: adding an SBT plugin to this project would leave the core library unchanged. The result would be publishing both a library and a complimentary SBT plugin.

If I have time, I'll put together a pull request to illustrate and for discussion.

@cornerman
Copy link
Contributor

cornerman commented Jun 22, 2024

Nice idea with the sbt-plugin! The configuration surface of such a plugin might be quite big, because I am guessing, we would need to add an option for everything that is currently configured in the projects/* scala files regarding dom-types. But I think, I would like such a declarative way. Still have to upgrade to the new version of scala-dom-types in outwatch - so all of this sounds great to me if it is possible 👍

I have just recently created two code-generation projects as well and for both have created an sbt and a mill plugin, so I am happy to help on that front if I can.

Actually, I was taking the idea of @raquo for the shoelace-components and tried to write a generic web-components generator project: https://github.com/cornerman/scala-web-components-codegen. You can write your own template to generate code for your ui framework, or it includes a predefined one for outwatch.

@markschaake
Copy link
Author

One of the great things about AutoPlugins is how they are composable. I imagine a separate AutoPlugin per use case, each with configuration (setting and task keys) specific to their uses. I.e. one for code gen, one for custom-elements.json parsing, etc. My pull request (coming soon) will illustrate.

@raquo
Copy link
Owner

raquo commented Jun 22, 2024

@markschaake Sounds good, thanks! If I understand correctly, it seems that the sbt part will be pretty small / self-contained.

It would be nice if you could keep the sbt API surface reasonably small. For example, we have methods like generateTagsTrait that take lots of params. I would prefer to avoid duplicating all those params as sbt keys, otherwise any developer who wants to e.g. add some params to generateTagsTrait would need to understand all the sbt stuff and duplicate their changes there. If we could call existing functions like generateTagsTrait from build.sbt instead, that would be great. If the functions' contract / signature needs to change for that (while retaining the ability for non-sbt usage), that would be ok I think.

@markschaake
Copy link
Author

@raquo yes agreed on keeping the API surface small. It might be only two SBT settings and one task, where one of the settings allows the user to do all the default configuration overrides.

I'll try to get something small up tomorrow so we can have a concrete reference to discuss (if I can steal an hour from family time).

@markschaake
Copy link
Author

Thanks for the discussion on #104 . I closed it with the following takeaways:

  • It doesn't make sense to provide a plugin in SDT for code generation. It would really only make sense if there were many users (client builds) and a very small subset of standard ways to configure code generation using SDT.
  • The plugin for parsing custom-elements.json doesn't make sense to be part of SDT in its current state: there is no parsing into SDT types, and the parser isn't production-ready anyway.
  • Pain points around caching / managing the generated source code can be handled simply in the client build itself without the need for a plugin (at least using SBT). Perhaps there is an opportunity to provide documentation guidance in the README, but a hand-holding plugin seems overkill.

Thanks again for taking the time to help me learn. I know for me and @YakimaProgrammer this knowledge will help us with work we're doing this summer around Shoelace.js integration with Laminar.

@cornerman I will taking a look at your https://github.com/cornerman/scala-web-components-codegen project along with @YakimaProgrammer. It looks like there is some overlap with what we're trying to do this summer - hopefully we can help out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants