From b5375e3f77b77e453e4d62e3846cb40c6dedf798 Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Fri, 31 May 2024 18:48:47 +0100 Subject: [PATCH] JAL-4421 Python script for customising DS_Store. Separate out more names for DMG volumes in install4j and gradle. Channel specific icon positioning for channel specific DMG background images. --- build.gradle | 31 +++-- gradle.properties | 2 + utils/channels/release/channel_gradle.properties | 1 + .../release/images/jalview_dmg_DS_Store.json | 39 +++++++ utils/install4j/install4j10_template.install4j | 38 ++++--- utils/macos_dmg/jalview_custom_dsstore.py | 119 ++++++++++++++++++++ 6 files changed, 203 insertions(+), 27 deletions(-) create mode 100644 utils/channels/release/images/jalview_dmg_DS_Store.json create mode 100755 utils/macos_dmg/jalview_custom_dsstore.py diff --git a/build.gradle b/build.gradle index 012d61e..2396e7d 100644 --- a/build.gradle +++ b/build.gradle @@ -43,6 +43,7 @@ buildscript { classpath "com.vladsch.flexmark:flexmark-all:0.62.0" classpath "org.jsoup:jsoup:1.14.3" classpath "com.eowise:gradle-imagemagick:0.5.1" + classpath 'ru.vyarus:gradle-use-python-plugin:4.0.0' } } @@ -56,6 +57,7 @@ plugins { id 'com.install4j.gradle' version '10.0.3' id 'com.dorongold.task-tree' version '2.1.1' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree id 'com.palantir.git-version' version '0.13.0' apply false + id 'ru.vyarus.use-python' version '4.0.0' } repositories { @@ -236,7 +238,7 @@ ext { install4jDMGBackgroundImageDir = "${install4j_images_dir}" install4jDMGBackgroundImageBuildDir = "build/imagemagick/install4j" install4jDMGBackgroundImageFile = "${install4j_dmg_background}" - install4jInstallerName = "${jalview_name} Non-Release Installer" + install4jmacOSArchiveName = "${jalview_name} Non-Release ${JALVIEW_VERSION} Installer" install4jExecutableName = install4j_executable_name install4jExtraScheme = "jalviewextra" install4jMacIconsFile = string("${install4j_images_dir}/${install4j_mac_icons_file}") @@ -244,6 +246,7 @@ ext { install4jPngIconFile = string("${install4j_images_dir}/${install4j_png_icon_file}") install4jBackground = string("${install4j_images_dir}/${install4j_background}") install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}" + install4jDMGFixedDSStore = "${install4jBuildDir}/${install4j_dmg_ds_store}" install4jCheckSums = true applicationName = "${jalview_name}" @@ -268,7 +271,7 @@ ext { getdownSetAppBaseProperty = true reportRsyncCommand = true install4jSuffix = "" - install4jInstallerName = "${jalview_name} Installer" + install4jmacOSArchiveName = "Install ${jalview_name} ${JALVIEW_VERSION}" install4jExtraScheme = (CHANNEL=="RELEASE")?"jalviewx":"jalviewjs" break @@ -311,7 +314,7 @@ ext { JALVIEW_VERSION=JALVIEW_VERSION+"-d${suffix}-${buildDate}" install4jSuffix = "Develop ${suffix}" install4jExtraScheme = "jalviewd" - install4jInstallerName = "${jalview_name} Develop ${suffix} Installer" + install4jmacOSArchiveName = "Install ${jalview_name} Develop ${suffix} ${JALVIEW_VERSION}" getdownChannelName = string("develop-${suffix}") getdownChannelDir = string("${getdown_website_dir}/${getdownChannelName}") getdownAppBaseDir = string("${jalviewDir}/${getdownChannelDir}/${JAVA_VERSION}") @@ -329,7 +332,7 @@ ext { install4jSuffix = "Develop" install4jExtraScheme = "jalviewd" - install4jInstallerName = "${jalview_name} Develop Installer" + install4jmacOSArchiveName = "Install ${jalview_name} Develop ${JALVIEW_VERSION}" backgroundImageText = true break @@ -344,7 +347,7 @@ ext { JALVIEW_VERSION = JALVIEW_VERSION+"-test" install4jSuffix = "Test" install4jExtraScheme = "jalviewt" - install4jInstallerName = "${jalview_name} Test Installer" + install4jmacOSArchiveName = "Install ${jalview_name} Test ${JALVIEW_VERSION}" backgroundImageText = true break @@ -368,7 +371,7 @@ ext { JALVIEW_VERSION = "TEST" install4jSuffix = "Test-Local" install4jExtraScheme = "jalviewt" - install4jInstallerName = "${jalview_name} Test Installer" + install4jmacOSArchiveName = "Install ${jalview_name} Test ${JALVIEW_VERSION}" backgroundImageText = true break @@ -434,6 +437,8 @@ ext { .replaceAll("_+", "_") // collapse __ .replaceAll("_*-_*", "-") // collapse _-_ .toLowerCase() + install4jmacOSArchiveX86Name = "${install4jmacOSArchiveName} (Intel)" + install4jmacOSArchiveAarch64Name = "${install4jmacOSArchiveName} (Apple Silicon)" getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local" getdownAppDir = string("${getdownAppBaseDir}/${getdownAppDistDir}") @@ -2829,8 +2834,14 @@ task install4jDMGBackgroundImageProcess { } } -task install4jDMGBackgroundImage { +task install4jDMGDS_Store { + //install4jDMGDS_Store + //install4jDMGFixedDSStore +} + +task install4jDMGProcesses { dependsOn install4jDMGBackgroundImageProcess + dependsOn install4jDMGDS_Store } task installerFiles(type: com.install4j.gradle.Install4jTask) { @@ -2839,7 +2850,7 @@ task installerFiles(type: com.install4j.gradle.Install4jTask) { dependsOn getdown dependsOn copyInstall4jTemplate dependsOn cleanInstallersDataFiles - dependsOn install4jDMGBackgroundImage + dependsOn install4jDMGProcesses projectFile = install4jConfFile @@ -2880,12 +2891,14 @@ task installerFiles(type: com.install4j.gradle.Install4jTask) { 'WINDOWS_APPLICATION_ID': install4jWinApplicationId, 'MACOS_DMG_DS_STORE': install4jDMGDSStore, 'MACOS_DMG_BG_IMAGE': "${install4jDMGBackgroundImageBuildDir}/${install4jDMGBackgroundImageFile}", + 'MACOS_DMG_BG_FILENAME': install4j_dmg_background_filename, 'WRAPPER_LINK': getdownWrapperLink, 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script, 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script, 'BATCH_WRAPPER_SCRIPT': getdown_batch_wrapper_script, 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir, - 'INSTALLER_NAME': install4jInstallerName, + 'MACOSARCHIVE_X86_NAME': install4jmacOSArchiveX86Name, + 'MACOSARCHIVE_AARCH64_NAME': install4jmacOSArchiveAarch64Name, 'INSTALL4J_UTILS_DIR': install4j_utils_dir, 'GETDOWN_CHANNEL_DIR': getdownChannelDir, 'GETDOWN_FILES_DIR': getdown_files_dir, diff --git a/gradle.properties b/gradle.properties index 79fb11d..0c05033 100644 --- a/gradle.properties +++ b/gradle.properties @@ -151,7 +151,9 @@ install4j_windows_icons_file = jalview_logo.ico install4j_png_icon_file = jalview_logo.png install4j_background = jalview_logo_background_fade-640x480.png install4j_dmg_background = jalview_dmg_background-NON-RELEASE.png +install4j_dmg_background_filename = background.png install4j_dmg_ds_store = jalview_dmg_DS_Store +install4j_dmg_ds_store_json = jalview_dmg_DS_Store.json getdown_wrapper_script_dir = bin getdown_bash_wrapper_script = jalview.sh getdown_powershell_wrapper_script = jalview.ps1 diff --git a/utils/channels/release/channel_gradle.properties b/utils/channels/release/channel_gradle.properties index fb8a62f..8d6c7ad 100644 --- a/utils/channels/release/channel_gradle.properties +++ b/utils/channels/release/channel_gradle.properties @@ -19,6 +19,7 @@ install4j_png_icon_file = jalview_logo.png install4j_background = jalview_logo_background_fade-640x480.png install4j_dmg_background = jalview_dmg_background-72dpi.png install4j_dmg_ds_store = jalview_dmg_DS_Store +install4j_dmg_ds_store_json = jalview_dmg_DS_Store.json getdown_background_image_text_font = utils/fonts/Roboto.ttf getdown_background_image_text_colour = #b4b4b4 diff --git a/utils/channels/release/images/jalview_dmg_DS_Store.json b/utils/channels/release/images/jalview_dmg_DS_Store.json new file mode 100644 index 0000000..5c1b506 --- /dev/null +++ b/utils/channels/release/images/jalview_dmg_DS_Store.json @@ -0,0 +1,39 @@ +{ + "files": [ + { + "name": "Jalview.app", + "xpos": 132, + "ypos": 124 + }, + { + "name": " ", + "xpos": 332, + "ypos": 124 + } + ], + "_comment": "bwsp and icvp are not being used yet", + "bwsp": { + "ShowStatusBar": false, + "SidebarWidthTenElevenOrLater": 160, + "ShowToolbar": false, + "ShowTabView": false, + "ContainerShowSidebar": false, + "WindowBounds": "{{355, 432}, {504, 324}}", + "ShowSidebar": false, + "ShowPathbar": false + }, + "icvp": { + "backgroundColorBlue": 1.0, + "backgroundColorGreen": 1.0, + "backgroundColorRed": 1.0, + "labelOnBottom": true, + "gridSpacing": 100, + "textSize": 12.0, + "backgroundType": 2, + "gridOffsetX": 0.0, + "gridOffsetY": 0.0, + "showItemInfo": false, + "viewOptionsVersion": 1, + "arrangeBy": "none" + } +} diff --git a/utils/install4j/install4j10_template.install4j b/utils/install4j/install4j10_template.install4j index 53b5b27..39c0b48 100644 --- a/utils/install4j/install4j10_template.install4j +++ b/utils/install4j/install4j10_template.install4j @@ -23,15 +23,15 @@ - + - - + + - + - - + + @@ -39,10 +39,12 @@ + - + + @@ -94,7 +96,7 @@ - + @@ -115,7 +117,7 @@ - + @@ -1493,17 +1495,17 @@ ${compiler:JALVIEW_APPLICATION_NAME} will now launch. - + - + - + - + @@ -1512,7 +1514,7 @@ ${compiler:JALVIEW_APPLICATION_NAME} will now launch. - + @@ -1520,7 +1522,7 @@ ${compiler:JALVIEW_APPLICATION_NAME} will now launch. - + @@ -1542,7 +1544,7 @@ ${compiler:JALVIEW_APPLICATION_NAME} will now launch. - + @@ -1568,7 +1570,7 @@ ${compiler:JALVIEW_APPLICATION_NAME} will now launch. - + @@ -1579,7 +1581,7 @@ ${compiler:JALVIEW_APPLICATION_NAME} will now launch. - + diff --git a/utils/macos_dmg/jalview_custom_dsstore.py b/utils/macos_dmg/jalview_custom_dsstore.py new file mode 100755 index 0000000..dc5d2e7 --- /dev/null +++ b/utils/macos_dmg/jalview_custom_dsstore.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +# Adapted from custom_dsstore.py by the Jalview team 2024 +# Copyright (c) 2013-2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +from ds_store import DSStore +from pprint import pprint +import mac_alias +import argparse +import json + +parser = argparse.ArgumentParser( + prog = "jalview_custom_dsstore.py", + description = "Take an existing DS_Store file and change the volume name and add path to background image" + ) +parser.add_argument("-i", "--input", help="The existing styled DS_Store file", dest="input") +parser.add_argument("-o", "--output", help="The output DS_Store file", dest="output") +parser.add_argument("-v", "--volumename", help="The name of the output DS_Store volume", dest="volumename") +parser.add_argument("-b", "--background", help="The background image filename to use", dest="background") +parser.add_argument("-c", "--config", help="YAML configuration for window and icon sizes and positions", dest="config") +parser.add_argument("-d", "--dump", help="Display contents of the input DS_Store to stdout", action="store_true", dest="dump") +parser.add_argument("-q", "--quiet", help="Don't print messages to stdout", action="store_true", dest="quiet") +parser.add_argument("-f", "--filenames", help="List of comma-separated filenames to show information for --dump", dest="filenames", default="") + +args = parser.parse_args() + +if (args.dump and not args.input): + exit("When --dump used, an --input must be given") + +if (args.dump): + with DSStore.open(args.input, 'r+') as d: + for key in ["bwsp", "icvp","Iloc"]: + try: + myprint(f"d['.']['{key}']=") + mypprint(str(d['.'][key])) + except: + myprint(f"No info for d['.']['{key}']") + + for data in d: + try: + data = str(data) + mypprint(f"d['{data}']=",d[data]) + except: + myprint(f"No info for d['{data}']") +# for filename in args.filenames.split(","): +# if (filename): +# for f in d.find(filename): +# myprint(f"d['{f}']=", d[f]) +# else: +# myprint(f"# No filename '{filename}' found in DS_Store '{args.input}'") + exit(0) + +if (args.output and not (args.input or args.config)): + exit("Need --input FILENAME or --config FILENAME to produce an --output") + +if (not args.output): + exit("Provide --output FILENAME to output DS_Store") + +if (not args.volumename): + exit("Provide a volume name with --volumename NAME") + +if (not args.background): + exit("Provide a background image filename (just the file, no path) with --background FILENAME") + +package_name_ns = args.volumename +configfilename = args.config +configfile = open(configfilename, 'r') + +config = json.load(configfile) +inputds = DSStore.open(args.input) +outputds = DSStore.open(args.output, 'w+') + +def myprint(string): + if (not args.quiet): + print(string) + +def mypprint(string): + if (not args.quiet): + pprint(string) + +bwsp = {} + +for key in "ShowStatusBar SidebarWidthTenElevenOrLater ShowToolbar ShowTabView ContainerShowSidebar WindowBounds ShowSidebar ShowPathbar".split(): + bwsp[key] = inputds['.']['bwsp'][key] + myprint(f"Setting bwsp['{key}'] to '"+str(inputds['.']['bwsp'][key])+"'") + +outputds['.']['bwsp'] = bwsp + +icvp = {} + +alias = mac_alias.Alias.from_bytes(inputds['.']['icvp']['backgroundImageAlias']) +alias.volume.name = args.volumename +alias.volume.posix_path = '/Volumes/' + args.volumename +alias.volume.disk_image_alias.target.filename = args.volumename + '.dmg' +alias.volume.disk_image_alias.target.carbon_path = 'Macintosh HD:Users:\x00Jalview:\x00' + args.volumename + ':\x00' + args.volumename + '.dmg' +alias.volume.disk_image_alias.target.posix_path = '/Users/Jalview/' + args.volumename + '.dmg' +alias.target.carbon_path = args.volumename + ':.background:\x00' + args.background + +icvp['backgroundImageAlias'] = alias.to_bytes() + +for key in "backgroundColorRed backgroundColorBlue backgroundColorGreen gridSpacing gridOffsetX gridOffsetY showItemInfo viewOptionsVersion arrangeBy textSize labelOnBottom backgroundType showIconPreview iconSize".split(): + icvp[key] = inputds['.']['icvp'][key] + myprint(f"Setting icvp['{key}'] to '"+str(inputds['.']['icvp'][key])+"'") + +outputds['.']['icvp'] = icvp + +# copy filenames properties? not working, using JSON config file +#for filename in args.filenames.split(","): +# outputds[filename]['Iloc'] = inputds[filename]['Iloc'] + +outputds['.']['vSrn'] = ('long', 1) + +for fileinfo in config['files']: + outputds[fileinfo['name']]['Iloc'] = (fileinfo['xpos'], fileinfo['ypos']) + +outputds.flush() +outputds.close() +inputds.close() + -- 1.7.10.2