8230654: jpackage package-type dmg on macOS
Submitted-by: almatvee
Reviewed-by: herrick, asemenyuk
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java Tue Sep 24 14:05:49 2019 -0400
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java Tue Sep 24 14:12:08 2019 -0400
@@ -94,8 +94,8 @@
data.put("DEPLOY_ACTUAL_VOLUME_NAME", volumeName);
data.put("DEPLOY_APPLICATION_NAME", APP_NAME.fetchFrom(params));
- data.put("DEPLOY_INSTALL_LOCATION", "(path to desktop folder)");
- data.put("DEPLOY_INSTALL_NAME", "Desktop");
+ data.put("DEPLOY_INSTALL_LOCATION", "(path to applications folder)");
+ data.put("DEPLOY_INSTALL_NAME", "Applications");
try (Writer w = Files.newBufferedWriter(dmgSetup.toPath())) {
w.write(preprocessTextResource(dmgSetup.getName(),
@@ -317,60 +317,75 @@
IOUtils.exec(pb);
File mountedRoot = new File(imagesRoot.getAbsolutePath(),
- APP_NAME.fetchFrom(params));
+ APP_NAME.fetchFrom(params));
- // volume icon
- File volumeIconFile = new File(mountedRoot, ".VolumeIcon.icns");
- IOUtils.copyFile(getConfig_VolumeIcon(params),
- volumeIconFile);
+ try {
+ // volume icon
+ File volumeIconFile = new File(mountedRoot, ".VolumeIcon.icns");
+ IOUtils.copyFile(getConfig_VolumeIcon(params),
+ volumeIconFile);
- pb = new ProcessBuilder("osascript",
- getConfig_VolumeScript(params).getAbsolutePath());
- IOUtils.exec(pb);
+ // background image
+ File bgdir = new File(mountedRoot, ".background");
+ bgdir.mkdirs();
+ IOUtils.copyFile(getConfig_VolumeBackground(params),
+ new File(bgdir, "background.png"));
- // Indicate that we want a custom icon
- // NB: attributes of the root directory are ignored
- // when creating the volume
- // Therefore we have to do this after we mount image
- String setFileUtility = findSetFileUtility();
- if (setFileUtility != null) {
+ // Indicate that we want a custom icon
+ // NB: attributes of the root directory are ignored
+ // when creating the volume
+ // Therefore we have to do this after we mount image
+ String setFileUtility = findSetFileUtility();
+ if (setFileUtility != null) {
//can not find utility => keep going without icon
+ try {
+ volumeIconFile.setWritable(true);
+ // The "creator" attribute on a file is a legacy attribute
+ // but it seems Finder excepts these bytes to be
+ // "icnC" for the volume icon
+ // http://endrift.com/blog/2010/06/14/dmg-files-volume-icons-cli
+ // (might not work on Mac 10.13 with old XCode)
+ pb = new ProcessBuilder(
+ setFileUtility,
+ "-c", "icnC",
+ volumeIconFile.getAbsolutePath());
+ IOUtils.exec(pb);
+ volumeIconFile.setReadOnly();
+
+ pb = new ProcessBuilder(
+ setFileUtility,
+ "-a", "C",
+ mountedRoot.getAbsolutePath());
+ IOUtils.exec(pb);
+ } catch (IOException ex) {
+ Log.error(ex.getMessage());
+ Log.verbose("Cannot enable custom icon using SetFile utility");
+ }
+ } else {
+ Log.verbose(I18N.getString("message.setfile.dmg"));
+ }
+
+ // We will not consider setting background image and creating link to
+ // /Application folder in DMG as critical error, since it can fail in
+ // headless enviroment.
try {
- volumeIconFile.setWritable(true);
- // The "creator" attribute on a file is a legacy attribute
- // but it seems Finder excepts these bytes to be
- // "icnC" for the volume icon
- // http://endrift.com/blog/2010/06/14/dmg-files-volume-icons-cli
- // (might not work on Mac 10.13 with old XCode)
- pb = new ProcessBuilder(
- setFileUtility,
- "-c", "icnC",
- volumeIconFile.getAbsolutePath());
- IOUtils.exec(pb);
- volumeIconFile.setReadOnly();
-
- pb = new ProcessBuilder(
- setFileUtility,
- "-a", "C",
- mountedRoot.getAbsolutePath());
+ pb = new ProcessBuilder("osascript",
+ getConfig_VolumeScript(params).getAbsolutePath());
IOUtils.exec(pb);
} catch (IOException ex) {
- Log.error(ex.getMessage());
- Log.verbose("Cannot enable custom icon using SetFile utility");
+ Log.verbose(ex);
}
- } else {
- Log.verbose(I18N.getString("message.setfile.dmg"));
+ } finally {
+ // Detach the temporary image
+ pb = new ProcessBuilder(
+ hdiutil,
+ "detach",
+ "-force",
+ hdiUtilVerbosityFlag,
+ mountedRoot.getAbsolutePath());
+ IOUtils.exec(pb);
}
- // Detach the temporary image
- pb = new ProcessBuilder(
- hdiutil,
- "detach",
- "-force",
- hdiUtilVerbosityFlag,
- mountedRoot.getAbsolutePath());
- IOUtils.exec(pb);
-
// Compress it to a new image
pb = new ProcessBuilder(
hdiutil,
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/DMGsetup.scpt Tue Sep 24 14:05:49 2019 -0400
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/DMGsetup.scpt Tue Sep 24 14:12:08 2019 -0400
@@ -1,2 +1,38 @@
-(* this script intentionally empty by default *)
+tell application "Finder"
+ tell disk "DEPLOY_ACTUAL_VOLUME_NAME"
+ open
+ set current view of container window to icon view
+ set toolbar visible of container window to false
+ set statusbar visible of container window to false
+
+ -- size of window should match size of background
+ set the bounds of container window to {400, 100, 917, 380}
+
+ set theViewOptions to the icon view options of container window
+ set arrangement of theViewOptions to not arranged
+ set icon size of theViewOptions to 128
+ set background picture of theViewOptions to file ".background:background.png"
+
+ -- Create alias for install location
+ make new alias file at container window to DEPLOY_INSTALL_LOCATION with properties {name:"DEPLOY_INSTALL_NAME"}
+ set allTheFiles to the name of every item of container window
+ repeat with theFile in allTheFiles
+ set theFilePath to POSIX Path of theFile
+ if theFilePath is "/DEPLOY_APPLICATION_NAME.app"
+ -- Position application location
+ set position of item theFile of container window to {120, 60}
+ else if theFilePath is "/DEPLOY_INSTALL_NAME"
+ -- Position install location
+ set position of item theFile of container window to {390, 60}
+ else
+ -- Move all other files far enough to be not visible if user has "show hidden files" option set
+ set position of item theFile of container window to {1000, 0}
+ end
+ end repeat
+
+ update without registering applications
+ delay 5
+ close
+ end tell
+end tell