For a couple of years, I have been releasing updates to a modest app on a yearly basis -- just before the summer swim league starts up.
In the past, I have specified the various icons (volume, app, etc.) by placing them in the package/macosx/
folder. The filenames, MyApp-volume.icns
etc., matched the <fx:application name="MyApp" .../>
and everything worked just fine.
But starting with this year's build and deployment, the app's name will contain the year -- i.e., MyApp 2016
. However, I don't want to be changing the icon filenames each year; I would like to keep them as they are (MyApp-volume.icns
, MyApp.icns
).
Is there a way to tell the Java packager to use a specific icon filename, one that is different from that of the app name or title? (I have looked at Oracle docs, but I don't see anything.)
As I wrote in my first comment to my question, javapackager doesn't have an option to do this.
Here's the solution that I worked out:
Create a new folder at the same level as the folder package
(this doesn't refer to Java package
but to Custom Resources). Name the new folder package-base
.
Move the macosx
and windows
folders from package
to package-base
. (I don't produce an executable for Linux because none of my users use Linux.) Now, the package
folder is empty.
In my build script, I added a step which, for every build that produces a "self-contained application package" (Oracle's terminology), cleans the package
folder, and then copies the contents of package-base
to package
.
The files are renamed as they are copied to include the desired wording -- in my case, that means the year is appended to the filename. For example, MyApp-volume.icns
when copied is renamed MyApp-2018-volume.icns
.
Here are the relevant Gradle snippets:
import org.gradle.internal.os.OperatingSystem
...
def getYear() {
new Date().format('yyyy')
}
...
ext {
...
year = getYear()
appNameBase = "MyApp"
appName = appNameBase + " " + year
...
}
...
task macCleanPackage {
doLast {
if (OperatingSystem.current().isMacOsX()) {
delete fileTree(dir: "./package/macosx", include: "*.*")
}
}
}
task macCopyAndRenamePackageResources {
dependsOn macCleanPackage
doLast {
if (OperatingSystem.current().isMacOsX()) {
def toDir = "./package/macosx"
copy {
from './package-base/macosx'
into "${toDir}"
include "*${appNameBase}*.*"
rename { String fileName -> fileName.replace("$appNameBase", "${appName}") }
}
ant.replaceregexp(file: "${toDir}/${appName}-dmg-setup.scpt", match:"${appNameBase}", replace:"${appName}", flags:'g')
}
}
}
task windowsCleanPackage {
doLast {
if (OperatingSystem.current().isWindows()) {
delete fileTree(dir: "package/windows", includes: ["*.bmp", "*.ico", "*.iss"])
}
}
}
task windowsCopyAndRenamePackageResources {
dependsOn windowsCleanPackage
doLast {
if (OperatingSystem.current().isWindows()) {
def toDir = "./package/windows"
copy {
from './package-base/windows'
into "${toDir}"
include "*${appNameBase}*.*"
rename { String fileName -> fileName.replace("$appNameBase", "${appName}") }
}
// Replace app name in iss setup script to include year.
def issFilename = "./package/windows/${appName}.iss"
ant.replaceregexp(file: "${issFilename}", match: "${appNameBase}", replace: "${appName}", flags: "g")
ant.replaceregexp(file: "${issFilename}", match: "AppCopyright=Copyright (C)", replace: "AppCopyright=Copyright (C) ${year}", byline: "on")
ant.replaceregexp(file: "${issFilename}", match: "AppVersion=", replace: "AppVersion=${year} build ${buildNumber}", byline: "on")
ant.replaceregexp(file: "${issFilename}", match: "OutputBaseFilename=.*", replace: "OutputBaseFilename=${appName}-(build ${buildNumber})", byline: "on")
}
}
}
I don't just change filenames.
For the OS X release, ant.replaceregexp
is used to modify the app's name in the custom AppleScript file.
For the Windows release, ant.replaceregexp
is used extensively to replace version numbers, copyright, as well as the application's name (including the year) in the InnoSetup configuration file.
It may seem like a lot of extra work, but once the script is written, it just works.