From 3d97c4b9a4716dd0fc28f16f3839073e699aae1b Mon Sep 17 00:00:00 2001 From: Lars Grefer Date: Sun, 23 Feb 2025 00:09:32 +0100 Subject: [PATCH] Initial GWT Plugin implementation --- examples/gwt/war/build.gradle | 15 ++ .../java/io/freefair/example/Example.gwt.xml | 3 + examples/settings.gradle | 2 + gwt-plugin/build.gradle | 44 ++++++ .../plugins/gwt/CommonGwtToolOptions.java | 80 +++++++++++ .../gradle/plugins/gwt/GwtBasePlugin.java | 82 +++++++++++ .../plugins/gwt/GwtCodeServerOptions.java | 77 ++++++++++ .../gradle/plugins/gwt/GwtCompileOptions.java | 133 ++++++++++++++++++ .../gradle/plugins/gwt/GwtDevModeOptions.java | 104 ++++++++++++++ .../gradle/plugins/gwt/GwtExtension.java | 18 +++ .../gradle/plugins/gwt/GwtPlugin.java | 21 +++ .../gradle/plugins/gwt/GwtWarPlugin.java | 34 +++++ .../gradle/plugins/gwt/GwtWebJarPlugin.java | 35 +++++ .../plugins/gwt/tasks/AbstractGwtTask.java | 88 ++++++++++++ .../plugins/gwt/tasks/GwtCodeServerTask.java | 53 +++++++ .../plugins/gwt/tasks/GwtCompileTask.java | 60 ++++++++ .../plugins/gwt/tasks/GwtDevModeTask.java | 54 +++++++ settings.gradle | 1 + 18 files changed, 904 insertions(+) create mode 100644 examples/gwt/war/build.gradle create mode 100644 examples/gwt/war/src/main/java/io/freefair/example/Example.gwt.xml create mode 100644 gwt-plugin/build.gradle create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/CommonGwtToolOptions.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtBasePlugin.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtCodeServerOptions.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtCompileOptions.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtDevModeOptions.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtExtension.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtPlugin.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtWarPlugin.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtWebJarPlugin.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/AbstractGwtTask.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtCodeServerTask.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtCompileTask.java create mode 100644 gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtDevModeTask.java diff --git a/examples/gwt/war/build.gradle b/examples/gwt/war/build.gradle new file mode 100644 index 00000000..3ff8a3b4 --- /dev/null +++ b/examples/gwt/war/build.gradle @@ -0,0 +1,15 @@ +import io.freefair.gradle.plugins.gwt.tasks.AbstractGwtTask + +plugins { + id "io.freefair.gwt-war" + id "war" +} + +gwt { + modules.add("io.freefair.example.Example") +} + +dependencies { + gwtClasspath "org.gwtproject:gwt-user:2.12.1" + gwtClasspath project(":code-generator:generator") +} diff --git a/examples/gwt/war/src/main/java/io/freefair/example/Example.gwt.xml b/examples/gwt/war/src/main/java/io/freefair/example/Example.gwt.xml new file mode 100644 index 00000000..5f1a494b --- /dev/null +++ b/examples/gwt/war/src/main/java/io/freefair/example/Example.gwt.xml @@ -0,0 +1,3 @@ + + + diff --git a/examples/settings.gradle b/examples/settings.gradle index 09dcf303..0e8fcd46 100644 --- a/examples/settings.gradle +++ b/examples/settings.gradle @@ -46,3 +46,5 @@ include 'plantuml' include ":mjml" include ":okhttp" + +include ":gwt:war" diff --git a/gwt-plugin/build.gradle b/gwt-plugin/build.gradle new file mode 100644 index 00000000..c01c403b --- /dev/null +++ b/gwt-plugin/build.gradle @@ -0,0 +1,44 @@ +plugins { + id "maven-publish" + id "java-gradle-plugin" + id "com.gradle.plugin-publish" +} + +dependencies { + + compileOnly 'org.gwtproject:gwt-dev:2.12.1' + +} + +gradlePlugin { + plugins { + gwt { + id = "io.freefair.gwt" + implementationClass = "io.freefair.gradle.plugins.gwt.GwtPlugin" + displayName = "GWT Plugin" + description = "GWT Plugin" + tags.set(['gwt']) + } + gwtBase { + id = "io.freefair.gwt-base" + implementationClass = "io.freefair.gradle.plugins.gwt.GwtBasePlugin" + displayName = "GWT Base Plugin" + description = "GWT Plugin" + tags.set(['gwt']) + } + gwtWar { + id = "io.freefair.gwt-war" + implementationClass = "io.freefair.gradle.plugins.gwt.GwtWarPlugin" + displayName = "GWT War Plugin" + description = "GWT Plugin" + tags.set(['gwt']) + } + gwtWebjar { + id = "io.freefair.gwt-webjar" + implementationClass = "io.freefair.gradle.plugins.gwt.GwtWebJarPlugin" + displayName = "GWT WebJar Plugin" + description = "GWT Plugin" + tags.set(['gwt']) + } + } +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/CommonGwtToolOptions.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/CommonGwtToolOptions.java new file mode 100644 index 00000000..76b366db --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/CommonGwtToolOptions.java @@ -0,0 +1,80 @@ +package io.freefair.gradle.plugins.gwt; + +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.provider.ListProperty; +import org.gradle.api.provider.MapProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Console; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.Optional; +import org.gradle.api.tasks.OutputDirectory; + +/** + * @author Lars Grefer + */ +public interface CommonGwtToolOptions { + + @Console + Property getLogLevel(); + + @Optional + @Input + Property getFailOnError(); + + @Optional + @OutputDirectory + DirectoryProperty getWorkDir(); + + @Optional + @Input + Property getStyle(); + + /** + * Set the values of a property in the form of propertyName=value1[,value2...]. + */ + @Optional + @Input + MapProperty getSetProperty(); + + @Optional + @Input + Property getIncremental(); + + @Optional + @Input + Property getSourceLevel(); + + /** + * Generate exports for JsInterop purposes. If no -includeJsInteropExport/-excludeJsInteropExport provided, generates all exports. (defaults to OFF) + */ + @Optional + @Input + Property getGenerateJsInteropExports(); + + /** + * Include members and classes while generating JsInterop exports. Flag could be set multiple times to expand the pattern. (The flag has only effect if exporting is enabled via -generateJsInteropExports) + */ + @Optional + @Input + ListProperty getIncludeJsInteropExports(); + + /** + * Include/exclude members and classes while generating JsInterop exports. Flag could be set multiple times to expand the pattern. (The flag has only effect if exporting is enabled via -generateJsInteropExports) + */ + @Optional + @Input + ListProperty getExcludeJsInteropExports(); + + /** + * @return EXPERIMENTAL: Specifies method display name mode for chrome devtools: NONE, ONLY_METHOD_NAME, ABBREVIATED or FULL (defaults to NONE) + */ + @Optional + @Input + Property getXmethodNameDisplayMode(); + + /** + * The GWT modules that the code server should compile. (Example: com.example.MyApp) + */ + @Input + ListProperty getModule(); +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtBasePlugin.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtBasePlugin.java new file mode 100644 index 00000000..d444b843 --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtBasePlugin.java @@ -0,0 +1,82 @@ +package io.freefair.gradle.plugins.gwt; + +import io.freefair.gradle.plugins.gwt.tasks.AbstractGwtTask; +import io.freefair.gradle.plugins.gwt.tasks.GwtCodeServerTask; +import io.freefair.gradle.plugins.gwt.tasks.GwtCompileTask; +import io.freefair.gradle.plugins.gwt.tasks.GwtDevModeTask; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.attributes.DocsType; +import org.gradle.api.attributes.VerificationType; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.plugins.JavaPluginExtension; +import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.TaskProvider; +import org.gradle.api.tasks.compile.AbstractCompile; +import org.gradle.api.tasks.compile.JavaCompile; + +/** + * @author Lars Grefer + */ +public class GwtBasePlugin implements Plugin { + + @Override + public void apply(Project project) { + + project.getPlugins().apply(JavaPlugin.class); + + Configuration gwtDev = project.getConfigurations().create("gwtDev"); + + Configuration gwtClasspath = project.getConfigurations().create("gwtClasspath"); + + Configuration gwtSources = project.getConfigurations().create("gwtSources"); + gwtSources.extendsFrom(gwtClasspath); + + gwtSources.getAttributes().attribute(VerificationType.VERIFICATION_TYPE_ATTRIBUTE, project.getObjects().named(VerificationType.class, VerificationType.MAIN_SOURCES)); + gwtSources.getAttributes().attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.getObjects().named(DocsType.class, DocsType.SOURCES)); + + GwtExtension gwtExtension = project.getExtensions().create("gwt", GwtExtension.class); + + project.afterEvaluate(p -> { + gwtDev.defaultDependencies(ds -> { + ds.add(project.getDependencies().create("org.gwtproject:gwt-dev:" + gwtExtension.getToolVersion().get())); + }); + }); + + project.getTasks().withType(AbstractGwtTask.class, gwtTask -> { + gwtTask.setGroup("gwt"); + + gwtTask.getGwtClasspath().from(gwtDev); + gwtTask.getGwtClasspath().from(gwtClasspath); + JavaPluginExtension pluginExtension = project.getExtensions().getByType(JavaPluginExtension.class); + SourceSet main = pluginExtension.getSourceSets().getByName("main"); + gwtTask.getGwtClasspath().from(main.getAllJava().getSourceDirectories()); + + gwtTask.getWorkDir().set(gwtTask.getTemporaryDir()); + + gwtTask.getModule().convention(gwtExtension.getModules()); + + gwtTask.getSourceLevel().convention(project.getTasks().named("compileJava", JavaCompile.class).map(AbstractCompile::getSourceCompatibility)); + }); + + TaskProvider gwtCompileTaskProvider = project.getTasks().register("gwtCompile", GwtCompileTask.class, gwtCompile -> { + gwtCompile.getWar().convention(project.getLayout().getBuildDirectory().dir("gwt/compile/war")); + gwtCompile.getDeploy().convention(project.getLayout().getBuildDirectory().dir("gwt/compile/deploy")); + gwtCompile.getExtra().convention(project.getLayout().getBuildDirectory().dir("gwt/compile/extra")); + + gwtCompile.getGwtClasspath().from(gwtSources); + }); + + TaskProvider gwtDevModeTaskProvider = project.getTasks().register("gwtDevMode", GwtDevModeTask.class, gwtDevMode -> { + gwtDevMode.getWar().convention(project.getLayout().getBuildDirectory().dir("gwt/dev-mode/war")); + gwtDevMode.getDeploy().convention(project.getLayout().getBuildDirectory().dir("gwt/dev-mode/deploy")); + gwtDevMode.getExtra().convention(project.getLayout().getBuildDirectory().dir("gwt/dev-mode/extra")); + }); + + project.getTasks().register("gwtCodeServer", GwtCodeServerTask.class, gwtCodeServer -> { + gwtCodeServer.getLauncherDir().convention(project.getLayout().getBuildDirectory().dir("gwt/code-server")); + }); + + } +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtCodeServerOptions.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtCodeServerOptions.java new file mode 100644 index 00000000..76e505e9 --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtCodeServerOptions.java @@ -0,0 +1,77 @@ +package io.freefair.gradle.plugins.gwt; + +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.*; + +/** + * @author Lars Grefer + */ +public interface GwtCodeServerOptions extends CommonGwtToolOptions { + + /** + * Allows -src flags to reference missing directories. (defaults to OFF) + */ + @Optional + @Input + Property getAllowMissingSrc(); + + /** + * Exits after compiling the modules. The exit code will be 0 if the compile succeeded. (defaults to OFF) + */ + @Optional + @Input + Property getCompileTest(); + + /** + * The number of times to recompile (after the first one) during a compile test. + */ + @Optional + @Input + Property getCompileTestRecompiles(); + + /** + * Precompile modules. (defaults to ON) + */ + @Optional + @Input + Property getPrecompile(); + + /** + * The port where the code server will run. + */ + @Optional + @Input + Property getPort(); + + /** + * A directory containing GWT source to be prepended to the classpath for compiling. + */ + @Optional + @InputDirectory + DirectoryProperty getSrc(); + + /** + * An output directory where files for launching Super Dev Mode will be written. (Optional.) + */ + @Optional + @OutputDirectory + DirectoryProperty getLauncherDir(); + + /** + * Specifies the bind address for the code server and web server (defaults to 127.0.0.1) + */ + @Optional + @Input + Property getBindAddress(); + + /** + * EXPERIMENTAL: Enables Javascript output suitable for post-compilation by Closure Compiler (defaults to OFF) + */ + @Optional + @Input + Property getXclosureFormattedOutput(); + + + +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtCompileOptions.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtCompileOptions.java new file mode 100644 index 00000000..63d970f2 --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtCompileOptions.java @@ -0,0 +1,133 @@ +package io.freefair.gradle.plugins.gwt; + +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.Optional; +import org.gradle.api.tasks.OutputDirectory; + +/** + * @author Lars Grefer + */ +public interface GwtCompileOptions extends CommonGwtToolOptions { + + /** + * EXPERIMENTAL: Enables Javascript output suitable for post-compilation by Closure Compiler (defaults to OFF) + */ + @Optional + @Input + Property getXClosureFormattedOutput(); + + /** + * Compile a report that tells the "Story of Your Compile". (defaults to OFF) + */ + @Optional + @Input + Property getCompileReport(); + + /** + * EXPERIMENTAL: DEPRECATED: use jre.checks.checkLevel instead. (defaults to OFF) + */ + @Optional + @Input + Property getXcheckCasts(); + + /** + * EXPERIMENTAL: Include metadata for some java.lang.Class methods (e.g. getName()). (defaults to ON) + */ + @Optional + @Input + Property getXclassMetadata(); + + /** + * Compile quickly with minimal optimizations. (defaults to OFF) + */ + @Optional + @Input + Property getDraftCompile(); + + /** + * Include assert statements in compiled output. (defaults to OFF) + */ + @Optional + @Input + Property getCheckAssertions(); + + /** + * EXPERIMENTAL: Limits of number of fragments using a code splitter that merges split points. + */ + @Optional + @Input + Property getXfragmentCount(); + + /** + * Debugging: causes normally-transient generated types to be saved in the specified directory + */ + @Optional + @OutputDirectory + DirectoryProperty getGen(); + + /** + * Puts most JavaScript globals into namespaces. Default: PACKAGE for -draftCompile, otherwise NONE + */ + @Optional + @Input + Property getXnamespace(); + + /** + * Sets the optimization level used by the compiler. 0=none 9=maximum. + */ + @Optional + @Input + Property getOptimize(); + + /** + * Enables saving source code needed by debuggers. Also see -debugDir. (defaults to OFF) + */ + @Optional + @Input + Property getSaveSource(); + + /** + * Validate all source code, but do not compile. (defaults to OFF) + */ + @Optional + @Input + Property getValidateOnly(); + + /** + * The number of local workers to use when compiling permutations + */ + @Optional + @Input + Property getLocalWorkers(); + + /** + * The directory into which deployable output files will be written (defaults to 'war') + */ + @OutputDirectory + DirectoryProperty getWar(); + + /** + * The directory into which deployable but not servable output files will be written (defaults to 'WEB-INF/deploy' under the -war directory/jar, and may be the same as the -extra directory/jar) + */ + @Optional + @OutputDirectory + DirectoryProperty getDeploy(); + + /** + * The directory into which extra files, not intended for deployment, will be written + */ + @Optional + @OutputDirectory + DirectoryProperty getExtra(); + + /** + * Overrides where source files useful to debuggers will be written. Default: saved with extras. + */ + @Optional + @OutputDirectory + DirectoryProperty getSaveSourceOutput(); + + +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtDevModeOptions.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtDevModeOptions.java new file mode 100644 index 00000000..b1f52760 --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtDevModeOptions.java @@ -0,0 +1,104 @@ +package io.freefair.gradle.plugins.gwt; + +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.Optional; +import org.gradle.api.tasks.OutputDirectory; + +/** + * @author Lars Grefer + */ +public interface GwtDevModeOptions extends CommonGwtToolOptions { + + /** + * Starts a servlet container serving the directory specified by the -war flag. (defaults to ON) + */ + @Optional + @Input + Property getStartServer(); + + /** + * Specifies the TCP port for the embedded web server (defaults to 8888) + */ + @Optional + @Input + Property getPort(); + + /** + * Logs to a file in the given directory, as well as graphically + */ + @Optional + @OutputDirectory + DirectoryProperty getLogdir(); + + /** + * Debugging: causes normally-transient generated types to be saved in the specified directory + */ + @Optional + @OutputDirectory + DirectoryProperty getGen(); + + /** + * Specifies the bind address for the code server and web server (defaults to 127.0.0.1) + */ + @Optional + @Input + Property getBindAddress(); + + /** + * Specifies the TCP port for the code server (defaults to 9997 for classic Dev Mode or 9876 for Super Dev Mode) + */ + @Optional + @Input + Property getCodeServerPort(); + + /** + * Runs Super Dev Mode instead of classic Development Mode. (defaults to ON) + */ + @Optional + @Input + Property getSuperDevMode(); + + /** + * Specify a different embedded web server to run (must implement ServletContainerLauncher) + */ + @Optional + @Input + Property getServer(); + + /** + * Automatically launches the specified URL + */ + @Optional + @Input + Property getStartupUrl(); + + /** + * The directory into which deployable output files will be written (defaults to 'war') + */ + @OutputDirectory + DirectoryProperty getWar(); + + /** + * The directory into which deployable but not servable output files will be written (defaults to 'WEB-INF/deploy' under the -war directory/jar, and may be the same as the -extra directory/jar) + */ + @Optional + @OutputDirectory + DirectoryProperty getDeploy(); + + /** + * The directory into which extra files, not intended for deployment, will be written + */ + @Optional + @OutputDirectory + DirectoryProperty getExtra(); + + /** + * The subdirectory inside the war dir where DevMode will create module directories. (defaults empty for top level) + */ + @Optional + @Input + Property getModulePathPrefix(); + +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtExtension.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtExtension.java new file mode 100644 index 00000000..b0b2b396 --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtExtension.java @@ -0,0 +1,18 @@ +package io.freefair.gradle.plugins.gwt; + +import org.gradle.api.provider.ListProperty; +import org.gradle.api.provider.Property; + +/** + * @author Lars Grefer + */ +public abstract class GwtExtension { + + public abstract Property getToolVersion(); + + public abstract ListProperty getModules(); + + public GwtExtension() { + getToolVersion().convention("2.12.1"); + } +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtPlugin.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtPlugin.java new file mode 100644 index 00000000..1f0c736d --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtPlugin.java @@ -0,0 +1,21 @@ +package io.freefair.gradle.plugins.gwt; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.WarPlugin; + +/** + * @author Lars Grefer + */ +public class GwtPlugin implements Plugin { + + @Override + public void apply(Project project) { + project.getPlugins().apply(GwtBasePlugin.class); + + project.getPlugins().withType(WarPlugin.class, warPlugin -> { + project.getPlugins().apply(GwtWarPlugin.class); + }); + + } +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtWarPlugin.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtWarPlugin.java new file mode 100644 index 00000000..ef17a95f --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtWarPlugin.java @@ -0,0 +1,34 @@ +package io.freefair.gradle.plugins.gwt; + +import io.freefair.gradle.plugins.gwt.tasks.GwtCompileTask; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.WarPlugin; +import org.gradle.api.tasks.TaskProvider; +import org.gradle.api.tasks.bundling.War; + +/** + * @author Lars Grefer + */ +public class GwtWarPlugin implements Plugin { + + @Override + public void apply(Project project) { + + project.getPlugins().apply(WarPlugin.class); + project.getPlugins().apply(GwtBasePlugin.class); + + TaskProvider warTask = project.getTasks().named(WarPlugin.WAR_TASK_NAME, War.class); + TaskProvider gwtCompile = project.getTasks().named("gwtCompile", GwtCompileTask.class); + + warTask.configure(war -> { + war.from(gwtCompile.flatMap(GwtCompileOptions::getWar)); + }); + + gwtCompile.configure(task -> { + task.getDeploy().unsetConvention(); + task.getDeploy().unset(); + }); + + } +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtWebJarPlugin.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtWebJarPlugin.java new file mode 100644 index 00000000..c194c113 --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/GwtWebJarPlugin.java @@ -0,0 +1,35 @@ +package io.freefair.gradle.plugins.gwt; + +import io.freefair.gradle.plugins.gwt.tasks.GwtCompileTask; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.tasks.TaskProvider; +import org.gradle.language.jvm.tasks.ProcessResources; + +/** + * @author Lars Grefer + */ +public class GwtWebJarPlugin implements Plugin { + + @Override + public void apply(Project project) { + + project.getPlugins().apply(GwtBasePlugin.class); + + TaskProvider gwtCompile = project.getTasks().named("gwtCompile", GwtCompileTask.class); + + project.getTasks() + .named(JavaPlugin.PROCESS_RESOURCES_TASK_NAME, ProcessResources.class) + .configure(processResources -> { + processResources.into("META-INF/resources", resources -> { + resources.from(gwtCompile.flatMap(GwtCompileOptions::getWar)); + }); + + processResources.into("deploy", resources -> { + resources.from(gwtCompile.flatMap(GwtCompileOptions::getDeploy)); + }); + }); + + } +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/AbstractGwtTask.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/AbstractGwtTask.java new file mode 100644 index 00000000..af5ec9e0 --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/AbstractGwtTask.java @@ -0,0 +1,88 @@ +package io.freefair.gradle.plugins.gwt.tasks; + +import io.freefair.gradle.plugins.gwt.CommonGwtToolOptions; +import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.provider.ListProperty; +import org.gradle.api.provider.MapProperty; +import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.Classpath; +import org.gradle.api.tasks.InputFiles; +import org.gradle.api.tasks.JavaExec; + +import java.util.Collection; + +/** + * @author Lars Grefer + */ +public abstract class AbstractGwtTask extends JavaExec implements CommonGwtToolOptions { + + @InputFiles + @Classpath + public abstract ConfigurableFileCollection getGwtClasspath(); + + public AbstractGwtTask() { + classpath(getGwtClasspath()); + } + + @Override + public void exec() { + args(getModule().get()); + super.exec(); + } + + + static void addStringArg(Collection args, String argName, DirectoryProperty property) { + + if (property.isPresent()) { + args.add("-" + argName); + args.add(property.get().getAsFile().getAbsolutePath()); + } + } + + static void addMapArg(Collection args, String argName, MapProperty property) { + + if (property.isPresent()) { + property.get().forEach((key, value) -> { + args.add("-" + argName); + args.add(key + "=" + value); + }); + } + } + + static void addListArg(Collection args, String argName, ListProperty property) { + + if (property.isPresent()) { + property.get().forEach(key -> { + args.add("-" + argName); + args.add(key); + }); + } + } + + static void addStringArg(Collection args, String argName, Provider property) { + + if (property.isPresent()) { + args.add("-" + argName); + args.add(property.get().toString()); + } + } + + static void addBooleanArg(Collection args, String argName, Provider property) { + + if (property.isPresent()) { + if (property.get()) { + args.add("-" + argName); + } + else { + if (argName.startsWith("X")) { + args.add("-Xno" + argName.substring(1)); + } + else { + args.add("-no" + argName); + } + } + + } + } +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtCodeServerTask.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtCodeServerTask.java new file mode 100644 index 00000000..91b294ed --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtCodeServerTask.java @@ -0,0 +1,53 @@ +package io.freefair.gradle.plugins.gwt.tasks; + +import io.freefair.gradle.plugins.gwt.GwtCodeServerOptions; +import org.gradle.process.CommandLineArgumentProvider; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Lars Grefer + */ +public abstract class GwtCodeServerTask extends AbstractGwtTask implements GwtCodeServerOptions { + + public GwtCodeServerTask() { + this.getOutputs().upToDateWhen(task -> false); + getMainClass().set("com.google.gwt.dev.codeserver.CodeServer"); + + getArgumentProviders().add(new ArgProvider()); + } + + + class ArgProvider implements CommandLineArgumentProvider { + + @Override + public Iterable asArguments() { + List args = new ArrayList<>(); + + addBooleanArg(args, "allowMissingSrc", getAllowMissingSrc()); + addBooleanArg(args, "compileTest", getCompileTest()); + addStringArg(args, "compileTestRecompiles", getCompileTestRecompiles()); + addBooleanArg(args, "failOnError", getFailOnError()); + addBooleanArg(args, "precompile", getPrecompile()); + addStringArg(args, "port", getPort()); + addStringArg(args, "src", getSrc()); + addStringArg(args, "workDir", getWorkDir()); + addStringArg(args, "launcherDir", getLauncherDir()); + addStringArg(args, "bindAddress", getBindAddress()); + addStringArg(args, "style", getStyle()); + addMapArg(args, "setProperty", getSetProperty()); + addBooleanArg(args, "incremental", getIncremental()); + addStringArg(args, "sourceLevel", getSourceLevel()); + addStringArg(args, "logLevel", getLogLevel()); + addBooleanArg(args, "generateJsInteropExports", getGenerateJsInteropExports()); + addListArg(args, "includeJsInteropExports", getIncludeJsInteropExports()); + addListArg(args, "excludeJsInteropExports", getExcludeJsInteropExports()); + addStringArg(args, "XmethodNameDisplayMode", getXmethodNameDisplayMode()); + addBooleanArg(args, "XclosureFormattedOutput", getXclosureFormattedOutput()); + + return args; + } + } + +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtCompileTask.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtCompileTask.java new file mode 100644 index 00000000..2a147175 --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtCompileTask.java @@ -0,0 +1,60 @@ +package io.freefair.gradle.plugins.gwt.tasks; + +import io.freefair.gradle.plugins.gwt.GwtCompileOptions; +import org.gradle.api.tasks.CacheableTask; +import org.gradle.process.CommandLineArgumentProvider; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Lars Grefer + */ +@CacheableTask +public abstract class GwtCompileTask extends AbstractGwtTask implements GwtCompileOptions { + + public GwtCompileTask() { + getMainClass().set("com.google.gwt.dev.Compiler"); + + getArgumentProviders().add(new ArgumentProvider()); + } + + class ArgumentProvider implements CommandLineArgumentProvider { + @Override + public Iterable asArguments() { + List args = new ArrayList<>(); + + + addStringArg(args, "logLevel", getLogLevel()); + addStringArg(args, "workDir", getWorkDir()); + addBooleanArg(args, "XclosureFormattedOutput", getXClosureFormattedOutput()); + addBooleanArg(args, "compileReport", getCompileReport()); + addBooleanArg(args, "XcheckCasts", getXcheckCasts()); + addBooleanArg(args, "XclassMetadata", getXclassMetadata()); + addBooleanArg(args, "draftCompile", getDraftCompile()); + addBooleanArg(args, "checkAssertions", getCheckAssertions()); + addStringArg(args, "XfragmentCount", getXfragmentCount()); + addStringArg(args, "gen", getGen()); + addBooleanArg(args, "generateJsInteropExports", getGenerateJsInteropExports()); + addListArg(args, "includeJsInteropExports", getIncludeJsInteropExports()); + addListArg(args, "excludeJsInteropExports", getExcludeJsInteropExports()); + addStringArg(args, "XmethodNameDisplayMode", getXmethodNameDisplayMode()); + addStringArg(args, "Xnamespace", getXnamespace()); + addStringArg(args, "optimize", getOptimize()); + addStringArg(args, "saveSource", getSaveSource()); + addMapArg(args, "setProperty", getSetProperty()); + addStringArg(args, "style", getStyle()); + addBooleanArg(args, "failOnError", getFailOnError()); + addBooleanArg(args, "validateOnly", getValidateOnly()); + addStringArg(args, "sourceLevel", getSourceLevel()); + addStringArg(args, "localWorkers", getLocalWorkers()); + addBooleanArg(args, "incremental", getIncremental()); + addStringArg(args, "war", getWar()); + addStringArg(args, "deploy", getDeploy()); + addStringArg(args, "extra", getExtra()); + addStringArg(args, "saveSourceOutput", getSaveSourceOutput()); + + return args; + } + } +} diff --git a/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtDevModeTask.java b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtDevModeTask.java new file mode 100644 index 00000000..86f29df0 --- /dev/null +++ b/gwt-plugin/src/main/java/io/freefair/gradle/plugins/gwt/tasks/GwtDevModeTask.java @@ -0,0 +1,54 @@ +package io.freefair.gradle.plugins.gwt.tasks; + +import io.freefair.gradle.plugins.gwt.GwtDevModeOptions; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Lars Grefer + */ +public abstract class GwtDevModeTask extends AbstractGwtTask implements GwtDevModeOptions { + + public GwtDevModeTask() { + this.getOutputs().upToDateWhen(task -> false); + + getMainClass().convention("com.google.gwt.dev.DevMode"); + + getArgumentProviders().add(new ArgumentProvider()); + } + + class ArgumentProvider implements org.gradle.process.CommandLineArgumentProvider { + @Override + public Iterable asArguments() { + List args = new ArrayList<>(); + + addBooleanArg(args, "startServer", getStartServer()); + addStringArg(args, "port", getPort()); + addStringArg(args, "logdir", getLogdir()); + addStringArg(args, "logLevel", getLogLevel()); + addStringArg(args, "gen", getGen()); + addStringArg(args, "bindAddress", getBindAddress()); + addStringArg(args, "codeServerPort", getCodeServerPort()); + addBooleanArg(args, "superDevMode", getSuperDevMode()); + addStringArg(args, "server", getServer()); + addStringArg(args, "startupUrl", getStartupUrl()); + addStringArg(args, "war", getWar()); + addStringArg(args, "deploy", getDeploy()); + addStringArg(args, "extra", getExtra()); + addStringArg(args, "modulePathPrefix", getModulePathPrefix()); + addStringArg(args, "workDir", getWorkDir()); + addStringArg(args, "XmethodNameDisplayMode", getXmethodNameDisplayMode()); + addStringArg(args, "sourceLevel", getSourceLevel()); + addBooleanArg(args, "generateJsInteropExports", getGenerateJsInteropExports()); + addListArg(args, "includeJsInteropExports", getIncludeJsInteropExports()); + addListArg(args, "excludeJsInteropExports", getExcludeJsInteropExports()); + addBooleanArg(args, "incremental", getIncremental()); + addStringArg(args, "style", getStyle()); + addBooleanArg(args, "failOnError", getFailOnError()); + addMapArg(args, "setProperty", getSetProperty()); + + return args; + } + } +} diff --git a/settings.gradle b/settings.gradle index 14f5f675..22c95eb6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -61,6 +61,7 @@ include "git-plugin" include "mkdocs-plugin" include "quicktype-plugin" include "plantuml-plugin" +include "gwt-plugin" include "mjml-plugin"