Closed kyngs closed 10 months ago
I really like the idea. Really useful especially if transitive dependencies are handled, personally I would not use transitive dependencies because I need to know on compile what libraries will be downloaded but the gradle plugin may handle that too when the JSON file is generated.
Just some ideas that came to my mind:
I use a similar approach in my projects to handle library versions synced with build.gradle
, I personally use java.util.Properties
to load a libraries.properties
file and get the versions.
To prevent NanoJSON bundling we may use different approaches like:
Just key-value based but still possible to make a list like:
[repositories]
[repo1]
url = "..."
[dependencies]
[dep1]
group = "..."
name = "..."
version = "..."
...
This is just a basic approach with no external libraries. I think it may possible to store it as XML too with Properties.storeToXML(...)
.
Google GSON is usually already bundled in all server platforms, so no need to download it or shade it if already class loaded. Between Properties and generic JSON, I would prefer JSON because easier to handle and probably already bundled (or loaded).
The library already downloads on runtime jar-relocator
(and other libraries) to relocate dependencies, NanoJSON (or GSON) may be handled like that in case configureFromJSON
is called.
I think both gradle and maven plugin should be in the same project, gradle-plugin
/maven-plugin
or plugins/gradle
/plugins/maven
folders to better maintain them.
Honestly, while properties or XML would probably work, I think JSON is the best choice here. I don't want to make Libby directly dependent on the assumption that GSON is already present in the classpath. While that assumption might work for the currently supported platforms, it doesn't necessarily need to work for new ones. Thus, if someone wanted to add support for a platform that does not use GSON, they would have to shade it. That's a really bad situation considering the size of GSON.
While Nanojson could be downloaded at runtime, I believe that the negatives would outweigh the positives. (Positives are saving 25kB (which is not a lot), and the negatives are that I would have to relocate the JSON parsing part into a separate class to prevent classloading issues. But if you insist, I will download it at runtime.
As for bundling the plugins into this mono repo, I don't think that's a great idea. This PR only aims to add a data-driven way of handling libraries, it does not aim to provide specific implementations. The libby-gradle-plugin was added as a example usage for this data-driven functionality, not as something to be directly part of Libby itself.
What I wrote are just some ideas to talk about :)
NanoJSON, its really lightweight 25kb instead of 280kb and may be shaded or easily downloaded runtime, I have no complain about that.
Shade vs download, its a way easier shade it instead of download in on runtime especially because its just 25kb but this approach is done for jar-relocator
too that is just 18kb (+ required libraries).
Furthermore, it would be downloaded only if actually used in the code, like the relocator.
About plugins, its not a problem to keep them separate but in this case I think that Libby should have an example on how to handle the JSON in the repo, like some examples of JSON that you can use + the given alternative to generate them via plugins. (Just a documentation page)
About plugins, its not a problem to keep them separate but in this case I think that Libby should have an example on how to handle the JSON in the repo, like some examples of JSON that you can use + the given alternative to generate them via plugins. (Just a documentation page)
Do you want to update the README accordingly, or should I edit it myself?
I will probably approve the PR the next week and change some things: I got the com.alessiodp
package from Maven central and I have plan to refactor the package name and switch to Gradle KTS the project.
I will just change the README after those changes ;)
Currently, the only way to configure Libby is by using the relevant methods on LibraryManager. While this is great, Libby currently lacks some data-driven approach. This PR aims to do the following things only by using a JSON file:
How could this be used
While this may sound like bloat initially, it has very lucrative uses.
Build system plugins
This PR (assuming a relevant build system plugin exists) allows specifying which dependencies should be downloaded at runtime directly in the build system configuration (pom.xml, build.gradle, etc.) Due to the nature of these systems, they can easily resolve transitive dependencies and calculate the checksum. This puts an end to writing boilerplate code and trying to guess dependencies that are required for a dependency to function (and thus partially addresses #18).
Gradle
To demonstrate the usefulness of this feature, I've created a plugin that aims to accomplish this.
I'll take my plugin as an example: An 100+LOC hard to maintain file which includes the dependencies for my plugin, can (using this gradle plugin) be rewritten only by modifying a few lines in the
build.gradle
file:And then calling a simple bootstrap method:
Maven (and other systems)
The same thing can be accomplished with any build system which supports plugins.
Other usages
Considering this PR allows to load the configuration from any JSON file (not only the libby.json file in the plugin JAR), it probably can be used for other things.
Technical info
This patch does not break the API in any way or matter
Considering there's really no way to document a JSON, I've documented the format in the
LibraryManager#configureFromJSON
method.Currently, Libby does not bundle any JSON library. To keep the size as small as possible, I've decided to choose the fantastic NanoJSON library which only adds about 25kB to the final JAR.
I've tested both the plugin and this PR by converting my plugin to this approach.
Finally
While I think the implementation is good as-is, I would love to hear some feedback (positive, or negative).