diff --git a/README.md b/README.md index d6c11227..ce0fdadc 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Add the following `plugin` tag to your `pom.xml`: io.github.fvarrui javapackager - 1.7.0-SNAPSHOT + 1.7.0 package @@ -88,15 +88,17 @@ apply plugin: 'io.github.fvarrui.javapackager.plugin' Create your packaging task: ```groovy -task packageMyApp(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - // mandatory - mainClass = 'path.to.your.mainClass' - // optional - bundleJre = true|false - generateInstaller = true|false - administratorRequired = true|false - platform = auto|linux|mac|windows - additionalResources = [ file('file path'), file('folder path'), ... ] +task packageMyApp(type: io.github.fvarrui.javapackager.GradlePackageTask, dependsOn: build) { + javapackager{ + // mandatory + mainClass = 'path.to.your.mainClass' + // optional + bundleJre = true|false + generateInstaller = true|false + administratorRequired = true|false + platform = auto|linux|mac|windows + additionalResources = [ file('file path'), file('folder path'), ... ] + } linuxConfig { ... } @@ -106,6 +108,12 @@ task packageMyApp(type: io.github.fvarrui.javapackager.gradle.PackageTask, depen winConfig { ... } + manifest { + .... + } + scripts { + ... + } ... } ``` @@ -118,6 +126,10 @@ And execute the next command in project's root folder: gradle packageMyApp ``` +### Package your app via CI + +- **GitHub:** You can find an example workflow file [here](https://github.com/fvarrui/JavaPackager/blob/pr-248/test/hello-world-maven/.github/workflows/package.yml). + ### Generated artifacts By default it will generate next artifacts in `${outputDirectory} ` folder: @@ -161,8 +173,12 @@ By default it will generate next artifacts in `${outputDirectory} ` folder: | `extra` | :x: | | Map with extra properties to be used in customized Velocity templates, accesible through `$info.extra` variable. | | `fileAssociations` | :x: | [`FileAssociation[]`](https://github.com/fvarrui/JavaPackager/blob/master/src/main/java/io/github/fvarrui/javapackager/model/FileAssociation.java) | Associate file extensions or MIME types to the app. | | `forceInstaller` | :x: | `false` | If `true`, skips operating system check when generating installers. | +| `nativeImage` | :x: | `false` | If `true`, generates a native image for the current operating system. Note that `jdkVendor` must be set to `graalvm` for this to work. | +| `sharedLibrary` | :x: | `false` | If `true`, generates a shared library for the current operating system. Note that `jdkVendor` must be set to `graalvm` for this to work. | | `generateInstaller` | :x: | `true` | Generates an installer for the app. | -| `jdkPath` | :x: | `${java.home}` | JDK used to generate a customized JRE. It allows to bundle customized JREs for different platforms. | +| `jdkVersion` | :x: | `latest` | JDK version to download and use. The latest version is used by default. See all available versions here: [adoptium](https://api.adoptium.net/v3/info/available_releases). | +| `jdkVendor` | :x: | `graalvm` | JDK vendor to download the JDK from. Currently supported: `adoptium, graalvm` | +| `jdkPath` | :x: | `null` | If null downloads (if necessary and also updates it if needed) the right JDK for the selected platform and sets this value to `/jdk/win` or `/jdk/linux` or `/jdk/mac`. The downloaded JDK will be used to generate a customized JRE. | | `jreDirectoryName` | :x: | `"jre"` | Bundled JRE directory name. | | `jreMinVersion` | :x: | | JRE minimum version. If an appropriate version cannot be found display error message. Disabled if a JRE is bundled. | | `jrePath` | :x: | `""` | Path to JRE folder. If specified, it will bundle this JRE with the app, and won't generate a customized JRE. For Java 8 version or least. | @@ -170,12 +186,12 @@ By default it will generate next artifacts in `${outputDirectory} ` folder: | `mainClass` | :heavy_check_mark: | `${exec.mainClass}` | Full path to your app main class. | | `manifest` | :x: | | [Allows adding additional entries to MANIFEST.MF file.](docs/manifest.md) | | `modules` | :x: | `[]` | Modules to customize the bundled JRE. Don't use `jdeps` to get module dependencies. | -| `name` | :x: | `${project.name}` or `${project.artifactId}` | App name. | +| `appName` | :x: | `${project.name}` or `${project.artifactId}` | App name. | | `organizationName` | :x: | `${project.organization.name}` or `"ACME"` | Organization name. | | `organizationUrl` | :x: | `${project.organization.url}` | Organization website URL. | | `organizationEmail` | :x: | | Organization email. | | `outputDirectory` | :x: | `${project.build.directory}` or `${project.builddir}` | Output directory (where the artifacts will be generated). | -| `packagingJdk` | :x: | `${java.home}` | JDK used in the execution of `jlink` and other JDK tools. | +| `packagingJdk` | :x: | `null` or same as `jdkPath` | JDK used in the execution of `jlink` and other JDK tools. If null `jdkPath` will be used. | | `platform` | :x: | `auto` | Defines the target platform, which could be different to the execution platform. Possible values: `auto`, `mac`, `linux`, `windows`. Use `auto` for using execution platform as target. | | `runnableJar` | :x: | | Defines your own JAR file to be bundled. If it's ommited, the plugin packages your code in a runnable JAR and bundle it with the app. | | `scripts` | :x: | | Specify bootstrap script. **Pre and post-install scripts comming soon!** | diff --git a/build.gradle b/build.gradle index e5657191..15b40c72 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { repositories { mavenLocal() mavenCentral() - maven { + maven { url 'https://plugins.gradle.org/m2/' } } @@ -55,13 +55,18 @@ dependencies { implementation 'net.jsign:jsign-core:3.1' implementation 'org.redline-rpm:redline:1.2.10' implementation 'io.github.fvarrui:launch4j:2.5.2' + implementation 'com.google.code.gson:gson:2.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.10.0' + implementation 'org.rauschig:jarchivelib:1.2.0' + implementation 'com.squareup:javapoet:1.13.0' - testImplementation 'junit:junit:4.13.1' + testImplementation 'org.junit.jupiter:junit-jupiter:5.9.0' + testImplementation 'org.apache.maven.shared:maven-invoker:3.2.0' compileOnly 'org.apache.maven.plugin-tools:maven-plugin-annotations:3.6.0' mavenEmbedder 'org.apache.maven:maven-embedder:3.6.0' - mavenEmbedder 'org.apache.maven:maven-compat:3.6.0' + mavenEmbedder 'org.apache.maven:maven-compat:3.6.0' mavenEmbedder 'org.slf4j:slf4j-simple:1.7.30' mavenEmbedder 'org.eclipse.aether:aether-connector-basic:1.1.0' mavenEmbedder 'org.eclipse.aether:aether-transport-wagon:1.1.0' @@ -69,8 +74,12 @@ dependencies { mavenEmbedder 'org.apache.maven.wagon:wagon-provider-api:3.4.1' } +test { + useJUnitPlatform() +} + group = 'io.github.fvarrui' -version = '1.7.0-SNAPSHOT' +version = '1.7.0' description = 'Hybrid Maven/Gradle plugin to package Java applications as native Windows, Mac OS X or GNU/Linux executables and create installers for them' sourceCompatibility = JavaVersion.VERSION_1_8 @@ -88,7 +97,7 @@ publishing { java { withSourcesJar() - // and/or analogously use “withJavadocJar()� to get a “javadocJar� task + // and/or analogously use "withJavadocJar()" to get a "javadocJar" task } install.repositories.mavenInstaller.pom.with { diff --git a/docs/gradle/plugin-configuration-samples.md b/docs/gradle/plugin-configuration-samples.md index 65aa30c8..795cc1bd 100644 --- a/docs/gradle/plugin-configuration-samples.md +++ b/docs/gradle/plugin-configuration-samples.md @@ -9,8 +9,10 @@ Add next task to your `build.gradle` file: ```groovy -task packageMyApp(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - mainClass = 'fvarrui.sample.Main' +task packageMyApp(type: io.github.fvarrui.javapackager.GradlePackageTask, dependsOn: build) { + javapackager{ + mainClass = 'fvarrui.sample.Main' + } } ``` @@ -30,9 +32,11 @@ And run `gradle package`. ## Bundle with a customized JRE ```groovy -task packageMyApp(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - mainClass = 'fvarrui.sample.Main' - bundleJre = true +task packageMyApp(type: io.github.fvarrui.javapackager.GradlePackageTask, dependsOn: build) { + javapackager{ + mainClass = 'fvarrui.sample.Main' + bundleJre = true + } } ``` @@ -41,31 +45,37 @@ task packageMyApp(type: io.github.fvarrui.javapackager.gradle.PackageTask, depen ## Bundle with a full JRE ```groovy -task packageMyApp(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - mainClass = 'fvarrui.sample.Main' - bundleJre = true - customizedJre = false +task packageMyApp(type: io.github.fvarrui.javapackager.GradlePackageTask, dependsOn: build) { + javapackager{ + mainClass = 'fvarrui.sample.Main' + bundleJre = true + customizedJre = false + } } ``` ## Bundle with an existing JRE ```groovy -task packageMyApp(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - mainClass = 'fvarrui.sample.Main' - bundleJre = true - jrePath = file('C:\Program Files\Java\jre1.8.0_231') +task packageMyApp(type: io.github.fvarrui.javapackager.GradlePackageTask, dependsOn: build) { + javapackager{ + mainClass = 'fvarrui.sample.Main' + bundleJre = true + jrePath = file('C:\Program Files\Java\jre1.8.0_231') + } } ``` ## Bundle your own fat JAR ```groovy -task packageMyApp(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - mainClass = 'fvarrui.sample.Main' - bundleJre = true - runnableJar = file('path/to/your/own/fat.jar') - copyDependencies = false +task packageMyApp(type: io.github.fvarrui.javapackager.GradlePackageTask, dependsOn: build) { + javapackager{ + mainClass = 'fvarrui.sample.Main' + bundleJre = true + runnableJar = file('path/to/your/own/fat.jar') + copyDependencies = false + } } ``` @@ -76,13 +86,17 @@ javapackager { // common configuration mainClass = 'fvarrui.sample.Main' } -task packageMyAppWithJRE(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - name = 'Sample' - bundleJre = true +task packageMyAppWithJRE(type: io.github.fvarrui.javapackager.GradlePackageTask, dependsOn: build) { + javapackager{ + name = 'Sample' + bundleJre = true + } } -task packageMyAppWithoutJRE(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - name = 'Sample-nojre' - bundleJre = false +task packageMyAppWithoutJRE(type: io.github.fvarrui.javapackager.GradlePackageTask, dependsOn: build) { + javapackager{ + name = 'Sample-nojre' + bundleJre = false + } } task packageMyApp(dependsOn: [ 'packageMyAppWithJRE', 'packageMyAppWithoutJRE' ]) ``` @@ -100,19 +114,23 @@ javapackager { bundleJre = true generateInstaller = false } -task packageMyAppForLinux(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - platform = linux - createTarball = true - jdkPath = file('X:\\path\to\linux\jdk') +task packageMyAppForLinux(type: io.github.fvarrui.javapackager.GradlePackageTask, dependsOn: build) { + javapackager{ + platform = linux + createTarball = true + } } -task packageMyAppForMac(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - platform = mac - createTarball = true - jdkPath = file('X:\\path\to\mac\jdk') +task packageMyAppForMac(type: io.github.fvarrui.javapackager.GradlePackageTask, dependsOn: build) { + javapackager{ + platform = mac + createTarball = true + } } -task packageMyAppForWindows(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - platform = windows - createZipball = true +task packageMyAppForWindows(type: io.github.fvarrui.javapackager.GradlePackageTask, dependsOn: build) { + javapackager{ + platform = windows + createZipball = true + } } task packageMyApp(dependsOn: [ 'packageMyAppForLinux', 'packageMyAppForMac', 'packageMyAppForWindows' ]) ``` @@ -121,6 +139,4 @@ E.g. on Windows, running `packageMyApp` task will generate next artifacts: * `${name}_${version}-linux.tar.gz` with the GNU/Linux application including a customized JRE. * `${name}_${version}-mac.tar.gz` with the Mac OS X application including a customized JRE. -* `${name}_${version}-windows.zip` with the Windows application including a customized JRE. - -As last sample is running on Windows, it's not necessary to specify a JDK when bundling for Windows (it uses current JDK by default). Otherwise, if running on GNU/Linux or Mac OS X, you have to specify a JDK for Windows. +* `${name}_${version}-windows.zip` with the Windows application including a customized JRE. \ No newline at end of file diff --git a/docs/maven/plugin-configuration-samples.md b/docs/maven/plugin-configuration-samples.md index fc4a1cfd..066df976 100644 --- a/docs/maven/plugin-configuration-samples.md +++ b/docs/maven/plugin-configuration-samples.md @@ -199,7 +199,6 @@ E.g. on Windows, last configuration will generate next artifacts: linux true - X:\\path\to\linux\jdk @@ -211,7 +210,6 @@ E.g. on Windows, last configuration will generate next artifacts: mac true - X:\\path\to\mac\jdk @@ -222,6 +220,4 @@ E.g. on Windows, last configuration will generate next artifacts: * `${name}_${version}-linux.tar.gz` with the GNU/Linux application including a customized JRE. * `${name}_${version}-mac.tar.gz` with the Mac OS X application including a customized JRE. -* `${name}_${version}-windows.zip` with the Windows application including a customized JRE. - -As last sample is running on Windows, it's not necessary to specify a JDK when bundling for Windows (it uses current JDK by default). Otherwise, if running on GNU/Linux or Mac OS X, you have to specify a JDK for Windows. \ No newline at end of file +* `${name}_${version}-windows.zip` with the Windows application including a customized JRE. \ No newline at end of file diff --git a/src/it/settings.xml b/src/it/settings.xml deleted file mode 100644 index 66c9e25d..00000000 --- a/src/it/settings.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - it-repo - - true - - - - local.central - @localRepositoryUrl@ - - true - - - true - - - - - - local.central - @localRepositoryUrl@ - - true - - - true - - - - - - diff --git a/src/it/simple-it/pom.xml b/src/it/simple-it/pom.xml deleted file mode 100644 index 0057fbd3..00000000 --- a/src/it/simple-it/pom.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - 4.0.0 - - fvarrui.maven.it - simple-it - 1.0-SNAPSHOT - - A simple IT verifying the basic use case. - - - UTF-8 - - - - - - @project.groupId@ - @project.artifactId@ - @project.version@ - - - touch - validate - - touch - - - - - - - diff --git a/src/it/simple-it/verify.groovy b/src/it/simple-it/verify.groovy deleted file mode 100644 index 7b307c78..00000000 --- a/src/it/simple-it/verify.groovy +++ /dev/null @@ -1,3 +0,0 @@ -File touchFile = new File( basedir, "target/touch.txt" ); - -assert touchFile.isFile() diff --git a/src/main/java/io/github/fvarrui/javapackager/GradlePackageTask.java b/src/main/java/io/github/fvarrui/javapackager/GradlePackageTask.java new file mode 100644 index 00000000..bed65d56 --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/GradlePackageTask.java @@ -0,0 +1,111 @@ +package io.github.fvarrui.javapackager; + +import groovy.lang.Closure; +import io.github.fvarrui.javapackager.gradle.GradleContext; +import io.github.fvarrui.javapackager.gradle.PackagePlugin; +import io.github.fvarrui.javapackager.model.*; +import io.github.fvarrui.javapackager.packagers.Context; +import io.github.fvarrui.javapackager.packagers.Packager; +import io.github.fvarrui.javapackager.packagers.PackagerFactory; +import org.gradle.api.DefaultTask; +import org.gradle.api.Project; +import org.gradle.api.tasks.OutputFiles; +import org.gradle.api.tasks.TaskAction; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class GradlePackageTask extends DefaultTask implements PackagerFactory { + private final Project gradleProject = Context.getGradleContext().getProject(); + /** + * This is the global javapackager extension instance.
+ * Sadly we need to do it like this because + * we cannot extend {@link PackageTask} because we already + * extend another class. This means that this task + * has no properties, instead we use this extensions properties. + * + * @see PackagePlugin + */ + public PackageTask extension; + private List outputFiles; + + public GradlePackageTask() { + setGroup(PackagePlugin.GROUP_NAME); + setDescription("Packages the application as a native Windows, Mac OS X or GNU/Linux executable and creates an installer"); + getOutputs().upToDateWhen(o -> false); + updateExtension(PackagePlugin.GLOBAL_EXTENSION); + } + + public void updateExtension(PackageTask extension) { + this.extension = extension; + // Defaults specific to gradle + this.extension.outputDirectory = gradleProject.getBuildDir(); + this.extension.description = gradleProject.getDescription(); + this.extension.appName = gradleProject.getName(); + this.extension.appDisplayName = gradleProject.getName(); + this.extension.version = gradleProject.getVersion().toString(); + this.extension.description = gradleProject.getDescription(); + this.extension.organizationName = null; + this.extension.organizationUrl = null; + this.extension.assetsDir = new File(gradleProject.getProjectDir(), "assets"); + } + + @OutputFiles + public List getOutputFiles() { + return outputFiles != null ? outputFiles : new ArrayList<>(); + } + + /** + * Packaging task action + * + * @throws Exception Throwed if something went wrong + */ + @TaskAction + public void doPackage() throws Exception { + + Packager packager = this.createPackager(extension); + // generates app, installers and bundles + File app = packager.createApp(); + List installers = packager.generateInstallers(); + List bundles = packager.createBundles(); + + // sets generated files as output + outputFiles = new ArrayList<>(); + outputFiles.add(app); + outputFiles.addAll(installers); + outputFiles.addAll(bundles); + + } + + public LinuxConfig linuxConfig(Closure closure) { + extension.linuxConfig = new LinuxConfig(); + GradleContext.getGradleContext().getProject().configure(extension.linuxConfig, closure); + return extension.linuxConfig; + } + + public MacConfig macConfig(Closure closure) { + extension.macConfig = new MacConfig(); + gradleProject.configure(extension.macConfig, closure); + return extension.macConfig; + } + + public WindowsConfig winConfig(Closure closure) { + extension.winConfig = new WindowsConfig(); + gradleProject.configure(extension.winConfig, closure); + return extension.winConfig; + } + + public Manifest manifest(Closure closure) { + extension.manifest = new Manifest(); + gradleProject.configure(extension.manifest, closure); + return extension.manifest; + } + + public Scripts scripts(Closure closure) { + extension.scripts = new Scripts(); + gradleProject.configure(extension.scripts, closure); + return extension.scripts; + } + +} diff --git a/src/main/java/io/github/fvarrui/javapackager/MavenPackageTask.java b/src/main/java/io/github/fvarrui/javapackager/MavenPackageTask.java new file mode 100644 index 00000000..40cc5e04 --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/MavenPackageTask.java @@ -0,0 +1,77 @@ +package io.github.fvarrui.javapackager; + +import io.github.fvarrui.javapackager.maven.MavenContext; +import io.github.fvarrui.javapackager.packagers.Context; +import io.github.fvarrui.javapackager.packagers.Packager; +import io.github.fvarrui.javapackager.packagers.PackagerFactory; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.*; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.plugin.logging.SystemStreamLog; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; + +import java.io.IOException; +import java.util.Map; + +import static org.twdata.maven.mojoexecutor.MojoExecutor.executionEnvironment; + +@org.apache.maven.plugins.annotations.Mojo(name = "package", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME) +public class MavenPackageTask extends PackageTask implements Mojo, ContextEnabled, PackagerFactory { + @Parameter(defaultValue = "${project}", readonly = true) + private MavenProject mavenProject; + @Parameter(defaultValue = "${session}", readonly = true) + private MavenSession mavenSession; + @Component + private BuildPluginManager pluginManager; + + private Log log; + private Map pluginContext; + + public MavenPackageTask() throws IOException { + } + + @Override + public void execute() throws MojoExecutionException, MojoFailureException { + Context.setContext( + new MavenContext( + executionEnvironment(mavenProject, mavenSession, pluginManager), + getLog() + ) + ); + try { + Packager packager = this.createPackager(this); + // generate app, installers and bundles + packager.createApp(); + packager.generateInstallers(); + packager.createBundles(); + } catch (Exception e) { + throw new MojoExecutionException(e.getMessage(), e); + } + } + + public Log getLog() { + if (this.log == null) { + this.log = new SystemStreamLog(); + } + + return this.log; + } + + public void setLog(Log log) { + this.log = log; + } + + public Map getPluginContext() { + return this.pluginContext; + } + + public void setPluginContext(Map pluginContext) { + this.pluginContext = pluginContext; + } + + +} diff --git a/src/main/java/io/github/fvarrui/javapackager/PackageTask.java b/src/main/java/io/github/fvarrui/javapackager/PackageTask.java new file mode 100644 index 00000000..39793e35 --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/PackageTask.java @@ -0,0 +1,1380 @@ +package io.github.fvarrui.javapackager; + +import io.github.fvarrui.javapackager.model.*; +import io.github.fvarrui.javapackager.packagers.PackagerFactory; +import io.github.fvarrui.javapackager.utils.Const; +import io.github.fvarrui.javapackager.utils.updater.AdoptV3API; +import org.apache.commons.lang3.StringUtils; +import org.apache.maven.plugins.annotations.Parameter; +import org.gradle.api.tasks.*; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Package task that gets detected by maven and gradle. + */ +public class PackageTask { + /** + * Output directory. + */ + @Parameter(property = "outputDirectory", defaultValue = "${project.build.directory}") + @OutputDirectory + @Optional + protected File outputDirectory; + /** + * Path to project license file. + */ + @Parameter(property = "licenseFile") + @InputFile + @Optional + protected File licenseFile; + /** + * Path to the app icon file (PNG, ICO or ICNS). + */ + @Parameter(property = "iconFile") + @InputFile + @Optional + protected File iconFile; + /** + * Generates an installer for the app. + */ + @Parameter(property = "generateInstaller") + @Input + @Optional + protected Boolean generateInstaller; + /** + * Forces installer generation. + */ + @Parameter(property = "forceInstaller") + @Input + @Optional + protected Boolean forceInstaller; + /** + * If true generates a native-image. Note that {@link #jdkVendor} must be set to graalvm for this to work. + */ + @Parameter(property = "nativeImage") + @Input + @Optional + protected Boolean nativeImage; + /** + * If true generates a shared library. Note that {@link #jdkVendor} must be set to graalvm for this to work. + */ + @Parameter(property = "sharedLibrary") + @Input + @Optional + protected Boolean sharedLibrary; + /** + * Full path to your app main class. + */ + @Parameter(property = "mainClass", required = true, defaultValue = "${exec.mainClass}") + @Input + @Optional + protected String mainClass; + /** + * App name. + */ + @Parameter(property = "appName", defaultValue = "${project.name}") + @Input + @Optional + protected String appName; + /** + * App name to show. + */ + @Parameter(property = "appDisplayName", defaultValue = "${project.name}") + @Input + @Optional + protected String appDisplayName; + /** + * Project version. + */ + @Parameter(property = "version", defaultValue = "${project.version}") + @Input + @Optional + protected String version; + /** + * Project description. + */ + @Parameter(property = "description", defaultValue = "${project.description}") + @Input + @Optional + protected String description; + /** + * App website URL. + */ + @Parameter(property = "url", defaultValue = "${project.url}") + @Input + @Optional + protected String url; + /** + * App will run as administrator (with elevated privileges). + */ + @Parameter(property = "administratorRequired") + @Input + @Optional + protected Boolean administratorRequired; + /** + * Organization name. + */ + @Parameter(property = "organizationName", defaultValue = "${project.organization.name}") + @Input + @Optional + protected String organizationName; + /** + * Organization website URL. + */ + @Parameter(property = "organizationUrl", defaultValue = "${project.organization.url}") + @Input + @Optional + protected String organizationUrl; + /** + * Organization email. + */ + @Parameter(property = "organizationEmail", required = false) + @Input + @Optional + protected String organizationEmail; + /** + * Embeds a customized JRE with the app. + */ + @Parameter(property = "bundleJre", required = false) + @Input + @Optional + protected Boolean bundleJre; + /** + * Generates a customized JRE, including only identified or specified modules. Otherwise, all modules will be included. + */ + @Parameter(property = "customizedJre", required = false) + @Input + @Optional + protected Boolean customizedJre; + /** + * Path to JRE folder. If specified, it will bundle this JRE with the app, and won't generate a customized JRE. For Java 8 version or least. + */ + @Parameter(property = "jrePath", required = false) + @InputDirectory + @Optional + protected File jrePath; + /** + * Path to JDK folder. If specified, it will use this JDK modules to generate a customized JRE. Allows generating JREs for different platforms. + */ + @Parameter(property = "jdkPath", required = false) + @InputDirectory + @Optional + protected File jdkPath; + /** + * The JDK version. Supported versions differ from vendor to vendor, thus its recommended checking the vendors' website first before doing any changes. + */ + @Parameter(property = "jdkVersion", required = false) + @Input + @Optional + protected String jdkVersion = "8"; + /** + * The JDK vendor. + */ + @Parameter(property = "jdkVendor", required = false) + @Input + @Optional + protected String jdkVendor = "adoptium"; + /** + * Additional files and folders to include in the bundled app. + */ + @Parameter(property = "additionalResources", required = false) + @Input + @Optional + protected List additionalResources; + /** + * Defines modules to customize the bundled JRE. Don't use jdeps to get module dependencies. + */ + @Parameter(property = "modules", required = false) + @Input + @Optional + protected List modules; + /** + * Additional modules to the ones identified by jdeps or the specified with modules property. + */ + @Parameter(property = "additionalModules", required = false) + @Input + @Optional + protected List additionalModules; + /** + * Which platform to build, one of: + *
    + *
  • auto - automatically detect based on the host OS (the default)
  • + *
  • mac
  • + *
  • linux
  • + *
  • windows
  • + *
+ * To build for multiple platforms at once, add multiple executions to the plugin's configuration. + */ + @Parameter(property = "platform", required = true) + @Input + @Optional + protected Platform platform; + /** + * Defines PATH environment variable in GNU/Linux and Mac OS X startup scripts. + */ + @Parameter(property = "envPath", required = false) + @Input + @Optional + protected String envPath; + /** + * Additional arguments to provide to the JVM (for example -Xmx2G). + */ + @Parameter(property = "vmArgs", required = false) + @Input + @Optional + protected List vmArgs; + /** + * Provide your own runnable .jar (for example, a shaded .jar) instead of letting this plugin create one via + * the maven-jar-plugin. + */ + @Parameter(property = "runnableJar", required = false) + @InputFile + @Optional + protected File runnableJar; + /** + * Whether or not to copy dependencies into the bundle. Generally, you will only disable this if you specified + * a runnableJar with all dependencies shaded into the .jar itself. + */ + @Parameter(property = "copyDependencies", required = true) + @Input + @Optional + protected Boolean copyDependencies; + /** + * Bundled JRE directory name + */ + @Parameter(property = "jreDirectoryName", required = false) + @Input + @Optional + protected String jreDirectoryName; + /** + * Windows specific config + */ + @Parameter(property = "winConfig", required = false) + @Input + @Optional + protected WindowsConfig winConfig; + /** + * GNU/Linux specific config + */ + @Parameter(property = "linuxConfig", required = false) + @Input + @Optional + protected LinuxConfig linuxConfig; + /** + * Mac OS X specific config + */ + @Parameter(property = "macConfig", required = false) + @Input + @Optional + protected MacConfig macConfig; + /** + * Bundles app in a tarball file + */ + @Parameter(property = "createTarball", required = false) + @Input + @Optional + protected Boolean createTarball; + /** + * Bundles app in a zipball file + */ + @Parameter(property = "createZipball", required = false) + @Input + @Optional + protected Boolean createZipball; + /** + * Extra properties for customized Velocity templates, accesible through '$this.extra' map. + */ + @Parameter(required = false) + @Input + @Optional + protected Map extra; + /** + * Uses app resources folder as default working directory. + */ + @Parameter(property = "useResourcesAsWorkingDir", required = false) + @Input + @Optional + protected Boolean useResourcesAsWorkingDir; + /** + * Assets directory + */ + @Parameter(property = "assetsDir", defaultValue = "${project.basedir}/assets") + @InputDirectory + @Optional + protected File assetsDir; + /** + * Classpath + */ + @Parameter(property = "classpath", required = false) + @Input + @Optional + protected String classpath; + /** + * JRE min version + */ + @Parameter(property = "jreMinVersion", required = false) + @Input + @Optional + protected String jreMinVersion; + /** + * Additional JAR manifest entries + */ + @Parameter(required = false) + @Input + @Optional + protected Manifest manifest; + /** + * Additional module paths + */ + @Parameter(property = "additionalModulePaths", required = false) + @Input + @Optional + protected List additionalModulePaths; + /** + * Additional module paths + */ + @Parameter(property = "fileAssociations", required = false) + @Input + @Optional + protected List fileAssociations; + /** + * Packaging JDK + */ + @Parameter(property = "packagingJdk", required = false) + @InputDirectory + @Optional + protected File packagingJdk; + /** + * Scripts + */ + @Parameter(property = "scripts", required = false) + @Input + @Optional + protected Scripts scripts; + + public PackageTask() throws IOException { + //this.outputDirectory = (isGradle ? gradleProject.getBuildDir() : new File("${project.build.directory}")); + this.platform = Platform.getCurrentPlatform(); + this.bundleJre = true; + this.copyDependencies = true; + this.createTarball = false; + this.createZipball = false; + //this.description = gradleProject.getDescription(); // TODO maven? + this.generateInstaller = true; + this.linuxConfig = new LinuxConfig(); + this.macConfig = new MacConfig(); + this.manifest = new Manifest(); + this.modules = new ArrayList<>(); + this.forceInstaller = false; + this.nativeImage = false; + this.sharedLibrary = false; + this.mainClass = "${exec.mainClass}"; //TODO gradle? + //this.appName = (isGradle ? gradleProject.getName() : "${project.name}"); + //this.appDisplayName = (isGradle ? gradleProject.getName() : "${project.name}"); + //this.version = (isGradle ? (String) gradleProject.getVersion() : "${project.version}"); + //this.description = (isGradle ? gradleProject.getDescription(): "${project.description}"); + this.url = "${project.url}"; //TODO gradle? + this.administratorRequired = false; + //this.organizationName = (isGradle ? null : "${project.organization.name}"); + //this.organizationUrl = (isGradle ? null : "${project.organization.url}"); + this.organizationEmail = ""; + this.bundleJre = false; + this.customizedJre = true; + this.jrePath = null; + this.jdkPath = null; + this.jdkVersion = new AdoptV3API().getLatestRelease(); + this.jdkVendor = Const.graalvm; + this.additionalResources = new ArrayList<>(); + this.modules = new ArrayList<>(); + this.additionalModules = new ArrayList<>(); + this.envPath = null; + this.vmArgs = new ArrayList<>(); + this.runnableJar = null; + this.copyDependencies = true; + this.jreDirectoryName = "jre"; + this.winConfig = new WindowsConfig(); + this.linuxConfig = new LinuxConfig(); + this.macConfig = new MacConfig(); + this.createTarball = false; + this.createZipball = false; + this.extra = new HashMap<>(); + this.useResourcesAsWorkingDir = true; + //this.assetsDir = (isGradle ? new File(gradleProject.getProjectDir(), "assets") : new File("${project.basedir}/assets")); + this.classpath = null; + this.jreMinVersion = null; + this.manifest = new Manifest(); + this.additionalModulePaths = new ArrayList<>(); + this.fileAssociations = null; + this.packagingJdk = null; + scripts = new Scripts(); + } + + /** + * Get packaging JDK + * + * @return Packaging JDK + */ + public File getPackagingJdk() { + return packagingJdk; + } + + /** + * Get output directory + * + * @return Output directory + */ + public File getOutputDirectory() { + return outputDirectory; + } + + /** + * Get license file + * + * @return License file + */ + public File getLicenseFile() { + return licenseFile; + } + + /** + * Get icon file + * + * @return Icon file + */ + public File getIconFile() { + return iconFile; + } + + /** + * Get generate installer + * + * @return Generate installer + */ + public Boolean getGenerateInstaller() { + return generateInstaller; + } + + /** + * Get force installer + * + * @return Force installer + */ + public Boolean isForceInstaller() { + return forceInstaller; + } + + public Boolean isNativeImage() { + return nativeImage; + } + + public Boolean isSharedLibrary() { + return sharedLibrary; + } + + /** + * Get main class + * + * @return Main class + */ + public String getMainClass() { + return mainClass; + } + + /** + * Get app name + * + * @return App name + */ + public String getAppName() { + return appName; + } + + /** + * Get display name + * + * @return Display name + */ + public String getAppDisplayName() { + return appDisplayName; + } + + /** + * Get version + * + * @return Version + */ + public String getVersion() { + return version; + } + + /** + * Get description + * + * @return Description + */ + public String getDescription() { + return description; + } + + /** + * Get URL + * + * @return URL + */ + public String getUrl() { + return url; + } + + /** + * Get administrator required + * + * @return Administrator required + */ + public Boolean getAdministratorRequired() { + return administratorRequired; + } + + /** + * Get organization name + * + * @return Organization name + */ + public String getOrganizationName() { + return organizationName; + } + + /** + * Get organization URL + * + * @return Organization URL + */ + public String getOrganizationUrl() { + return organizationUrl; + } + + /** + * Get organization email + * + * @return Organization email + */ + public String getOrganizationEmail() { + return organizationEmail; + } + + /** + * Get bundle JRE + * + * @return Bundle JRE + */ + public Boolean getBundleJre() { + return bundleJre; + } + + /** + * Get customized JRE + * + * @return Customized JRE + */ + public Boolean getCustomizedJre() { + return customizedJre; + } + + /** + * Get JRE path + * + * @return JRE path + */ + public File getJrePath() { + return jrePath; + } + + /** + * Get JDK path + * + * @return JDK path + */ + public File getJdkPath() { + return jdkPath; + } + + /** + * Get JDK version + * + * @return JDK version + */ + public String getJdkVersion() { + return jdkVersion; + } + + /** + * Get JDK vendor + * + * @return JDK vendor + */ + public String getJdkVendor() { + return jdkVendor; + } + + /** + * Get additional resourcxes + * + * @return Additional resources + */ + public List getAdditionalResources() { + return additionalResources; + } + + /** + * Get Modules + * + * @return Modules + */ + public List getModules() { + return modules; + } + + /** + * Get additional modules + * + * @return Additional modules + */ + public List getAdditionalModules() { + return additionalModules; + } + + /** + * Get platform + * + * @return Platform + */ + public Platform getPlatform() { + return platform; + } + + /** + * Get env path + * + * @return Env path + */ + public String getEnvPath() { + return envPath; + } + + /** + * Get VM args + * + * @return VM args + */ + public List getVmArgs() { + return vmArgs; + } + + /** + * Get runnable JAR + * + * @return Runnable JAR + */ + public File getRunnableJar() { + return runnableJar; + } + + /** + * Get copy dependencies + * + * @return Copy dependencies + */ + public Boolean getCopyDependencies() { + return copyDependencies; + } + + /** + * Get JRE directory name + * + * @return JRE directory name + */ + public String getJreDirectoryName() { + return jreDirectoryName; + } + + /** + * Get Windows config + * + * @return Windows config + */ + public WindowsConfig getWinConfig() { + return winConfig; + } + + /** + * Get Linux config + * + * @return Linux config + */ + public LinuxConfig getLinuxConfig() { + return linuxConfig; + } + + /** + * Get Mac OS config + * + * @return Mac OS config + */ + public MacConfig getMacConfig() { + return macConfig; + } + + /** + * Get create tarball + * + * @return Create tarball + */ + public Boolean getCreateTarball() { + return createTarball; + } + + /** + * Get create zipball + * + * @return Create zipball + */ + public Boolean getCreateZipball() { + return createZipball; + } + + /** + * Get extra parameters + * + * @return Extra parameters + */ + public Map getExtra() { + return extra; + } + + /** + * Get if it has to use resources folder as working directory + * + * @return Use resources folder as working directory + */ + public Boolean isUseResourcesAsWorkingDir() { + return useResourcesAsWorkingDir; + } + + /** + * Get assets dir + * + * @return Assets dir + */ + public File getAssetsDir() { + return assetsDir; + } + + /** + * Get classpath + * + * @return Classpath + */ + public String getClasspath() { + return classpath; + } + + /** + * Get JRE min version + * + * @return JRE min version + */ + public String getJreMinVersion() { + return jreMinVersion; + } + + /** + * Get Manifest + * + * @return manifest + */ + public Manifest getManifest() { + return manifest; + } + + /** + * Get additional modules paths + * + * @return Additional module paths + */ + public List getAdditionalModulePaths() { + return additionalModulePaths; + } + + /** + * Get file associations + * + * @return File associations + */ + public List getFileAssociations() { + return fileAssociations; + } + + /** + * Get scripts + * + * @return Scripts + */ + public Scripts getScripts() { + return scripts; + } + + // fluent api + + /** + * Set output directory + * + * @param outputDirectory Output directory + * @return Packager settings + */ + public PackageTask outputDirectory(File outputDirectory) { + this.outputDirectory = outputDirectory; + return this; + } + + /** + * Set packaging JDK + * + * @param packagingJdk Packaging JDK + * @return Packager settings + */ + public PackageTask packagingJdk(File packagingJdk) { + this.packagingJdk = packagingJdk; + return this; + } + + /** + * Set license file + * + * @param licenseFile License file + * @return Packager settings + */ + public PackageTask licenseFile(File licenseFile) { + this.licenseFile = licenseFile; + return this; + } + + /** + * Set icon file + * + * @param iconFile Icon file + * @return Packager settings + */ + public PackageTask iconFile(File iconFile) { + this.iconFile = iconFile; + return this; + } + + /** + * Set generate installer + * + * @param generateInstaller Generate installer + * @return Packager settings + */ + public PackageTask generateInstaller(Boolean generateInstaller) { + this.generateInstaller = generateInstaller; + return this; + } + + /** + * Set force installer + * + * @param forceInstaller Force installer + * @return Packager settings + */ + public PackageTask forceInstaller(Boolean forceInstaller) { + this.forceInstaller = forceInstaller; + return this; + } + + public PackageTask nativeImage(Boolean nativeImage) { + this.nativeImage = nativeImage; + return this; + } + + public PackageTask sharedLibrary(Boolean sharedLibrary) { + this.sharedLibrary = sharedLibrary; + return this; + } + + /** + * Set main class + * + * @param mainClass Main class + * @return Packager settings + */ + public PackageTask mainClass(String mainClass) { + this.mainClass = mainClass; + return this; + } + + /** + * Set name + * + * @param appName Name + * @return Packager settings + */ + public PackageTask appName(String appName) { + this.appName = appName; + return this; + } + + /** + * Set display name + * + * @param appDisplayName Display name + * @return Packager settings + */ + public PackageTask appDisplayName(String appDisplayName) { + this.appDisplayName = appDisplayName; + return this; + } + + /** + * Set version + * + * @param version Version + * @return Packager settings + */ + public PackageTask version(String version) { + this.version = version; + return this; + } + + /** + * Set description + * + * @param description Description + * @return Packager settings + */ + public PackageTask description(String description) { + this.description = description; + return this; + } + + /** + * Set URL + * + * @param url URL + * @return Packager settings + */ + public PackageTask url(String url) { + this.url = url; + return this; + } + + /** + * Set administrator required + * + * @param administratorRequired Administrator required + * @return Packager settings + */ + public PackageTask administratorRequired(Boolean administratorRequired) { + this.administratorRequired = administratorRequired; + return this; + } + + /** + * Set organizstion name + * + * @param organizationName Organization name + * @return Packager settings + */ + public PackageTask organizationName(String organizationName) { + this.organizationName = organizationName; + return this; + } + + /** + * Set organization URL + * + * @param organizationUrl Organization URL + * @return Packager settings + */ + public PackageTask organizationUrl(String organizationUrl) { + this.organizationUrl = organizationUrl; + return this; + } + + /** + * Set organization email + * + * @param organizationEmail + * @return Packager settings + */ + public PackageTask organizationEmail(String organizationEmail) { + this.organizationEmail = organizationEmail; + return this; + } + + /** + * Set bundle JRE + * + * @param bundleJre Bundle JRE + * @return Packager settings + */ + public PackageTask bundleJre(Boolean bundleJre) { + this.bundleJre = bundleJre; + return this; + } + + /** + * Set customized JRE + * + * @param customizedJre Customized JRE + * @return Packager settings + */ + public PackageTask customizedJre(Boolean customizedJre) { + this.customizedJre = customizedJre; + return this; + } + + /** + * Set JRE path + * + * @param jrePath JRE path + * @return Packager settings + */ + public PackageTask jrePath(File jrePath) { + this.jrePath = jrePath; + return this; + } + + /** + * Set JDK path + * + * @param jdkPath JDK path + * @return Packager settings + */ + public PackageTask jdkPath(File jdkPath) { + this.jdkPath = jdkPath; + return this; + } + + /** + * Set JDK version + * + * @param jdkVersion JDK version + * @return Packager settings + */ + public PackageTask jdkVersion(String jdkVersion) { + this.jdkVersion = jdkVersion; + return this; + } + + /** + * Set JDK vendor + * + * @param jdkVendor JDK vendor + * @return Packager settings + */ + public PackageTask jdkVendor(String jdkVendor) { + this.jdkVendor = jdkVendor; + return this; + } + + /** + * Set additional resources list + * + * @param additionalResources Additional resources list + * @return Packager settings + */ + public PackageTask additionalResources(List additionalResources) { + this.additionalResources = new ArrayList<>(additionalResources); + return this; + } + + /** + * Set modules list + * + * @param modules Modules list + * @return Packager settings + */ + public PackageTask modules(List modules) { + this.modules = new ArrayList<>(modules); + return this; + } + + /** + * Set additional modules list + * + * @param additionalModules Additional modules list + * @return Packager settings + */ + public PackageTask additionalModules(List additionalModules) { + this.additionalModules = new ArrayList<>(additionalModules); + return this; + } + + /** + * Set platform + * + * @param platform Platform + * @return Packager settings + */ + public PackageTask platform(Platform platform) { + this.platform = platform; + return this; + } + + /** + * Set ENV path + * + * @param envPath ENV path + * @return Packager settings + */ + public PackageTask envPath(String envPath) { + this.envPath = envPath; + return this; + } + + /** + * Set VM arguments + * + * @param vmArgs VM arguments + * @return Packager settings + */ + public PackageTask vmArgs(List vmArgs) { + this.vmArgs = new ArrayList<>(vmArgs); + return this; + } + + /** + * Set runnable JAR + * + * @param runnableJar Runnable JAR + * @return Packager settings + */ + public PackageTask runnableJar(File runnableJar) { + this.runnableJar = runnableJar; + return this; + } + + /** + * Set copy dependencies + * + * @param copyDependencies Copy dependencies + * @return Packager settings + */ + public PackageTask copyDependencies(Boolean copyDependencies) { + this.copyDependencies = copyDependencies; + return this; + } + + /** + * Set JRE directory name + * + * @param jreDirectoryName JRE directory name + * @return Packager settings + */ + public PackageTask jreDirectoryName(String jreDirectoryName) { + this.jreDirectoryName = jreDirectoryName; + return this; + } + + /** + * Set Windows specific configuration + * + * @param winConfig Windows specific configuration + * @return Packager settings + */ + public PackageTask winConfig(WindowsConfig winConfig) { + this.winConfig = winConfig; + return this; + } + + /** + * Set GNU/Linux specific configuration + * + * @param linuxConfig GNU/Linux specific configuration + * @return Packager settings + */ + public PackageTask linuxConfig(LinuxConfig linuxConfig) { + this.linuxConfig = linuxConfig; + return this; + } + + /** + * Set Mac OS specific configuration + * + * @param macConfig Mac OS specific configuration + * @return Packager settings + */ + public PackageTask macConfig(MacConfig macConfig) { + this.macConfig = macConfig; + return this; + } + + /** + * Set create tarball + * + * @param createTarball Create tarball + * @return Packager settings + */ + public PackageTask createTarball(Boolean createTarball) { + this.createTarball = createTarball; + return this; + } + + /** + * Set create zipball + * + * @param createZipball Create zipball + * @return Packager settings + */ + public PackageTask createZipball(Boolean createZipball) { + this.createZipball = createZipball; + return this; + } + + /** + * Set extra parameters map + * + * @param extra Extra parameters map + * @return Packager settings + */ + public PackageTask extra(Map extra) { + this.extra = extra; + return this; + } + + /** + * Set if it use resources folder as working directory + * + * @param useResourcesAsWorkingDir Use resources folder as working directory + * @return Packager settings + */ + public PackageTask useResourcesAsWorkingDir(boolean useResourcesAsWorkingDir) { + this.useResourcesAsWorkingDir = useResourcesAsWorkingDir; + return this; + } + + /** + * Set asstes directory + * + * @param assetsDir Assets directory + * @return Packager settings + */ + public PackageTask assetsDir(File assetsDir) { + this.assetsDir = assetsDir; + return this; + } + + /** + * Set classpath + * + * @param classpath Classpath + * @return Packager settings + */ + public PackageTask classpath(String classpath) { + this.classpath = classpath; + return this; + } + + /** + * Set minimal JRE version + * + * @param jreMinVersion JRE minimal version + * @return Packager settings + */ + public PackageTask jreMinVersion(String jreMinVersion) { + this.jreMinVersion = jreMinVersion; + return this; + } + + /** + * Set Manifest configuration + * + * @param manifest Manifest + * @return Packager settings + */ + public PackageTask manifest(Manifest manifest) { + this.manifest = manifest; + return this; + } + + /** + * Set additional module paths + * + * @param additionalModulePaths Additional module path list + * @return Packager settings + */ + public PackageTask additionalModulePaths(List additionalModulePaths) { + this.additionalModulePaths = additionalModulePaths; + return this; + } + + /** + * Set file associations + * + * @param fileAssociations File associations list + * @return Packager settings + */ + public PackageTask fileAssociations(List fileAssociations) { + this.fileAssociations = fileAssociations; + return this; + } + + /** + * Set scripts + * + * @param scripts Scripts + * @return Packager settings + */ + public PackageTask scripts(Scripts scripts) { + this.scripts = scripts; + return this; + } + + // some helpful methods + + /** + * Checks if there are file associations specified + * + * @return true if there are file asociations, otherwise false + */ + public boolean isThereFileAssociations() { + return fileAssociations != null && !fileAssociations.isEmpty(); + } + + /** + * Mime types list to string + * + * @param separator Character used to join mime types into one string + * @return Mime type list string + */ + public String getMimeTypesListAsString(String separator) { + return StringUtils.join(fileAssociations.stream().map(fa -> fa.getMimeType()).collect(Collectors.toList()), + separator); + } + + @Override + public String toString() { + return "PackageTask [outputDirectory=" + outputDirectory + ", licenseFile=" + licenseFile + ", iconFile=" + + iconFile + ", generateInstaller=" + generateInstaller + ", forceInstaller=" + forceInstaller + + ", mainClass=" + mainClass + ", name=" + appName + ", displayName=" + appDisplayName + ", version=" + + version + ", description=" + description + ", url=" + url + ", administratorRequired=" + + administratorRequired + ", organizationName=" + organizationName + ", organizationUrl=" + + organizationUrl + ", organizationEmail=" + organizationEmail + ", bundleJre=" + bundleJre + + ", customizedJre=" + customizedJre + ", jrePath=" + jrePath + ", jdkPath=" + jdkPath + + ", additionalResources=" + additionalResources + ", modules=" + modules + ", additionalModules=" + + additionalModules + ", platform=" + platform + ", envPath=" + envPath + ", vmArgs=" + vmArgs + + ", runnableJar=" + runnableJar + ", copyDependencies=" + copyDependencies + ", jreDirectoryName=" + + jreDirectoryName + ", winConfig=" + winConfig + ", linuxConfig=" + linuxConfig + ", macConfig=" + + macConfig + ", createTarball=" + createTarball + ", createZipball=" + createZipball + ", extra=" + + extra + ", useResourcesAsWorkingDir=" + useResourcesAsWorkingDir + ", assetsDir=" + assetsDir + + ", classpath=" + classpath + ", jreMinVersion=" + jreMinVersion + ", manifest=" + manifest + + ", additionalModulePaths=" + additionalModulePaths + ", fileAssociations=" + fileAssociations + + ", packagingJdk=" + packagingJdk + ", scripts=" + scripts + "]"; + } +} \ No newline at end of file diff --git a/src/main/java/io/github/fvarrui/javapackager/gradle/AbstractPackageTask.java b/src/main/java/io/github/fvarrui/javapackager/gradle/AbstractPackageTask.java deleted file mode 100644 index 5cf1bc8a..00000000 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/AbstractPackageTask.java +++ /dev/null @@ -1,64 +0,0 @@ -package io.github.fvarrui.javapackager.gradle; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import org.gradle.api.DefaultTask; -import org.gradle.api.tasks.OutputFiles; -import org.gradle.api.tasks.TaskAction; - -import io.github.fvarrui.javapackager.packagers.Packager; - -/** - * Abstract packaging task for Gradle - */ -public abstract class AbstractPackageTask extends DefaultTask { - - private List outputFiles; - - @OutputFiles - public List getOutputFiles() { - return outputFiles != null ? outputFiles : new ArrayList<>(); - } - - /** - * Task constructor - */ - public AbstractPackageTask() { - super(); - setGroup(PackagePlugin.GROUP_NAME); - setDescription("Packages the application as a native Windows, Mac OS X or GNU/Linux executable and creates an installer"); - getOutputs().upToDateWhen(o -> false); - } - - /** - * Packaging task action - * @throws Exception Throwed if something went wrong - */ - @TaskAction - public void doPackage() throws Exception { - - Packager packager = createPackager(); - - // generates app, installers and bundles - File app = packager.createApp(); - List installers = packager.generateInstallers(); - List bundles = packager.createBundles(); - - // sets generated files as output - outputFiles = new ArrayList<>(); - outputFiles.add(app); - outputFiles.addAll(installers); - outputFiles.addAll(bundles); - - } - - /** - * Creates a platform specific packager - * @return Packager - * @throws Exception Throwed if something went wrong - */ - protected abstract Packager createPackager() throws Exception; - -} diff --git a/src/main/java/io/github/fvarrui/javapackager/gradle/CopyDependencies.java b/src/main/java/io/github/fvarrui/javapackager/gradle/CopyDependencies.java index a4f0e250..654377e2 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/CopyDependencies.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/CopyDependencies.java @@ -22,7 +22,7 @@ public CopyDependencies() { @Override public boolean skip(Packager packager) { - return !packager.getCopyDependencies(); + return !packager.task.getCopyDependencies(); } @Override diff --git a/src/main/java/io/github/fvarrui/javapackager/gradle/CreateRunnableJar.java b/src/main/java/io/github/fvarrui/javapackager/gradle/CreateRunnableJar.java index 46d93d55..4592a16f 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/CreateRunnableJar.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/CreateRunnableJar.java @@ -28,13 +28,13 @@ public CreateRunnableJar() { protected File doApply(Packager packager) { String classifier = "runnable"; - String name = packager.getName(); - String version = packager.getVersion(); - String mainClass = packager.getMainClass(); - File outputDirectory = packager.getOutputDirectory(); + String name = packager.task.getAppName(); + String version = packager.task.getVersion(); + String mainClass = packager.task.getMainClass(); + File outputDirectory = packager.task.getOutputDirectory(); Project project = Context.getGradleContext().getProject(); File libsFolder = packager.getLibsFolder(); - Manifest manifest = packager.getManifest(); + Manifest manifest = packager.task.getManifest(); List dependencies = new ArrayList<>(); if (libsFolder != null && libsFolder.exists()) { diff --git a/src/main/java/io/github/fvarrui/javapackager/gradle/CreateTarball.java b/src/main/java/io/github/fvarrui/javapackager/gradle/CreateTarball.java index f2ce76f7..710b5079 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/CreateTarball.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/CreateTarball.java @@ -23,19 +23,19 @@ public CreateTarball() { @Override public boolean skip(Packager packager) { - return !packager.getCreateTarball(); + return !packager.task.getCreateTarball(); } @Override protected File doApply(Packager packager) throws Exception { - String name = packager.getName(); - String version = packager.getVersion(); - Platform platform = packager.getPlatform(); - File outputDirectory = packager.getOutputDirectory(); + String name = packager.task.getAppName(); + String version = packager.task.getVersion(); + Platform platform = packager.task.getPlatform(); + File outputDirectory = packager.task.getOutputDirectory(); File appFolder = packager.getAppFolder(); File executable = packager.getExecutable(); - String jreDirectoryName = packager.getJreDirectoryName(); + String jreDirectoryName = packager.task.getJreDirectoryName(); File tarFile = new File(outputDirectory, name + "-" + version + "-" + platform + ".tar.gz"); diff --git a/src/main/java/io/github/fvarrui/javapackager/gradle/CreateWindowsExeLaunch4j.java b/src/main/java/io/github/fvarrui/javapackager/gradle/CreateWindowsExeLaunch4j.java index 3ba3221f..3f6ab5fc 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/CreateWindowsExeLaunch4j.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/CreateWindowsExeLaunch4j.java @@ -25,14 +25,14 @@ public CreateWindowsExeLaunch4j() { @Override protected File doApply(WindowsPackager packager) throws Exception { - List vmArgs = packager.getVmArgs(); - WindowsConfig winConfig = packager.getWinConfig(); + List vmArgs = packager.task.getVmArgs(); + WindowsConfig winConfig = packager.task.getWinConfig(); File executable = packager.getExecutable(); - String mainClass = packager.getMainClass(); - boolean useResourcesAsWorkingDir = packager.isUseResourcesAsWorkingDir(); - boolean bundleJre = packager.getBundleJre(); - String jreDirectoryName = packager.getJreDirectoryName(); - String jreMinVersion = packager.getJreMinVersion(); + String mainClass = packager.task.getMainClass(); + boolean useResourcesAsWorkingDir = packager.task.isUseResourcesAsWorkingDir(); + boolean bundleJre = packager.task.getBundleJre(); + String jreDirectoryName = packager.task.getJreDirectoryName(); + String jreMinVersion = packager.task.getJreMinVersion(); File jarFile = packager.getJarFile(); File appFolder = packager.getAppFolder(); diff --git a/src/main/java/io/github/fvarrui/javapackager/gradle/CreateZipball.java b/src/main/java/io/github/fvarrui/javapackager/gradle/CreateZipball.java index 401c3025..76079778 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/CreateZipball.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/CreateZipball.java @@ -22,19 +22,19 @@ public CreateZipball() { @Override public boolean skip(Packager packager) { - return !packager.getCreateZipball(); + return !packager.task.getCreateZipball(); } @Override protected File doApply(Packager packager) throws Exception { - String name = packager.getName(); - String version = packager.getVersion(); - Platform platform = packager.getPlatform(); - File outputDirectory = packager.getOutputDirectory(); + String name = packager.task.getAppName(); + String version = packager.task.getVersion(); + Platform platform = packager.task.getPlatform(); + File outputDirectory = packager.task.getOutputDirectory(); File appFolder = packager.getAppFolder(); File executable = packager.getExecutable(); - String jreDirectoryName = packager.getJreDirectoryName(); + String jreDirectoryName = packager.task.getJreDirectoryName(); File zipFile = new File(outputDirectory, name + "-" + version + "-" + platform + ".zip"); diff --git a/src/main/java/io/github/fvarrui/javapackager/gradle/DefaultPackageTask.java b/src/main/java/io/github/fvarrui/javapackager/gradle/DefaultPackageTask.java deleted file mode 100644 index 791a23be..00000000 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/DefaultPackageTask.java +++ /dev/null @@ -1,65 +0,0 @@ -package io.github.fvarrui.javapackager.gradle; - -import static io.github.fvarrui.javapackager.utils.ObjectUtils.defaultIfNull; - -import io.github.fvarrui.javapackager.packagers.Packager; -import io.github.fvarrui.javapackager.packagers.PackagerFactory; - -/** - * Default packaging task for Gradle - */ -public class DefaultPackageTask extends AbstractPackageTask { - - @Override - protected Packager createPackager() throws Exception { - - PackagePluginExtension extension = getProject().getExtensions().findByType(PackagePluginExtension.class); - - return - (Packager) PackagerFactory - .createPackager(extension.getPlatform()) - .additionalModules(extension.getAdditionalModules()) - .additionalModulePaths(extension.getAdditionalModulePaths()) - .additionalResources(extension.getAdditionalResources()) - .administratorRequired(extension.getAdministratorRequired()) - .assetsDir(extension.getAssetsDir()) - .bundleJre(extension.getBundleJre()) - .classpath(extension.getClasspath()) - .copyDependencies(extension.getCopyDependencies()) - .createTarball(extension.getCreateTarball()) - .createZipball(extension.getCreateZipball()) - .customizedJre(extension.getCustomizedJre()) - .description(extension.getDescription()) - .displayName(extension.getDisplayName()) - .envPath(extension.getEnvPath()) - .extra(extension.getExtra()) - .fileAssociations(extension.getFileAssociations()) - .forceInstaller(extension.isForceInstaller()) - .generateInstaller(extension.getGenerateInstaller()) - .jdkPath(extension.getJdkPath()) - .jreDirectoryName(extension.getJreDirectoryName()) - .jreMinVersion(extension.getJreMinVersion()) - .jrePath(extension.getJrePath()) - .licenseFile(extension.getLicenseFile()) - .linuxConfig(extension.getLinuxConfig()) - .macConfig(extension.getMacConfig()) - .mainClass(extension.getMainClass()) - .manifest(extension.getManifest()) - .modules(extension.getModules()) - .name(extension.getName()) - .organizationEmail(extension.getOrganizationEmail()) - .organizationName(extension.getOrganizationName()) - .organizationUrl(extension.getOrganizationUrl()) - .outputDirectory(extension.getOutputDirectory()) - .packagingJdk(extension.getPackagingJdk()) - .runnableJar(extension.getRunnableJar()) - .scripts(extension.getScripts()) - .useResourcesAsWorkingDir(extension.isUseResourcesAsWorkingDir()) - .url(extension.getUrl()) - .version(defaultIfNull(extension.getVersion(), getProject().getVersion().toString())) - .vmArgs(extension.getVmArgs()) - .winConfig(extension.getWinConfig()); - - } - -} diff --git a/src/main/java/io/github/fvarrui/javapackager/gradle/GradleContext.java b/src/main/java/io/github/fvarrui/javapackager/gradle/GradleContext.java index b83eea0e..d6a4fd9b 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/GradleContext.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/GradleContext.java @@ -111,7 +111,7 @@ private File getToolchain() { @Override public File createWindowsExe(WindowsPackager packager) throws Exception { AbstractCreateWindowsExe createWindowsExe; - switch (packager.getWinConfig().getExeCreationTool()) { + switch (packager.task.getWinConfig().getExeCreationTool()) { case launch4j: createWindowsExe = new CreateWindowsExeLaunch4j(); break; case winrun4j: createWindowsExe = new CreateWindowsExeWinRun4j(); break; case why: createWindowsExe = new CreateWindowsExeWhy(); break; diff --git a/src/main/java/io/github/fvarrui/javapackager/gradle/PackagePlugin.java b/src/main/java/io/github/fvarrui/javapackager/gradle/PackagePlugin.java index acc47b3d..38042d65 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/PackagePlugin.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/PackagePlugin.java @@ -1,6 +1,8 @@ package io.github.fvarrui.javapackager.gradle; import edu.sc.seis.launch4j.tasks.Launch4jLibraryTask; +import io.github.fvarrui.javapackager.GradlePackageTask; +import io.github.fvarrui.javapackager.PackageTask; import io.github.fvarrui.javapackager.packagers.Context; import org.gradle.api.Plugin; import org.gradle.api.Project; @@ -14,7 +16,8 @@ public class PackagePlugin implements Plugin { public static final String GROUP_NAME = "JavaPackager"; public static final String SETTINGS_EXT_NAME = "javapackager"; - public static final String PACKAGE_TASK_NAME = "package"; + public static final String PACKAGE_TASK_NAME = "package"; + public static PackageTask GLOBAL_EXTENSION; @Override public void apply(Project project) { @@ -22,13 +25,13 @@ public void apply(Project project) { Context.setContext(new GradleContext(project)); project.getPluginManager().apply("java"); - project.getPluginManager().apply("edu.sc.seis.launch4j"); - - project.getExtensions().create(SETTINGS_EXT_NAME, PackagePluginExtension.class, project); - project.getTasks().create(PACKAGE_TASK_NAME, DefaultPackageTask.class).dependsOn("build"); + project.getPluginManager().apply("edu.sc.seis.launch4j"); - Context.getGradleContext().setLibraryTask(project.getTasks().create("launch4j_" + UUID.randomUUID(), Launch4jLibraryTask.class)); + GLOBAL_EXTENSION = project.getExtensions().create(SETTINGS_EXT_NAME, PackageTask.class); + GradlePackageTask task = (GradlePackageTask) project.getTasks().create(PACKAGE_TASK_NAME, GradlePackageTask.class).dependsOn("build"); + task.getExtensions().add(SETTINGS_EXT_NAME, GLOBAL_EXTENSION); + Context.getGradleContext().setLibraryTask(project.getTasks().create("launch4j_" + UUID.randomUUID(), Launch4jLibraryTask.class)); } } diff --git a/src/main/java/io/github/fvarrui/javapackager/gradle/PackagePluginExtension.java b/src/main/java/io/github/fvarrui/javapackager/gradle/PackagePluginExtension.java deleted file mode 100644 index e4a311b8..00000000 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/PackagePluginExtension.java +++ /dev/null @@ -1,87 +0,0 @@ -package io.github.fvarrui.javapackager.gradle; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; - -import org.gradle.api.Project; - -import groovy.lang.Closure; -import io.github.fvarrui.javapackager.model.LinuxConfig; -import io.github.fvarrui.javapackager.model.MacConfig; -import io.github.fvarrui.javapackager.model.Manifest; -import io.github.fvarrui.javapackager.model.Platform; -import io.github.fvarrui.javapackager.model.Scripts; -import io.github.fvarrui.javapackager.model.WindowsConfig; -import io.github.fvarrui.javapackager.packagers.PackagerSettings; - -/** - * JavaPackager plugin extension for Gradle - */ -public class PackagePluginExtension extends PackagerSettings { - - private Project project; - - public PackagePluginExtension(Project project) { - super(); - this.project = project; - this.platform = Platform.auto; - this.additionalModules = new ArrayList<>(); - this.additionalModulePaths = new ArrayList<>(); - this.additionalResources = new ArrayList<>(); - this.administratorRequired = false; - this.assetsDir = new File(project.getProjectDir(), "assets"); - this.bundleJre = true; - this.copyDependencies = true; - this.createTarball = false; - this.createZipball = false; - this.customizedJre = true; - this.description = project.getDescription(); - this.extra = new HashMap<>(); - this.generateInstaller = true; - this.jreDirectoryName = "jre"; - this.linuxConfig = new LinuxConfig(); - this.macConfig = new MacConfig(); - this.manifest = new Manifest(); - this.modules = new ArrayList<>(); - this.name = project.getName(); - this.organizationEmail = ""; - this.useResourcesAsWorkingDir = true; - this.vmArgs = new ArrayList<>(); - this.winConfig = new WindowsConfig(); - this.outputDirectory = project.getBuildDir(); - this.scripts = new Scripts(); - this.forceInstaller = false; - } - - public LinuxConfig linuxConfig(Closure closure) { - linuxConfig = new LinuxConfig(); - project.configure(linuxConfig, closure); - return linuxConfig; - } - - public MacConfig macConfig(Closure closure) { - macConfig = new MacConfig(); - project.configure(macConfig, closure); - return macConfig; - } - - public WindowsConfig winConfig(Closure closure) { - winConfig = new WindowsConfig(); - project.configure(winConfig, closure); - return winConfig; - } - - public Manifest manifest(Closure closure) { - manifest = new Manifest(); - project.configure(manifest, closure); - return manifest; - } - - public Scripts scripts(Closure closure) { - scripts = new Scripts(); - project.configure(scripts, closure); - return scripts; - } - -} \ No newline at end of file diff --git a/src/main/java/io/github/fvarrui/javapackager/gradle/PackageTask.java b/src/main/java/io/github/fvarrui/javapackager/gradle/PackageTask.java deleted file mode 100644 index 1e9d109a..00000000 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/PackageTask.java +++ /dev/null @@ -1,620 +0,0 @@ -package io.github.fvarrui.javapackager.gradle; - -import static io.github.fvarrui.javapackager.utils.ObjectUtils.defaultIfBlank; -import static io.github.fvarrui.javapackager.utils.ObjectUtils.defaultIfNull; - -import java.io.File; -import java.util.List; -import java.util.Map; - -import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.InputDirectory; -import org.gradle.api.tasks.InputFile; -import org.gradle.api.tasks.Optional; -import org.gradle.api.tasks.OutputDirectory; - -import groovy.lang.Closure; -import io.github.fvarrui.javapackager.model.FileAssociation; -import io.github.fvarrui.javapackager.model.LinuxConfig; -import io.github.fvarrui.javapackager.model.MacConfig; -import io.github.fvarrui.javapackager.model.Manifest; -import io.github.fvarrui.javapackager.model.Platform; -import io.github.fvarrui.javapackager.model.Scripts; -import io.github.fvarrui.javapackager.model.WindowsConfig; -import io.github.fvarrui.javapackager.packagers.Context; -import io.github.fvarrui.javapackager.packagers.Packager; -import io.github.fvarrui.javapackager.packagers.PackagerFactory; - -/** - * Packaging task fro Gradle - */ -public class PackageTask extends AbstractPackageTask { - - // =============== - // task parameters - // =============== - - @Input - @Optional - private Platform platform; - - public Platform getPlatform() { - return platform; - } - - public void setPlatform(Platform platform) { - this.platform = platform; - } - - @Input - @Optional - private List additionalModules; - - public List getAdditionalModules() { - return additionalModules; - } - - public void setAdditionalModules(List additionalModules) { - this.additionalModules = additionalModules; - } - - @Input - @Optional - private List additionalResources; - - public List getAdditionalResources() { - return additionalResources; - } - - public void setAdditionalResources(List additionalResources) { - this.additionalResources = additionalResources; - } - - @Input - @Optional - private Boolean administratorRequired; - - public Boolean isAdministratorRequired() { - return administratorRequired; - } - - public void setAdministratorRequired(Boolean administratorRequired) { - this.administratorRequired = administratorRequired; - } - - @InputDirectory - @Optional - private File assetsDir; - - public File getAssetsDir() { - return assetsDir; - } - - public void setAssetsDir(File assetsDir) { - this.assetsDir = assetsDir; - } - - @InputDirectory - @Optional - private File packagingJdk; - - public File getPackagingJdk() { - return packagingJdk; - } - - public void setPackagingJdk(File packagingJdk) { - this.packagingJdk = packagingJdk; - } - - @Input - @Optional - private Boolean bundleJre; - - public Boolean isBundleJre() { - return bundleJre; - } - - public void setBundleJre(Boolean bundleJre) { - this.bundleJre = bundleJre; - } - - @Input - @Optional - private Boolean copyDependencies; - - public Boolean isCopyDependencies() { - return copyDependencies; - } - - public void setCopyDependencies(Boolean copyDependencies) { - this.copyDependencies = copyDependencies; - } - - @Input - @Optional - private Boolean createTarball; - - public Boolean isCreateTarball() { - return createTarball; - } - - public void setCreateTarball(Boolean createTarball) { - this.createTarball = createTarball; - } - - @Input - @Optional - private Boolean createZipball; - - public Boolean isCreateZipball() { - return createZipball; - } - - public void setCreateZipball(Boolean createZipball) { - this.createZipball = createZipball; - } - - @Input - @Optional - private Boolean customizedJre; - - public Boolean isCustomizedJre() { - return customizedJre; - } - - public void setCustomizedJre(Boolean customizedJre) { - this.customizedJre = customizedJre; - } - - @Input - @Optional - private String appDescription; - - public String getAppDescription() { - return appDescription; - } - - public void setAppDescription(String appDescription) { - this.appDescription = appDescription; - } - - @Input - @Optional - private String displayName; - - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - @Input - @Optional - private String envPath; - - public String getEnvPath() { - return envPath; - } - - public void setEnvPath(String envPath) { - this.envPath = envPath; - } - - @Input - @Optional - private Map extra; - - public Map getExtra() { - return extra; - } - - public void setExtra(Map extra) { - this.extra = extra; - } - - @Input - @Optional - private Boolean generateInstaller; - - public Boolean isGenerateInstaller() { - return generateInstaller; - } - - public void setGenerateInstaller(Boolean generateInstaller) { - this.generateInstaller = generateInstaller; - } - - @Input - @Optional - private Boolean forceInstaller; - - public Boolean isForceInstaller() { - return forceInstaller; - } - - public void setForceInstaller(Boolean forceInstaller) { - this.forceInstaller = forceInstaller; - } - - @InputDirectory - @Optional - private File jdkPath; - - public File getJdkPath() { - return jdkPath; - } - - public void setJdkPath(File jdkPath) { - this.jdkPath = jdkPath; - } - - @Input - @Optional - private String jreDirectoryName; - - public String getJreDirectoryName() { - return jreDirectoryName; - } - - public void setJreDirectoryName(String jreDirectoryName) { - this.jreDirectoryName = jreDirectoryName; - } - - @InputDirectory - @Optional - private File jrePath; - - public File getJrePath() { - return jrePath; - } - - public void setJrePath(File jrePath) { - this.jrePath = jrePath; - } - - @InputFile - @Optional - private File licenseFile; - - public File getLicenseFile() { - return licenseFile; - } - - public void setLicenseFile(File licenseFile) { - this.licenseFile = licenseFile; - } - - @Input - @Optional - private LinuxConfig linuxConfig; - - public LinuxConfig getLinuxConfig() { - return linuxConfig; - } - - public void setLinuxConfig(LinuxConfig linuxConfig) { - this.linuxConfig = linuxConfig; - } - - public LinuxConfig linuxConfig(Closure closure) { - linuxConfig = new LinuxConfig(); - getProject().configure(linuxConfig, closure); - return linuxConfig; - } - - @Input - @Optional - private MacConfig macConfig; - - public MacConfig getMacConfig() { - return macConfig; - } - - public void setMacConfig(MacConfig macConfig) { - this.macConfig = macConfig; - } - - public MacConfig macConfig(Closure closure) { - macConfig = new MacConfig(); - getProject().configure(macConfig, closure); - return macConfig; - } - - @Input - @Optional - private String mainClass; - - public String getMainClass() { - return mainClass; - } - - public void setMainClass(String mainClass) { - this.mainClass = mainClass; - } - - @Input - @Optional - private List modules; - - public List getModules() { - return modules; - } - - public void setModules(List modules) { - this.modules = modules; - } - - @Input - @Optional - private String appName; - - public String getAppName() { - return appName; - } - - public void setAppName(String appName) { - this.appName = appName; - } - - @Input - @Optional - private String organizationEmail; - - public String getOrganizationEmail() { - return organizationEmail; - } - - public void setOrganizationEmail(String organizationEmail) { - this.organizationEmail = organizationEmail; - } - - @Input - @Optional - private String organizationName; - - public String getOrganizationName() { - return organizationName; - } - - public void setOrganizationName(String organizationName) { - this.organizationName = organizationName; - } - - @Input - @Optional - private String organizationUrl; - - public String getOrganizationUrl() { - return organizationUrl; - } - - public void setOrganizationUrl(String organizationUrl) { - this.organizationUrl = organizationUrl; - } - - @InputFile - @Optional - private File runnableJar; - - public File getRunnableJar() { - return runnableJar; - } - - public void setRunnableJar(File runnableJar) { - this.runnableJar = runnableJar; - } - - @Input - @Optional - private Boolean useResourcesAsWorkingDir; - - public Boolean isUseResourcesAsWorkingDir() { - return useResourcesAsWorkingDir; - } - - public void setUseResourcesAsWorkingDir(Boolean useResourcesAsWorkingDir) { - this.useResourcesAsWorkingDir = useResourcesAsWorkingDir; - } - - @Input - @Optional - private String url; - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - @Input - @Optional - private List vmArgs; - - public List getVmArgs() { - return vmArgs; - } - - public void setVmArgs(List vmArgs) { - this.vmArgs = vmArgs; - } - - @Input - @Optional - private WindowsConfig winConfig; - - public WindowsConfig getWinConfig() { - return winConfig; - } - - public WindowsConfig winConfig(Closure closure) { - winConfig = new WindowsConfig(); - getProject().configure(winConfig, closure); - return winConfig; - } - - @Input - @Optional - private String version; - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - @OutputDirectory - @Optional - private File outputDirectory; - - public File getOutputDirectory() { - return outputDirectory; - } - - public void setOutputDirectory(File outputDirectory) { - this.outputDirectory = outputDirectory; - } - - @Input - @Optional - private String classpath; - - public String getClasspath() { - return classpath; - } - - public void setClasspath(String classpath) { - this.classpath = classpath; - } - - @Input - @Optional - private String jreMinVersion; - - public String getJreMinVersion() { - return jreMinVersion; - } - - public void setJreMinVersion(String jreMinVersion) { - this.jreMinVersion = jreMinVersion; - } - - @Input - @Optional - private Manifest manifest; - - public Manifest getManifest() { - return manifest; - } - - public Manifest manifest(Closure closure) { - manifest = new Manifest(); - getProject().configure(manifest, closure); - return manifest; - } - - @Input - @Optional - private List additionalModulePaths; - - public List getAdditionalModulePaths() { - return additionalModulePaths; - } - - public void setAdditionalModulePaths(List additionalModulePaths) { - this.additionalModulePaths = additionalModulePaths; - } - - @Input - @Optional - private List fileAssociations; - - public List getFileAssociations() { - return fileAssociations; - } - - public void setFileAssociations(List fileAssociations) { - this.fileAssociations = fileAssociations; - } - - @Input - @Optional - private Scripts scripts; - - public Scripts getScripts() { - return scripts; - } - - public void setScripts(Scripts scripts) { - this.scripts = scripts; - } - - public Scripts scripts(Closure closure) { - scripts = new Scripts(); - getProject().configure(scripts, closure); - return scripts; - } - - // =============== - // create packager - // =============== - - @SuppressWarnings("unchecked") - @Override - protected Packager createPackager() throws Exception { - - PackagePluginExtension extension = getProject().getExtensions().findByType(PackagePluginExtension.class); - - return - (Packager) PackagerFactory - .createPackager(defaultIfNull(platform, extension.getPlatform())) - .additionalModules(defaultIfNull(additionalModules, extension.getAdditionalModules())) - .additionalModulePaths(defaultIfNull(additionalModulePaths, extension.getAdditionalModulePaths())) - .additionalResources(defaultIfNull(additionalResources, extension.getAdditionalResources())) - .administratorRequired(defaultIfNull(administratorRequired, extension.getAdministratorRequired())) - .assetsDir(defaultIfNull(assetsDir, extension.getAssetsDir())) - .bundleJre(defaultIfNull(bundleJre, extension.getBundleJre())) - .classpath(defaultIfNull(classpath, extension.getClasspath())) - .copyDependencies(defaultIfNull(copyDependencies, extension.getCopyDependencies())) - .createTarball(defaultIfNull(createTarball, extension.getCreateTarball())) - .createZipball(defaultIfNull(createZipball, extension.getCreateZipball())) - .customizedJre(defaultIfNull(customizedJre, extension.getCustomizedJre())) - .description(defaultIfNull(appDescription, extension.getDescription())) - .displayName(defaultIfNull(displayName, extension.getDisplayName())) - .envPath(defaultIfNull(envPath, extension.getEnvPath())) - .extra(defaultIfNull(extra, extension.getExtra())) - .fileAssociations(defaultIfNull(fileAssociations, extension.getFileAssociations())) - .forceInstaller(defaultIfNull(forceInstaller, extension.isForceInstaller())) - .generateInstaller(defaultIfNull(generateInstaller, extension.getGenerateInstaller())) - .jdkPath(defaultIfNull(jdkPath, extension.getJdkPath())) - .jreDirectoryName(defaultIfBlank(jreDirectoryName, extension.getJreDirectoryName())) - .jreMinVersion(defaultIfBlank(jreMinVersion, extension.getJreMinVersion())) - .jrePath(defaultIfNull(jrePath, extension.getJrePath())) - .licenseFile(defaultIfNull(licenseFile, extension.getLicenseFile())) - .linuxConfig(defaultIfNull(linuxConfig, extension.getLinuxConfig())) - .macConfig(defaultIfNull(macConfig, extension.getMacConfig())) - .mainClass(defaultIfNull(mainClass, extension.getMainClass())) - .manifest(defaultIfNull(manifest, extension.getManifest())) - .modules(defaultIfNull(modules, extension.getModules())) - .name(defaultIfNull(appName, extension.getName())) - .organizationEmail(defaultIfNull(organizationEmail, extension.getOrganizationEmail())) - .organizationName(defaultIfNull(organizationName, extension.getOrganizationName())) - .organizationUrl(defaultIfNull(organizationUrl, extension.getOrganizationUrl())) - .outputDirectory(defaultIfNull(outputDirectory, extension.getOutputDirectory())) - .packagingJdk(defaultIfNull(packagingJdk, extension.getPackagingJdk(), Context.getGradleContext().getDefaultToolchain())) - .runnableJar(defaultIfNull(runnableJar, extension.getRunnableJar())) - .scripts(defaultIfNull(scripts, extension.getScripts())) - .useResourcesAsWorkingDir(defaultIfNull(useResourcesAsWorkingDir, extension.isUseResourcesAsWorkingDir())) - .url(defaultIfNull(url, extension.getUrl())) - .version(defaultIfNull(version, extension.getVersion(), getProject().getVersion().toString())) - .vmArgs(defaultIfNull(vmArgs, extension.getVmArgs())) - .winConfig(defaultIfNull(winConfig, extension.getWinConfig())); - - } - -} diff --git a/src/main/java/io/github/fvarrui/javapackager/maven/CopyDependencies.java b/src/main/java/io/github/fvarrui/javapackager/maven/CopyDependencies.java index 1fc5be50..5c9174fe 100644 --- a/src/main/java/io/github/fvarrui/javapackager/maven/CopyDependencies.java +++ b/src/main/java/io/github/fvarrui/javapackager/maven/CopyDependencies.java @@ -28,7 +28,7 @@ public CopyDependencies() { @Override public boolean skip(Packager packager) { - return !packager.getCopyDependencies(); + return !packager.task.getCopyDependencies(); } @Override diff --git a/src/main/java/io/github/fvarrui/javapackager/maven/CreateRunnableJar.java b/src/main/java/io/github/fvarrui/javapackager/maven/CreateRunnableJar.java index 3760ea38..d6233df7 100644 --- a/src/main/java/io/github/fvarrui/javapackager/maven/CreateRunnableJar.java +++ b/src/main/java/io/github/fvarrui/javapackager/maven/CreateRunnableJar.java @@ -38,12 +38,12 @@ public CreateRunnableJar() { protected File doApply(Packager packager) { String classifier = "runnable"; - String name = packager.getName(); - String version = packager.getVersion(); - String mainClass = packager.getMainClass(); - File outputDirectory = packager.getOutputDirectory(); + String name = packager.task.getAppName(); + String version = packager.task.getVersion(); + String mainClass = packager.task.getMainClass(); + File outputDirectory = packager.task.getOutputDirectory(); ExecutionEnvironment env = Context.getMavenContext().getEnv(); - Manifest manifest = packager.getManifest(); + Manifest manifest = packager.task.getManifest(); File jarFile = new File(outputDirectory, name + "-" + version + "-" + classifier + ".jar"); diff --git a/src/main/java/io/github/fvarrui/javapackager/maven/CreateTarball.java b/src/main/java/io/github/fvarrui/javapackager/maven/CreateTarball.java index 73a65ffd..c149698e 100644 --- a/src/main/java/io/github/fvarrui/javapackager/maven/CreateTarball.java +++ b/src/main/java/io/github/fvarrui/javapackager/maven/CreateTarball.java @@ -28,17 +28,17 @@ public CreateTarball() { @Override public boolean skip(Packager packager) { - return !packager.getCreateTarball(); + return !packager.task.getCreateTarball(); } @Override protected File doApply(Packager packager) { File assetsFolder = packager.getAssetsFolder(); - String name = packager.getName(); - String version = packager.getVersion(); - Platform platform = packager.getPlatform(); - File outputDirectory = packager.getOutputDirectory(); + String name = packager.task.getAppName(); + String version = packager.task.getVersion(); + Platform platform = packager.task.getPlatform(); + File outputDirectory = packager.task.getOutputDirectory(); try { diff --git a/src/main/java/io/github/fvarrui/javapackager/maven/CreateWindowsExeLaunch4j.java b/src/main/java/io/github/fvarrui/javapackager/maven/CreateWindowsExeLaunch4j.java index 48babc91..318f9fa1 100644 --- a/src/main/java/io/github/fvarrui/javapackager/maven/CreateWindowsExeLaunch4j.java +++ b/src/main/java/io/github/fvarrui/javapackager/maven/CreateWindowsExeLaunch4j.java @@ -35,15 +35,15 @@ public CreateWindowsExeLaunch4j() { @Override protected File doApply(WindowsPackager packager) throws Exception { - List vmArgs = packager.getVmArgs(); - WindowsConfig winConfig = packager.getWinConfig(); + List vmArgs = packager.task.getVmArgs(); + WindowsConfig winConfig = packager.task.getWinConfig(); File executable = packager.getExecutable(); - String mainClass = packager.getMainClass(); - boolean useResourcesAsWorkingDir = packager.isUseResourcesAsWorkingDir(); - boolean bundleJre = packager.getBundleJre(); - String jreDirectoryName = packager.getJreDirectoryName(); - String classpath = packager.getClasspath(); - String jreMinVersion = packager.getJreMinVersion(); + String mainClass = packager.task.getMainClass(); + boolean useResourcesAsWorkingDir = packager.task.isUseResourcesAsWorkingDir(); + boolean bundleJre = packager.task.getBundleJre(); + String jreDirectoryName = packager.task.getJreDirectoryName(); + String classpath = packager.task.getClasspath(); + String jreMinVersion = packager.task.getJreMinVersion(); File jarFile = packager.getJarFile(); File appFolder = packager.getAppFolder(); diff --git a/src/main/java/io/github/fvarrui/javapackager/maven/CreateZipball.java b/src/main/java/io/github/fvarrui/javapackager/maven/CreateZipball.java index 561b9620..1b70ede3 100644 --- a/src/main/java/io/github/fvarrui/javapackager/maven/CreateZipball.java +++ b/src/main/java/io/github/fvarrui/javapackager/maven/CreateZipball.java @@ -28,17 +28,17 @@ public CreateZipball() { @Override public boolean skip(Packager packager) { - return !packager.getCreateZipball(); + return !packager.task.getCreateZipball(); } @Override protected File doApply(Packager packager) { File assetsFolder = packager.getAssetsFolder(); - String name = packager.getName(); - String version = packager.getVersion(); - Platform platform = packager.getPlatform(); - File outputDirectory = packager.getOutputDirectory(); + String name = packager.task.getAppName(); + String version = packager.task.getVersion(); + Platform platform = packager.task.getPlatform(); + File outputDirectory = packager.task.getOutputDirectory(); try { diff --git a/src/main/java/io/github/fvarrui/javapackager/maven/MavenContext.java b/src/main/java/io/github/fvarrui/javapackager/maven/MavenContext.java index 49506334..a66daf09 100644 --- a/src/main/java/io/github/fvarrui/javapackager/maven/MavenContext.java +++ b/src/main/java/io/github/fvarrui/javapackager/maven/MavenContext.java @@ -66,7 +66,7 @@ public File resolveLicense(Packager packager) throws Exception { @Override public File createWindowsExe(WindowsPackager packager) throws Exception { AbstractCreateWindowsExe createWindowsExe; - switch (packager.getWinConfig().getExeCreationTool()) { + switch (packager.task.getWinConfig().getExeCreationTool()) { case launch4j: createWindowsExe = new CreateWindowsExeLaunch4j(); break; case why: createWindowsExe = new CreateWindowsExeWhy(); break; case winrun4j: createWindowsExe = new CreateWindowsExeWinRun4j(); break; diff --git a/src/main/java/io/github/fvarrui/javapackager/maven/PackageMojo.java b/src/main/java/io/github/fvarrui/javapackager/maven/PackageMojo.java deleted file mode 100644 index ab46e81e..00000000 --- a/src/main/java/io/github/fvarrui/javapackager/maven/PackageMojo.java +++ /dev/null @@ -1,390 +0,0 @@ -package io.github.fvarrui.javapackager.maven; - -import static org.apache.commons.lang3.StringUtils.defaultIfBlank; -import static org.twdata.maven.mojoexecutor.MojoExecutor.executionEnvironment; - -import java.io.File; -import java.util.List; -import java.util.Map; - -import org.apache.maven.execution.MavenSession; -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.BuildPluginManager; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugins.annotations.Component; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.plugins.annotations.ResolutionScope; -import org.apache.maven.project.MavenProject; - -import io.github.fvarrui.javapackager.model.FileAssociation; -import io.github.fvarrui.javapackager.model.LinuxConfig; -import io.github.fvarrui.javapackager.model.MacConfig; -import io.github.fvarrui.javapackager.model.Manifest; -import io.github.fvarrui.javapackager.model.Platform; -import io.github.fvarrui.javapackager.model.Scripts; -import io.github.fvarrui.javapackager.model.WindowsConfig; -import io.github.fvarrui.javapackager.packagers.Context; -import io.github.fvarrui.javapackager.packagers.Packager; -import io.github.fvarrui.javapackager.packagers.PackagerFactory; - -/** - * JavaPackager packaging mojo - */ -@Mojo(name = "package", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME) -public class PackageMojo extends AbstractMojo { - - // maven components - - @Parameter(defaultValue = "${project}", readonly = true) - private MavenProject mavenProject; - - @Parameter(defaultValue = "${session}", readonly = true) - private MavenSession mavenSession; - - @Component - private BuildPluginManager pluginManager; - - // plugin parameters - - /** - * Output directory. - */ - @Parameter(defaultValue = "${project.build.directory}", property = "outputDirectory", required = false) - private File outputDirectory; - - /** - * Path to project license file. - */ - @Parameter(property = "licenseFile", required = false) - private File licenseFile; - - /** - * Path to the app icon file (PNG, ICO or ICNS). - */ - @Parameter(property = "iconFile", required = false) - private File iconFile; - - /** - * Generates an installer for the app. - */ - @Parameter(defaultValue = "true", property = "generateInstaller", required = false) - private Boolean generateInstaller; - - /** - * Forces installer generation. - */ - @Parameter(defaultValue = "false", property = "forceInstaller", required = false) - private Boolean forceInstaller; - - /** - * Full path to your app main class. - */ - @Parameter(defaultValue = "${exec.mainClass}", property = "mainClass", required = true) - private String mainClass; - - /** - * App name. - */ - @Parameter(defaultValue = "${project.name}", property = "name", required = false) - private String name; - - /** - * App name to show. - */ - @Parameter(defaultValue = "${project.name}", property = "displayName", required = false) - private String displayName; - - /** - * Project version. - */ - @Parameter(defaultValue = "${project.version}", property = "version", required = false) - private String version; - - /** - * Project description. - */ - @Parameter(defaultValue = "${project.description}", property = "description", required = false) - private String description; - - /** - * App website URL. - */ - @Parameter(defaultValue = "${project.url}", property = "url", required = false) - private String url; - - /** - * App will run as administrator (with elevated privileges). - */ - @Parameter(defaultValue = "false", property = "administratorRequired", required = false) - private Boolean administratorRequired; - - /** - * Organization name. - */ - @Parameter(defaultValue = "${project.organization.name}", property = "organizationName", required = false) - private String organizationName; - - /** - * Organization website URL. - */ - @Parameter(defaultValue = "${project.organization.url}", property = "organizationUrl", required = false) - private String organizationUrl; - - /** - * Organization email. - */ - @Parameter(defaultValue = "", property = "organizationEmail", required = false) - private String organizationEmail; - - /** - * Embeds a customized JRE with the app. - */ - @Parameter(defaultValue = "false", property = "bundleJre", required = false) - private Boolean bundleJre; - - /** - * Generates a customized JRE, including only identified or specified modules. Otherwise, all modules will be included. - */ - @Parameter(defaultValue = "true", property = "customizedJre", required = false) - private Boolean customizedJre; - - /** - * Path to JRE folder. If specified, it will bundle this JRE with the app, and won't generate a customized JRE. For Java 8 version or least. - */ - @Parameter(property = "jrePath", required = false) - private File jrePath; - - /** - * Path to JDK folder. If specified, it will use this JDK modules to generate a customized JRE. Allows generating JREs for different platforms. - */ - @Parameter(property = "jdkPath", required = false) - private File jdkPath; - - /** - * Additional files and folders to include in the bundled app. - */ - @Parameter(property = "additionalResources", required = false) - private List additionalResources; - - /** - * Defines modules to customize the bundled JRE. Don't use jdeps to get module dependencies. - */ - @Parameter(property = "modules", required = false) - private List modules; - - /** - * Additional modules to the ones identified by jdeps or the specified with modules property. - */ - @Parameter(property = "additionalModules", required = false) - private List additionalModules; - - /** - * Which platform to build, one of: - *
    - *
  • auto - automatically detect based on the host OS (the default)
  • - *
  • mac
  • - *
  • linux
  • - *
  • windows
  • - *
- * To build for multiple platforms at once, add multiple executions to the plugin's configuration. - */ - @Parameter(defaultValue = "auto", property = "platform", required = true) - private Platform platform; - - /** - * Defines PATH environment variable in GNU/Linux and Mac OS X startup scripts. - */ - @Parameter(property = "envPath", required = false) - private String envPath; - - /** - * Additional arguments to provide to the JVM (for example -Xmx2G). - */ - @Parameter(property = "vmArgs", required = false) - private List vmArgs; - - /** - * Provide your own runnable .jar (for example, a shaded .jar) instead of letting this plugin create one via - * the maven-jar-plugin. - */ - @Parameter(property = "runnableJar", required = false) - private File runnableJar; - - /** - * Whether or not to copy dependencies into the bundle. Generally, you will only disable this if you specified - * a runnableJar with all dependencies shaded into the .jar itself. - */ - @Parameter(defaultValue = "true", property = "copyDependencies", required = true) - private Boolean copyDependencies; - - /** - * Bundled JRE directory name - */ - @Parameter(defaultValue = "jre", property = "jreDirectoryName", required = false) - private String jreDirectoryName; - - /** - * GNU/Linux specific config - */ - @Parameter(property = "linuxConfig", required = false) - private LinuxConfig linuxConfig; - - /** - * Mac OS X specific config - */ - @Parameter(property = "macConfig", required = false) - private MacConfig macConfig; - - /** - * Windows specific config - */ - @Parameter(property = "winConfig", required = false) - private WindowsConfig winConfig; - - /** - * Bundles app in a tarball file - */ - @Parameter(defaultValue = "false", property = "createTarball", required = false) - private Boolean createTarball; - - /** - * Bundles app in a zipball file - */ - @Parameter(defaultValue = "false", property = "createZipball", required = false) - private Boolean createZipball; - - /** - * Extra properties for customized Velocity templates, accesible through '$this.extra' map. - */ - @Parameter(required = false) - private Map extra; - - /** - * Uses app resources folder as default working directory. - */ - @Parameter(defaultValue = "true", property = "useResourcesAsWorkingDir", required = false) - private boolean useResourcesAsWorkingDir; - - /** - * Assets directory - */ - @Parameter(defaultValue = "${project.basedir}/assets", property = "assetsDir", required = false) - private File assetsDir; - - /** - * Classpath - */ - @Parameter(property = "classpath", required = false) - private String classpath; - - /** - * JRE min version - */ - @Parameter(property = "jreMinVersion", required = false) - private String jreMinVersion; - - /** - * Additional JAR manifest entries - */ - @Parameter(required = false) - private Manifest manifest; - - /** - * Additional module paths - */ - @Parameter(property = "additionalModulePaths", required = false) - private List additionalModulePaths; - - /** - * Packaging JDK - */ - @Parameter(defaultValue = "${java.home}", property = "packagingJdk", required = false) - private File packagingJdk; - - /** - * Additional module paths - */ - @Parameter(property = "fileAssociations", required = false) - private List fileAssociations; - - /** - * Scripts - */ - @Parameter(property = "scripts", required = false) - private Scripts scripts; - - public void execute() throws MojoExecutionException { - - Context.setContext( - new MavenContext( - executionEnvironment(mavenProject, mavenSession, pluginManager), - getLog() - ) - ); - - try { - - Packager packager = - (Packager) PackagerFactory - .createPackager(platform) - .additionalModules(additionalModules) - .additionalModulePaths(additionalModulePaths) - .additionalResources(additionalResources) - .administratorRequired(administratorRequired) - .assetsDir(assetsDir) - .bundleJre(bundleJre) - .classpath(classpath) - .copyDependencies(copyDependencies) - .createTarball(createTarball) - .createZipball(createZipball) - .customizedJre(customizedJre) - .description(description) - .displayName(displayName) - .envPath(envPath) - .extra(extra) - .fileAssociations(fileAssociations) - .forceInstaller(forceInstaller) - .generateInstaller(generateInstaller) - .iconFile(iconFile) - .jdkPath(jdkPath) - .jreDirectoryName(jreDirectoryName) - .jreMinVersion(jreMinVersion) - .jrePath(jrePath) - .licenseFile(licenseFile) - .linuxConfig(linuxConfig) - .macConfig(macConfig) - .mainClass(mainClass) - .manifest(manifest) - .modules(modules) - .name(defaultIfBlank(name, Context.getMavenContext().getEnv().getMavenProject().getArtifactId())) - .organizationEmail(organizationEmail) - .organizationName(organizationName) - .organizationUrl(organizationUrl) - .outputDirectory(outputDirectory) - .packagingJdk(packagingJdk) - .runnableJar(runnableJar) - .scripts(scripts) - .useResourcesAsWorkingDir(useResourcesAsWorkingDir) - .url(url) - .version(version) - .vmArgs(vmArgs) - .winConfig(winConfig); - - // generate app, installers and bundles - packager.createApp(); - packager.generateInstallers(); - packager.createBundles(); - - } catch (Exception e) { - - throw new MojoExecutionException(e.getMessage(), e); - - } - - - } - - -} diff --git a/src/main/java/io/github/fvarrui/javapackager/maven/ResolveLicenseFromPOM.java b/src/main/java/io/github/fvarrui/javapackager/maven/ResolveLicenseFromPOM.java index d3498ae5..2d729cdf 100644 --- a/src/main/java/io/github/fvarrui/javapackager/maven/ResolveLicenseFromPOM.java +++ b/src/main/java/io/github/fvarrui/javapackager/maven/ResolveLicenseFromPOM.java @@ -27,7 +27,7 @@ public ResolveLicenseFromPOM() { protected File doApply(Packager packager) { Logger.infoIndent("Trying to resolve license from POM ..."); - File licenseFile = packager.getLicenseFile(); + File licenseFile = packager.task.getLicenseFile(); List licenses = Context.getMavenContext().getEnv().getMavenProject().getLicenses(); File assetsFolder = packager.getAssetsFolder(); diff --git a/src/main/java/io/github/fvarrui/javapackager/model/MacConfig.java b/src/main/java/io/github/fvarrui/javapackager/model/MacConfig.java index 96e4010a..825a72b0 100644 --- a/src/main/java/io/github/fvarrui/javapackager/model/MacConfig.java +++ b/src/main/java/io/github/fvarrui/javapackager/model/MacConfig.java @@ -285,6 +285,6 @@ public void setDefaults(Packager packager) { this.setIconY(defaultIfNull(this.getIconY(), 116)); this.setAppsLinkIconX(defaultIfNull(this.getAppsLinkIconX(), 360)); this.setAppsLinkIconY(defaultIfNull(this.getAppsLinkIconY(), 116)); - this.setAppId(defaultIfNull(this.getAppId(), packager.getMainClass())); + this.setAppId(defaultIfNull(this.getAppId(), packager.task.getMainClass())); } } diff --git a/src/main/java/io/github/fvarrui/javapackager/model/WindowsConfig.java b/src/main/java/io/github/fvarrui/javapackager/model/WindowsConfig.java index 8f7637e3..51b5f0d8 100644 --- a/src/main/java/io/github/fvarrui/javapackager/model/WindowsConfig.java +++ b/src/main/java/io/github/fvarrui/javapackager/model/WindowsConfig.java @@ -329,15 +329,15 @@ public String toString() { public void setDefaults(Packager packager) { this.setHeaderType(ObjectUtils.defaultIfNull(this.getHeaderType(), HeaderType.gui)); this.setFileVersion(defaultIfBlank(this.getFileVersion(), "1.0.0.0")); - this.setTxtFileVersion(defaultIfBlank(this.getTxtFileVersion(), "" + packager.getVersion())); + this.setTxtFileVersion(defaultIfBlank(this.getTxtFileVersion(), "" + packager.task.getVersion())); this.setProductVersion(defaultIfBlank(this.getProductVersion(), "1.0.0.0")); - this.setTxtProductVersion(defaultIfBlank(this.getTxtProductVersion(), "" + packager.getVersion())); - this.setCompanyName(defaultIfBlank(this.getCompanyName(), packager.getOrganizationName())); - this.setCopyright(defaultIfBlank(this.getCopyright(), packager.getOrganizationName())); - this.setFileDescription(defaultIfBlank(this.getFileDescription(), packager.getDescription())); - this.setProductName(defaultIfBlank(this.getProductName(), packager.getName())); - this.setInternalName(defaultIfBlank(this.getInternalName(), packager.getName())); - this.setOriginalFilename(defaultIfBlank(this.getOriginalFilename(), packager.getName() + ".exe")); + this.setTxtProductVersion(defaultIfBlank(this.getTxtProductVersion(), "" + packager.task.getVersion())); + this.setCompanyName(defaultIfBlank(this.getCompanyName(), packager.task.getOrganizationName())); + this.setCopyright(defaultIfBlank(this.getCopyright(), packager.task.getOrganizationName())); + this.setFileDescription(defaultIfBlank(this.getFileDescription(), packager.task.getDescription())); + this.setProductName(defaultIfBlank(this.getProductName(), packager.task.getAppName())); + this.setInternalName(defaultIfBlank(this.getInternalName(), packager.task.getAppName())); + this.setOriginalFilename(defaultIfBlank(this.getOriginalFilename(), packager.task.getAppName() + ".exe")); this.setMsiUpgradeCode(defaultIfBlank(this.getMsiUpgradeCode(), UUID.randomUUID().toString())); } diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/AbstractCreateWindowsExe.java b/src/main/java/io/github/fvarrui/javapackager/packagers/AbstractCreateWindowsExe.java index 6f7288a6..22f5c361 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/AbstractCreateWindowsExe.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/AbstractCreateWindowsExe.java @@ -65,7 +65,7 @@ public File getOutputFolder() { protected void createAssets(WindowsPackager packager) throws Exception { File manifestFile = packager.getManifestFile(); - File iconFile = packager.getIconFile(); + File iconFile = packager.task.getIconFile(); File jarFile = packager.getJarFile(); FileUtils.mkdir(outputFolder); @@ -90,10 +90,10 @@ protected void createAssets(WindowsPackager packager) throws Exception { protected File createBootstrapScript(WindowsPackager packager) throws Exception { File executable = packager.getExecutable(); - if (FileUtils.exists(packager.getScripts().getBootstrap())) { + if (FileUtils.exists(packager.task.getScripts().getBootstrap())) { // generates startup VBS script file - File vbsFile = new File(packager.getAppFolder(), packager.getName() + ".vbs"); + File vbsFile = new File(packager.getAppFolder(), packager.task.getAppName() + ".vbs"); VelocityUtils.render(Platform.windows + "/startup.vbs.vtl", vbsFile, packager); executable = vbsFile; diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/BundleJre.java b/src/main/java/io/github/fvarrui/javapackager/packagers/BundleJre.java index b649623d..8e945f13 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/BundleJre.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/BundleJre.java @@ -27,25 +27,25 @@ public BundleJre() { @Override public boolean skip(Packager packager) { - return !packager.getBundleJre(); + return !packager.task.getBundleJre(); } @Override protected File doApply(Packager packager) throws Exception { - boolean bundleJre = packager.getBundleJre(); - File specificJreFolder = packager.getJrePath(); - Platform platform = packager.getPlatform(); + boolean bundleJre = packager.task.getBundleJre(); + File specificJreFolder = packager.task.getJrePath(); + Platform platform = packager.task.getPlatform(); File destinationFolder = packager.getJreDestinationFolder(); - File jdkPath = packager.getJdkPath(); + File jdkPath = packager.task.getJdkPath(); File libsFolder = packager.getLibsFolder(); - boolean customizedJre = packager.getCustomizedJre(); + boolean customizedJre = packager.task.getCustomizedJre(); File jarFile = packager.getJarFile(); - List requiredModules = packager.getModules(); - List additionalModules = packager.getAdditionalModules(); - List additionalModulePaths = packager.getAdditionalModulePaths(); + List requiredModules = packager.task.getModules(); + List additionalModules = packager.task.getAdditionalModules(); + List additionalModulePaths = packager.task.getAdditionalModulePaths(); - File currentJdk = packager.getPackagingJdk(); + File currentJdk = packager.task.getPackagingJdk(); Logger.infoIndent("Bundling JRE ... with " + currentJdk); @@ -165,7 +165,7 @@ protected File doApply(Packager packager) throws Exception { // updates bundle jre property value, as this artifact generator could disable this option // (e.g. when bundling a jre from a different platform than the current one) - packager.bundleJre(bundleJre); + packager.task.bundleJre(bundleJre); return destinationFolder; } diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/Context.java b/src/main/java/io/github/fvarrui/javapackager/packagers/Context.java index be4527e0..4bd3a938 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/Context.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/Context.java @@ -28,7 +28,14 @@ public Context() { getInstallerGenerators(Platform.windows).add(new GenerateSetup()); getInstallerGenerators(Platform.windows).add(new GenerateMsm()); getInstallerGenerators(Platform.windows).add(new GenerateMsi()); - + + getInstallerGenerators(Platform.linux).add(new GenerateNativeImage()); + getInstallerGenerators(Platform.mac).add(new GenerateNativeImage()); + getInstallerGenerators(Platform.windows).add(new GenerateNativeImage()); + + getInstallerGenerators(Platform.linux).add(new GenerateSharedLibrary()); + getInstallerGenerators(Platform.mac).add(new GenerateSharedLibrary()); + getInstallerGenerators(Platform.windows).add(new GenerateSharedLibrary()); } // common properties diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/CreateWindowsExeWhy.java b/src/main/java/io/github/fvarrui/javapackager/packagers/CreateWindowsExeWhy.java index e424d26e..4875614d 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/CreateWindowsExeWhy.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/CreateWindowsExeWhy.java @@ -21,8 +21,8 @@ public CreateWindowsExeWhy() { @Override public boolean skip(WindowsPackager packager) { - if (!packager.getPlatform().isCurrentPlatform()) { - Logger.error(getArtifactName() + " cannot be generated with Why due to the target platform (" + packager.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); + if (!packager.task.getPlatform().isCurrentPlatform()) { + Logger.error(getArtifactName() + " cannot be generated with Why due to the target platform (" + packager.task.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); return true; } @@ -32,13 +32,13 @@ public boolean skip(WindowsPackager packager) { @Override protected File doApply(WindowsPackager packager) throws Exception { - String name = packager.getName(); + String name = packager.task.getAppName(); File executable = packager.getExecutable(); File manifestFile = packager.getManifestFile(); - File iconFile = packager.getIconFile(); + File iconFile = packager.task.getIconFile(); File appFolder = packager.getAppFolder(); File jarFile = packager.getJarFile(); - WindowsConfig winConfig = packager.getWinConfig(); + WindowsConfig winConfig = packager.task.getWinConfig(); if (winConfig.isWrapJar()) { Logger.warn("'wrapJar' property ignored when building EXE with " + getArtifactName()); @@ -53,7 +53,7 @@ protected File doApply(WindowsPackager packager) throws Exception { FileUtils.copyFileToFile(iconFile, getGenericIcon()); // creates generic exe - FileUtils.copyResourceToFile("/windows/JavaLauncher.exe", getGenericExe(), packager.getAssetsDir()); + FileUtils.copyResourceToFile("/windows/JavaLauncher.exe", getGenericExe(), packager.task.getAssetsDir()); // copies rcedit command line tool (needed to manipulate exe) File rcedit = new File(getOutputFolder(), "rcedit.exe"); diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/CreateWindowsExeWinRun4j.java b/src/main/java/io/github/fvarrui/javapackager/packagers/CreateWindowsExeWinRun4j.java index 840e0e4c..dbdfd8c1 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/CreateWindowsExeWinRun4j.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/CreateWindowsExeWinRun4j.java @@ -34,8 +34,8 @@ public CreateWindowsExeWinRun4j() { @Override public boolean skip(WindowsPackager packager) { - if (!packager.getPlatform().isCurrentPlatform()) { - Logger.error(getArtifactName() + " cannot be generated with WinRun4J due to the target platform (" + packager.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); + if (!packager.task.getPlatform().isCurrentPlatform()) { + Logger.error(getArtifactName() + " cannot be generated with WinRun4J due to the target platform (" + packager.task.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); return true; } @@ -45,18 +45,18 @@ public boolean skip(WindowsPackager packager) { @Override protected File doApply(WindowsPackager packager) throws Exception { - String name = packager.getName(); + String name = packager.task.getAppName(); File executable = packager.getExecutable(); File jarFile = packager.getJarFile(); File manifestFile = packager.getManifestFile(); - File iconFile = packager.getIconFile(); + File iconFile = packager.task.getIconFile(); File libsFolder = packager.getLibsFolder(); File appFolder = packager.getAppFolder(); - String mainClass = packager.getMainClass(); + String mainClass = packager.task.getMainClass(); File jreDestinationFolder = packager.getJreDestinationFolder(); - boolean bundleJre = packager.getBundleJre(); - String vmLocation = packager.getWinConfig().getVmLocation(); - WindowsConfig winConfig = packager.getWinConfig(); + boolean bundleJre = packager.task.getBundleJre(); + String vmLocation = packager.task.getWinConfig().getVmLocation(); + WindowsConfig winConfig = packager.task.getWinConfig(); if (winConfig.isWrapJar()) { Logger.warn("'wrapJar' property ignored when building EXE with " + getArtifactName()); @@ -112,7 +112,7 @@ protected File doApply(WindowsPackager packager) throws Exception { } // sets vmLocation in winConfig, so it will be used when rendering INI file - packager.getWinConfig().setVmLocation(vmLocation); + packager.task.getWinConfig().setVmLocation(vmLocation); Logger.info("Using 'vmLocation=" + vmLocation + "'!"); diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateAppImage.java b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateAppImage.java index a076215e..a63bf6bf 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateAppImage.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateAppImage.java @@ -23,12 +23,12 @@ public GenerateAppImage() { @Override public boolean skip(LinuxPackager packager) { - if (!packager.getLinuxConfig().isGenerateAppImage()) { + if (!packager.task.getLinuxConfig().isGenerateAppImage()) { return true; } - if (!packager.getPlatform().isCurrentPlatform() && !packager.isForceInstaller()) { - Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); + if (!packager.task.getPlatform().isCurrentPlatform() && !packager.task.isForceInstaller()) { + Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.task.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); return true; } @@ -40,11 +40,11 @@ public boolean skip(LinuxPackager packager) { protected File doApply(LinuxPackager packager) throws Exception { File appFolder = packager.getAppFolder(); - File outputFolder = packager.getOutputDirectory(); - String name = packager.getName(); + File outputFolder = packager.task.getOutputDirectory(); + String name = packager.task.getAppName(); File executable = packager.getExecutable(); File assetsFolder = packager.getAssetsFolder(); - File iconFile = packager.getIconFile(); + File iconFile = packager.task.getIconFile(); // output AppImage file File appImage = new File(outputFolder, name + ".AppImage"); diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateDeb.java b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateDeb.java index 8c4852b1..3667eee6 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateDeb.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateDeb.java @@ -48,19 +48,19 @@ public void debug(String message) { @Override public boolean skip(LinuxPackager packager) { - return !packager.getLinuxConfig().isGenerateDeb(); + return !packager.task.getLinuxConfig().isGenerateDeb(); } @Override protected File doApply(LinuxPackager packager) throws Exception { File assetsFolder = packager.getAssetsFolder(); - String name = packager.getName(); + String name = packager.task.getAppName(); File appFolder = packager.getAppFolder(); - File outputDirectory = packager.getOutputDirectory(); - String version = packager.getVersion(); - boolean bundleJre = packager.getBundleJre(); - String jreDirectoryName = packager.getJreDirectoryName(); + File outputDirectory = packager.task.getOutputDirectory(); + String version = packager.task.getVersion(); + boolean bundleJre = packager.task.getBundleJre(); + String jreDirectoryName = packager.task.getJreDirectoryName(); File executable = packager.getExecutable(); File javaFile = new File(appFolder, jreDirectoryName + "/bin/java"); diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateDmg.java b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateDmg.java index e0b2d610..7910ba8f 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateDmg.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateDmg.java @@ -28,12 +28,12 @@ public GenerateDmg() { @Override public boolean skip(MacPackager packager) { - if (!packager.getMacConfig().isGenerateDmg()) { + if (!packager.task.getMacConfig().isGenerateDmg()) { return true; } - if (!packager.getPlatform().isCurrentPlatform() && !packager.isForceInstaller()) { - Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); + if (!packager.task.getPlatform().isCurrentPlatform() && !packager.task.isForceInstaller()) { + Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.task.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); return true; } @@ -45,11 +45,11 @@ protected File doApply(MacPackager packager) throws Exception { File appFolder = packager.getAppFolder(); File assetsFolder = packager.getAssetsFolder(); - String name = packager.getName(); - File outputDirectory = packager.getOutputDirectory(); - File iconFile = packager.getIconFile(); - String version = packager.getVersion(); - MacConfig macConfig = packager.getMacConfig(); + String name = packager.task.getAppName(); + File outputDirectory = packager.task.getOutputDirectory(); + File iconFile = packager.task.getIconFile(); + String version = packager.task.getVersion(); + MacConfig macConfig = packager.task.getMacConfig(); // sets volume name if blank String volumeName = defaultIfBlank(macConfig.getVolumeName(), name); diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateMsi.java b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateMsi.java index 10f3e9ca..3ac3e134 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateMsi.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateMsi.java @@ -22,12 +22,12 @@ public GenerateMsi() { @Override public boolean skip(WindowsPackager packager) { - if (!packager.getWinConfig().isGenerateMsi()) { + if (!packager.task.getWinConfig().isGenerateMsi()) { return true; } - if (!packager.getPlatform().isCurrentPlatform() && !packager.isForceInstaller()) { - Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); + if (!packager.task.getPlatform().isCurrentPlatform() && !packager.task.isForceInstaller()) { + Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.task.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); return true; } @@ -41,9 +41,9 @@ protected File doApply(WindowsPackager packager) throws Exception { Logger.info("MSM file generated in " + msmFile); File assetsFolder = packager.getAssetsFolder(); - String name = packager.getName(); - File outputDirectory = packager.getOutputDirectory(); - String version = packager.getVersion(); + String name = packager.task.getAppName(); + File outputDirectory = packager.task.getOutputDirectory(); + String version = packager.task.getVersion(); // generates WXS file from velocity template File wxsFile = new File(assetsFolder, name + ".wxs"); diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateMsm.java b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateMsm.java index 3aad9dc4..01c40bea 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateMsm.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateMsm.java @@ -21,12 +21,12 @@ public GenerateMsm() { @Override public boolean skip(WindowsPackager packager) { - if (!packager.getWinConfig().isGenerateMsm() && !packager.getWinConfig().isGenerateMsi()) { + if (!packager.task.getWinConfig().isGenerateMsm() && !packager.task.getWinConfig().isGenerateMsi()) { return true; } - if (!packager.getPlatform().isCurrentPlatform() && !packager.isForceInstaller()) { - Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); + if (!packager.task.getPlatform().isCurrentPlatform() && !packager.task.isForceInstaller()) { + Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.task.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); return true; } @@ -41,9 +41,9 @@ protected File doApply(WindowsPackager packager) throws Exception { } File assetsFolder = packager.getAssetsFolder(); - String name = packager.getName(); - File outputDirectory = packager.getOutputDirectory(); - String version = packager.getVersion(); + String name = packager.task.getAppName(); + File outputDirectory = packager.task.getOutputDirectory(); + String version = packager.task.getVersion(); // generates WXS file from velocity template File wxsFile = new File(assetsFolder, name + ".msm.wxs"); diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateNativeImage.java b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateNativeImage.java new file mode 100644 index 00000000..dfd61b20 --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateNativeImage.java @@ -0,0 +1,36 @@ +package io.github.fvarrui.javapackager.packagers; + +import io.github.fvarrui.javapackager.utils.*; + +import java.io.File; +import java.util.Objects; + +public class GenerateNativeImage extends ArtifactGenerator { + + public GenerateNativeImage() { + super("Native Image"); + } + + @Override + public boolean skip(Packager packager) { + + if (!packager.task.isNativeImage()) { + return true; + } + + if (!Objects.equals(packager.task.getJdkVendor(), Const.graalvm)) { + Logger.warn(getArtifactName() + " cannot be generated because '"+Const.graalvm +"' was expected as jdkVendor, but provided '"+packager.task.getJdkVendor()+"'!"); + return true; + } + + return false; + } + + @Override + protected File doApply(Packager packager) throws Exception { + File outputDirectory = packager.task.getOutputDirectory(); + GraalVM graalVM = new GraalVM(packager.task.getJdkPath()); + return graalVM.generateNativeImage(packager.task.getPlatform(), outputDirectory); + } + +} diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/GeneratePkg.java b/src/main/java/io/github/fvarrui/javapackager/packagers/GeneratePkg.java index 69e595be..0113f3aa 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/GeneratePkg.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/GeneratePkg.java @@ -19,12 +19,12 @@ public GeneratePkg() { @Override public boolean skip(MacPackager packager) { - if (!packager.getMacConfig().isGeneratePkg()) { + if (!packager.task.getMacConfig().isGeneratePkg()) { return true; } - if (!packager.getPlatform().isCurrentPlatform() && !packager.isForceInstaller()) { - Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); + if (!packager.task.getPlatform().isCurrentPlatform() && !packager.task.isForceInstaller()) { + Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.task.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); return true; } @@ -35,9 +35,9 @@ public boolean skip(MacPackager packager) { protected File doApply(MacPackager packager) throws Exception { File appFile = packager.getAppFile(); - String name = packager.getName(); - File outputDirectory = packager.getOutputDirectory(); - String version = packager.getVersion(); + String name = packager.task.getAppName(); + File outputDirectory = packager.task.getOutputDirectory(); + String version = packager.task.getVersion(); File pkgFile = new File(outputDirectory, name + "_" + version + ".pkg"); diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateRpm.java b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateRpm.java index b139a373..45d85b19 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateRpm.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateRpm.java @@ -27,21 +27,21 @@ public GenerateRpm() { @Override public boolean skip(LinuxPackager packager) { - return !packager.getLinuxConfig().isGenerateRpm(); + return !packager.task.getLinuxConfig().isGenerateRpm(); } @Override protected File doApply(LinuxPackager packager) throws Exception { File appFolder = packager.getAppFolder(); - String name = packager.getName(); - String version = packager.getVersion().replaceAll("-", "_"); - String description = packager.getDescription(); - String organizationName = packager.getOrganizationName(); - File outputDirectory = packager.getOutputDirectory(); + String name = packager.task.getAppName(); + String version = packager.task.getVersion().replaceAll("-", "_"); + String description = packager.task.getDescription(); + String organizationName = packager.task.getOrganizationName(); + File outputDirectory = packager.task.getOutputDirectory(); File executable = packager.getExecutable(); File assetsFolder = packager.getAssetsFolder(); - String jreDirectoryName = packager.getJreDirectoryName(); + String jreDirectoryName = packager.task.getJreDirectoryName(); // generates desktop file from velocity template File desktopFile = new File(assetsFolder, name + ".desktop"); diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateSetup.java b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateSetup.java index 5821da62..9977ccd2 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateSetup.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateSetup.java @@ -24,12 +24,12 @@ public GenerateSetup() { @Override public boolean skip(WindowsPackager packager) { - if (!packager.getWinConfig().isGenerateSetup()) { + if (!packager.task.getWinConfig().isGenerateSetup()) { return true; } - if (!packager.getPlatform().isCurrentPlatform() && !packager.isForceInstaller()) { - Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); + if (!packager.task.getPlatform().isCurrentPlatform() && !packager.task.isForceInstaller()) { + Logger.warn(getArtifactName() + " cannot be generated due to the target platform (" + packager.task.getPlatform() + ") is different from the execution platform (" + Platform.getCurrentPlatform() + ")!"); return true; } @@ -39,12 +39,12 @@ public boolean skip(WindowsPackager packager) { @Override protected File doApply(WindowsPackager packager) throws Exception { - File iconFile = packager.getIconFile(); + File iconFile = packager.task.getIconFile(); File assetsFolder = packager.getAssetsFolder(); - String name = packager.getName(); - File outputDirectory = packager.getOutputDirectory(); - String version = packager.getVersion(); - Registry registry = packager.getWinConfig().getRegistry(); + String name = packager.task.getAppName(); + File outputDirectory = packager.task.getOutputDirectory(); + String version = packager.task.getVersion(); + Registry registry = packager.task.getWinConfig().getRegistry(); // checks if registry entries' names are not empy if (registry.getEntries().stream().anyMatch(e -> StringUtils.isBlank(e.getKey()) || StringUtils.isBlank(e.getValueName()))) { diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateSharedLibrary.java b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateSharedLibrary.java new file mode 100644 index 00000000..aa522d39 --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/GenerateSharedLibrary.java @@ -0,0 +1,38 @@ +package io.github.fvarrui.javapackager.packagers; + +import io.github.fvarrui.javapackager.utils.Const; +import io.github.fvarrui.javapackager.utils.GraalVM; +import io.github.fvarrui.javapackager.utils.Logger; + +import java.io.File; +import java.util.Objects; + +public class GenerateSharedLibrary extends ArtifactGenerator { + + public GenerateSharedLibrary() { + super("Shared library"); + } + + @Override + public boolean skip(Packager packager) { + + if (!packager.task.isSharedLibrary()) { + return true; + } + + if (!Objects.equals(packager.task.getJdkVendor(), Const.graalvm)) { + Logger.warn(getArtifactName() + " cannot be generated because '"+Const.graalvm +"' was expected as jdkVendor, but provided '"+packager.task.getJdkVendor()+"'!"); + return true; + } + + return false; + } + + @Override + protected File doApply(Packager packager) throws Exception { + File outputDirectory = packager.task.getOutputDirectory(); + GraalVM graalVM = new GraalVM(packager.task.getJdkPath()); + return graalVM.generateSharedLibrary(packager.task.getPlatform(), outputDirectory); + } + +} diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/LinuxPackager.java b/src/main/java/io/github/fvarrui/javapackager/packagers/LinuxPackager.java index 8a1d091a..e095f083 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/LinuxPackager.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/LinuxPackager.java @@ -4,6 +4,7 @@ import java.util.Arrays; import java.util.stream.Collectors; +import io.github.fvarrui.javapackager.PackageTask; import org.apache.commons.lang3.StringUtils; import io.github.fvarrui.javapackager.model.Platform; @@ -19,8 +20,8 @@ public class LinuxPackager extends Packager { private File desktopFile; private File mimeXmlFile = null; - public LinuxPackager() { - super(); + public LinuxPackager(PackageTask task) { + super(task); installerGenerators.addAll(Context.getContext().getInstallerGenerators(Platform.linux)); } @@ -36,7 +37,7 @@ public File getMimeXmlFile() { public void doInit() throws Exception { // sets linux config default values - this.linuxConfig.setDefaults(this); + task.getLinuxConfig().setDefaults(this); } @@ -46,7 +47,7 @@ protected void doCreateAppStructure() throws Exception { // sets common folders this.executableDestinationFolder = appFolder; this.jarFileDestinationFolder = appFolder; - this.jreDestinationFolder = new File(appFolder, jreDirectoryName); + this.jreDestinationFolder = new File(appFolder, task.getJreDirectoryName()); this.resourcesDestinationFolder = appFolder; } @@ -60,25 +61,25 @@ public File doCreateApp() throws Exception { Logger.infoIndent("Creating GNU/Linux executable ..."); // sets executable file - this.executable = new File(appFolder, name); + this.executable = new File(appFolder, task.getAppName()); // process classpath - if (classpath != null) { - classpaths = Arrays.asList(classpath.split("[:;]")); - if (!isUseResourcesAsWorkingDir()) { + if (task.getClasspath() != null) { + classpaths = Arrays.asList(task.getClasspath().split("[:;]")); + if (!task.isUseResourcesAsWorkingDir()) { classpaths = classpaths.stream().map(cp -> new File(cp).isAbsolute() ? cp : "$SCRIPTPATH/" + cp).collect(Collectors.toList()); } - classpath = StringUtils.join(classpaths, ":"); + task.classpath(StringUtils.join(classpaths, ":")); } // generates desktop file from velocity template - desktopFile = new File(assetsFolder, name + ".desktop"); + desktopFile = new File(assetsFolder, task.getAppName() + ".desktop"); VelocityUtils.render("linux/desktop.vtl", desktopFile, this); Logger.info("Rendering desktop file to " + desktopFile.getAbsolutePath()); // generates mime.xml file from velocity template - if (isThereFileAssociations()) { - mimeXmlFile = new File(assetsFolder, name + ".xml"); + if (task.isThereFileAssociations()) { + mimeXmlFile = new File(assetsFolder, task.getAppName() + ".xml"); VelocityUtils.render("linux/mime.xml.vtl", mimeXmlFile, this); Logger.info("Rendering mime.xml file to " + mimeXmlFile.getAbsolutePath()); } @@ -89,7 +90,7 @@ public File doCreateApp() throws Exception { Logger.info("Startup script generated in " + startupFile.getAbsolutePath()); // concats linux startup.sh script + generated jar in executable (binary) - if (getLinuxConfig().isWrapJar()) + if (task.getLinuxConfig().isWrapJar()) FileUtils.concat(executable, startupFile, jarFile); else { FileUtils.copyFileToFile(startupFile, executable); diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/MacPackager.java b/src/main/java/io/github/fvarrui/javapackager/packagers/MacPackager.java index e7da3a5d..a5e48aaa 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/MacPackager.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/MacPackager.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.stream.Collectors; +import io.github.fvarrui.javapackager.PackageTask; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.SystemUtils; @@ -29,6 +30,10 @@ public class MacPackager extends Packager { private File javaFolder; private File macOSFolder; + public MacPackager(PackageTask task) { + super(task); + } + public File getAppFile() { return appFile; } @@ -36,12 +41,12 @@ public File getAppFile() { @Override public void doInit() throws Exception { - this.macConfig.setDefaults(this); + this.task.getMacConfig().setDefaults(this); // FIX useResourcesAsWorkingDir=false doesn't work fine on Mac OS (option // disabled) - if (!this.isUseResourcesAsWorkingDir()) { - this.useResourcesAsWorkingDir = true; + if (!this.task.isUseResourcesAsWorkingDir()) { + this.task.useResourcesAsWorkingDir(true); Logger.warn( "'useResourcesAsWorkingDir' property disabled on Mac OS (useResourcesAsWorkingDir is always true)"); } @@ -52,10 +57,10 @@ public void doInit() throws Exception { protected void doCreateAppStructure() throws Exception { // initializes the references to the app structure folders - this.appFile = new File(appFolder, name + ".app"); + this.appFile = new File(appFolder, task.getAppName() + ".app"); this.contentsFolder = new File(appFile, "Contents"); this.resourcesFolder = new File(contentsFolder, "Resources"); - this.javaFolder = new File(resourcesFolder, this.macConfig.isRelocateJar() ? "Java" : ""); + this.javaFolder = new File(resourcesFolder, this.task.getMacConfig().isRelocateJar() ? "Java" : ""); this.macOSFolder = new File(contentsFolder, "MacOS"); // makes dirs @@ -78,7 +83,7 @@ protected void doCreateAppStructure() throws Exception { // sets common folders this.executableDestinationFolder = macOSFolder; this.jarFileDestinationFolder = javaFolder; - this.jreDestinationFolder = new File(contentsFolder, "PlugIns/" + jreDirectoryName + "/Contents/Home"); + this.jreDestinationFolder = new File(contentsFolder, "PlugIns/" + task.getJreDirectoryName() + "/Contents/Home"); this.resourcesDestinationFolder = resourcesFolder; } @@ -107,7 +112,7 @@ public File doCreateApp() throws Exception { private void processStartupScript() throws Exception { - if (this.administratorRequired) { + if (task.getAdministratorRequired()) { // We need a helper script ("startup") in this case, // which invokes the launcher script/ executable with administrator rights. @@ -121,7 +126,7 @@ private void processStartupScript() throws Exception { } else { - File launcher = macConfig.getCustomLauncher(); + File launcher = task.getMacConfig().getCustomLauncher(); if(launcher != null && launcher.canRead() && launcher.isFile()){ FileUtils.copyFileToFolder(launcher, macOSFolder); this.executable = new File(macOSFolder, launcher.getName()); @@ -136,15 +141,15 @@ private void processStartupScript() throws Exception { private void processClasspath() { // TODO: Why are we doing this here? I do not see any usage of 'classpath' or 'classpaths' here. - classpath = (this.macConfig.isRelocateJar() ? "Java/" : "") + this.jarFile.getName() + (classpath != null ? ":" + classpath : ""); - classpaths = Arrays.asList(classpath.split("[:;]")); - if (!isUseResourcesAsWorkingDir()) { + task.classpath((task.getMacConfig().isRelocateJar() ? "Java/" : "") + this.jarFile.getName() + (task.getClasspath() != null ? ":" + task.getClasspath() : "")); + classpaths = Arrays.asList(task.getClasspath().split("[:;]")); + if (!task.isUseResourcesAsWorkingDir()) { classpaths = classpaths .stream() .map(cp -> new File(cp).isAbsolute() ? cp : "$ResourcesFolder/" + cp) .collect(Collectors.toList()); } - classpath = StringUtils.join(classpaths, ":"); + task.classpath(StringUtils.join(classpaths, ":")); } /** @@ -153,8 +158,8 @@ private void processClasspath() { */ private void processInfoPlistFile() throws Exception { File infoPlistFile = new File(contentsFolder, "Info.plist"); - if(macConfig.getCustomInfoPlist() != null && macConfig.getCustomInfoPlist().isFile() && macConfig.getCustomInfoPlist().canRead()){ - FileUtils.copyFileToFile(macConfig.getCustomInfoPlist(), infoPlistFile); + if(task.getMacConfig().getCustomInfoPlist() != null && task.getMacConfig().getCustomInfoPlist().isFile() && task.getMacConfig().getCustomInfoPlist().canRead()){ + FileUtils.copyFileToFile(task.getMacConfig().getCustomInfoPlist(), infoPlistFile); } else { VelocityUtils.render("mac/Info.plist.vtl", infoPlistFile, this); XMLUtils.prettify(infoPlistFile); @@ -165,20 +170,20 @@ private void processInfoPlistFile() throws Exception { private void codesign() throws Exception { if (!Platform.mac.isCurrentPlatform()) { Logger.warn("Generated app could not be signed due to current platform is " + Platform.getCurrentPlatform()); - } else if (!getMacConfig().isCodesignApp()) { + } else if (!task.getMacConfig().isCodesignApp()) { Logger.warn("App codesigning disabled"); } else { - codesign(this.macConfig.getDeveloperId(), this.macConfig.getEntitlements(), this.appFile); + codesign(task.getMacConfig().getDeveloperId(), task.getMacConfig().getEntitlements(), this.appFile); } } private void processProvisionProfileFile() throws Exception { - if (macConfig.getProvisionProfile() != null && macConfig.getProvisionProfile().isFile() && macConfig.getProvisionProfile().canRead()) { + if (task.getMacConfig().getProvisionProfile() != null && task.getMacConfig().getProvisionProfile().isFile() && task.getMacConfig().getProvisionProfile().canRead()) { // file name must be 'embedded.provisionprofile' File provisionProfile = new File(contentsFolder, "embedded.provisionprofile"); - FileUtils.copyFileToFile(macConfig.getProvisionProfile(), provisionProfile); + FileUtils.copyFileToFile(task.getMacConfig().getProvisionProfile(), provisionProfile); Logger.info("Provision profile file created from " + "\n" + - macConfig.getProvisionProfile() + " to \n" + + task.getMacConfig().getProvisionProfile() + " to \n" + provisionProfile.getAbsolutePath()); } } @@ -187,14 +192,14 @@ private File preparePrecompiledStartupStub() throws Exception { // sets startup file File appStubFile = new File(macOSFolder, "universalJavaApplicationStub"); String universalJavaApplicationStubResource = null; - switch (macConfig.getMacStartup()) { + switch (task.getMacConfig().getMacStartup()) { case UNIVERSAL: universalJavaApplicationStubResource = "universalJavaApplicationStub"; break; case X86_64: universalJavaApplicationStubResource = "universalJavaApplicationStub.x86_64"; break; case ARM64: universalJavaApplicationStubResource = "universalJavaApplicationStub.arm64"; break; case SCRIPT: universalJavaApplicationStubResource = "universalJavaApplicationStub.sh"; break; } // unixStyleNewLinux=true if startup is a script (this will replace '\r\n' with '\n') - FileUtils.copyResourceToFile("/mac/" + universalJavaApplicationStubResource, appStubFile, macConfig.getMacStartup() == MacStartup.SCRIPT); + FileUtils.copyResourceToFile("/mac/" + universalJavaApplicationStubResource, appStubFile, task.getMacConfig().getMacStartup() == MacStartup.SCRIPT); return appStubFile; } @@ -202,7 +207,7 @@ private void codesign(String developerId, File entitlements, File appFile) throw // checks --option flags List flags = new ArrayList<>(); - if (macConfig.isHardenedCodesign()) { + if (task.getMacConfig().isHardenedCodesign()) { if (VersionUtils.compareVersions("10.13.6", SystemUtils.OS_VERSION) >= 0) { flags.add("runtime"); // enable hardened runtime if Mac OS version >= 10.13.6 } else { diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/Packager.java b/src/main/java/io/github/fvarrui/javapackager/packagers/Packager.java index 63f64d58..43604670 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/Packager.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/Packager.java @@ -10,18 +10,21 @@ import java.util.ArrayList; import java.util.List; +import io.github.fvarrui.javapackager.PackageTask; +import io.github.fvarrui.javapackager.model.LinuxConfig; +import io.github.fvarrui.javapackager.model.MacConfig; import io.github.fvarrui.javapackager.model.Platform; -import io.github.fvarrui.javapackager.utils.FileUtils; -import io.github.fvarrui.javapackager.utils.IconUtils; -import io.github.fvarrui.javapackager.utils.Logger; -import io.github.fvarrui.javapackager.utils.VelocityUtils; +import io.github.fvarrui.javapackager.model.WindowsConfig; +import io.github.fvarrui.javapackager.utils.*; +import io.github.fvarrui.javapackager.utils.updater.TaskJavaUpdater; /** * Packager base class */ -public abstract class Packager extends PackagerSettings { +public abstract class Packager { private static final String DEFAULT_ORGANIZATION_NAME = "ACME"; + public PackageTask task; // artifact generators protected List> installerGenerators = new ArrayList<>(); @@ -88,79 +91,89 @@ public File getBootstrapFile() { // =============================================== - public Packager() { + public Packager(PackageTask task) { super(); + this.task = task; Logger.info("Using packager " + this.getClass().getName()); } + private void init() throws Exception { Logger.infoIndent("Initializing packager ..."); - if (mainClass == null || mainClass.isEmpty()) { + if (task.getMainClass() == null || task.getMainClass().isEmpty()) { throw new Exception("'mainClass' cannot be null"); } // sets assetsDir for velocity to locate custom velocity templates - VelocityUtils.setAssetsDir(assetsDir); + VelocityUtils.setAssetsDir(task.getAssetsDir()); // using name as displayName, if it's not specified - displayName = defaultIfBlank(displayName, name); + task.appDisplayName(defaultIfBlank(task.getAppDisplayName(), task.getAppName())); // using displayName as description, if it's not specified - description = defaultIfBlank(description, displayName); + task.description(defaultIfBlank(task.getDescription(), task.getAppDisplayName())); // using "ACME" as organizationName, if it's not specified - organizationName = defaultIfBlank(organizationName, DEFAULT_ORGANIZATION_NAME); + task.organizationName(defaultIfBlank(task.getOrganizationName(), DEFAULT_ORGANIZATION_NAME)); // using empty string as organizationUrl, if it's not specified - organizationUrl = defaultIfBlank(organizationUrl, ""); + task.organizationUrl(defaultIfBlank(task.getOrganizationUrl(), "")); // determines target platform if not specified - if (platform == null || platform == Platform.auto) { - platform = Platform.getCurrentPlatform(); + if (task.getPlatform() == null || task.getPlatform() == Platform.auto) { + task.platform(Platform.getCurrentPlatform()); } // sets jdkPath by default if not specified - if (jdkPath == null) { - jdkPath = new File(System.getProperty("java.home")); + if (task.getJdkPath() == null) { + TaskJavaUpdater taskJavaUpdater = new TaskJavaUpdater(task.getPlatform()); + taskJavaUpdater.execute(task.getJdkVersion(), task.getJdkVendor()); + task.jdkPath(taskJavaUpdater.jdkPath); + if(task.getPackagingJdk() == null) task.packagingJdk(taskJavaUpdater.jdkPath); + } else{ + // Custom JDK path doesn't support native image + // since there is currently no check to see if the JDK is GraalVM + if(task.isNativeImage()) + throw new Exception("Custom JDK does not support native-image! Select "+ Const.graalvm+" as JDK vendor to fix this."); } - if (!jdkPath.exists()) { - throw new Exception("JDK path doesn't exist: " + jdkPath); + if (!task.getJdkPath().exists()) { + throw new Exception("JDK path doesn't exist: " + task.getJdkPath()); } // check if name is valid as filename try { - Paths.get(name); - if (name.contains("/")) - throw new InvalidPathException(name, "Illegal char "); - if (name.contains("\\")) - throw new InvalidPathException(name, "Illegal char <\\>"); + Paths.get(task.getAppName()); + if (task.getAppName().contains("/")) + throw new InvalidPathException(task.getAppName(), "Illegal char "); + if (task.getAppName().contains("\\")) + throw new InvalidPathException(task.getAppName(), "Illegal char <\\>"); } catch (InvalidPathException e) { - throw new Exception("Invalid name specified: " + name, e); + throw new Exception("Invalid name specified: " + task.getAppName(), e); } // init setup languages - if (platform.equals(Platform.windows) && (winConfig.getSetupLanguages() == null || winConfig.getSetupLanguages().isEmpty())) { - winConfig.getSetupLanguages().put("english", "compiler:Default.isl"); - winConfig.getSetupLanguages().put("spanish", "compiler:Languages\\Spanish.isl"); + if (task.getPlatform().equals(Platform.windows) && (task.getWinConfig().getSetupLanguages() == null || task.getWinConfig().getSetupLanguages().isEmpty())) { + task.getWinConfig().getSetupLanguages().put("english", "compiler:Default.isl"); + task.getWinConfig().getSetupLanguages().put("spanish", "compiler:Languages\\Spanish.isl"); } doInit(); // removes not necessary platform specific configs - switch (platform) { + switch (task.getPlatform()) { case linux: - macConfig = null; - winConfig = null; + task.macConfig((MacConfig) null); + task.winConfig((WindowsConfig) null); break; case mac: - winConfig = null; - linuxConfig = null; + task.winConfig((WindowsConfig) null); + task.linuxConfig((LinuxConfig) null); break; case windows: - linuxConfig = null; - macConfig = null; + task.linuxConfig((LinuxConfig) null); + task.macConfig((MacConfig) null); break; default: } @@ -176,16 +189,16 @@ public void resolveResources() throws Exception { Logger.infoIndent("Resolving resources ..."); // locates license file - licenseFile = resolveLicense(licenseFile); + task.licenseFile(resolveLicense(task.getLicenseFile())); // locates icon file - iconFile = resolveIcon(iconFile, name, assetsFolder); + task.iconFile(resolveIcon(task.getIconFile(), task.getAppName(), assetsFolder)); // adds to additional resources - if (additionalResources != null) { - if (licenseFile != null) additionalResources.add(licenseFile); - additionalResources.add(iconFile); - Logger.info("Effective additional resources " + additionalResources); + if (task.getAdditionalResources() != null) { + if (task.getLicenseFile() != null) task.getAdditionalResources().add(task.getLicenseFile()); + task.getAdditionalResources().add(task.getIconFile()); + Logger.info("Effective additional resources " + task.getAdditionalResources()); } Logger.infoUnindent("Resources resolved!"); @@ -220,12 +233,12 @@ protected void copyAdditionalResources(List resources, File destination) { }); // copy bootstrap script - if (FileUtils.exists(getScripts().getBootstrap())) { - String scriptExtension = getExtension(getScripts().getBootstrap().getName()); + if (FileUtils.exists(task.getScripts().getBootstrap())) { + String scriptExtension = getExtension(task.getScripts().getBootstrap().getName()); File scriptsFolder = new File(destination, "scripts"); bootstrapFile = new File(scriptsFolder, "bootstrap" + (!scriptExtension.isEmpty() ? "." + scriptExtension : "")); try { - FileUtils.copyFileToFile(getScripts().getBootstrap(), bootstrapFile); + FileUtils.copyFileToFile(task.getScripts().getBootstrap(), bootstrapFile); bootstrapFile.setExecutable(true, false); } catch (Exception e) { Logger.error(e.getMessage(), e); @@ -287,31 +300,31 @@ protected File resolveLicense(File licenseFile) { protected File resolveIcon(File iconFile, String name, File assetsFolder) throws Exception { // searchs for specific icons - switch (platform) { + switch (task.getPlatform()) { case linux: - iconFile = FileUtils.exists(linuxConfig.getPngFile()) ? linuxConfig.getPngFile() : null; + iconFile = FileUtils.exists(task.getLinuxConfig().getPngFile()) ? task.getLinuxConfig().getPngFile() : null; break; case mac: - iconFile = FileUtils.exists(macConfig.getIcnsFile()) ? macConfig.getIcnsFile() : null; + iconFile = FileUtils.exists(task.getMacConfig().getIcnsFile()) ? task.getMacConfig().getIcnsFile() : null; break; case windows: - iconFile = FileUtils.exists(winConfig.getIcoFile()) ? winConfig.getIcoFile() : null; + iconFile = FileUtils.exists(task.getWinConfig().getIcoFile()) ? task.getWinConfig().getIcoFile() : null; break; default: } - String iconExtension = IconUtils.getIconFileExtensionByPlatform(platform); + String iconExtension = IconUtils.getIconFileExtensionByPlatform(task.getPlatform()); // if not specific icon specified for target platform, searchs for an icon in // "${assetsDir}" folder if (iconFile == null) { - iconFile = new File(assetsDir, platform + "/" + name + iconExtension); + iconFile = new File(task.getAssetsDir(), task.getPlatform() + "/" + name + iconExtension); } // if there's no icon yet, uses default one if (!iconFile.exists()) { iconFile = new File(assetsFolder, iconFile.getName()); - FileUtils.copyResourceToFile("/" + platform + "/default-icon" + iconExtension, iconFile); + FileUtils.copyResourceToFile("/" + task.getPlatform() + "/default-icon" + iconExtension, iconFile); } Logger.info("Icon file resolved: " + iconFile.getAbsolutePath()); @@ -331,13 +344,13 @@ public List createBundles() throws Exception { Logger.infoIndent("Creating bundles ..."); - if (createZipball) { + if (task.getCreateZipball()) { File zipball = Context.getContext().createZipball(this); Logger.info("Zipball created: " + zipball); bundles.add(zipball); } - if (createTarball) { + if (task.getCreateTarball()) { File tarball = Context.getContext().createTarball(this); Logger.info("Tarball created: " + tarball); bundles.add(tarball); @@ -353,21 +366,21 @@ private void createAppStructure() throws Exception { Logger.infoIndent("Creating app structure ..."); // creates output directory if it doesn't exist - if (!outputDirectory.exists()) { - outputDirectory.mkdirs(); + if (!task.getOutputDirectory().exists()) { + task.getOutputDirectory().mkdirs(); } // creates app destination folder - appFolder = new File(outputDirectory, name); + appFolder = new File(task.getOutputDirectory(), task.getAppName()); if (appFolder.exists()) { FileUtils.removeFolder(appFolder); Logger.info("Old app folder removed " + appFolder.getAbsolutePath()); } - appFolder = FileUtils.mkdir(outputDirectory, name); + appFolder = FileUtils.mkdir(task.getOutputDirectory(), task.getAppName()); Logger.info("App folder created: " + appFolder.getAbsolutePath()); // creates folder for intermmediate assets - assetsFolder = FileUtils.mkdir(outputDirectory, "assets"); + assetsFolder = FileUtils.mkdir(task.getOutputDirectory(), "assets"); Logger.info("Assets folder created: " + assetsFolder.getAbsolutePath()); // create the rest of the structure @@ -390,17 +403,17 @@ public File createApp() throws Exception { resolveResources(); // copies additional resources - copyAdditionalResources(additionalResources, resourcesDestinationFolder); + copyAdditionalResources(task.getAdditionalResources(), resourcesDestinationFolder); // copies all dependencies to Java folder Logger.infoIndent("Copying all dependencies ..."); - libsFolder = copyDependencies ? Context.getContext().copyDependencies(this) : null; + libsFolder = task.getCopyDependencies() ? Context.getContext().copyDependencies(this) : null; Logger.infoUnindent("Dependencies copied to " + libsFolder + "!"); // creates a runnable jar file - if (runnableJar != null && runnableJar.exists()) { - Logger.info("Using runnable JAR: " + runnableJar); - jarFile = runnableJar; + if (task.getRunnableJar() != null && task.getRunnableJar().exists()) { + Logger.info("Using runnable JAR: " + task.getRunnableJar()); + jarFile = task.getRunnableJar(); } else { Logger.infoIndent("Creating runnable JAR..."); jarFile = Context.getContext().createRunnableJar(this); @@ -420,7 +433,7 @@ public File createApp() throws Exception { public List generateInstallers() throws Exception { List installers = new ArrayList<>(); - if (!generateInstaller) { + if (!task.getGenerateInstaller()) { Logger.warn("Installer generation is disabled by 'generateInstaller' property!"); return installers; } @@ -430,11 +443,11 @@ public List generateInstallers() throws Exception { init(); // creates folder for intermmediate assets if it doesn't exist - assetsFolder = FileUtils.mkdir(outputDirectory, "assets"); + assetsFolder = FileUtils.mkdir(task.getOutputDirectory(), "assets"); // invokes installer producers - for (ArtifactGenerator generator : Context.getContext().getInstallerGenerators(platform)) { + for (ArtifactGenerator generator : Context.getContext().getInstallerGenerators(task.getPlatform())) { try { Logger.infoIndent("Generating " + generator.getArtifactName() + "..."); File artifact = generator.apply(this); diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/PackagerFactory.java b/src/main/java/io/github/fvarrui/javapackager/packagers/PackagerFactory.java index 14ae94b4..834f5831 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/PackagerFactory.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/PackagerFactory.java @@ -1,29 +1,24 @@ package io.github.fvarrui.javapackager.packagers; +import io.github.fvarrui.javapackager.PackageTask; import org.apache.commons.lang3.SystemUtils; -import io.github.fvarrui.javapackager.model.Platform; - -/** - * Packager factory - */ -public class PackagerFactory { - - public static Packager createPackager(Platform platform) throws Exception { - if (platform == Platform.auto || platform == null) platform = Platform.getCurrentPlatform(); - Packager packager = null; - switch (platform) { - case mac: - packager = new MacPackager(); break; - case linux: - packager = new LinuxPackager(); break; - case windows: - packager = new WindowsPackager(); break; - default: - throw new Exception("Unsupported operating system: " + SystemUtils.OS_NAME + " " + SystemUtils.OS_VERSION + " " + SystemUtils.OS_ARCH); - } - packager.platform(platform); - return packager; - } - +public interface PackagerFactory { + default Packager createPackager(PackageTask task) { + Packager packager = null; + switch (task.getPlatform()) { + case mac: + packager = new MacPackager(task); + break; + case linux: + packager = new LinuxPackager(task); + break; + case windows: + packager = new WindowsPackager(task); + break; + default: + throw new RuntimeException("Unsupported operating system: " + SystemUtils.OS_NAME + " " + SystemUtils.OS_VERSION + " " + SystemUtils.OS_ARCH); + } + return packager; + } } diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/PackagerSettings.java b/src/main/java/io/github/fvarrui/javapackager/packagers/PackagerSettings.java deleted file mode 100644 index fd5f8554..00000000 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/PackagerSettings.java +++ /dev/null @@ -1,882 +0,0 @@ -package io.github.fvarrui.javapackager.packagers; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; - -import io.github.fvarrui.javapackager.model.FileAssociation; -import io.github.fvarrui.javapackager.model.LinuxConfig; -import io.github.fvarrui.javapackager.model.MacConfig; -import io.github.fvarrui.javapackager.model.Manifest; -import io.github.fvarrui.javapackager.model.Platform; -import io.github.fvarrui.javapackager.model.Scripts; -import io.github.fvarrui.javapackager.model.WindowsConfig; - -/** - * Common packagers' settings - */ -public class PackagerSettings { - - protected File outputDirectory; - protected File licenseFile; - protected File iconFile; - protected Boolean generateInstaller; - protected boolean forceInstaller; - protected String mainClass; - protected String name; - protected String displayName; - protected String version; - protected String description; - protected String url; - protected Boolean administratorRequired; - protected String organizationName; - protected String organizationUrl; - protected String organizationEmail; - protected Boolean bundleJre; - protected Boolean customizedJre; - protected File jrePath; - protected File jdkPath; - protected List additionalResources; - protected List modules; - protected List additionalModules; - protected Platform platform; - protected String envPath; - protected List vmArgs; - protected File runnableJar; - protected Boolean copyDependencies; - protected String jreDirectoryName; - protected WindowsConfig winConfig; - protected LinuxConfig linuxConfig; - protected MacConfig macConfig; - protected Boolean createTarball; - protected Boolean createZipball; - protected Map extra; - protected boolean useResourcesAsWorkingDir; - protected File assetsDir; - protected String classpath; - protected String jreMinVersion; - protected Manifest manifest; - protected List additionalModulePaths; - protected List fileAssociations; - protected File packagingJdk; - protected Scripts scripts; - - /** - * Get packaging JDK - * @return Packaging JDK - */ - public File getPackagingJdk() { - return packagingJdk; - } - - /** - * Get output directory - * @return Output directory - */ - public File getOutputDirectory() { - return outputDirectory; - } - - /** - * Get license file - * @return License file - */ - public File getLicenseFile() { - return licenseFile; - } - - /** - * Get icon file - * @return Icon file - */ - public File getIconFile() { - return iconFile; - } - - /** - * Get generate installer - * @return Generate installer - */ - public Boolean getGenerateInstaller() { - return generateInstaller; - } - - /** - * Get force installer - * @return Force installer - */ - public boolean isForceInstaller() { - return forceInstaller; - } - - /** - * Get main class - * @return Main class - */ - public String getMainClass() { - return mainClass; - } - - /** - * Get name - * @return Name - */ - public String getName() { - return name; - } - - /** - * Get display name - * @return Display name - */ - public String getDisplayName() { - return displayName; - } - - /** - * Get version - * @return Version - */ - public String getVersion() { - return version; - } - - /** - * Get description - * @return Description - */ - public String getDescription() { - return description; - } - - /** - * Get URL - * @return URL - */ - public String getUrl() { - return url; - } - - /** - * Get administrator required - * @return Administrator required - */ - public Boolean getAdministratorRequired() { - return administratorRequired; - } - - /** - * Get organization name - * @return Organization name - */ - public String getOrganizationName() { - return organizationName; - } - - /** - * Get organization URL - * @return Organization URL - */ - public String getOrganizationUrl() { - return organizationUrl; - } - - /** - * Get organization email - * @return Organization email - */ - public String getOrganizationEmail() { - return organizationEmail; - } - - /** - * Get bundle JRE - * @return Bundle JRE - */ - public Boolean getBundleJre() { - return bundleJre; - } - - /** - * Get customized JRE - * @return Customized JRE - */ - public Boolean getCustomizedJre() { - return customizedJre; - } - - /** - * Get JRE path - * @return JRE path - */ - public File getJrePath() { - return jrePath; - } - - /** - * Get JDK path - * @return JDK path - */ - public File getJdkPath() { - return jdkPath; - } - - /** - * Get additional resourcxes - * @return Additional resources - */ - public List getAdditionalResources() { - return additionalResources; - } - - /** - * Get Modules - * @return Modules - */ - public List getModules() { - return modules; - } - - /** - * Get additional modules - * @return Additional modules - */ - public List getAdditionalModules() { - return additionalModules; - } - - /** - * Get platform - * @return Platform - */ - public Platform getPlatform() { - return platform; - } - - /** - * Get env path - * @return Env path - */ - public String getEnvPath() { - return envPath; - } - - /** - * Get VM args - * @return VM args - */ - public List getVmArgs() { - return vmArgs; - } - - /** - * Get runnable JAR - * @return Runnable JAR - */ - public File getRunnableJar() { - return runnableJar; - } - - /** - * Get copy dependencies - * @return Copy dependencies - */ - public Boolean getCopyDependencies() { - return copyDependencies; - } - - /** - * Get JRE directory name - * @return JRE directory name - */ - public String getJreDirectoryName() { - return jreDirectoryName; - } - - /** - * Get Windows config - * @return Windows config - */ - public WindowsConfig getWinConfig() { - return winConfig; - } - - /** - * Get Linux config - * @return Linux config - */ - public LinuxConfig getLinuxConfig() { - return linuxConfig; - } - - /** - * Get Mac OS config - * @return Mac OS config - */ - public MacConfig getMacConfig() { - return macConfig; - } - - /** - * Get create tarball - * @return Create tarball - */ - public Boolean getCreateTarball() { - return createTarball; - } - - /** - * Get create zipball - * @return Create zipball - */ - public Boolean getCreateZipball() { - return createZipball; - } - - /** - * Get extra parameters - * @return Extra parameters - */ - public Map getExtra() { - return extra; - } - - /** - * Get if it has to use resources folder as working directory - * @return Use resources folder as working directory - */ - public boolean isUseResourcesAsWorkingDir() { - return useResourcesAsWorkingDir; - } - - /** - * Get assets dir - * @return Assets dir - */ - public File getAssetsDir() { - return assetsDir; - } - - /** - * Get classpath - * @return Classpath - */ - public String getClasspath() { - return classpath; - } - - /** - * Get JRE min version - * @return JRE min version - */ - public String getJreMinVersion() { - return jreMinVersion; - } - - /** - * Get Manifest - * @return manifest - */ - public Manifest getManifest() { - return manifest; - } - - /** - * Get additional modules paths - * @return Additional module paths - */ - public List getAdditionalModulePaths() { - return additionalModulePaths; - } - - /** - * Get file associations - * @return File associations - */ - public List getFileAssociations() { - return fileAssociations; - } - - /** - * Get scripts - * @return Scripts - */ - public Scripts getScripts() { - return scripts; - } - - // fluent api - - /** - * Set output directory - * @param outputDirectory Output directory - * @return Packager settings - */ - public PackagerSettings outputDirectory(File outputDirectory) { - this.outputDirectory = outputDirectory; - return this; - } - - /** - * Set packaging JDK - * @param packagingJdk Packaging JDK - * @return Packager settings - */ - public PackagerSettings packagingJdk(File packagingJdk) { - this.packagingJdk = packagingJdk; - return this; - } - - /** - * Set license file - * @param licenseFile License file - * @return Packager settings - */ - public PackagerSettings licenseFile(File licenseFile) { - this.licenseFile = licenseFile; - return this; - } - - /** - * Set icon file - * @param iconFile Icon file - * @return Packager settings - */ - public PackagerSettings iconFile(File iconFile) { - this.iconFile = iconFile; - return this; - } - - /** - * Set generate installer - * @param generateInstaller Generate installer - * @return Packager settings - */ - public PackagerSettings generateInstaller(Boolean generateInstaller) { - this.generateInstaller = generateInstaller; - return this; - } - - /** - * Set force installer - * @param forceInstaller Force installer - * @return Packager settings - */ - public PackagerSettings forceInstaller(Boolean forceInstaller) { - this.forceInstaller = forceInstaller; - return this; - } - - /** - * Set main class - * @param mainClass Main class - * @return Packager settings - */ - public PackagerSettings mainClass(String mainClass) { - this.mainClass = mainClass; - return this; - } - - /** - * Set name - * @param name Name - * @return Packager settings - */ - public PackagerSettings name(String name) { - this.name = name; - return this; - } - - /** - * Set display name - * @param displayName Display name - * @return Packager settings - */ - public PackagerSettings displayName(String displayName) { - this.displayName = displayName; - return this; - } - - /** - * Set version - * @param version Version - * @return Packager settings - */ - public PackagerSettings version(String version) { - this.version = version; - return this; - } - - /** - * Set description - * @param description Description - * @return Packager settings - */ - public PackagerSettings description(String description) { - this.description = description; - return this; - } - - /** - * Set URL - * @param url URL - * @return Packager settings - */ - public PackagerSettings url(String url) { - this.url = url; - return this; - } - - /** - * Set administrator required - * @param administratorRequired Administrator required - * @return Packager settings - */ - public PackagerSettings administratorRequired(Boolean administratorRequired) { - this.administratorRequired = administratorRequired; - return this; - } - - /** - * Set organizstion name - * @param organizationName Organization name - * @return Packager settings - */ - public PackagerSettings organizationName(String organizationName) { - this.organizationName = organizationName; - return this; - } - - /** - * Set organization URL - * @param organizationUrl Organization URL - * @return Packager settings - */ - public PackagerSettings organizationUrl(String organizationUrl) { - this.organizationUrl = organizationUrl; - return this; - } - - /** - * Set organization email - * @param organizationEmail - * @return Packager settings - */ - public PackagerSettings organizationEmail(String organizationEmail) { - this.organizationEmail = organizationEmail; - return this; - } - - /** - * Set bundle JRE - * @param bundleJre Bundle JRE - * @return Packager settings - */ - public PackagerSettings bundleJre(Boolean bundleJre) { - this.bundleJre = bundleJre; - return this; - } - - /** - * Set customized JRE - * @param customizedJre Customized JRE - * @return Packager settings - */ - public PackagerSettings customizedJre(Boolean customizedJre) { - this.customizedJre = customizedJre; - return this; - } - - /** - * Set JRE path - * @param jrePath JRE path - * @return Packager settings - */ - public PackagerSettings jrePath(File jrePath) { - this.jrePath = jrePath; - return this; - } - - /** - * Set JDK path - * @param jdkPath JDK path - * @return Packager settings - */ - public PackagerSettings jdkPath(File jdkPath) { - this.jdkPath = jdkPath; - return this; - } - - /** - * Set additional resources list - * @param additionalResources Additional resources list - * @return Packager settings - */ - public PackagerSettings additionalResources(List additionalResources) { - this.additionalResources = new ArrayList<>(additionalResources); - return this; - } - - /** - * Set modules list - * @param modules Modules list - * @return Packager settings - */ - public PackagerSettings modules(List modules) { - this.modules = new ArrayList<>(modules); - return this; - } - - /** - * Set additional modules list - * @param additionalModules Additional modules list - * @return Packager settings - */ - public PackagerSettings additionalModules(List additionalModules) { - this.additionalModules = new ArrayList<>(additionalModules); - return this; - } - - /** - * Set platform - * @param platform Platform - * @return Packager settings - */ - public PackagerSettings platform(Platform platform) { - this.platform = platform; - return this; - } - - /** - * Set ENV path - * @param envPath ENV path - * @return Packager settings - */ - public PackagerSettings envPath(String envPath) { - this.envPath = envPath; - return this; - } - - /** - * Set VM arguments - * @param vmArgs VM arguments - * @return Packager settings - */ - public PackagerSettings vmArgs(List vmArgs) { - this.vmArgs = new ArrayList<>(vmArgs); - return this; - } - - /** - * Set runnable JAR - * @param runnableJar Runnable JAR - * @return Packager settings - */ - public PackagerSettings runnableJar(File runnableJar) { - this.runnableJar = runnableJar; - return this; - } - - /** - * Set copy dependencies - * @param copyDependencies Copy dependencies - * @return Packager settings - */ - public PackagerSettings copyDependencies(Boolean copyDependencies) { - this.copyDependencies = copyDependencies; - return this; - } - - /** - * Set JRE directory name - * @param jreDirectoryName JRE directory name - * @return Packager settings - */ - public PackagerSettings jreDirectoryName(String jreDirectoryName) { - this.jreDirectoryName = jreDirectoryName; - return this; - } - - /** - * Set Windows specific configuration - * @param winConfig Windows specific configuration - * @return Packager settings - */ - public PackagerSettings winConfig(WindowsConfig winConfig) { - this.winConfig = winConfig; - return this; - } - - /** - * Set GNU/Linux specific configuration - * @param linuxConfig GNU/Linux specific configuration - * @return Packager settings - */ - public PackagerSettings linuxConfig(LinuxConfig linuxConfig) { - this.linuxConfig = linuxConfig; - return this; - } - - /** - * Set Mac OS specific configuration - * @param macConfig Mac OS specific configuration - * @return Packager settings - */ - public PackagerSettings macConfig(MacConfig macConfig) { - this.macConfig = macConfig; - return this; - } - - /** - * Set create tarball - * @param createTarball Create tarball - * @return Packager settings - */ - public PackagerSettings createTarball(Boolean createTarball) { - this.createTarball = createTarball; - return this; - } - - /** - * Set create zipball - * @param createZipball Create zipball - * @return Packager settings - */ - public PackagerSettings createZipball(Boolean createZipball) { - this.createZipball = createZipball; - return this; - } - - /** - * Set extra parameters map - * @param extra Extra parameters map - * @return Packager settings - */ - public PackagerSettings extra(Map extra) { - this.extra = extra; - return this; - } - - /** - * Set if it use resources folder as working directory - * @param useResourcesAsWorkingDir Use resources folder as working directory - * @return Packager settings - */ - public PackagerSettings useResourcesAsWorkingDir(boolean useResourcesAsWorkingDir) { - this.useResourcesAsWorkingDir = useResourcesAsWorkingDir; - return this; - } - - /** - * Set asstes directory - * @param assetsDir Assets directory - * @return Packager settings - */ - public PackagerSettings assetsDir(File assetsDir) { - this.assetsDir = assetsDir; - return this; - } - - /** - * Set classpath - * @param classpath Classpath - * @return Packager settings - */ - public PackagerSettings classpath(String classpath) { - this.classpath = classpath; - return this; - } - - /** - * Set minimal JRE version - * @param jreMinVersion JRE minimal version - * @return Packager settings - */ - public PackagerSettings jreMinVersion(String jreMinVersion) { - this.jreMinVersion = jreMinVersion; - return this; - } - - /** - * Set Manifest configuration - * @param manifest Manifest - * @return Packager settings - */ - public PackagerSettings manifest(Manifest manifest) { - this.manifest = manifest; - return this; - } - - /** - * Set additional module paths - * @param additionalModulePaths Additional module path list - * @return Packager settings - */ - public PackagerSettings additionalModulePaths(List additionalModulePaths) { - this.additionalModulePaths = additionalModulePaths; - return this; - } - - /** - * Set file associations - * @param fileAssociations File associations list - * @return Packager settings - */ - public PackagerSettings fileAssociations(List fileAssociations) { - this.fileAssociations = fileAssociations; - return this; - } - - /** - * Set scripts - * @param scripts Scripts - * @return Packager settings - */ - public PackagerSettings scripts(Scripts scripts) { - this.scripts = scripts; - return this; - } - - // some helpful methods - - /** - * Checks if there are file associations specified - * @return true if there are file asociations, otherwise false - */ - public boolean isThereFileAssociations() { - return fileAssociations != null && !fileAssociations.isEmpty(); - } - - /** - * Mime types list to string - * @param separator Character used to join mime types into one string - * @return Mime type list string - */ - public String getMimeTypesListAsString(String separator) { - return StringUtils.join(fileAssociations.stream().map(fa -> fa.getMimeType()).collect(Collectors.toList()), - separator); - } - - @Override - public String toString() { - return "PackagerSettings [outputDirectory=" + outputDirectory + ", licenseFile=" + licenseFile + ", iconFile=" - + iconFile + ", generateInstaller=" + generateInstaller + ", forceInstaller=" + forceInstaller - + ", mainClass=" + mainClass + ", name=" + name + ", displayName=" + displayName + ", version=" - + version + ", description=" + description + ", url=" + url + ", administratorRequired=" - + administratorRequired + ", organizationName=" + organizationName + ", organizationUrl=" - + organizationUrl + ", organizationEmail=" + organizationEmail + ", bundleJre=" + bundleJre - + ", customizedJre=" + customizedJre + ", jrePath=" + jrePath + ", jdkPath=" + jdkPath - + ", additionalResources=" + additionalResources + ", modules=" + modules + ", additionalModules=" - + additionalModules + ", platform=" + platform + ", envPath=" + envPath + ", vmArgs=" + vmArgs - + ", runnableJar=" + runnableJar + ", copyDependencies=" + copyDependencies + ", jreDirectoryName=" - + jreDirectoryName + ", winConfig=" + winConfig + ", linuxConfig=" + linuxConfig + ", macConfig=" - + macConfig + ", createTarball=" + createTarball + ", createZipball=" + createZipball + ", extra=" - + extra + ", useResourcesAsWorkingDir=" + useResourcesAsWorkingDir + ", assetsDir=" + assetsDir - + ", classpath=" + classpath + ", jreMinVersion=" + jreMinVersion + ", manifest=" + manifest - + ", additionalModulePaths=" + additionalModulePaths + ", fileAssociations=" + fileAssociations - + ", packagingJdk=" + packagingJdk + ", scripts=" + scripts + "]"; - }} diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/WindowsArtifactGenerator.java b/src/main/java/io/github/fvarrui/javapackager/packagers/WindowsArtifactGenerator.java index 56e0bee4..244bbef9 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/WindowsArtifactGenerator.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/WindowsArtifactGenerator.java @@ -19,23 +19,23 @@ public WindowsArtifactGenerator(String name) { protected void sign(File file, WindowsPackager packager) { - if (packager.getWinConfig().getSigning() == null) { + if (packager.task.getWinConfig().getSigning() == null) { return; } Logger.infoIndent("Signing " + file); - File keystore = packager.getWinConfig().getSigning().getKeystore(); - File certfile = packager.getWinConfig().getSigning().getCertfile(); - File keyfile = packager.getWinConfig().getSigning().getKeyfile(); - String alg = packager.getWinConfig().getSigning().getAlg(); - String storetype = packager.getWinConfig().getSigning().getStoretype(); - String storepass = packager.getWinConfig().getSigning().getStorepass(); - String alias = packager.getWinConfig().getSigning().getAlias(); - String keypass = packager.getWinConfig().getSigning().getKeypass(); + File keystore = packager.task.getWinConfig().getSigning().getKeystore(); + File certfile = packager.task.getWinConfig().getSigning().getCertfile(); + File keyfile = packager.task.getWinConfig().getSigning().getKeyfile(); + String alg = packager.task.getWinConfig().getSigning().getAlg(); + String storetype = packager.task.getWinConfig().getSigning().getStoretype(); + String storepass = packager.task.getWinConfig().getSigning().getStorepass(); + String alias = packager.task.getWinConfig().getSigning().getAlias(); + String keypass = packager.task.getWinConfig().getSigning().getKeypass(); String tsa = TIMESTAMPING_AUTHORITY; - String displayName = packager.getDisplayName(); - String url = packager.getUrl(); + String displayName = packager.task.getAppDisplayName(); + String url = packager.task.getUrl(); try { diff --git a/src/main/java/io/github/fvarrui/javapackager/packagers/WindowsPackager.java b/src/main/java/io/github/fvarrui/javapackager/packagers/WindowsPackager.java index 24b02bca..2cb17a8b 100644 --- a/src/main/java/io/github/fvarrui/javapackager/packagers/WindowsPackager.java +++ b/src/main/java/io/github/fvarrui/javapackager/packagers/WindowsPackager.java @@ -4,6 +4,7 @@ import java.util.Arrays; import java.util.stream.Collectors; +import io.github.fvarrui.javapackager.PackageTask; import org.apache.commons.lang3.StringUtils; import io.github.fvarrui.javapackager.utils.Logger; @@ -16,7 +17,11 @@ public class WindowsPackager extends Packager { private File manifestFile; private File msmFile; - + + public WindowsPackager(PackageTask task) { + super(task); + } + public File getManifestFile() { return manifestFile; } @@ -33,7 +38,7 @@ public void setMsmFile(File msmFile) { public void doInit() throws Exception { // sets windows config default values - this.winConfig.setDefaults(this); + task.getWinConfig().setDefaults(this); } @@ -43,7 +48,7 @@ protected void doCreateAppStructure() throws Exception { // sets common folders this.executableDestinationFolder = appFolder; this.jarFileDestinationFolder = appFolder; - this.jreDestinationFolder = new File(appFolder, jreDirectoryName); + this.jreDestinationFolder = new File(appFolder, task.getJreDirectoryName()); this.resourcesDestinationFolder = appFolder; } @@ -54,23 +59,23 @@ protected void doCreateAppStructure() throws Exception { @Override public File doCreateApp() throws Exception { - Logger.infoIndent("Creating windows EXE ... with " + getWinConfig().getExeCreationTool()); + Logger.infoIndent("Creating windows EXE ... with " + task.getWinConfig().getExeCreationTool()); // generates manifest file to require administrator privileges from velocity template - manifestFile = new File(assetsFolder, name + ".exe.manifest"); + manifestFile = new File(assetsFolder, task.getAppName() + ".exe.manifest"); VelocityUtils.render("windows/exe.manifest.vtl", manifestFile, this); Logger.info("Exe manifest file generated in " + manifestFile.getAbsolutePath() + "!"); // sets executable file - executable = new File(appFolder, name + ".exe"); + executable = new File(appFolder, task.getAppName() + ".exe"); // process classpath - if (classpath != null) { - classpaths = Arrays.asList(classpath.split("[;:]")); - if (!isUseResourcesAsWorkingDir()) { + if (task.getClasspath() != null) { + classpaths = Arrays.asList(task.getClasspath().split("[;:]")); + if (!task.isUseResourcesAsWorkingDir()) { classpaths = classpaths.stream().map(cp -> new File(cp).isAbsolute() ? cp : "%EXEDIR%/" + cp).collect(Collectors.toList()); } - classpath = StringUtils.join(classpaths, ";"); + task.classpath(StringUtils.join(classpaths, ";")); } // invokes launch4j to generate windows executable diff --git a/src/main/java/io/github/fvarrui/javapackager/utils/Const.java b/src/main/java/io/github/fvarrui/javapackager/utils/Const.java new file mode 100644 index 00000000..89aaccf1 --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/utils/Const.java @@ -0,0 +1,6 @@ +package io.github.fvarrui.javapackager.utils; + +public class Const { + public static final String graalvm = "graalvm"; + public static final String adoptium = "adoptium"; +} diff --git a/src/main/java/io/github/fvarrui/javapackager/utils/GraalVM.java b/src/main/java/io/github/fvarrui/javapackager/utils/GraalVM.java new file mode 100644 index 00000000..bed2db55 --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/utils/GraalVM.java @@ -0,0 +1,82 @@ +package io.github.fvarrui.javapackager.utils; + +import io.github.fvarrui.javapackager.model.Platform; +import org.codehaus.plexus.util.cli.CommandLineException; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.NotDirectoryException; + +public class GraalVM { + public File dir; + public File dirBin; + public File guScript; + + public GraalVM(File dir) throws NotDirectoryException, FileNotFoundException { + if(!dir.isDirectory()) throw new NotDirectoryException(dir.toString()); + this.dir = dir; + this.dirBin = new File(dir+"/bin"); + if(!dirBin.exists()) throw new FileNotFoundException(dirBin.toString()); + for (File file : dirBin.listFiles()) { + if(file.getName().contains("gu.")){ + this.guScript = file; + break; + } + } + if(guScript==null || !guScript.exists()) throw new FileNotFoundException("gu script not found inside: "+dirBin); + } + + public void guInstall(String name) throws IOException, CommandLineException { + CommandUtils.execute(guScript, "install", name); + } + + public File getNativeImageExe(){ + File nativeImage = null; + for (File file : dirBin.listFiles()) { + if(file.getName().contains("native-image")){ + nativeImage = file; + break; + } + } + return nativeImage; + } + + public File generateNativeImage(Platform platform, File outputDirectory) throws IOException, CommandLineException { + guInstall("native-image"); + // TODO install other platform dependent dependencies here + + File jarFile = null; + for (File file : outputDirectory.listFiles()) { + if(file.getName().endsWith("shaded.jar") || file.getName().endsWith("all.jar") || file.getName().endsWith("dependencies.jar")){ + jarFile = file; + break; + } + } + if(jarFile==null || !jarFile.exists()) + throw new FileNotFoundException("File ending with \"shaded.jar\" or \"all.jar\" or \"dependencies.jar\"" + + " not found inside: "+outputDirectory); + CommandUtils.executeWithResult(outputDirectory, // working dir = output dir + getNativeImageExe().toString(), "-jar", jarFile, jarFile.getName()); + return new File(outputDirectory+"/"+jarFile.getName() + (platform == Platform.windows ? ".exe" : "")); + } + + public File generateSharedLibrary(Platform platform, File outputDirectory) throws IOException, CommandLineException { + guInstall("native-image"); + // TODO install other platform dependent dependencies here + + File jarFile = null; + for (File file : outputDirectory.listFiles()) { + if(file.getName().endsWith("shaded.jar") || file.getName().endsWith("all.jar") || file.getName().endsWith("dependencies.jar")){ + jarFile = file; + break; + } + } + if(jarFile==null || !jarFile.exists()) + throw new FileNotFoundException("File ending with \"shaded.jar\" or \"all.jar\" or \"dependencies.jar\"" + + " not found inside: "+outputDirectory); + CommandUtils.executeWithResult(outputDirectory, // working dir = output dir + getNativeImageExe().toString(), "-jar", jarFile, jarFile.getName(), "--shared"); + return new File(outputDirectory+"/"+jarFile.getName() + (platform == Platform.windows ? ".dll" : ".so")); + } +} diff --git a/src/main/java/io/github/fvarrui/javapackager/utils/NativeUtils.java b/src/main/java/io/github/fvarrui/javapackager/utils/NativeUtils.java new file mode 100644 index 00000000..d9562c4f --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/utils/NativeUtils.java @@ -0,0 +1,13 @@ +package io.github.fvarrui.javapackager.utils; + +import java.io.File; + +public class NativeUtils { + /** + * @return JavaPackager temp directory. Example on Windows:
+ * C:\Users\Name\AppData\Local\Temp\JavaPackager + */ + public static File getUserTempFolder(){ + return new File(System.getProperty("java.io.tmpdir") +"/JavaPackager"); + } +} diff --git a/src/main/java/io/github/fvarrui/javapackager/utils/updater/AdoptV3API.java b/src/main/java/io/github/fvarrui/javapackager/utils/updater/AdoptV3API.java new file mode 100644 index 00000000..99ad68dc --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/utils/updater/AdoptV3API.java @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2021-2022 Osiris-Team. + * All rights reserved. + * + * This software is copyrighted work, licensed under the terms + * of the MIT-License. Consult the "LICENSE" file for details. + */ + +package io.github.fvarrui.javapackager.utils.updater; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +import java.io.IOException; + +/** + * Details here: https://api.adoptium.net/q/swagger-ui + */ +public class AdoptV3API { + private final String BASE = "https://api.adoptium.net/v3"; + private final String START_DOWNLOAD_URL = BASE + "/binary/version/"; + private final String START_RELEASES_URL = BASE + "/info/release_versions?architecture="; + private final String START_ASSETS_URL = BASE + "/assets/version/"; + + public JsonObject getAvailableReleases() throws IOException { + return Json.fromUrlAsObject(BASE + "/info/available_releases"); + } + + public String getLatestLTSRelease() throws IOException { + JsonArray arr = getAvailableReleases().getAsJsonArray("available_lts_releases"); + return arr.get(arr.size() - 1).getAsString(); + } + + public String getLatestRelease() throws IOException { + JsonArray arr = getAvailableReleases().getAsJsonArray("available_releases"); + return arr.get(arr.size() - 1).getAsString(); + } + + /** + * Creates and returns a new url from the provided parameters.
+ * For a list of all available parameters types see: https://api.adoptium.net/q/swagger-ui/#/Assets/searchReleasesByVersion + * + * @param releaseVersionName Example: 11.0.4.1+11.1 + * @param isLargeHeapSize If true allows your jvm to use more that 57gb of ram. + * @param isHotspotImpl If true uses hotspot, otherwise the openj9 implementation. + * @param isOnlyLTS If true only shows LTS (Long Term Support) releases. + * @param maxItems Example: 20 + * @return + */ + public String getVersionInformationUrl(String releaseVersionName, OperatingSystemArchitectureType osArchitectureType, boolean isLargeHeapSize, ImageType imageType, + boolean isHotspotImpl, boolean isOnlyLTS, OperatingSystemType osType, int maxItems, + VendorProjectType vendorProject, ReleaseType releaseType) { + String jvmImplementation = isHotspotImpl ? "hotspot" : "openj9"; + String heapSize = isLargeHeapSize ? "large" : "normal"; + return START_ASSETS_URL + + "%5B" + releaseVersionName.replace("+", "%2B") + "%2C%29" + + "?architecture=" + osArchitectureType.name + + "&heap_size=" + heapSize + + "&image_type=" + imageType.name + + "&jvm_impl=" + jvmImplementation + + "<s=" + isOnlyLTS + + "&os=" + osType.name + + "&page=0" + + "&page_size=" + maxItems + + "&project=" + vendorProject.name + + "&release_type=" + releaseType.name + + "&sort_method=DEFAULT&sort_order=DESC" + + "&vendor=eclipse"; + } + + public JsonArray getVersionInformation(String releaseVersionName, OperatingSystemArchitectureType osArchitectureType, boolean isLargeHeapSize, ImageType imageType, + boolean isHotspotImpl, boolean isOnlyLTS, OperatingSystemType osType, int maxItems, + VendorProjectType vendorProject, ReleaseType releaseType) throws IOException { + return Json.fromUrlAsJsonArray(getVersionInformationUrl( + releaseVersionName, osArchitectureType, isLargeHeapSize, imageType, isHotspotImpl, + isOnlyLTS, osType, maxItems, vendorProject, releaseType + )); + } + + /** + * Creates and returns a new url from the provided parameters.
+ * For a list of all available parameters types see: https://api.adoptium.net/q/swagger-ui/#/Release%20Info/getReleaseVersions + * + * @param isLargeHeapSize If true allows your jvm to use more that 57gb of ram. + * @param isHotspotImpl If true uses hotspot, otherwise the openj9 implementation. + * @param isOnlyLTS If true only shows LTS (Long Term Support) releases. + * @param maxItems Example: 20 + * @return + */ + public String getReleasesUrl(OperatingSystemArchitectureType osArchitectureType, boolean isLargeHeapSize, ImageType imageType, + boolean isHotspotImpl, boolean isOnlyLTS, OperatingSystemType osType, int maxItems, + VendorProjectType vendorProject, ReleaseType releaseType) { + String jvmImplementation = isHotspotImpl ? "hotspot" : "openj9"; + String heapSize = isLargeHeapSize ? "large" : "normal"; + return START_RELEASES_URL + + osArchitectureType.name + + "&heap_size=" + heapSize + + "&image_type=" + imageType.name + + "&jvm_impl=" + jvmImplementation + + "<s=" + isOnlyLTS + + "&os=" + osType.name + + "&page=0" + + "&page_size=" + maxItems + + "&project=" + vendorProject.name + + "&release_type=" + releaseType.name + + "&sort_method=DEFAULT&sort_order=DESC" + + "&vendor=eclipse"; + } + + public JsonObject getReleases(OperatingSystemArchitectureType osArchitectureType, boolean isLargeHeapSize, ImageType imageType, + boolean isHotspotImpl, boolean isOnlyLTS, OperatingSystemType osType, int maxItems, + VendorProjectType vendorProject, ReleaseType releaseType) throws IOException { + return Json.fromUrlAsObject(getReleasesUrl(osArchitectureType, isLargeHeapSize, imageType, + isHotspotImpl, isOnlyLTS, osType, maxItems, vendorProject, releaseType)); + } + + /** + * Creates and returns a new url from the provided parameters.
+ * For a list of all available parameters types see: https://api.adoptium.net/q/swagger-ui/#/Binary/getBinaryByVersion + * + * @param releaseName Note that this is not the regular version name. Example: jdk-15.0.2+7 + * @param isHotspotImpl If true uses hotspot, otherwise the openj9 implementation. + * @param isLargeHeapSize If true allows your jvm to use more that 57gb of ram. + */ + public String getDownloadUrl(String releaseName, OperatingSystemType osType, OperatingSystemArchitectureType osArchitectureType, + ImageType imageType, boolean isHotspotImpl, boolean isLargeHeapSize, + VendorProjectType vendorProject) { + String jvmImplementation = isHotspotImpl ? "hotspot" : "openj9"; + String heapSize = isLargeHeapSize ? "large" : "normal"; + return START_DOWNLOAD_URL + + releaseName + "/" + + osType.name + "/" + + osArchitectureType.name + "/" + + imageType.name + "/" + + jvmImplementation + "/" + + heapSize + "/" + + "eclipse?project=" + vendorProject.name; + } + + + // ENUMS: + + + public enum VendorProjectType { + JDK("jdk"), + VALHALLA("valhalla"), + METROPOLIS("metropolis"), + JFR("jfr"), + SHENANDOAH("shenandoah"); + + private final String name; + + VendorProjectType(String name) { + this.name = name; + } + } + + public enum ImageType { + JDK("jdk"), + JRE("jre"), + TEST_IMAGE("testimage"), + DEBUG_IMAGE("debugimage"), + STATIC_LIBS("staticlibs"); + + private final String name; + + ImageType(String name) { + this.name = name; + } + } + + public enum OperatingSystemArchitectureType { + X64("x64"), + X86("x86"), + X32("x32"), + PPC64("ppc64"), + PPC64LE("ppc64le"), + S390X("s390x"), + AARCH64("aarch64"), + ARM("arm"), + SPARCV9("sparcv9"), + RISCV64("riscv64"), + // x64 with alternative names: + AMD64("x64"), + X86_64("x64"), + // x32 with alternative names: + I386("x32"), + // AARCHx64 with alternative names: + ARM64("aarch64"); + + public final String name; + + OperatingSystemArchitectureType(String name) { + this.name = name; + } + } + + public enum OperatingSystemType { + LINUX("linux"), + WINDOWS("windows"), + MAC("mac"), + SOLARIS("solaris"), + AIX("aix"), + ALPINE_LINUX("alpine-linux"); + + private final String name; + + OperatingSystemType(String name) { + this.name = name; + } + } + + public enum ReleaseType { + GENERAL_AVAILABILITY("ga"), + EARLY_ACCESS("ea"); + + private final String name; + + ReleaseType(String name) { + this.name = name; + } + } +} diff --git a/src/main/java/io/github/fvarrui/javapackager/utils/updater/Github.java b/src/main/java/io/github/fvarrui/javapackager/utils/updater/Github.java new file mode 100644 index 00000000..2e49bb5a --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/utils/updater/Github.java @@ -0,0 +1,98 @@ +package io.github.fvarrui.javapackager.utils.updater; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.apache.commons.io.IOUtils; + +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; + +public class Github { + + /** + * Searches the latest GitHub release and returns a {@link SearchResult} object with all the relevant information. + * + * @param repoName GitHub repository name. + * @param currentVersion current version of the installed software. + * @param assetNamePredicate predicate that contains the asset name and ist used to determine the asset to download. + */ + public static SearchResult searchUpdate(String repoName, String currentVersion, Predicate assetNamePredicate) { + Exception exception = null; + boolean updateAvailable = false; + String downloadUrl = null; + String latestVersion = null; + String downloadFile = null; + String sha256 = null; + try { + JsonObject latestRelease = Json.fromUrlAsObject("https://api.github.com/repos/" + repoName + "/releases/latest"); + latestVersion = latestRelease.get("tag_name").getAsString(); + if (latestVersion != null) + latestVersion = latestVersion.replaceAll("[^0-9.]", ""); // Before passing over remove everything except numbers and dots + if (new UtilsVersion().isLatestBigger(currentVersion, latestVersion)) { + updateAvailable = true; + // Contains JsonObjects sorted by their asset-names lengths, from smallest to longest. + // The following does that sorting. + List sortedArtifactObjects = new ArrayList<>(); + for (JsonElement e : + latestRelease.getAsJsonArray("assets")) { + JsonObject obj = e.getAsJsonObject(); + String name = obj.get("name").getAsString(); + if (sortedArtifactObjects.size() == 0) sortedArtifactObjects.add(obj); + else { + int finalIndex = 0; + boolean isSmaller = false; + for (int i = 0; i < sortedArtifactObjects.size(); i++) { + String n = sortedArtifactObjects.get(i).get("name").getAsString(); + if (name.length() < n.length()) { + isSmaller = true; + finalIndex = i; + break; + } + } + if (!isSmaller) sortedArtifactObjects.add(obj); + else sortedArtifactObjects.add(finalIndex, obj); + } + } + + // Find asset-name containing our provided asset-name + for (JsonObject obj : sortedArtifactObjects) { + String name = obj.get("name").getAsString(); + if (assetNamePredicate.test(name)) { + downloadFile = name; + downloadUrl = obj.get("browser_download_url").getAsString(); + break; + } + } + + if (downloadUrl == null) { + List names = new ArrayList<>(); + for (JsonObject obj : + sortedArtifactObjects) { + String n = obj.get("name").getAsString(); + names.add(n); + } + throw new Exception("Failed to find an asset-name matching the assetNamePredicate inside of " + Arrays.toString(names.toArray())); + } + + // Determine sha256 + String expectedShaAssetName = downloadFile + ".sha256"; + for (JsonObject obj : sortedArtifactObjects) { + String name = obj.get("name").getAsString(); + if (name.equals(expectedShaAssetName)) { + sha256 = IOUtils.toString(new URL(obj.get("browser_download_url").getAsString()), StandardCharsets.UTF_8); + break; + } + } + + } + } catch (Exception e) { + exception = e; + } + + return new SearchResult(updateAvailable, exception, latestVersion, downloadUrl, downloadFile, sha256); + } +} diff --git a/src/main/java/io/github/fvarrui/javapackager/utils/updater/Json.java b/src/main/java/io/github/fvarrui/javapackager/utils/updater/Json.java new file mode 100644 index 00000000..2a76ea22 --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/utils/updater/Json.java @@ -0,0 +1,105 @@ +package io.github.fvarrui.javapackager.utils.updater; + +import com.google.gson.*; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +public class Json { + + /** + * Reads/Parses the provided String to a {@link JsonElement}. + */ + public static JsonElement from(String s) { + return JsonParser.parseString(s); + } + + /** + * Writes/Parses the provided {@link JsonElement} to a String. + */ + public static String toString(JsonElement el) { + return new Gson().toJson(el); + } + + /** + * Returns the json-element. This can be a json-array or a json-object. + * + * @param url The url which leads to the json file. + * @return JsonElement + * @throws IOException When status code other than 200. + */ + public static JsonElement fromUrl(String url) throws IOException { + HttpURLConnection con = null; + JsonElement element; + try { + con = (HttpURLConnection) new URL(url).openConnection(); + con.addRequestProperty("User-Agent", "JavaPackager"); + con.setConnectTimeout(1000); + con.connect(); + + if (con.getResponseCode() == 200) { + try (InputStreamReader inr = new InputStreamReader(con.getInputStream())) { + element = JsonParser.parseReader(inr); + } + } else { + throw new IOException("error: " + con.getResponseCode() + " message: \"" + con.getResponseMessage() + "\" url: " + url); + } + } catch (IOException e) { + if (con != null) con.disconnect(); + throw e; + } finally { + if (con != null) con.disconnect(); + } + return element; + } + + public static JsonArray fromUrlAsJsonArray(String url) throws IOException { + JsonElement element = fromUrl(url); + if (element != null && element.isJsonArray()) { + return element.getAsJsonArray(); + } else { + throw new IOException("Its not a json array! Check it out -> " + url); + } + } + + /** + * Turns a JsonArray with its objects into a list. + * + * @param url The url where to find the json file. + * @return A list with JsonObjects or null if there was a error with the url. + */ + public static List fromUrlAsList(String url) throws IOException { + List objectList = new ArrayList<>(); + JsonElement element = fromUrl(url); + if (element != null && element.isJsonArray()) { + final JsonArray ja = element.getAsJsonArray(); + for (int i = 0; i < ja.size(); i++) { + JsonObject jo = ja.get(i).getAsJsonObject(); + objectList.add(jo); + } + return objectList; + } else { + throw new IOException("Its not a json array! Check it out -> " + url); + } + } + + /** + * Gets a single JsonObject. + * + * @param url The url where to find the json file. + * @return A JsonObject or null if there was a error with the url. + */ + public static JsonObject fromUrlAsObject(String url) throws IOException { + JsonElement element = fromUrl(url); + if (element != null && element.isJsonObject()) { + return element.getAsJsonObject(); + } else { + throw new IOException("Its not a json object! Check it out -> " + url); + } + } + +} diff --git a/src/main/java/io/github/fvarrui/javapackager/utils/updater/SearchResult.java b/src/main/java/io/github/fvarrui/javapackager/utils/updater/SearchResult.java new file mode 100644 index 00000000..728e614c --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/utils/updater/SearchResult.java @@ -0,0 +1,19 @@ +package io.github.fvarrui.javapackager.utils.updater; + +public class SearchResult { + public boolean isUpdateAvailable; + public Exception exception; + public String latestVersion; + public String downloadUrl; + public String downloadFileExtension; + public String sha256; + + public SearchResult(boolean isUpdateAvailable, Exception exception, String latestVersion, String downloadUrl, String downloadFileExtension, String sha256) { + this.isUpdateAvailable = isUpdateAvailable; + this.exception = exception; + this.latestVersion = latestVersion; + this.downloadUrl = downloadUrl; + this.downloadFileExtension = downloadFileExtension; + this.sha256 = sha256; + } +} diff --git a/src/main/java/io/github/fvarrui/javapackager/utils/updater/TaskJavaDownload.java b/src/main/java/io/github/fvarrui/javapackager/utils/updater/TaskJavaDownload.java new file mode 100644 index 00000000..cd47ce44 --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/utils/updater/TaskJavaDownload.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2021-2022 Osiris-Team. + * All rights reserved. + * + * This software is copyrighted work, licensed under the terms + * of the MIT-License. Consult the "LICENSE" file for details. + */ + +package io.github.fvarrui.javapackager.utils.updater; + +import io.github.fvarrui.javapackager.utils.Logger; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import org.apache.commons.io.FileUtils; +import org.jetbrains.annotations.NotNull; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.security.MessageDigest; +import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TaskJavaDownload { + private File newDest; + private boolean isTar; + private String url; + private File dest; + private AdoptV3API.OperatingSystemType osType; + + /** + * @param url the download-url. + * @param dest the downloads final destination. Note that the file name must end with '.file', because + * the actual file type gets set when there is download information available. + */ + public void execute(String url, File dest, AdoptV3API.OperatingSystemType osType) throws Exception { + this.url = url; + this.dest = dest; + this.osType = osType; + + String fileName = dest.getName(); + Logger.info("Fetching file " + fileName + " from: " + url); + + Request request = new Request.Builder().url(url) + .header("User-Agent", "AutoPlug Client/" + new Random().nextInt() + " - https://autoplug.one") + .build(); + Response response = new OkHttpClient().newCall(request).execute(); + ResponseBody body = null; + try { + if (response.code() != 200) + throw new Exception("Download of '" + fileName + "' failed! Code: " + response.code() + " Message: " + response.message() + " Url: " + url); + + body = response.body(); + if (body == null) + throw new Exception("Download of '" + fileName + "' failed because of null response body!"); + else if (body.contentType() == null) + throw new Exception("Download of '" + fileName + "' failed because of null content type!"); + else if (!body.contentType().type().equals("application")) + throw new Exception("Download of '" + fileName + "' failed because of invalid content type: " + body.contentType().type()); + else if (!body.contentType().subtype().equals("java-archive") + && !body.contentType().subtype().equals("jar") + && !body.contentType().subtype().equals("octet-stream") + && !body.contentType().subtype().equals("x-gtar") // ADDITIONS FOR JAVA DOWNLOADS + && !body.contentType().subtype().equals("zip")) + throw new Exception("Download of '" + fileName + "' failed because of invalid sub-content type: " + body.contentType().subtype()); + + // Set the file name + if (body.contentType().subtype().equals("x-gtar")) { + isTar = true; + fileName = fileName.replace(".file", ".tar.gz"); + } else { + // In this case we check the response header for file information + // Example: (content-disposition, attachment; filename=JDK15U-jre_x86-32_windows_hotspot_15.0.2_7.zip) + String contentDispo = response.headers().get("content-disposition"); + if (contentDispo == null) + throw new Exception("Failed to determine download file type!"); + + if (contentDispo.contains(".tar.gz")) { + isTar = true; + fileName = fileName.replace(".file", ".tar.gz"); + } else { + Pattern p = Pattern.compile("[.][^.]+$"); // Returns the file extension with dot. example.txt -> .txt + Matcher m = p.matcher(contentDispo); + if (m.find()) { + String fileExtension = m.group(); + fileName = fileName.replace(".file", fileExtension); + } else + throw new Exception("Failed to determine download file type! Download-Url: " + contentDispo); + } + } + + + // We need to at least create the cache dest to then rename it + if (dest.exists()) dest.delete(); + dest.getParentFile().mkdirs(); + dest.createNewFile(); + + // The actual file with the correct file extension + newDest = new File(dest.getParentFile().getAbsolutePath() + "/" + fileName); + if (newDest.exists()) newDest.delete(); + newDest.getParentFile().mkdirs(); + newDest.createNewFile(); + + long completeFileSize = body.contentLength(); + + BufferedInputStream in = new BufferedInputStream(body.byteStream()); + FileOutputStream fos = new FileOutputStream(dest); + BufferedOutputStream bout = new BufferedOutputStream(fos, 1024); + byte[] data = new byte[1024]; + long downloadedFileSize = 0; + int x = 0; + Logger.info("Downloading " + fileName + " with " + completeFileSize / (1024 * 1024) + "mb. This may take a bit..."); + while ((x = in.read(data, 0, 1024)) >= 0) { + downloadedFileSize += x; + bout.write(data, 0, x); + } + + Logger.info("Downloaded " + fileName + " (" + downloadedFileSize / (1024 * 1024) + "mb/" + completeFileSize / (1024 * 1024) + "mb)"); + bout.close(); + in.close(); + body.close(); + response.close(); + + Files.copy(dest.toPath(), newDest.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (Exception e) { + if (body != null) body.close(); + response.close(); + throw e; + } + } + + /** + * Retrieve this once the task finished to get a correct result. + */ + public boolean isTar() { + return isTar; + } + + public File getNewCacheDest() { + return newDest; + } + + /** + * Only use this method after finishing the download. + * It will get the hash for the newly downloaded file and + * compare it with the given hash. + * + * @param sha256 + * @return true if the hashes match + */ + public boolean compareWithSHA256(String sha256) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] encodedhash = digest.digest( + FileUtils.readFileToByteArray(dest)); + final String hashResult = bytesToHex(encodedhash); + Logger.debug("Comparing hashes (SHA-256):"); + Logger.debug("Expected hash: " + sha256); + Logger.debug("Actual hash: " + hashResult); + return hashResult.equals(sha256); + } catch (Exception e) { + Logger.error("Failed to compare hashes.", e); + return false; + } + + } + + @NotNull + private String bytesToHex(@NotNull byte[] hash) { + StringBuilder hexString = new StringBuilder(2 * hash.length); + for (int i = 0; i < hash.length; i++) { + String hex = Integer.toHexString(0xff & hash[i]); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } + +} diff --git a/src/main/java/io/github/fvarrui/javapackager/utils/updater/TaskJavaUpdater.java b/src/main/java/io/github/fvarrui/javapackager/utils/updater/TaskJavaUpdater.java new file mode 100644 index 00000000..ca7d713b --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/utils/updater/TaskJavaUpdater.java @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2021-2022 Osiris-Team. + * All rights reserved. + * + * This software is copyrighted work, licensed under the terms + * of the MIT-License. Consult the "LICENSE" file for details. + */ + +package io.github.fvarrui.javapackager.utils.updater; + +import com.google.common.io.Files; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.github.fvarrui.javapackager.model.Platform; +import io.github.fvarrui.javapackager.utils.Const; +import io.github.fvarrui.javapackager.utils.Logger; +import io.github.fvarrui.javapackager.utils.NativeUtils; +import org.apache.commons.io.FileUtils; +import org.rauschig.jarchivelib.ArchiveFormat; +import org.rauschig.jarchivelib.Archiver; +import org.rauschig.jarchivelib.ArchiverFactory; +import org.rauschig.jarchivelib.CompressionType; + +import java.io.File; +import java.io.IOException; +import java.util.Objects; +import java.util.regex.Pattern; + +/** + * Searches for updates and installs them is AUTOMATIC profile is selected. + */ +public class TaskJavaUpdater { + + public File downloadsDir = new File(NativeUtils.getUserTempFolder() + "/downloads"); + public File jdkPath; + public Platform platform; + public AdoptV3API.OperatingSystemType osType; + + public TaskJavaUpdater(Platform platform) { + this.platform = platform; + switch (platform) { + case linux: + jdkPath = new File(NativeUtils.getUserTempFolder() + "/jdk/linux"); + osType = AdoptV3API.OperatingSystemType.LINUX; + break; + case mac: + jdkPath = new File(NativeUtils.getUserTempFolder() + "/jdk/mac"); + osType = AdoptV3API.OperatingSystemType.MAC; + break; + case windows: + jdkPath = new File(NativeUtils.getUserTempFolder() + "/jdk/win"); + osType = AdoptV3API.OperatingSystemType.WINDOWS; + break; + default: + throw new RuntimeException(); + } + jdkPath.mkdirs(); + } + + public void execute(String javaVersion, String javaVendor) throws Exception { + Objects.requireNonNull(javaVersion); + Objects.requireNonNull(javaVendor); + if (javaVendor.equals(Const.graalvm)) { + Logger.info("Checking java installation..."); + + String currentVersion = getBuildID(javaVersion, javaVendor); + String osName = (platform.equals(Platform.linux) ? "linux" : + platform.equals(Platform.mac) ? "darwin" : + platform.equals(Platform.windows) ? "windows" : + null); + Objects.requireNonNull(osName); + Pattern pattern = Pattern.compile("(java)(\\d+)"); // matches java11 or java17 for example + SearchResult result = Github.searchUpdate("graalvm/graalvm-ce-builds", currentVersion, + assetName -> assetName.contains(osName) + && assetName.contains("amd64") + && new UtilsVersion().isLatestBiggerOrEqual(javaVersion, pattern.matcher(assetName).group()) + && !assetName.endsWith(".sha256") + && !assetName.endsWith(".jar")); + if (result.exception != null) throw result.exception; + if (!result.isUpdateAvailable) { + Logger.info("Your Java installation is on the latest version!"); + return; + } + + if (result.downloadUrl == null) { + Logger.error("Couldn't find a matching asset to download."); + return; + } + + download(result.downloadUrl, result.sha256, + currentVersion, result.latestVersion, + javaVersion, javaVendor); + + } else if (javaVendor.equals(Const.adoptium)) { + Logger.info("Checking java installation..."); + + AdoptV3API.OperatingSystemArchitectureType osArchitectureType = AdoptV3API.OperatingSystemArchitectureType.X64; + int currentBuildId = Integer.parseInt(getBuildID(javaVersion, javaVendor)); + AdoptV3API.ImageType imageType = AdoptV3API.ImageType.JDK; + + JsonObject jsonReleases = new AdoptV3API().getReleases( + osArchitectureType, + false, + imageType, + true, + true, // Changing this to false makes the api return even fewer versions, which is pretty weird. + osType, + 20, + AdoptV3API.VendorProjectType.JDK, + AdoptV3API.ReleaseType.GENERAL_AVAILABILITY + ); + + JsonObject jsonLatestRelease = null; + for (JsonElement e : + jsonReleases.getAsJsonArray("versions")) { + JsonObject o = e.getAsJsonObject(); + if (o.get("major").getAsString().equals(javaVersion)) { + jsonLatestRelease = o; + break; + } + } + + if (jsonLatestRelease == null) { + Logger.error("Couldn't find a matching major version to '" + javaVersion + "'."); + return; + } + + int latestBuildId = jsonLatestRelease.get("build").getAsInt(); + if (latestBuildId <= currentBuildId) { + Logger.info("Your Java installation is on the latest version!"); + return; + } + + // semver = the version string like: 11.0.0+28 for example // Not a typo ^-^ + String versionString = jsonLatestRelease.get("semver").toString().replace("\"", ""); // Returns with apostrophes "" + + JsonArray jsonVersionDetails = new AdoptV3API().getVersionInformation( + versionString, + osArchitectureType, + false, + imageType, + true, + true, + osType, + 20, + AdoptV3API.VendorProjectType.JDK, + AdoptV3API.ReleaseType.GENERAL_AVAILABILITY); + + String checksum = jsonVersionDetails.get(0).getAsJsonObject().getAsJsonArray("binaries") + .get(0).getAsJsonObject().get("package").getAsJsonObject().get("checksum").getAsString(); + + // The release name that can be used to retrieve the download link + String releaseName = jsonVersionDetails.get(0).getAsJsonObject().get("release_name").getAsString(); + String downloadURL = new AdoptV3API().getDownloadUrl( + releaseName, + osType, + osArchitectureType, + imageType, + true, + false, + AdoptV3API.VendorProjectType.JDK + ); + + download(downloadURL, checksum, + "" + currentBuildId, "" + latestBuildId, + javaVersion, javaVendor); + + } else { + throw new IllegalArgumentException("The provided Java vendor '" + javaVendor + "' is currently not supported!" + + " Supported: " + Const.adoptium + " and " + Const.graalvm + "."); + } + } + + private void download(String downloadURL, String expectedSha256, + String currentVersion, String latestVersion, + String javaVersion, String javaVendor) throws Exception { + Logger.info("Update found " + currentVersion + " -> " + latestVersion); + File final_dir_dest = jdkPath; + File cache_dest = new File(downloadsDir + "/" + javaVendor + "-" + javaVersion + "-" + latestVersion + ".file"); + TaskJavaDownload download = new TaskJavaDownload(); + download.execute(downloadURL, cache_dest, osType); + + Logger.info("Java update downloaded. Checking hash..."); + if (!download.compareWithSHA256(expectedSha256)) + throw new IOException("Hash of downloaded Java update is not valid!"); + Logger.info("Hash is valid, removing old installation..."); + FileUtils.deleteDirectory(final_dir_dest); + final_dir_dest.mkdirs(); + + Archiver archiver; + if (download.isTar()) + archiver = ArchiverFactory.createArchiver(ArchiveFormat.TAR, CompressionType.GZIP); + else // A zip + archiver = ArchiverFactory.createArchiver(ArchiveFormat.ZIP); + + // The zip/archive contains another folder inside like /jdk8+189 + // thus we need to move that folders content to its parent dir + archiver.extract(download.getNewCacheDest(), final_dir_dest); + setBuildID("" + latestVersion, javaVersion, javaVendor); + File actualJdkPath = null; + for (File file : jdkPath.listFiles()) { + if (file.isDirectory()) { + actualJdkPath = file; + break; + } + } + for (File file : actualJdkPath.listFiles()) { + Files.move(file, new File(jdkPath + "/" + file.getName())); + } + FileUtils.deleteDirectory(actualJdkPath); + FileUtils.deleteDirectory(downloadsDir); + Logger.info("Java update was installed successfully (" + currentVersion + " -> " + latestVersion + ") at " + jdkPath); + } + + private String getFileNameWithoutID(String javaVersion, String javaVendor) { + return "java_packager_jdk_" + javaVersion + "_" + javaVendor + "_build_id"; + } + + private String getBuildID(String javaVersion, String javaVendor) throws IOException { + for (File file : jdkPath.listFiles()) { + if (file.getName().startsWith(getFileNameWithoutID(javaVersion, javaVendor))) { + return file.getName().split(" ")[1]; + } + } + setBuildID("0", javaVersion, javaVendor); + return "0"; + } + + private void setBuildID(String id, String javaVersion, String javaVendor) throws IOException { + for (File file : jdkPath.listFiles()) { + if (file.getName().startsWith(getFileNameWithoutID(javaVersion, javaVendor))) { + file.delete(); + } + } + File file = new File(jdkPath + "/" + getFileNameWithoutID(javaVersion, javaVendor) + " " + id); + file.createNewFile(); + } + +} diff --git a/src/main/java/io/github/fvarrui/javapackager/utils/updater/UtilsVersion.java b/src/main/java/io/github/fvarrui/javapackager/utils/updater/UtilsVersion.java new file mode 100644 index 00000000..33c6ef65 --- /dev/null +++ b/src/main/java/io/github/fvarrui/javapackager/utils/updater/UtilsVersion.java @@ -0,0 +1,67 @@ +package io.github.fvarrui.javapackager.utils.updater; + +import java.util.Objects; + +public class UtilsVersion { + + /** + * Compares the current version with the latest + * version and returns true if the latest version is + * bigger than the current version. + */ + public boolean isLatestBigger(String currentVersion, String latestVersion) { + try { + String[] arrCurrent = cleanAndSplitByDots(currentVersion); + String[] arrLatest = cleanAndSplitByDots(latestVersion); + + if (arrLatest.length == arrCurrent.length) { + int latest, current; + for (int i = 0; i < arrLatest.length; i++) { + latest = Integer.parseInt(arrLatest[i]); + current = Integer.parseInt(arrCurrent[i]); + if (latest == current) continue; + else return latest > current; + } + return false; // All are the same + } else return arrLatest.length > arrCurrent.length; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * Compares the current version with the latest + * version and returns true if the latest version is + * bigger or equal to the current version. + */ + public boolean isLatestBiggerOrEqual(String currentVersion, String latestVersion) { + try { + String[] arrCurrent = cleanAndSplitByDots(currentVersion); + String[] arrLatest = cleanAndSplitByDots(latestVersion); + + if (arrLatest.length == arrCurrent.length) { + int latest, current; + for (int i = 0; i < arrLatest.length; i++) { + latest = Integer.parseInt(arrLatest[i]); + current = Integer.parseInt(arrCurrent[i]); + if (latest == current) continue; + else return latest >= current; + } + return true; // All are the same + } else return arrLatest.length >= arrCurrent.length; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + private String[] cleanAndSplitByDots(String version) throws Exception { + Objects.requireNonNull(version); + version = version.trim() // Remove left and right spaces + .replaceAll("[^0-9.]", ""); // Remove everything except numbers and dots + if (version.isEmpty()) throw new Exception("Empty version string!"); + return version.split("\\."); // Split string by . + } + +} diff --git a/src/test/java/io/github/fvarrui/javapackager/RealTest.java b/src/test/java/io/github/fvarrui/javapackager/RealTest.java new file mode 100644 index 00000000..2c4b4076 --- /dev/null +++ b/src/test/java/io/github/fvarrui/javapackager/RealTest.java @@ -0,0 +1,94 @@ +package io.github.fvarrui.javapackager; + +import io.github.fvarrui.javapackager.model.Platform; +import org.apache.maven.shared.invoker.*; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; + +public class RealTest { + + @Test + void helloWorldMaven() throws Exception { + publishPluginLocally(); + // PACKAGE MAVEN HELLO WORLD WITH CURRENT JAVA PACKAGER + InvocationRequest request = new DefaultInvocationRequest(); + request.setMavenHome(findMavenHome()); + request.setJavaHome(new File(System.getProperty("java.home"))); + request.setPomFile(new File(System.getProperty("user.dir") + "/test/hello-world-maven/pom.xml")); + request.setGoals(Arrays.asList("clean", "package")); + request.addArg("-Dmaven.javadoc.skip=true"); + request.addArg("-Dmaven.test.skip=true"); + request.addArg("-e"); + Invoker invoker = new DefaultInvoker(); + InvocationResult result = invoker.execute(request); + if(result.getExitCode() != 0 || result.getExecutionException() != null) + throw new RuntimeException("Maven exit code != 0, see the cause below for details.", result.getExecutionException()); + } + + @Test + void helloWorldGradle() throws Exception { + publishPluginLocally(); + // PACKAGE GRADLE HELLO WORLD WITH CURRENT JAVA PACKAGER + if (getBuilder(getGradlew().getAbsolutePath(), + "clean", "package", "-x", "test", "-x", "javadoc", "--stacktrace") + .directory(new File(System.getProperty("user.dir") + "/test/hello-world-gradle")) + .inheritIO().start().waitFor() + != 0) throw new Exception("Failed! Exit code is not 0, see details further below:"); + } + + @Test + void publishPluginLocally() throws Exception { + System.out.println("Building and publishing plugin locally..."); + // PUBLISH CURRENT JAVA PACKAGER TO LOCAL MAVEN REPO TO BE USED BY THE HELLO WORLD PROJECTS + if (getBuilder(getGradlew().getAbsolutePath(), "build", "publishToMavenLocal", "-x", "validatePlugins", "-x", "test", "-x", "javadoc", "--stacktrace") + .start().waitFor() + != 0) throw new Exception("Failed! Exit code is not 0, see details further below:"); + System.out.println("Successfully built and published plugin locally."); + } + + private File getGradlew(){ + return new File(System.getProperty("user.dir") + + "/gradlew" + (Platform.getCurrentPlatform() == Platform.windows ? ".bat" : ".sh")); + } + + private File findMavenHome() { + File startDir; + if(Platform.getCurrentPlatform() == Platform.windows){ + startDir = new File(System.getProperty("user.home") + "\\.m2\\wrapper\\dists"); + return startDir.listFiles()[0].listFiles()[0].listFiles()[0]; + } else{ // LINUX OR MAC + // TODO + throw new RuntimeException("Failed to determine maven home folder! Linux is currently not supported."); + } + } + + private ProcessBuilder getBuilder(String... arguments) throws IOException { + ProcessBuilder builder = new ProcessBuilder().command(arguments) + .inheritIO(); + Map environment = builder.environment(); + setValueIgnoreCase(environment, "JAVA_HOME", System.getProperty("java.home")); + return builder; + } + + private String getValueIgnoreCase(Map map, String key) { + for (String _key : map.keySet()) { + if (_key != null && _key.equalsIgnoreCase(key)) + return map.get(_key); + } + return null; + } + + private void setValueIgnoreCase(Map map, String key, String value) { + for (String _key : map.keySet()) { + if (_key != null && _key.equalsIgnoreCase(key)) { + map.put(_key, value); + return; + } + } + } + +} diff --git a/src/test/java/io/github/fvarrui/javapackager/utils/updater/TaskJavaUpdaterTest.java b/src/test/java/io/github/fvarrui/javapackager/utils/updater/TaskJavaUpdaterTest.java new file mode 100644 index 00000000..8ce76f14 --- /dev/null +++ b/src/test/java/io/github/fvarrui/javapackager/utils/updater/TaskJavaUpdaterTest.java @@ -0,0 +1,33 @@ +package io.github.fvarrui.javapackager.utils.updater; + +import io.github.fvarrui.javapackager.model.Platform; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class TaskJavaUpdaterTest { + @Test + void testWindows() throws Exception { + TaskJavaUpdater taskJavaUpdater = new TaskJavaUpdater(Platform.windows); + taskJavaUpdater.execute("8", "adoptium"); + assertNotNull(taskJavaUpdater.jdkPath); + assertTrue(taskJavaUpdater.jdkPath.listFiles().length != 0); + System.out.println(taskJavaUpdater.jdkPath); + } + @Test + void testLinux() throws Exception { + TaskJavaUpdater taskJavaUpdater = new TaskJavaUpdater(Platform.linux); + taskJavaUpdater.execute("8", "adoptium"); + assertNotNull(taskJavaUpdater.jdkPath); + assertTrue(taskJavaUpdater.jdkPath.listFiles().length != 0); + System.out.println(taskJavaUpdater.jdkPath); + } + @Test + void testMac() throws Exception { + TaskJavaUpdater taskJavaUpdater = new TaskJavaUpdater(Platform.mac); + taskJavaUpdater.execute("8", "adoptium"); + assertNotNull(taskJavaUpdater.jdkPath); + assertTrue(taskJavaUpdater.jdkPath.listFiles().length != 0); + System.out.println(taskJavaUpdater.jdkPath); + } +} \ No newline at end of file diff --git a/test/hello-world-gradle/.gitattributes b/test/hello-world-gradle/.gitattributes new file mode 100644 index 00000000..dfe07704 --- /dev/null +++ b/test/hello-world-gradle/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/test/hello-world-gradle/.gitignore b/test/hello-world-gradle/.gitignore new file mode 100644 index 00000000..528763a4 --- /dev/null +++ b/test/hello-world-gradle/.gitignore @@ -0,0 +1,8 @@ +.gradle +**/build/ + +bin +target + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar \ No newline at end of file diff --git a/test/hello-world-gradle/LICENSE b/test/hello-world-gradle/LICENSE new file mode 100644 index 00000000..e62ec04c --- /dev/null +++ b/test/hello-world-gradle/LICENSE @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/test/hello-world-gradle/README.md b/test/hello-world-gradle/README.md new file mode 100644 index 00000000..0013138f --- /dev/null +++ b/test/hello-world-gradle/README.md @@ -0,0 +1,3 @@ +# HelloWorld + +JavaPackager sample project. \ No newline at end of file diff --git a/test/hello-world-gradle/addons/commons-test-1.2.3.jar b/test/hello-world-gradle/addons/commons-test-1.2.3.jar new file mode 100644 index 00000000..98467d3a Binary files /dev/null and b/test/hello-world-gradle/addons/commons-test-1.2.3.jar differ diff --git a/test/hello-world-gradle/assets/bootstrap.sh b/test/hello-world-gradle/assets/bootstrap.sh new file mode 100644 index 00000000..0658ed83 --- /dev/null +++ b/test/hello-world-gradle/assets/bootstrap.sh @@ -0,0 +1,2 @@ +#!/bin/bash +echo "$(date +"%Y-%m-%d %H:%M:%S") Running bootstrap script" >> $HOME/log.txt \ No newline at end of file diff --git a/test/hello-world-gradle/assets/linux/HelloWorldGradle.png b/test/hello-world-gradle/assets/linux/HelloWorldGradle.png new file mode 100644 index 00000000..4ecb0f2d Binary files /dev/null and b/test/hello-world-gradle/assets/linux/HelloWorldGradle.png differ diff --git a/test/hello-world-gradle/assets/mac/HelloWorldGradle.icns b/test/hello-world-gradle/assets/mac/HelloWorldGradle.icns new file mode 100644 index 00000000..c70ef779 Binary files /dev/null and b/test/hello-world-gradle/assets/mac/HelloWorldGradle.icns differ diff --git a/test/hello-world-gradle/assets/windows/HelloWorldGradle.ico b/test/hello-world-gradle/assets/windows/HelloWorldGradle.ico new file mode 100644 index 00000000..12a838fc Binary files /dev/null and b/test/hello-world-gradle/assets/windows/HelloWorldGradle.ico differ diff --git a/test/hello-world-gradle/assets/windows/script.bat b/test/hello-world-gradle/assets/windows/script.bat new file mode 100644 index 00000000..28cc521a --- /dev/null +++ b/test/hello-world-gradle/assets/windows/script.bat @@ -0,0 +1,4 @@ +@echo off +FOR /F "tokens=*" %%g IN ('date /t') do (SET DATE=%%g) +FOR /F "tokens=*" %%g IN ('time /t') do (SET TIME=%%g) +echo %DATE%%TIME% >> %USERPROFILE%\log.txt \ No newline at end of file diff --git a/test/hello-world-gradle/build.gradle b/test/hello-world-gradle/build.gradle new file mode 100644 index 00000000..122b6cdf --- /dev/null +++ b/test/hello-world-gradle/build.gradle @@ -0,0 +1,106 @@ +buildscript { + repositories { + mavenLocal() + mavenCentral() + } + dependencies { + classpath 'io.github.fvarrui:javapackager:latest.release' + } +} + +plugins { + id 'java' + id 'maven-publish' + id 'com.github.ben-manes.versions' version '0.42.0' +} + +apply plugin: 'io.github.fvarrui.javapackager.plugin' + +dependencies { + implementation 'commons-io:commons-io:2.6' +} + +import io.github.fvarrui.javapackager.GradlePackageTask; +import io.github.fvarrui.javapackager.model.*; + +group = 'io.github.fvarrui' +version = '1.0.0' +description = 'HelloWorld for Gradle' +sourceCompatibility = '1.8' +compileJava.options.encoding = 'UTF-8' + +javapackager { + mainClass = 'io.github.fvarrui.helloworld.Main' + additionalResources = [ file('src/main/resources/info.txt') ] + bundleJre = true + generateInstaller = true + vmArgs = ["-Djava.library.path=."] + administratorRequired = false +} + +task packageForWindows(type: GradlePackageTask, dependsOn: build) { + javapackager{ + description = 'Packages the application as a native Windows executable and bundles it in a zipball' + platform = 'windows' + winConfig { + exeCreationTool = 'winrun4j' + vmArgs = ["-Dprism.maxvram=512m -XX:+UseG1GC"] + generateSetup = false + generateMsi = false + registry = new Registry([ + entries: [ + new RegistryEntry([ + key: "HKCU:MyGradleApp", + valueName: "greeting", + valueType: ValueType.REG_SZ, + valueData: "hello" + ]) + ] + ]) + icoFile = file("windows/HelloWorldGradle.ico") + setupMode = SetupMode.askTheUser + removeOldLibs = true + disableDirPage = false + disableFinishedPage = false + disableWelcomePage = false + createDesktopIconTask = false + } + } +} + +task packageForLinux(type: GradlePackageTask, dependsOn: build) { + javapackager{ + description = 'Packages the application as a native GNU/Linux executable and bundles it in a tarball' + platform = 'linux' + bundleJre = true + createTarball = true + scripts { + bootstrap = file('assets/bootstrap.sh') + } + } +} + +task packageForMac(type: GradlePackageTask, dependsOn: build) { + javapackager{ + description = 'Packages the application as a native Mac OS app and bundles it in a tarball' + platform = 'mac' + createTarball = true + scripts { + bootstrap = file('assets/bootstrap.sh') + } + macConfig { + infoPlist.additionalEntries = ''' + LSUIElement + + ''' + } + } +} + +task packageForAllPlatforms(dependsOn: [ packageForWindows, packageForMac, packageForLinux ]) { + javapackager{ + description = 'Packages the application for all platforms' + group = 'JavaPackager' + } +} + diff --git a/test/hello-world-gradle/gradlew b/test/hello-world-gradle/gradlew new file mode 100644 index 00000000..b0d6d0ab --- /dev/null +++ b/test/hello-world-gradle/gradlew @@ -0,0 +1,188 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/test/hello-world-gradle/gradlew.bat b/test/hello-world-gradle/gradlew.bat new file mode 100644 index 00000000..9991c503 --- /dev/null +++ b/test/hello-world-gradle/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/test/hello-world-gradle/info.txt b/test/hello-world-gradle/info.txt new file mode 100644 index 00000000..9673394d --- /dev/null +++ b/test/hello-world-gradle/info.txt @@ -0,0 +1 @@ +Soy otro fichero! Hahaha \ No newline at end of file diff --git a/test/hello-world-gradle/plugins/commons-lang-2.6.jar b/test/hello-world-gradle/plugins/commons-lang-2.6.jar new file mode 100644 index 00000000..98467d3a Binary files /dev/null and b/test/hello-world-gradle/plugins/commons-lang-2.6.jar differ diff --git a/test/hello-world-gradle/settings.gradle b/test/hello-world-gradle/settings.gradle new file mode 100644 index 00000000..180b9335 --- /dev/null +++ b/test/hello-world-gradle/settings.gradle @@ -0,0 +1,9 @@ +pluginManagement { + repositories { + mavenLocal() + mavenCentral() + gradlePluginPortal() + } +} + +rootProject.name = 'HelloWorldGradle' diff --git a/test/hello-world-gradle/src/main/java/io/github/fvarrui/helloworld/HelloWorldFrame.java b/test/hello-world-gradle/src/main/java/io/github/fvarrui/helloworld/HelloWorldFrame.java new file mode 100644 index 00000000..eff10d56 --- /dev/null +++ b/test/hello-world-gradle/src/main/java/io/github/fvarrui/helloworld/HelloWorldFrame.java @@ -0,0 +1,117 @@ +package io.github.fvarrui.helloworld; + +import java.awt.BorderLayout; +//import java.awt.Desktop; +import java.awt.Font; +//import java.awt.desktop.OpenFilesEvent; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +import org.apache.commons.io.FileUtils; + +@SuppressWarnings("serial") +public class HelloWorldFrame extends JFrame { + + private static String [] args; + + public HelloWorldFrame() throws IOException { + super("Hello World"); + initFrame(); + initContent(); + setVisible(true); + setExtendedState(getExtendedState() | JFrame.MAXIMIZED_BOTH); + } + + public void initContent() throws IOException { + + File info = new File("info.txt"); + + String content = FileUtils.readFileToString(info, StandardCharsets.UTF_8); + + JTextArea text = new JTextArea(); + text.setFont(new Font("monospaced", Font.PLAIN, 12)); + text.setEditable(false); + + getContentPane().setLayout(new BorderLayout()); + getContentPane().add(new JScrollPane(text), BorderLayout.CENTER); + + StringBuffer buffer = new StringBuffer(); + buffer.append("Additional resource: " + info + "\n"); + buffer.append("Content: " + content + "\n\n"); + + buffer.append("==============================================\n"); + buffer.append("ARGUMENTS ====================================\n"); + buffer.append("==============================================\n\n"); + buffer.append("args=" + Arrays.asList(args) + "\n"); + buffer.append("\n"); + + buffer.append("==============================================\n"); + buffer.append("ENVIRONMENT VARIABLES ========================\n"); + buffer.append("==============================================\n\n"); + List envKeys = System.getenv().keySet().stream().collect(Collectors.toList()); + Collections.sort(envKeys, (a, b) -> a.compareTo(b)); + for (String key : envKeys) { + buffer.append(key + "=" + System.getenv(key) + "\n"); + } + buffer.append("\n"); + + buffer.append("==============================================\n"); + buffer.append("PROPERTIES ===================================\n"); + buffer.append("==============================================\n\n"); + List propKeys = System.getProperties().keySet().stream().collect(Collectors.toList()); + Collections.sort(propKeys, (a, b) -> a.toString().compareTo(b.toString())); + for (Object key : propKeys) { + buffer.append(key + "=" + System.getProperty("" + key) + "\n"); + } + + text.setText(buffer.toString()); + + } + + public void initFrame() throws IOException { + setSize(640, 200); + setLocationRelativeTo(null); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setIconImage(ImageIO.read(getClass().getResourceAsStream("/images/world.png"))); + } + + public static void main(String[] args) { + + HelloWorldFrame.args = args; + + // read double-clicked files on mac os +// if (System.getProperty("os.name").contains("OS X")) { +// +// java.awt.Desktop.getDesktop().setOpenFileHandler((java.awt.desktop.OpenFilesEvent e) -> { +// File f = e.getFiles().stream().findFirst().get(); +// HelloWorldFrame.args = new String[] { f.getAbsolutePath() }; +// }); +// +// } + + System.out.println("Starting app ... "); + System.out.println("PATH=" + System.getenv("PATH")); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + try { + HelloWorldFrame.args = args; + new HelloWorldFrame(); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + } + +} diff --git a/test/hello-world-gradle/src/main/java/io/github/fvarrui/helloworld/Main.java b/test/hello-world-gradle/src/main/java/io/github/fvarrui/helloworld/Main.java new file mode 100644 index 00000000..ec4738ca --- /dev/null +++ b/test/hello-world-gradle/src/main/java/io/github/fvarrui/helloworld/Main.java @@ -0,0 +1,13 @@ +package io.github.fvarrui.helloworld; + +public class Main { + + public static void main(String[] args) { + if (args.length > 0 && args[0].equals("--help")) { + System.out.println("HelloWorld 1.0.0"); + return; + } + HelloWorldFrame.main(args); + } + +} diff --git a/test/hello-world-gradle/src/main/resources/images/world.png b/test/hello-world-gradle/src/main/resources/images/world.png new file mode 100644 index 00000000..4ecb0f2d Binary files /dev/null and b/test/hello-world-gradle/src/main/resources/images/world.png differ diff --git a/test/hello-world-gradle/src/main/resources/info.txt b/test/hello-world-gradle/src/main/resources/info.txt new file mode 100644 index 00000000..f5c4294c --- /dev/null +++ b/test/hello-world-gradle/src/main/resources/info.txt @@ -0,0 +1 @@ +Heeellllloooooooo!!! \ No newline at end of file diff --git a/test/hello-world-maven/.gitattributes b/test/hello-world-maven/.gitattributes new file mode 100644 index 00000000..dfe07704 --- /dev/null +++ b/test/hello-world-maven/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/test/hello-world-maven/.github/workflows/package.yml b/test/hello-world-maven/.github/workflows/package.yml new file mode 100644 index 00000000..e955e95e --- /dev/null +++ b/test/hello-world-maven/.github/workflows/package.yml @@ -0,0 +1,24 @@ +name: Packaging for Windows +on: workflow_dispatch # manually triggered +jobs: + windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Set path for candle and light + run: echo "C:\Program Files (x86)\WiX Toolset v3.11\bin" >> $GITHUB_PATH + shell: bash + - name: Package app + run: mvn clean package + - uses: actions/upload-artifact@v2 + with: + name: Windows Setup Installer (.exe) + path: target/HelloWorldMaven_*.exe + - uses: actions/upload-artifact@v2 + with: + name: Windows MSI Installer (.msi) + path: target/HelloWorldMaven_*.msi diff --git a/test/hello-world-maven/.gitignore b/test/hello-world-maven/.gitignore new file mode 100644 index 00000000..aa3b4f16 --- /dev/null +++ b/test/hello-world-maven/.gitignore @@ -0,0 +1,5 @@ +target +.classpath +.project +.settings +jdks \ No newline at end of file diff --git a/test/hello-world-maven/CustomMessages_en.isl b/test/hello-world-maven/CustomMessages_en.isl new file mode 100644 index 00000000..1ce6192e --- /dev/null +++ b/test/hello-world-maven/CustomMessages_en.isl @@ -0,0 +1,2 @@ +[Messages] +WelcomeLabel2=This will install [name/ver] on your system. diff --git a/test/hello-world-maven/CustomMessages_es.isl b/test/hello-world-maven/CustomMessages_es.isl new file mode 100644 index 00000000..7f92454e --- /dev/null +++ b/test/hello-world-maven/CustomMessages_es.isl @@ -0,0 +1,2 @@ +[Messages] +WelcomeLabel2=Se va a instalar [name/ver] en tu sistema. diff --git a/test/hello-world-maven/LICENSE b/test/hello-world-maven/LICENSE new file mode 100644 index 00000000..e62ec04c --- /dev/null +++ b/test/hello-world-maven/LICENSE @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/test/hello-world-maven/README.md b/test/hello-world-maven/README.md new file mode 100644 index 00000000..0013138f --- /dev/null +++ b/test/hello-world-maven/README.md @@ -0,0 +1,3 @@ +# HelloWorld + +JavaPackager sample project. \ No newline at end of file diff --git a/test/hello-world-maven/assets/HelloWorldMaven.icns b/test/hello-world-maven/assets/HelloWorldMaven.icns new file mode 100644 index 00000000..1a4d7638 Binary files /dev/null and b/test/hello-world-maven/assets/HelloWorldMaven.icns differ diff --git a/test/hello-world-maven/assets/HelloWorldMaven.ico b/test/hello-world-maven/assets/HelloWorldMaven.ico new file mode 100644 index 00000000..5960b3d5 Binary files /dev/null and b/test/hello-world-maven/assets/HelloWorldMaven.ico differ diff --git a/test/hello-world-maven/assets/HelloWorldMaven.png b/test/hello-world-maven/assets/HelloWorldMaven.png new file mode 100644 index 00000000..ca4f09f6 Binary files /dev/null and b/test/hello-world-maven/assets/HelloWorldMaven.png differ diff --git a/test/hello-world-maven/assets/linux/HelloWorldMaven.png b/test/hello-world-maven/assets/linux/HelloWorldMaven.png new file mode 100644 index 00000000..4ecb0f2d Binary files /dev/null and b/test/hello-world-maven/assets/linux/HelloWorldMaven.png differ diff --git a/test/hello-world-maven/assets/mac/HelloWorldMaven.icns b/test/hello-world-maven/assets/mac/HelloWorldMaven.icns new file mode 100644 index 00000000..c70ef779 Binary files /dev/null and b/test/hello-world-maven/assets/mac/HelloWorldMaven.icns differ diff --git a/test/hello-world-maven/assets/windows/HelloWorldMaven.ico b/test/hello-world-maven/assets/windows/HelloWorldMaven.ico new file mode 100644 index 00000000..12a838fc Binary files /dev/null and b/test/hello-world-maven/assets/windows/HelloWorldMaven.ico differ diff --git a/test/hello-world-maven/info.txt b/test/hello-world-maven/info.txt new file mode 100644 index 00000000..4ac0d102 --- /dev/null +++ b/test/hello-world-maven/info.txt @@ -0,0 +1 @@ +Soy otro info.txt \ No newline at end of file diff --git a/test/hello-world-maven/pom.xml b/test/hello-world-maven/pom.xml new file mode 100644 index 00000000..8977f515 --- /dev/null +++ b/test/hello-world-maven/pom.xml @@ -0,0 +1,93 @@ + + + 4.0.0 + + io.github.fvarrui + HelloWorldMaven + 1.0.0 + + + 11 + 11 + UTF-8 + io.github.fvarrui.helloworld.Main + + + + + commons-io + commons-io + 2.7 + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + + ${exec.mainClass} + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + + io.github.fvarrui + javapackager + + + + package + + package + + + windows + ${exec.mainClass} + true + true + true + true + + src/main/resources/info.txt + + + -Dcustom.variable="Hi!" + -Dother.custom.variable="Bye!" + + + + HelloWorld File + hello + application/hello + + + + + + + + + + + \ No newline at end of file diff --git a/test/hello-world-maven/src/main/java/io/github/fvarrui/helloworld/HelloWorldFrame.java b/test/hello-world-maven/src/main/java/io/github/fvarrui/helloworld/HelloWorldFrame.java new file mode 100644 index 00000000..f43afa05 --- /dev/null +++ b/test/hello-world-maven/src/main/java/io/github/fvarrui/helloworld/HelloWorldFrame.java @@ -0,0 +1,115 @@ +package io.github.fvarrui.helloworld; + +import java.awt.BorderLayout; +import java.awt.Font; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +import org.apache.commons.io.FileUtils; + +@SuppressWarnings("serial") +public class HelloWorldFrame extends JFrame { + + private static String[] args; + + public HelloWorldFrame() throws IOException { + super("Hello World"); + initFrame(); + initContent(); + setVisible(true); + setExtendedState(getExtendedState() | JFrame.MAXIMIZED_BOTH); + } + + public void initContent() throws IOException { + + File info = new File("info.txt"); + + String content = FileUtils.readFileToString(info, StandardCharsets.UTF_8); + + JTextArea text = new JTextArea(); + text.setFont(new Font("monospaced", Font.PLAIN, 12)); + text.setEditable(false); + + getContentPane().setLayout(new BorderLayout()); + getContentPane().add(new JScrollPane(text), BorderLayout.CENTER); + + StringBuffer buffer = new StringBuffer(); + buffer.append("Additional resource: " + info + "\n"); + buffer.append("Content: " + content + "\n\n"); + + buffer.append("==============================================\n"); + buffer.append("ARGUMENTS ====================================\n"); + buffer.append("==============================================\n\n"); + buffer.append("args=" + Arrays.asList(args) + "\n"); + buffer.append("\n"); + + buffer.append("==============================================\n"); + buffer.append("ENVIRONMENT VARIABLES ========================\n"); + buffer.append("==============================================\n\n"); + List envKeys = System.getenv().keySet().stream().collect(Collectors.toList()); + Collections.sort(envKeys, (a, b) -> a.compareTo(b)); + for (String key : envKeys) { + buffer.append(key + "=" + System.getenv(key) + "\n"); + } + buffer.append("\n"); + + buffer.append("==============================================\n"); + buffer.append("PROPERTIES ===================================\n"); + buffer.append("==============================================\n\n"); + List propKeys = System.getProperties().keySet().stream().collect(Collectors.toList()); + Collections.sort(propKeys, (a, b) -> a.toString().compareTo(b.toString())); + for (Object key : propKeys) { + buffer.append(key + "=" + System.getProperty("" + key) + "\n"); + } + + text.setText(buffer.toString()); + + } + + public void initFrame() throws IOException { + setSize(640, 200); + setLocationRelativeTo(null); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setIconImage(ImageIO.read(getClass().getResourceAsStream("/images/world.png"))); + } + + public static void main(String[] args) { + + HelloWorldFrame.args = args; + + // read double-clicked files on mac os +// if (System.getProperty("os.name").contains("OS X")) { +// +// java.awt.Desktop.getDesktop().setOpenFileHandler((java.awt.desktop.OpenFilesEvent e) -> { +// File f = e.getFiles().stream().findFirst().get(); +// HelloWorldFrame.args = new String[] { f.getAbsolutePath() }; +// }); +// +// } + + System.out.println("Starting app ... "); + System.out.println("PATH=" + System.getenv("PATH")); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + try { + new HelloWorldFrame(); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + + } + +} diff --git a/test/hello-world-maven/src/main/java/io/github/fvarrui/helloworld/Main.java b/test/hello-world-maven/src/main/java/io/github/fvarrui/helloworld/Main.java new file mode 100644 index 00000000..4e718024 --- /dev/null +++ b/test/hello-world-maven/src/main/java/io/github/fvarrui/helloworld/Main.java @@ -0,0 +1,38 @@ +package io.github.fvarrui.helloworld; + +import java.lang.module.ModuleDescriptor; + +public class Main { + + public static void main(String[] args) { + if (args.length > 0) { + String argument = args[0]; + switch (argument) { + case "--version": + version(); + return; + case "--module-info": + moduleInfo(); + return; + } + } + HelloWorldFrame.main(args); + } + + private static void version() { + System.out.println("HelloWorld 1.0.0"); + } + + private static void moduleInfo() { + ModuleDescriptor descriptor = Main.class.getModule().getDescriptor(); + if (descriptor != null) { + System.out.println("Modular version of HelloWorldMaven:"); + System.out.println("- Module name : " + descriptor.name()); + System.out.println("- Requires : " + descriptor.requires()); + System.out.println("- Exports : " + descriptor.exports()); + } else { + System.out.println("Non modular version of HelloWorldMaven!"); + } + } + +} diff --git a/test/hello-world-maven/src/main/resources/images/world.png b/test/hello-world-maven/src/main/resources/images/world.png new file mode 100644 index 00000000..4ecb0f2d Binary files /dev/null and b/test/hello-world-maven/src/main/resources/images/world.png differ diff --git a/test/hello-world-maven/src/main/resources/info.txt b/test/hello-world-maven/src/main/resources/info.txt new file mode 100644 index 00000000..f5c4294c --- /dev/null +++ b/test/hello-world-maven/src/main/resources/info.txt @@ -0,0 +1 @@ +Heeellllloooooooo!!! \ No newline at end of file