libgdx/gdx-liftoff

Suggestions to HTML/GWT gradle scripts

cosmicdan opened this issue · 7 comments

Hi there,

Not exactly a problem nor a "fix" but an FYI for future improvements.

The current HTML gradle scripts are a little flawed. The main issue is that they're using implementation to declare dependencies when they should be using gwt, as per GWT plugin docs. This is important because it allows the GWT build process to pull in dependencies of the subprojects, without it you have to provide implementation dependencies for everything in the HTML platform gradle script.

So, before, a HTML platform script had something like this (pulled from my current work, apologies for differences to basic gdx-liftoff templates):

dependencies {
    implementation "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion"
    implementation "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion:sources"
    implementation "com.badlogicgames.gdx:gdx:$gdxVersion:sources"
    implementation "com.kotcrab.vis:vis-ui:$visUiVersion:sources"
    implementation "space.earlygrey:shapedrawer:$shapeDrawerVersion:sources"
    annotationProcessor "org.projectlombok:lombok:$lombokVersion"
    api "org.projectlombok:lombok:$lombokVersion"
    implementation project(':shared')
    implementation project(':core')
    implementation project(':platform:html')

...though with gwt keyword, my main script looks like this now:

dependencies {
    annotationProcessor "org.projectlombok:lombok:$lombokVersion"
    api "org.projectlombok:lombok:$lombokVersion"
    gwt project(':shared')
    gwt project(':core')
    gwt project(':platform:html')

...note now that the GDX, VisUI and ShapeDrawer libs are implementations in core (where they were originally anyway) and GWT backend stuff is in my :platform:html project.

So, we don't need to define dependencies multiple times by using the proper gwt keyword for dependencies.

BONUS: We can now programmatically add all sources to the classpath in the addSource task, instead of having to hard-code them again. Horray for less maintenance!

Originally, I had this:

task addSource {
    doLast {
        sourceSets.main.compileClasspath += files(project(':core').sourceSets.main.allJava.srcDirs)
        sourceSets.main.compileClasspath += files(project(':shared').sourceSets.main.allJava.srcDirs)
        sourceSets.main.compileClasspath += files(project(':platform:html').sourceSets.main.allJava.srcDirs)
    }
}

...which has now become this...

task addSource {
    doLast {
        DomainObjectSet<ProjectDependency> gwtDeps = project.configurations.gwt.dependencies.withType ProjectDependency
        gwtDeps.forEach {ProjectDependency gwtDep ->
            sourceSets.main.compileClasspath += files(project(gwtDep.dependencyProject.path).sourceSets.main.allJava.srcDirs)
        }
    }
}

...its basically doing the same thing, except iterating over the previously-defined gwt dependencies instead of needing us to hardcode them.

Anyway, as I said, not a problem per-se, just something that could be improved in future so I wanted to bring it up. No doubt it's a benefit for maintenance because we no longer have to update 3 places when we want a new lib for a GWT project.

Cheers!

Should also add that IntelliJ handles all this fine when using it's own compiler/runner instead of gradlew, Untested with Eclipse.

Good catch, wow... I guess some GWT-related plugin we already have enables that gwt keyword. This should make the dependencies much cleaner; I'll start trying to implement this now.

No worries!

I see you already did a WIP commit but it's not working right for you...? There could be a chance I've missed something, or my gradle cache might have had those missing deps still there (gradle can be weird with it's cache sometimes)...

...wasn't expecting you to jump right on this haha, but let me know if you want me to double-check everything and I can do a proper before/after via a github repo (based on a liftoff template, VisUI showcase I suppose). And of course, make sure I actually covered everything.

Oh FWIW, just to be clear, these are the deps in my :platform:html subproject (they would typically go in the Launcher)

implementation "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion"
implementation "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion:sources"

...gdx backend is still implementation, not gwt. Not sure if I was clear there.

However, I don't know if these should be gwt or implementation once they're back in the original HTML launcher project 😊 Its been a short while since I wrote this issue, the details have been GC'd from my mind so I apologize if it doesn't work right.

OK, that helps, thanks. I don't really know how the gwt deps work -- they seem to be pulling in transitive dependencies correctly with their :sources classifier, but when I define a gwt dependency in the html/build.gradle file, it doesn't seem to add a :sources dependency for that dependency itself. So if I do

gwt "com.github.tommyettinger:jdkgdxds_interop:$jdkgdxdsInteropVersion"

Then the transitive dependencies are OK, but jdkgdxds_interop only has the non-sources jar, which isn't used by GWT. I think I should be able to just not declare the deps again in most cases, and use gwt on the projects, but I haven't gotten this working yet. Lots of the third-party libraries that Liftoff knows about have special situations for some part of GWT compatibility, also.

I'm definitely still having problems getting this going. The :sources classifier just seems to be missing from many deps unless I add it manually. If you want to try this as a PR, that would be great, and I could try to help with any odd requirements the code base has. I think for now, I'll revert my WIP changes, because they do not work for HTML projects right now, and that should also make adding a PR that was based on the original code easier (I really hope nothing needs to do what I was hacking in earlier, with addSpecialDependency() used nearly everywhere there's a dependency).

Fair point, I may have actually jumped the gun on making this suggestion because I don't actually use any addons in my HTML project yet 😅

That sounds good, I'll take a closer look at a later date and figure it out properly. I won't forget, I like to share work back to projects I appreciate where I can ❤️ And I'm probably one of the four people in 2022 who is learning GWT from scratch 😆 but as someone who wants to see more web apps written with Java/GWT instead of the six hundred other JS stacks out there today, it's definitely worth doing for me on a personal note.

Cheers for your work on Liftoff, I'll do a PR at a later date.