diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..634955e2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,111 @@ +name: Bug report +description: Report a bug to help us improve +labels: + - bug +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to file a bug. Please fill in the details below. + + - type: input + id: version + attributes: + label: JavaPackager version + description: Exact version used (e.g., 1.7.5). If built from source, include the commit. + placeholder: e.g., 1.7.5 + validations: + required: true + + - type: dropdown + id: os + attributes: + label: Operating system + options: + - Windows + - macOS + - Linux + - Other + validations: + required: true + + - type: input + id: os_version + attributes: + label: OS version + placeholder: e.g., Windows 11 23H2, Ubuntu 22.04, macOS 14.5 + + - type: dropdown + id: build_tool + attributes: + label: Build tool + options: + - Gradle + - Maven + - Other / N/A + validations: + required: true + + - type: input + id: jdk + attributes: + label: JDK version + placeholder: e.g., Temurin 21.0.3+9, Oracle JDK 17.0.10 + validations: + required: true + + - type: textarea + id: short_description + attributes: + label: Short description + description: What happens in one or two sentences? + placeholder: Clear and concise description of the problem. + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Steps to reproduce + description: Provide minimal, reproducible steps. + placeholder: | + 1. Step one + 2. Step two + 3. Observed result + render: text + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behavior + placeholder: What did you expect to happen? + validations: + required: true + + - type: textarea + id: actual + attributes: + label: Actual behavior + placeholder: What actually happens? + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Logs and output + description: Paste relevant output or attach files. + placeholder: Add logs, stack traces, console output, etc. + render: text + + - type: checkboxes + id: checklist + attributes: + label: Checklist + options: + - label: I searched for existing related issues + required: true + - label: I can provide a minimal reproducible example if needed + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..dec06859 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Documentation + url: https://github.com/javapackager/JavaPackager/blob/master/README.md + about: Check the documentation before opening an issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..a19ed75b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,55 @@ +name: Feature request +description: Suggest a new feature or improvement +labels: + - enhancement +body: + - type: markdown + attributes: + value: | + Thanks for suggesting an improvement. Tell us the problem and your proposed solution. + + - type: textarea + id: problem + attributes: + label: Problem to solve + description: What need or pain point motivates this feature? + placeholder: Describe the problem or use case. + validations: + required: true + + - type: textarea + id: proposal + attributes: + label: Proposed solution + description: Explain how you would like it to work. + placeholder: Detail the proposed change and expected behavior. + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + placeholder: What other options did you consider? + + - type: textarea + id: impact + attributes: + label: Impact and scope + placeholder: Affected users, compatibility, risks, etc. + + - type: input + id: version + attributes: + label: JavaPackager version (if applicable) + placeholder: e.g., 1.7.5 + + - type: checkboxes + id: checklist + attributes: + label: Checklist + options: + - label: I searched for existing similar issues + required: true + - label: I am willing to contribute a PR + required: false diff --git a/.github/issue_template.md b/.github/issue_template.md deleted file mode 100644 index c1254cc1..00000000 --- a/.github/issue_template.md +++ /dev/null @@ -1,42 +0,0 @@ -I'm submitting a… - -- [ ] bug report -- [ ] feature request -- [ ] other - -**Short description of the issue/suggestion:** - - - -**Steps to reproduce the issue/enhancement:** - -1. [First Step] -2. [Second Step] -3. [Other Steps...] - -**What is the expected behavior?** - - - -**What is the current behavior?** - - - -**Do you have outputs, screenshots, demos or samples which demonstrate the problem or enhancement?** - - - -**What is the motivation / use case for changing the behavior?** - - - -**Please tell us about your environment:** - -- JavaPackager version: -- OS version: -- JDK version: -- Build tool: - - [ ] Maven - - [ ] Gradle - -**Other information** (e.g. related issues, suggestions how to fix, links for us to have context) \ No newline at end of file diff --git a/.gitignore b/.gitignore index b5a5361b..9c64626e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,24 @@ target # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar src/main/resources/windows/winrun4j-launcher.jar + +# Log file +*.log + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +# IntelliJ +**/.idea/ +**.iml + +# Eclipse +**/.settings/ + +# Maven +**/target/ +**/*.xml.releaseBackup +/release.properties + +## More +.DS_Store diff --git a/README.md b/README.md index eff203a5..b4ddf145 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,31 @@ # JavaPackager -[![Maven Central](http://img.shields.io/maven-central/v/io.github.fvarrui/javapackager)](https://search.maven.org/artifact/io.github.fvarrui/javapackager) +[![Maven Central](http://img.shields.io/maven-central/v/io.github.fvarrui/javapackager)](https://central.sonatype.com/search?smo=true&q=a%3Ajavapackager+g%3Aio.github.fvarrui) [![GPL-3.0](https://img.shields.io/badge/license-GPL--3.0-%250778B9.svg)](https://www.gnu.org/licenses/gpl-3.0.html) -JavaPackager is a hybrid plugin for **Maven** and **Gradle** which provides an easy way to package Java applications in native Windows, Mac OS X or GNU/Linux executables, and generate installers for them. +JavaPackager is a hybrid plugin for **Maven** and **Gradle** which provides an easy way to package Java applications in native Windows, MacOS or GNU/Linux executables, and generate installers for them. -> SNAPSHOT version is not released to Maven Central, so you have to [install it manually](#how-to-build-and-install-the-plugin). +> [!IMPORTANT] +> See [JavaPackager changes and fixes](https://github.com/fvarrui/JavaPackager/releases). -> :eyes: See [JavaPackager changes and fixes](https://github.com/fvarrui/JavaPackager/releases). +## Project maintainers needed + +This project has been actively maintained for many years, but due to lack of time, I can no longer dedicate the attention it deserves. To keep it alive and evolving, I’m looking for contributors to help with its maintenance. + +:point_right: **[Join the discussion](https://github.com/fvarrui/JavaPackager/discussions/460)** + +Any help is welcome! Thank you for your support. ## History -It was born while teaching to my students how to build and distribute their Java apps, and after seeing that a chain of several plugins was needed to achieve this task, I decided to develop a plugin :ring: to govern them all. +It was born while teaching to my students how to build and distribute their Java apps, and after seeing that a chain of several plugins was needed to achieve this task, I decided to develop a plugin :ring: to rule them all. ## Apps packaged with JavaPackager -- [Spektar Design Lab](https://spektar.io/) +- [AstroImageJ](http://astroimagej.com/) - [Astro Pixel Processor](https://www.astropixelprocessor.com/) - [GistFX](https://github.com/RedmondSims/GistFX) -- [AstroImageJ](http://astroimagej.com/) +- [Spektar Design Lab](https://spektar.io/) ## How to use this plugin @@ -30,7 +37,7 @@ Add the following `plugin` tag to your `pom.xml`: io.github.fvarrui javapackager - 1.6.7 + {latest.version} package @@ -60,6 +67,7 @@ Add the following `plugin` tag to your `pom.xml`: ``` +> [!tip] > See [Maven plugin configuration samples](docs/maven/plugin-configuration-samples.md) to know more. And execute the next command in project's root folder: @@ -78,7 +86,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'io.github.fvarrui:javapackager:1.6.7' + classpath 'io.github.fvarrui:javapackager:{latest.version}' } } @@ -95,7 +103,7 @@ task packageMyApp(type: io.github.fvarrui.javapackager.gradle.PackageTask, depen bundleJre = true|false generateInstaller = true|false administratorRequired = true|false - platform = auto|linux|mac|windows + platform = "auto"|"linux"|"mac"|"windows" additionalResources = [ file('file path'), file('folder path'), ... ] linuxConfig { ... @@ -110,7 +118,8 @@ task packageMyApp(type: io.github.fvarrui.javapackager.gradle.PackageTask, depen } ``` -> See [Gradle plugin configuration samples](docs/gradle/plugin-configuration-samples.md) to know more. +> [!TIP] +> See [Gradle plugin configuration samples](docs/gradle/plugin-configuration-samples.md) to know more. And execute the next command in project's root folder: @@ -122,22 +131,23 @@ gradle packageMyApp By default it will generate next artifacts in `${outputDirectory} ` folder: -| Artifact | Description | Platform | Requires | -| --------------------------------------- | ---------------------------------------------------------------- | --------- | --------------------------------------------------------------------------- | -| `${name}` | Directory with native application and other assets. | All | | -| `${name}-${version}-runnable.jar` | Runnable JAR file. | All | | -| `${name}_${version}.AppImage` | AppImage package file. | GNU/Linux | [FUSE 2](https://github.com/AppImage/AppImageKit/wiki/FUSE) to run the app. | -| `${name}_${version}.deb` | DEB package file. | All | | -| `${name}_${version}.rpm` | RPM package file. | All | | -| `${name}_${version}.exe` | Setup file. | Windows | [Inno Setup](http://www.jrsoftware.org/isinfo.php) | -| `${name}_${version}.msi` | MSI installer file. | Windows | [WiX Toolset](https://wixtoolset.org/) | -| `${name}_${version}.msm` | MSI merge module file. | Windows | [WiX Toolset](https://wixtoolset.org/) | -| `${name}_${version}.dmg` | Disk image file (uses **hdiutil**). | Mac OS | | -| `${name}_${version}.pkg` | PKG installer file (uses **pkgbuild**). | Mac OS | | -| `${name}-${version}-${platform}.zip` | Zipball containing generated directory `${name}`. | All | | -| `${name}-${version}-${platform}.tar.gz` | Compressed tarball containing generated directory `${name}`. | All | | -| `assets` | Directory with all intermediate files generated by JavaPackager. | All | | - +| Artifact | Description | Platform | Requires | +| --------------------------------------- | ---------------------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------ | +| `${name}` | Directory with native application and other assets. | All | | +| `${name}-${version}-runnable.jar` | Runnable JAR file. | All | | +| `${name}_${version}.AppImage` | AppImage package file. | GNU/Linux | [FUSE 2](https://github.com/AppImage/AppImageKit/wiki/FUSE) to run the app. | +| `${name}_${version}.deb` | DEB package file. | All | | +| `${name}_${version}.rpm` | RPM package file. | All | | +| `${name}_${version}.exe` | Setup file. | Windows | [Inno Setup](http://www.jrsoftware.org/isinfo.php) (`iscc` command must be in PATH variable) | +| `${name}_${version}.msi` | MSI installer file. | Windows | [WiX Toolset](https://wixtoolset.org/) (`candle` and `light` commands must be in PATH variable) | +| `${name}_${version}.msm` | MSI merge module file. | Windows | [WiX Toolset](https://wixtoolset.org/) ( `candle` and `light` commands must be in PATH variable) | +| `${name}_${version}.dmg` | Disk image file (uses **hdiutil**). | MacOS | | +| `${name}_${version}.pkg` | PKG installer file (uses **pkgbuild**). | MacOS | | +| `${name}-${version}-${platform}.zip` | Zipball containing generated directory `${name}`. | All | | +| `${name}-${version}-${platform}.tar.gz` | Compressed tarball containing generated directory `${name}`. | All | | +| `assets` | Directory with all intermediate files generated by JavaPackager. | All | | + +> [!TIP] > **Inno Setup** and **WiX Toolset** installation [guide](docs/windows-tools-guide.md). ### Plugin configuration properties @@ -147,6 +157,7 @@ By default it will generate next artifacts in `${outputDirectory} ` folder: | `additionalModulePaths` | :x: | `[]` | Additional module paths for `jdeps`. | | `additionalModules` | :x: | `[]` | Additional modules to the ones identified by `jdeps` or the specified with `modules` property. | | `additionalResources` | :x: | `[]` | Additional files and folders to include in the bundled app. | +| `arch` | :x: | `${os.arch}` | The dependency of some ArtifactGenerator objects in the process of making packages, such as GenerateDeb | | `administratorRequired` | :x: | `false` | App will run as administrator (with elevated privileges). | | `assetsDir` | :x: | `${basedir}/assets` or `${projectdir}/assets` | Assets location (icons and custom Velocity templates). | | `bundleJre` | :x: | `false` | Embeds a customized JRE with the app. | @@ -157,7 +168,7 @@ By default it will generate next artifacts in `${outputDirectory} ` folder: | `customizedJre` | :x: | `true` | Generates a customized JRE, including only identified or specified modules. Otherwise, all modules will be included. | | `description` | :x: | `${project.description}` or `${displayName}` | Project description. | | `displayName` | :x: | `${project.name}` or `${name}` | App name to show. | -| `envPath` | :x: | | Defines PATH environment variable in GNU/Linux and Mac OS X startup scripts. | +| `envPath` | :x: | | Defines PATH environment variable in GNU/Linux and MacOS startup scripts. | | `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. | @@ -180,10 +191,11 @@ By default it will generate next artifacts in `${outputDirectory} ` folder: | `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!** | | `url` | :x: | | App website URL. | -| `useResourcesAsWorkingDir` | :x: | `true` | Uses app resources folder as default working directory (always `true` on Mac OS). | +| `useResourcesAsWorkingDir` | :x: | `true` | Uses app resources folder as default working directory (always `true` on MacOS). | | `version` | :x: | `${project.version}` | App version. | | `vmArgs` | :x: | `[]` | VM arguments. | +> [!IMPORTANT] > Some default values depends on the used building tool. **Platform specific properties** @@ -191,10 +203,11 @@ By default it will generate next artifacts in `${outputDirectory} ` folder: | Property | Mandatory | Description | | ------------- | --------- | ------------------------------------------------------------------- | | `linuxConfig` | :x: | [GNU/Linux specific properties](docs/linux-specific-properties.md). | -| `macConfig` | :x: | [Mac OS X specific properties](docs/macosx-specific-properties.md). | +| `macConfig` | :x: | [MacOS specific properties](docs/macosx-specific-properties.md). | | `winConfig` | :x: | [Windows specific properties](docs/windows-specific-properties.md). | -> :warning: Be careful when using the `platform` property if your project uses platform dependent libraries, so the libraries of the current platform will be copied, not those required for the target platform. You can solve this problem using `classifiers`. +> [!WARNING] +> Be careful when using the `platform` property if your project uses platform dependent libraries, so the libraries of the current platform will be copied, not those required for the target platform. You can solve this problem using `classifiers`. ### Plugin assets @@ -216,12 +229,13 @@ ${assetsDir}/ ├── linux/ │ └── ${name}.png # on GNU/Linux it has to be a PNG file ├── mac/ -│ └── ${name}.icns # on Mac OS X it has to be a ICNS file +│ └── ${name}.icns # on MacOS it has to be a ICNS file └── windows/ └── ${name}.ico # on Windows it has to be a ICO file ``` -> :warning: If icon is not specified , it will use an [icon by default](https://raw.githubusercontent.com/fvarrui/JavaPackager/master/src/main/resources/linux/default-icon.png) for all platforms. +> [!WARNING] +> If icon is not specified , it will use an [icon by default](https://raw.githubusercontent.com/fvarrui/JavaPackager/master/src/main/resources/linux/default-icon.png) for all platforms. #### Templates @@ -239,7 +253,7 @@ ${assetsDir}/ | ├── mime.xml.vtl # MIME.XML template │ └── startup.sh.vtl # Startup script template ├── mac/ -| ├── assembly.xml.vtl # maven-assembly-plugin template to generate ZIP/TGZ bundles for Mac OS X +| ├── assembly.xml.vtl # maven-assembly-plugin template to generate ZIP/TGZ bundles for MacOS | ├── customize-dmg.applescript.vtl # DMG customization Applescript template | ├── Info.plist.vtl # Info.plist template │ └── startup.vtl # Startup script template @@ -260,9 +274,9 @@ You can use [default templates](https://github.com/fvarrui/JavaPackager/tree/mas ### Additional JVM options at runtime -When you build your app, all configuration details are hardcoded into the executable and cannot be changed without recreating it or hacking with a resource editor. JavaPackager introduces a feature that allows to pass additional JVM options at runtime from an `.l4j.ini` file (like [Launch4j](http://launch4j.sourceforge.net/docs.html) does, but available for all platforms in the same way). So, you can specify these options in the packager's configuration (packaging time), in INI file (runtime) or in both. +When you build your app, all configuration details are hardcoded into the executable and cannot be changed without recreating or hacking it with a resource editor. JavaPackager introduces a feature that allows to pass additional JVM options at runtime from an `.l4j.ini` file (like [Launch4j](http://launch4j.sourceforge.net/docs.html) does, but available for all platforms in the same way). So, you can specify these options in the packager's configuration (packaging time), in INI file (runtime) or in both. -The INI file's name must correspond to `${name}.l4j.ini` and it has to be located next to the executable on Windows and GNU/Linux, and in `Resources` folder on Mac OS X. +The INI file's name must correspond to `${name}.l4j.ini` and it has to be located next to the executable on Windows and GNU/Linux, and in `Resources` folder on MacOS. The options should be separated with spaces or new lines: @@ -273,7 +287,8 @@ The options should be separated with spaces or new lines: -Xms16m ``` -> An VM argument per line. +> [!IMPORTANT] +> An VM argument per line. And then bundle this file with your app: @@ -283,39 +298,112 @@ And then bundle this file with your app: ``` +> [!NOTE] > Last property copies `${name}.l4j.ini` file next to the EXE/binary on Windows/Linux, and in `Resources` folder on MacOS. -## How to build and install the plugin +## How to use SNAPSHOT versions + +[Here](https://oss.sonatype.org/content/repositories/snapshots/io/github/fvarrui/javapackager/) you can find the uploaded JavaPackager SNAPSHOT versions. + +### Maven + +Add the plugin repository to your `pom.xml`: + +```xml + + + nexus + nexus-snapshot-repository + https://oss.sonatype.org/content/repositories/snapshots + + true + always + + + false + + + +``` + +And then you can use the latest SNAPSHOT version: + +```xml + + io.github.fvarrui + javapackager + {javapackager.version}-SNAPSHOT + [...] + +``` + +Or a specific SNAPSHOT version (specifying its timestamp and index): -Useful to try SNAPSHOT versions. +```xml + + io.github.fvarrui + javapackager + {javapackager.version}-{timestamp}-{index} + [...] + +``` + +> SNAPSHOT version example: `1.7.2-20230505.095442-5`. + +### Gradle + +Add the plugin repository to your `build.gradle` and use the latest SNAPSHOT version: + +```groovy +buildscript { + repositories { + maven { + url "https://oss.sonatype.org/content/repositories/snapshots" + } + } + dependencies { + classpath 'io.github.fvarrui:javapackager:{javapackager.version}-SNAPSHOT' + } +} +``` + +Or set a specific SNAPSHOT version specifying its timestamp and index: + +```groovy +buildscript { + [...] + dependencies { + classpath 'io.github.fvarrui:javapackager:{javapackager.version}-{timestamp}-{index}' + } +} +``` + +> SNAPSHOT version example: `1.7.2-20230505.095442-5`. + +## How to build and install the plugin in your local repo Execute next commands in BASH (GNU/Linux or macOS) or CMD (Windows): 1. Download source code and change to the project directory: ```bash -git clone https://github.com/fvarrui/JavaPackager.git [--branch x] +git clone https://github.com/fvarrui/JavaPackager.git [--branch devel] cd JavaPackager ``` -> where `x` is branch name (e.g. `devel`) - 2. Compile, package and install the plugin in your local repository (ommit `./` on Windows): ```bash ./gradlew publishToMavenLocal ``` +> [!IMPORTANT] +> It is recommended to build the plugin with Java 19. + ## How to release the plugin to Maven Central Run next command (ommit `./` on Windows): ```bash -./gradlew -Prelease uploadArchives closeAndReleaseRepository +./gradlew publish closeAndReleaseRepository ``` - -> Related [guide](https://nemerosa.ghost.io/2015/07/01/publishing-to-the-maven-central-using-gradle/). - -## Future features - -Check the [TO-DO list](https://github.com/fvarrui/JavaPackager/projects/1#column-7704117) to know the features we plan to add to JavaPackager. diff --git a/build.gradle b/build.gradle index af811bca..454b9f65 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,12 @@ plugins { id 'java' - id 'maven' id 'maven-publish' id 'java-gradle-plugin' - id 'com.gradle.plugin-publish' version '0.12.0' + id 'com.gradle.plugin-publish' version '1.1.0' id 'io.codearte.nexus-staging' version '0.21.2' id 'eclipse' id 'de.undercouch.download' version '5.0.4' + id 'signing' } repositories { @@ -18,22 +18,16 @@ repositories { } gradlePlugin { - plugins { - javaPackagerPlugin { - id = 'io.github.fvarrui.javapackager.plugin' - implementationClass = 'io.github.fvarrui.javapackager.gradle.PackagePlugin' - } - } -} - -pluginBundle { website = 'http://github.com/fvarrui/JavaPackager' vcsUrl = 'http://github.com/fvarrui/JavaPackager.git' - description = 'Packages Java applications as native Windows, Mac OS X or GNU/Linux executables and creates installers for them' - tags = ['java', 'packager', 'gradle-plugin', 'maven-plugin', 'native', 'installer', 'debian-packages', 'rpm-packages', 'dmg', 'maven', 'gradle', 'distribution', 'javapackager', 'linux-executables', 'deb', 'rpm', 'native-windows', 'java-applications', 'pkg', 'msi'] + description = 'Packages Java applications as native Windows, MacOS or GNU/Linux executables and creates installers for them' + plugins { - javaPackagerPlugin { + create("javaPackagerPlugin") { + id = 'io.github.fvarrui.javapackager.plugin' displayName = 'JavaPackager' + implementationClass = 'io.github.fvarrui.javapackager.gradle.PackagePlugin' + tags.set(['java', 'packager', 'gradle-plugin', 'maven-plugin', 'native', 'installer', 'debian-packages', 'rpm-packages', 'dmg', 'maven', 'gradle', 'distribution', 'javapackager', 'linux-executables', 'deb', 'rpm', 'native-windows', 'java-applications', 'pkg', 'msi']) } } } @@ -44,19 +38,19 @@ configurations { dependencies { implementation 'org.apache.maven:maven-plugin-api:3.6.0' - implementation 'org.codehaus.plexus:plexus-utils:3.1.1' + implementation 'org.codehaus.plexus:plexus-utils:3.5.1' implementation 'org.twdata.maven:mojo-executor:2.3.0' - implementation 'commons-io:commons-io:2.6' + implementation 'commons-io:commons-io:2.16.1' implementation 'org.apache.commons:commons-lang3:3.9' - implementation 'org.apache.commons:commons-collections4:4.1' + implementation 'org.apache.commons:commons-collections4:4.3' implementation 'org.apache.commons:commons-compress:1.21' - implementation 'org.apache.velocity:velocity-engine-core:2.0' + implementation 'org.apache.velocity:velocity-engine-core:2.3' implementation 'org.vafer:jdeb:1.9' - implementation 'net.jsign:jsign-core:3.1' + implementation 'net.jsign:jsign-core:6.0' implementation 'org.redline-rpm:redline:1.2.10' - implementation 'io.github.fvarrui:launch4j:2.5.2' + implementation 'edu.sc.seis.launch4j:launch4j:3.0.5' - testImplementation 'junit:junit:4.12' + testImplementation 'junit:junit:4.13.1' compileOnly 'org.apache.maven.plugin-tools:maven-plugin-annotations:3.6.0' @@ -70,7 +64,7 @@ dependencies { } group = 'io.github.fvarrui' -version = '1.6.7' +version = '1.7.6' 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 @@ -78,164 +72,152 @@ targetCompatibility = JavaVersion.VERSION_1_8 compileJava.options.encoding = 'UTF-8' +// suppress javadoc warnings +javadoc.options.addStringOption('Xdoclint:none', '-quiet') + +java { + withSourcesJar() + withJavadocJar() +} + +// OSSRH publication publishing { + repositories { + maven { + def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" + def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots" + name = "OSSRH" + url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl + credentials { + username = project.findProperty("ossrhUsername") ?: '' + password = project.findProperty("ossrhPassword") ?: '' + } + } + } publications { - mavenJava(MavenPublication) { - from(components.java) + pluginMaven(MavenPublication) { + def directory = buildDir.canonicalPath + def outputDirectory = compileJava.destinationDirectory.asFile.get().canonicalPath + pom.withXml { + asNode().appendNode('build') + .with { + appendNode('directory', directory) + appendNode('outputDirectory', outputDirectory) + } + asNode().appendNode('repositories').appendNode('repository') + .with { + appendNode('id', 'gradle') + appendNode('name', 'Gradle Plugin Portal') + appendNode('url', 'https://plugins.gradle.org/m2/') + } + } + pom { + name = project.name + groupId = project.group + artifactId = project.name + packaging = 'maven-plugin' + } } } -} -install.repositories.mavenInstaller.pom.with { - groupId = project.group - artifactId = project.name - version = project.version - description = project.description - packaging = 'maven-plugin' + afterEvaluate { + publications { + withType(MavenPublication) { + // customize all publications here + pom { + version = project.version + description = project.description + url = 'https://github.com/fvarrui/JavaPackager' + scm { + connection = 'scm:git:git://github.com/fvarrui/JavaPackager.git' + developerConnection = 'scm:git:git@github.com:fvarrui/fvarrui.git' + url = 'https://github.com/fvarrui/JavaPackager' + } + licenses { + license { + name = 'GPL-v3.0' + url = 'http://www.gnu.org/licenses/gpl-3.0.txt' + distribution = 'repo' + } + } + developers { + developer { + id = 'fvarrui' + name = 'Francisco Vargas Ruiz' + url = 'https://github.com/fvarrui' + } + } + } + } + } + } } -build.dependsOn ':winrun4j-launcher:build' - // runs the plugin description generator -task generatePluginDescriptor(type: JavaExec, dependsOn: compileJava) { - - def pomFile = file("$buildDir/pom.xml") - def pluginDescriptorFile = new File(project.compileJava.destinationDir, 'META-INF/maven/plugin.xml') - def directory = buildDir.canonicalPath - def outputDirectory = compileJava.destinationDir.canonicalPath +tasks.register('generatePluginDescriptor', JavaExec) { + dependsOn compileJava + def pluginDescriptorFile = new File(project.compileJava.destinationDirectory.asFile.get(), 'META-INF/maven/plugin.xml') // FIXME: this does not seem to be working inputs.files project.compileJava.outputs.files outputs.file pluginDescriptorFile classpath = configurations.mavenEmbedder - main = 'org.apache.maven.cli.MavenCli' + mainClass = 'org.apache.maven.cli.MavenCli' systemProperties['maven.multiModuleProjectDirectory'] = projectDir args = [ '--errors', '--batch-mode', - '--file', "${buildDir}/pom.xml", - 'org.apache.maven.plugins:maven-plugin-plugin:3.6.0:descriptor', + '--file', generatePomFileForPluginMavenPublication.destination, + 'org.apache.maven.plugins:maven-plugin-plugin:3.9.0:descriptor', '-Dproject.build.sourceEncoding=' + compileJava.options.encoding ] - - doFirst { - install.repositories - .mavenInstaller - .pom - .withXml { - asNode().appendNode('repositories').appendNode('repository') - .with { - appendNode('id', 'gradle') - appendNode('name', 'Gradle Plugin Portal') - appendNode('url', 'https://plugins.gradle.org/m2/') - } - asNode().appendNode('build') - .with { - appendNode('directory', directory) - appendNode('outputDirectory', outputDirectory) - } - } - .writeTo(pomFile) - - assert pomFile.file, "${pomFile.canonicalPath}: was not generated" - logger.info("POM is generated in ${pomFile.canonicalPath}") - } - doLast { assert pluginDescriptorFile.file, "${pluginDescriptorFile.canonicalPath}: was not generated" logger.info("Plugin descriptor is generated in ${pluginDescriptorFile.canonicalPath}") } } +generatePluginDescriptor.dependsOn(generatePomFileForPluginMavenPublication) -project.jar.dependsOn(generatePluginDescriptor) +project.classes.dependsOn(generatePluginDescriptor) +project.validatePlugins.dependsOn(generatePluginDescriptor) publishToMavenLocal.dependsOn(build) - -if (project.hasProperty('release')) { - - apply plugin: 'signing' - apply plugin: 'maven' - - task javadocJar(type: Jar) { - classifier = 'javadoc' - from javadoc - } - - task sourcesJar(type: Jar) { - classifier = 'sources' - from sourceSets.main.allSource - } - - artifacts { - archives javadocJar, sourcesJar - } - - // Signature of artifacts - signing { - sign configurations.archives - } - - // OSSRH publication - uploadArchives { - repositories { - mavenDeployer { - // POM signature - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - // Target repository - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: ossrhUser, password: ossrhPassword) - } - pom.project { - name project.name - description project.description - packaging = 'maven-plugin' - url 'https://github.com/fvarrui/JavaPackager' - scm { - connection 'scm:git:git://github.com/fvarrui/JavaPackager.git' - developerConnection 'scm:git:git@github.com:fvarrui/fvarrui.git' - url 'https://github.com/fvarrui/JavaPackager' - } - - licenses { - license { - name 'GPL-v3.0' - url 'http://www.gnu.org/licenses/gpl-3.0.txt' - distribution 'repo' - } - } - - developers { - developer { - id = 'fvarrui' - name = 'Francisco Vargas Ruiz' - url = 'https://github.com/fvarrui' - } - } - } - } - } +// Signature of publication +signing { + setRequired { + // signing is only required if the artifacts are to be published + gradle.taskGraph.allTasks.any { it instanceof PublishToMavenRepository } } - + sign publishing.publications.pluginMaven } nexusStaging { - username = project.findProperty('ossrhUser') ?: '' + username = project.findProperty('ossrhUsername') ?: '' password = project.findProperty('ossrhPassword') ?: '' } - -task updateUniversalJavaApplicationStub(type : Download) { - def version = '20220410.162252' - group 'Update universalJavaApplicationStub' - description 'Downloads and ovewrites compiled and scripted versions of universalJavaApplicationStub to src/main/resources/mac and overrides the existing ones.' +tasks.register('updateUniversalJavaApplicationStub', Download) { + def version = '20230601.235708' + group 'Update assets' + description 'Downloads compiled and scripted versions of universalJavaApplicationStub to src/main/resources/mac overriding the existing ones.' src([ - "https://github.com/fvarrui/universalJavaApplicationStub/releases/download/${version}/universalJavaApplicationStub.sh", - "https://github.com/fvarrui/universalJavaApplicationStub/releases/download/${version}/universalJavaApplicationStub.x86_64", - "https://github.com/fvarrui/universalJavaApplicationStub/releases/download/${version}/universalJavaApplicationStub.arm64", - "https://github.com/fvarrui/universalJavaApplicationStub/releases/download/${version}/universalJavaApplicationStub" + "https://github.com/fvarrui/universalJavaApplicationStub/releases/download/${version}/universalJavaApplicationStub.sh", + "https://github.com/fvarrui/universalJavaApplicationStub/releases/download/${version}/universalJavaApplicationStub.x86_64", + "https://github.com/fvarrui/universalJavaApplicationStub/releases/download/${version}/universalJavaApplicationStub.arm64", + "https://github.com/fvarrui/universalJavaApplicationStub/releases/download/${version}/universalJavaApplicationStub" ]) dest file('src/main/resources/mac') - overwrite true + overwrite true } +tasks.register('updateWhyJavaLauncher', Download) { + def version = '1.1.2' + group 'Update assets' + description 'Downloads JavaLauncher.exe to src/main/resources/windows and overwrites the existing one.' + src([ + "https://github.com/AstroImageJ/Why/releases/download/${version}/JavaLauncher.exe" + ]) + dest file('src/main/resources/windows') + overwrite true +} diff --git a/docs/gradle/plugin-configuration-samples.md b/docs/gradle/plugin-configuration-samples.md index 65aa30c8..60411c08 100644 --- a/docs/gradle/plugin-configuration-samples.md +++ b/docs/gradle/plugin-configuration-samples.md @@ -120,7 +120,7 @@ task packageMyApp(dependsOn: [ 'packageMyAppForLinux', 'packageMyAppForMac', 'pa 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}-mac.tar.gz` with the MacOS 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. +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 MacOS, you have to specify a JDK for Windows. diff --git a/docs/macosx-specific-properties.md b/docs/macosx-specific-properties.md index f0059c9c..d104c2e4 100644 --- a/docs/macosx-specific-properties.md +++ b/docs/macosx-specific-properties.md @@ -1,4 +1,4 @@ -# Mac OS X specific properties +# MacOS specific properties ```xml @@ -16,6 +16,8 @@ path/to/entitlements.plist true|false true|false + true|false + xcrun_notarytool_profile_name path/to/png @@ -51,21 +53,25 @@ | Property | Mandatory | Default value | Description | | ------------- | --------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| `icnsFile` | :x: | | Icon file. | +| `icnsFile` | :x: | | ICNS format icon file.\* | | `generateDmg` | :x: | `true` | Enables DMG disk image file generation. | | `generatePkg` | :x: | `true` | Enables installation package generation. | | `relocateJar` | :x: | `true` | If `true`, Jar files are located in `Contents/Resources/Java` folder, otherwise they are located in `Contents/Resources` folder. | | `appId` | :x: | `${mainClass}` | App unique identifier. | +> \* You can use [MacICNS](https://github.com/EasyG0ing1/MacIcns) to convert your PNG icon file to ICNS. + ## Signing properties -| Property | Mandatory | Default value | Description | -| ------------------ | --------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -| `developerId` | :x: | | Signing identity. | -| `entitlements` | :x: | | Path to [entitlements](https://developer.apple.com/documentation/bundleresources/entitlements) file. | -| `codesignApp` | :x: | `true` | If it is set to `false`, generated app will not be codesigned. | -| `hardenedCodesign` | :x: | `true` | If it is set to `true`, enable [hardened runtime](https://developer.apple.com/documentation/security/hardened_runtime) if Mac OS version >= 10.13.6. | -| `macStartup` | :x: | `SCRIPT` | App startup type, using a `SCRIPT` or a binary (compiled version of the script: `UNIVERSAL`, `X86_64` or `ARM64`). | +| Property | Mandatory | Default value | Description | +|--------------------| --------- |---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| +| `developerId` | :x: | | Signing identity. | +| `entitlements` | :x: | | Path to [entitlements](https://developer.apple.com/documentation/bundleresources/entitlements) file. | +| `codesignApp` | :x: | `true` | If it is set to `false`, generated app will not be codesigned. | +| `hardenedCodesign` | :x: | `true` | If it is set to `true`, enable [hardened runtime](https://developer.apple.com/documentation/security/hardened_runtime) if MacOS version >= 10.13.6. | +| `notarizeApp` | :x: | `false` | If it is set to `true`, generated app will be submitted to apple for notarization and the ticket will be stapled. | +| `keyChainProfile` | :x: | | Profile name originally provided to `xcrun notarytool store-credentials`. Must be set if `notarizeApp` is `true`. +| `macStartup` | :x: | `SCRIPT` | App startup type, using a `SCRIPT` or a binary (compiled version of the script: `UNIVERSAL`, `X86_64` or `ARM64`). | ## DMG generation properties diff --git a/docs/maven/plugin-configuration-samples.md b/docs/maven/plugin-configuration-samples.md index fc4a1cfd..db759041 100644 --- a/docs/maven/plugin-configuration-samples.md +++ b/docs/maven/plugin-configuration-samples.md @@ -221,7 +221,7 @@ E.g. on Windows, last configuration will generate next artifacts: 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}-mac.tar.gz` with the MacOS 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 +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 MacOS, you have to specify a JDK for Windows. diff --git a/docs/windows-specific-properties.md b/docs/windows-specific-properties.md index 9aac4ac5..aefe27aa 100644 --- a/docs/windows-specific-properties.md +++ b/docs/windows-specific-properties.md @@ -10,7 +10,7 @@ true|false - gui + gui|console true|false ${organizationName} 1.0.0.0 @@ -21,6 +21,7 @@ ${organizationName} ${name} ${name} + ${name} ${name}.exe @@ -55,10 +56,10 @@ - root:path/to/my/key - name - type - data + root:path/to/my/key + name + type + data [...] @@ -103,6 +104,7 @@ | ------------------------- | --------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | | `setupMode` | :x: | `installForAllUsers` | Setup installation mode: require administrative privileges or not. [*](#setupmode) | | `setupLanguages` | :x: | `compiler:Default.islcompiler:Languages\Spanish.isl` | Map with setup languages. | +| `shortcutName` | :x: | `${name}` | Sets the name of the user optional shortcut created on the desktop | | `disableDirPage` | :x: | `true` | If this is set to `true`, Setup will not show the **Select Destination Location** wizard page. | | `disableProgramGroupPage` | :x: | `true` | If this is set to `true`, Setup will not show the **Select Start Menu Folder** wizard page. | | `disableFinishedPage` | :x: | `true` | If this is set to `true`, Setup will not show the **Setup Completed** wizard page. | diff --git a/docs/windows-tools-guide.md b/docs/windows-tools-guide.md index 2a4fa382..e41b8391 100644 --- a/docs/windows-tools-guide.md +++ b/docs/windows-tools-guide.md @@ -1,6 +1,8 @@ # Windows tools installation guide -As explained in the [docs](https://github.com/fvarrui/JavaPackager#generated-artifacts), you must install [Inno Setup (iscc)](https://jrsoftware.org/isinfo.php) to generate an EXE installer and [WIX Toolset (candle and light)](https://wixtoolset.org/) to generate a MSI file. +As explained in the [docs](https://github.com/fvarrui/JavaPackager#generated-artifacts), you must install [Inno Setup (iscc)](https://jrsoftware.org/isinfo.php) to generate an EXE installer and [WIX Toolset (candle and light)](https://wixtoolset.org/) to generate an MSI file. + +For Inno Setup 5.x, the Unicode version should be used, because the scripts that JavaPacker will be creating as an input will be UTF-8 encoded. ## Using Chocolatey You can install both tools in a simple way using [Chocolatey](https://chocolatey.org/) package manager: diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e64ee76b..e1bef7e8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=7faa7198769f872826c8ef4f1450f839ec27f0b4d5d1e51bade63667cbccd205 -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists \ No newline at end of file +zipStorePath=wrapper/dists diff --git a/settings.gradle b/settings.gradle index 03800abd..b4ae1d88 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1 @@ -rootProject.name = 'javapackager' -include 'winrun4j-launcher' \ No newline at end of file +rootProject.name = 'javapackager' \ 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 index 5cf1bc8a..e8f94a8e 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/AbstractPackageTask.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/AbstractPackageTask.java @@ -28,7 +28,7 @@ public List getOutputFiles() { 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"); + setDescription("Packages the application as a native Windows, MacOS or GNU/Linux executable and creates an installer"); getOutputs().upToDateWhen(o -> false); } 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..f6881ad0 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/CopyDependencies.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/CopyDependencies.java @@ -35,7 +35,8 @@ protected File doApply(Packager packager) { if (copyLibsTask == null) { copyLibsTask = project.getTasks().create("copyLibs", Copy.class); } - copyLibsTask.from(project.getConfigurations().getByName("default")); + copyLibsTask.setDuplicatesStrategy(Context.getGradleContext().getDuplicatesStrategy()); + copyLibsTask.from(project.getConfigurations().getByName("runtimeClasspath")); copyLibsTask.into(project.file(libsFolder)); copyLibsTask.getActions().forEach(action -> action.execute(copyLibsTask)); 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..917fac8d 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/CreateTarball.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/CreateTarball.java @@ -36,8 +36,11 @@ protected File doApply(Packager packager) throws Exception { File appFolder = packager.getAppFolder(); File executable = packager.getExecutable(); String jreDirectoryName = packager.getJreDirectoryName(); - - File tarFile = new File(outputDirectory, name + "-" + version + "-" + platform + ".tar.gz"); + + // tgz file name + String finalName = packager.getTarballName() != null ? packager.getTarballName() : name + "-" + version + "-" + platform; + String format = ".tar.gz"; + File tarFile = new File(outputDirectory, finalName + format); Tar tarTask = createTarTask(); tarTask.setProperty("archiveFileName", tarFile.getName()); 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..0af1f1a5 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/CreateWindowsExeLaunch4j.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/CreateWindowsExeLaunch4j.java @@ -4,10 +4,12 @@ import java.util.HashSet; import java.util.List; +import net.jsign.WindowsSigner; import org.apache.commons.lang3.StringUtils; import edu.sc.seis.launch4j.tasks.Launch4jLibraryTask; import io.github.fvarrui.javapackager.model.WindowsConfig; +import io.github.fvarrui.javapackager.model.WindowsExeCreationTool; import io.github.fvarrui.javapackager.packagers.AbstractCreateWindowsExe; import io.github.fvarrui.javapackager.packagers.Context; import io.github.fvarrui.javapackager.packagers.WindowsPackager; @@ -19,7 +21,7 @@ public class CreateWindowsExeLaunch4j extends AbstractCreateWindowsExe { public CreateWindowsExeLaunch4j() { - super("launch4j"); + super(WindowsExeCreationTool.launch4j); } @Override @@ -48,36 +50,35 @@ protected File doApply(WindowsPackager packager) throws Exception { } Launch4jLibraryTask l4jTask = Context.getGradleContext().getLibraryTask(); + l4jTask.getDuplicatesStrategy().set(Context.getGradleContext().getDuplicatesStrategy()); l4jTask.getOutputs().upToDateWhen(task -> false); - l4jTask.setHeaderType(winConfig.getHeaderType().toString()); - l4jTask.setJar(jarPath); - l4jTask.setDontWrapJar(!winConfig.isWrapJar()); - l4jTask.setOutfile(getGenericExe().getName()); - l4jTask.setIcon(getGenericIcon().getAbsolutePath()); - l4jTask.setManifest(getGenericManifest().getAbsolutePath()); - l4jTask.setMainClassName(mainClass); - l4jTask.setClasspath(new HashSet<>(packager.getClasspaths())); - l4jTask.setChdir(useResourcesAsWorkingDir ? "." : ""); + l4jTask.getHeaderType().set(winConfig.getHeaderType().toString()); + l4jTask.getJarFiles().set(Context.getGradleContext().getProject().files(jarPath)); + l4jTask.getDontWrapJar().set(!winConfig.isWrapJar()); + l4jTask.getOutfile().set(getGenericExe().getName()); + l4jTask.getIcon().set(getGenericIcon().getAbsolutePath()); + l4jTask.getManifest().set(getGenericManifest().getAbsolutePath()); + l4jTask.getMainClassName().set(mainClass); + l4jTask.getClasspath().set(new HashSet<>(packager.getClasspaths())); + l4jTask.getChdir().set(useResourcesAsWorkingDir ? "." : ""); if (bundleJre) { - l4jTask.setBundledJrePath(jreDirectoryName); + l4jTask.getBundledJrePath().set(jreDirectoryName); } if (!StringUtils.isBlank(jreMinVersion)) { - l4jTask.setJreMinVersion(jreMinVersion); + l4jTask.getJreMinVersion().set(jreMinVersion); } l4jTask.getJvmOptions().addAll(vmArgs); - l4jTask.setVersion(winConfig.getProductVersion()); - l4jTask.setTextVersion(winConfig.getTxtProductVersion()); - l4jTask.setCopyright(winConfig.getCopyright()); - l4jTask.setCompanyName(winConfig.getCompanyName()); - l4jTask.setFileDescription(winConfig.getFileDescription()); - l4jTask.setProductName(winConfig.getProductName()); - l4jTask.setInternalName(winConfig.getInternalName()); - l4jTask.setTrademarks(winConfig.getTrademarks()); - l4jTask.setLanguage(winConfig.getLanguage()); + l4jTask.getVersion().set(winConfig.getProductVersion()); + l4jTask.getTextVersion().set(winConfig.getTxtProductVersion()); + l4jTask.getCopyright().set(winConfig.getCopyright()); + l4jTask.getCompanyName().set(winConfig.getCompanyName()); + l4jTask.getFileDescription().set(winConfig.getFileDescription()); + l4jTask.getProductName().set(winConfig.getProductName()); + l4jTask.getInternalName().set(winConfig.getInternalName()); + l4jTask.getTrademarks().set(winConfig.getTrademarks()); + l4jTask.getLanguage().set(winConfig.getLanguage()); l4jTask.getActions().forEach(action -> action.execute(l4jTask)); - sign(getGenericExe(), packager); - FileUtils.copyFileToFile(getGenericExe(), executable); return createBootstrapScript(packager); 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..cdd85c46 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/CreateZipball.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/CreateZipball.java @@ -35,8 +35,9 @@ protected File doApply(Packager packager) throws Exception { File appFolder = packager.getAppFolder(); File executable = packager.getExecutable(); String jreDirectoryName = packager.getJreDirectoryName(); - - File zipFile = new File(outputDirectory, name + "-" + version + "-" + platform + ".zip"); + + String zipFileName = packager.getZipballName() != null ? packager.getZipballName() : name + "-" + version + "-" + platform + ".zip"; + File zipFile = new File(outputDirectory, zipFileName); Zip zipTask = createZipTask(); zipTask.setProperty("archiveFileName", zipFile.getName()); 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..b2e1f206 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/GradleContext.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/GradleContext.java @@ -4,6 +4,7 @@ import io.github.fvarrui.javapackager.packagers.*; import org.gradle.api.Project; +import org.gradle.api.file.DuplicatesStrategy; import org.gradle.api.internal.provider.Providers; import org.gradle.api.logging.Logger; import org.gradle.api.plugins.JavaPluginExtension; @@ -20,8 +21,8 @@ public class GradleContext extends Context { private Project project; - private Launch4jLibraryTask libraryTask; + private DuplicatesStrategy duplicatesStrategy; public GradleContext(Project project) { super(); @@ -80,6 +81,14 @@ public void setLibraryTask(Launch4jLibraryTask libraryTask) { this.libraryTask = libraryTask; } + public DuplicatesStrategy getDuplicatesStrategy() { + return duplicatesStrategy; + } + + public void setDuplicatesStrategy(DuplicatesStrategy duplicatesStrategy) { + this.duplicatesStrategy = duplicatesStrategy; + } + /** * Returns project's default toolchain * @@ -122,7 +131,5 @@ public File createWindowsExe(WindowsPackager packager) throws Exception { } return null; } - - } 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..b817168b 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/PackagePlugin.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/PackagePlugin.java @@ -1,11 +1,12 @@ package io.github.fvarrui.javapackager.gradle; -import edu.sc.seis.launch4j.tasks.Launch4jLibraryTask; -import io.github.fvarrui.javapackager.packagers.Context; +import java.util.UUID; + import org.gradle.api.Plugin; import org.gradle.api.Project; -import java.util.UUID; +import edu.sc.seis.launch4j.tasks.Launch4jLibraryTask; +import io.github.fvarrui.javapackager.packagers.Context; /** * JavaPackager Gradle plugin @@ -18,14 +19,13 @@ public class PackagePlugin implements Plugin { @Override 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.getTasks().create(PACKAGE_TASK_NAME, PackageTask.class).dependsOn("build"); 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 index e4a311b8..da793647 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/PackagePluginExtension.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/PackagePluginExtension.java @@ -5,8 +5,10 @@ import java.util.HashMap; import org.gradle.api.Project; +import org.gradle.api.file.DuplicatesStrategy; import groovy.lang.Closure; +import io.github.fvarrui.javapackager.model.Arch; import io.github.fvarrui.javapackager.model.LinuxConfig; import io.github.fvarrui.javapackager.model.MacConfig; import io.github.fvarrui.javapackager.model.Manifest; @@ -21,6 +23,7 @@ public class PackagePluginExtension extends PackagerSettings { private Project project; + private DuplicatesStrategy duplicatesStrategy; public PackagePluginExtension(Project project) { super(); @@ -52,6 +55,8 @@ public PackagePluginExtension(Project project) { this.outputDirectory = project.getBuildDir(); this.scripts = new Scripts(); this.forceInstaller = false; + this.arch = Arch.getDefault(); + this.duplicatesStrategy = DuplicatesStrategy.WARN; } public LinuxConfig linuxConfig(Closure closure) { @@ -83,5 +88,13 @@ public Scripts scripts(Closure closure) { project.configure(scripts, closure); return scripts; } + + public void setDuplicatesStrategy(DuplicatesStrategy duplicatesStrategy) { + this.duplicatesStrategy = duplicatesStrategy; + } + + public DuplicatesStrategy getDuplicatesStrategy() { + return duplicatesStrategy; + } } \ 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 index 1e9d109a..ce6a321a 100644 --- a/src/main/java/io/github/fvarrui/javapackager/gradle/PackageTask.java +++ b/src/main/java/io/github/fvarrui/javapackager/gradle/PackageTask.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Map; +import org.gradle.api.file.DuplicatesStrategy; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputDirectory; import org.gradle.api.tasks.InputFile; @@ -14,12 +15,14 @@ import org.gradle.api.tasks.OutputDirectory; import groovy.lang.Closure; +import io.github.fvarrui.javapackager.model.Arch; 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.Template; import io.github.fvarrui.javapackager.model.WindowsConfig; import io.github.fvarrui.javapackager.packagers.Context; import io.github.fvarrui.javapackager.packagers.Packager; @@ -559,6 +562,42 @@ public Scripts scripts(Closure closure) { getProject().configure(scripts, closure); return scripts; } + + @Input + @Optional + private Arch arch; + + public Arch getArch() { + return arch; + } + + public void setArch(Arch arch) { + this.arch = arch; + } + + @Input + @Optional + private List