diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index a494de1..853b2b5 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -31,10 +31,14 @@ jobs: java-version: '25' distribution: 'corretto' - uses: gradle/actions/setup-gradle@v4 - - run: ./gradlew jpackage + # See https://docs.gradle.org/current/userguide/logging.html#sec:choosing_a_log_level for the log levels + # We opted for "-i", because it outputs the commands used to build the application image + - run: ./gradlew -i jpackage + - run: ls -la /Users/runner/work/javafxreproducer/javafxreproducer/build/tmp/jpackage/macos-14/app-content/Resources + if: ${{ always() && runner.os == 'macOS' }} - name: Upload a Build Artifact uses: actions/upload-artifact@v4 with: name: javafxreproducer-${{ matrix.os }} - path: build/distributions + path: build/packages compression-level: 0 diff --git a/build.gradle.kts b/build.gradle.kts index 751d3ce..88e612b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -108,4 +108,24 @@ javaModulePackaging { architecture = MachineArchitecture.X86_64 packageTypes = listOf("app-image", "msi") } + + targetsWithOs("macos") { + options.addAll( + // "--icon", "$projectDir/src/main/resources/icons/jabref.icns", + "--mac-package-identifier", "JabRef", + "--mac-package-name", "JabRef", + "--file-associations", "$projectDir/buildres/macos/bibtexAssociations.properties", + ) + if (providers.environmentVariable("OSXCERT").orNull?.isNotBlank() ?: false) { + options.addAll( + "--mac-sign", + "--mac-signing-key-user-name", "JabRef e.V. (6792V39SK3)", + "--mac-package-signing-prefix", "org.jabref", + ) + } + targetResources.from(layout.projectDirectory.dir("buildres/macos").asFileTree.matching { + include("Resources/**") + }) + } + } diff --git a/buildres/macos/Info-lite.plist.template b/buildres/macos/Info-lite.plist.template new file mode 100644 index 0000000..509eb84 --- /dev/null +++ b/buildres/macos/Info-lite.plist.template @@ -0,0 +1,39 @@ + + + + + LSMinimumSystemVersion + 10.9 + CFBundleDevelopmentRegion + English + CFBundleAllowMixedLocalizations + + CFBundleExecutable + DEPLOY_LAUNCHER_NAME + CFBundleIconFile + DEPLOY_ICON_FILE + CFBundleIdentifier + DEPLOY_BUNDLE_IDENTIFIER + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + DEPLOY_BUNDLE_NAME + CFBundlePackageType + APPL + CFBundleShortVersionString + DEPLOY_BUNDLE_SHORT_VERSION + CFBundleSignature + ???? + + LSApplicationCategoryType + Unknown + CFBundleVersion + DEPLOY_BUNDLE_CFBUNDLE_VERSION + NSHumanReadableCopyright + DEPLOY_BUNDLE_COPYRIGHTDEPLOY_FILE_ASSOCIATIONS + NSHighResolutionCapable + true + NSSupportsAutomaticGraphicsSwitching + + + diff --git a/buildres/macos/Info.plist b/buildres/macos/Info.plist new file mode 100644 index 0000000..509eb84 --- /dev/null +++ b/buildres/macos/Info.plist @@ -0,0 +1,39 @@ + + + + + LSMinimumSystemVersion + 10.9 + CFBundleDevelopmentRegion + English + CFBundleAllowMixedLocalizations + + CFBundleExecutable + DEPLOY_LAUNCHER_NAME + CFBundleIconFile + DEPLOY_ICON_FILE + CFBundleIdentifier + DEPLOY_BUNDLE_IDENTIFIER + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + DEPLOY_BUNDLE_NAME + CFBundlePackageType + APPL + CFBundleShortVersionString + DEPLOY_BUNDLE_SHORT_VERSION + CFBundleSignature + ???? + + LSApplicationCategoryType + Unknown + CFBundleVersion + DEPLOY_BUNDLE_CFBUNDLE_VERSION + NSHumanReadableCopyright + DEPLOY_BUNDLE_COPYRIGHTDEPLOY_FILE_ASSOCIATIONS + NSHighResolutionCapable + true + NSSupportsAutomaticGraphicsSwitching + + + diff --git a/buildres/macos/Info.plist.template b/buildres/macos/Info.plist.template new file mode 100644 index 0000000..509eb84 --- /dev/null +++ b/buildres/macos/Info.plist.template @@ -0,0 +1,39 @@ + + + + + LSMinimumSystemVersion + 10.9 + CFBundleDevelopmentRegion + English + CFBundleAllowMixedLocalizations + + CFBundleExecutable + DEPLOY_LAUNCHER_NAME + CFBundleIconFile + DEPLOY_ICON_FILE + CFBundleIdentifier + DEPLOY_BUNDLE_IDENTIFIER + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + DEPLOY_BUNDLE_NAME + CFBundlePackageType + APPL + CFBundleShortVersionString + DEPLOY_BUNDLE_SHORT_VERSION + CFBundleSignature + ???? + + LSApplicationCategoryType + Unknown + CFBundleVersion + DEPLOY_BUNDLE_CFBUNDLE_VERSION + NSHumanReadableCopyright + DEPLOY_BUNDLE_COPYRIGHTDEPLOY_FILE_ASSOCIATIONS + NSHighResolutionCapable + true + NSSupportsAutomaticGraphicsSwitching + + + diff --git a/buildres/macos/JabRef-background-darkAqua.png b/buildres/macos/JabRef-background-darkAqua.png new file mode 100644 index 0000000..0612c82 Binary files /dev/null and b/buildres/macos/JabRef-background-darkAqua.png differ diff --git a/buildres/macos/JabRef-background.png b/buildres/macos/JabRef-background.png new file mode 100644 index 0000000..0612c82 Binary files /dev/null and b/buildres/macos/JabRef-background.png differ diff --git a/buildres/macos/JabRef-background.tiff b/buildres/macos/JabRef-background.tiff new file mode 100644 index 0000000..62782b1 Binary files /dev/null and b/buildres/macos/JabRef-background.tiff differ diff --git a/buildres/macos/JabRef-dmg-setup.scpt b/buildres/macos/JabRef-dmg-setup.scpt new file mode 100644 index 0000000..1ed57f9 --- /dev/null +++ b/buildres/macos/JabRef-dmg-setup.scpt @@ -0,0 +1,44 @@ +tell application "Finder" + set theDisk to a reference to (disks whose URL = "DEPLOY_VOLUME_URL") + open theDisk + + set theWindow to a reference to (container window of disks whose URL = "DEPLOY_VOLUME_URL") + + set current view of theWindow to icon view + set toolbar visible of theWindow to false + set statusbar visible of theWindow to false + + -- size of window should fit the size of background + set the bounds of theWindow to {346, 100, 920, 500} + + set theViewOptions to a reference to the icon view options of theWindow + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 128 + set background picture of theViewOptions to POSIX file "DEPLOY_BG_FILE" + + -- Create alias for install location + make new alias file at POSIX file "DEPLOY_VOLUME_PATH" to POSIX file "DEPLOY_INSTALL_LOCATION" with properties {name:"DEPLOY_INSTALL_LOCATION_DISPLAY_NAME"} + + set allTheFiles to the name of every item of theWindow + set xpos to 120 + repeat with theFile in allTheFiles + set theFilePath to POSIX path of theFile + set appFilePath to POSIX path of "/DEPLOY_TARGET" + if theFilePath ends with "DEPLOY_INSTALL_LOCATION_DISPLAY_NAME" then + -- Position install location application + set position of item theFile of theWindow to {440, 170} + else if theFilePath ends with appFilePath then + -- Position application or runtime + set position of item theFile of theWindow to {140, 170} + else + -- Position all other items in a second row. + set position of item theFile of theWindow to {xpos, 400} + set xpos to xpos + 150 + end if + end repeat + + + update theDisk without registering applications + delay 5 + close (get window of theDisk) +end tell diff --git a/buildres/macos/Jabref-volume.icns b/buildres/macos/Jabref-volume.icns new file mode 100644 index 0000000..e231e8d Binary files /dev/null and b/buildres/macos/Jabref-volume.icns differ diff --git a/buildres/macos/README.md b/buildres/macos/README.md new file mode 100644 index 0000000..495b574 --- /dev/null +++ b/buildres/macos/README.md @@ -0,0 +1,12 @@ +# Mac Resources + +## Modifying DMG Setup scpt + +Rename `JabRef-dmg-setup.scpt script` to `JabRef-dmg-setup.applescript`. +Only modify the `JabRef-dmg-setup.applescript` in the macOS Script Editor. Afterwards copy over the file and rename it to `JabRef-dmg-setup.scpt`. +Normally the `scpt` file is a binary compiled variant and the `.applescript` the uncompiled format but jpackage expects the sctp in uncompiled format + +## Generate iconsets + +To generate icns files use the script under `src/main/resources/icons` +Install [svg2png](https://formulae.brew.sh/formula/svg2png) and call the script with the svg filename as first argument. diff --git a/buildres/macos/Resources/jabref.icns b/buildres/macos/Resources/jabref.icns new file mode 100644 index 0000000..e231e8d Binary files /dev/null and b/buildres/macos/Resources/jabref.icns differ diff --git a/buildres/macos/Resources/jabrefHost.py b/buildres/macos/Resources/jabrefHost.py new file mode 100644 index 0000000..815363b --- /dev/null +++ b/buildres/macos/Resources/jabrefHost.py @@ -0,0 +1,101 @@ +#!/usr/bin/python3 + +import json +import logging +import platform +import shlex +import shutil +import struct +import subprocess +import sys +from pathlib import Path + +# We assume that this python script is located in "jabref/lib" while the executable is "jabref/bin/JabRef" +# Note that the package structure is different when installed as a .app bundle on MacOs, so the path must be altered. +script_dir = Path(__file__).resolve().parent.parent +JABREF_PATH = script_dir / "bin/JabRef" + +# on mac we must only two folder upwards +if sys.platform.startswith('darwin'): + script_dir = Path(__file__).resolve().parent.parent +if not JABREF_PATH.exists(): + JABREF_PATH = script_dir / "MacOS/JabRef" + +if not JABREF_PATH.exists(): + logging.error("Could not determine JABREF_PATH") + send_message({"message": "error", "output": "Could not find JabRef. Please check that it is installed correctly."}) + sys.exit(-1) + +logging_dir = Path.home() / ".mozilla/native-messaging-hosts/" +if not logging_dir.exists(): + logging_dir.mkdir(parents=True) +logging.basicConfig(filename=str(logging_dir / "jabref_browser_extension.log")) + +# Read a message from stdin and decode it. +def get_message(): + raw_length = sys.stdin.buffer.read(4) + if not raw_length: + logging.error("Raw_length null") + sys.exit(0) + message_length = struct.unpack("=I", raw_length)[0] + logging.info("Got length: {} bytes to be read".format(message_length)) + message = sys.stdin.buffer.read(message_length).decode("utf-8") + logging.info("Got message of {} chars".format(len(message))) + data = json.loads(message) + logging.info("Successfully retrieved JSON") + return data + + +# Encode a message for transmission, given its content. +def encode_message(message_content): + encoded_content = json.dumps(message_content).encode("utf-8") + encoded_length = struct.pack("=I", len(encoded_content)) + return { + "length": encoded_length, + "content": struct.pack(str(len(encoded_content)) + "s", encoded_content), + } + + +# Send an encoded message to stdout. +def send_message(message): + encoded_message = encode_message(message) + sys.stdout.buffer.write(encoded_message["length"]) + sys.stdout.buffer.write(encoded_message["content"]) + sys.stdout.buffer.flush() + + +def add_jabref_entry(data): + """Send string via cli as literal to preserve special characters""" + cmd = str(JABREF_PATH).split() + ["--importBibtex", r"{}".format(data)] + logging.info("Try to execute command {}".format(cmd)) + response = subprocess.check_output(cmd, stderr=subprocess.STDOUT) + logging.info("Called JabRef and got: {}".format(response)) + return response + + +logging.info("Starting JabRef backend") + +try: + message = get_message() +except Exception as e: + message = str(e) +logging.info(str(message)) + +if "status" in message and message["status"] == "validate": + cmd = str(JABREF_PATH).split() + ["--version"] + try: + response = subprocess.check_output(cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + logging.error("Failed to call JabRef: {} {}".format(exc.returncode, exc.output)) + send_message({"message": "jarNotFound", "path": JABREF_PATH}) + else: + logging.info("Response: {}".format(response)) + send_message({"message": "jarFound"}) +else: + entry = message["text"] + try: + output = add_jabref_entry(entry) + send_message({"message": "ok", "output": str(output)}) + except subprocess.CalledProcessError as exc: + logging.error("Failed to call JabRef: {} {}".format(exc.returncode, exc.output)) + send_message({"message": "error", "output": str(exc.output)}) diff --git a/buildres/macos/Resources/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json b/buildres/macos/Resources/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json new file mode 100644 index 0000000..17f681d --- /dev/null +++ b/buildres/macos/Resources/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json @@ -0,0 +1,3 @@ +{ + "external_update_url": "https://clients2.google.com/service/update2/crx" +} diff --git a/buildres/macos/Resources/native-messaging-host/chromium/org.jabref.jabref.json b/buildres/macos/Resources/native-messaging-host/chromium/org.jabref.jabref.json new file mode 100644 index 0000000..e07d623 --- /dev/null +++ b/buildres/macos/Resources/native-messaging-host/chromium/org.jabref.jabref.json @@ -0,0 +1,10 @@ +{ + "name": "org.jabref.jabref", + "description": "JabRef", + "path": "/Applications/JabRef.app/Contents/Resources/jabrefHost.py", + "type": "stdio", + "allowed_origins": [ + "chrome-extension://bifehkofibaamoeaopjglfkddgkijdlh/", + "chrome-extension://pgkajmkfgbehiomipedjhoddkejohfna/" + ] +} diff --git a/buildres/macos/Resources/native-messaging-host/firefox/org.jabref.jabref.json b/buildres/macos/Resources/native-messaging-host/firefox/org.jabref.jabref.json new file mode 100644 index 0000000..66177c6 --- /dev/null +++ b/buildres/macos/Resources/native-messaging-host/firefox/org.jabref.jabref.json @@ -0,0 +1,7 @@ +{ + "name": "org.jabref.jabref", + "description": "JabRef", + "path": "/Applications/JabRef.app/Contents/Resources/jabrefHost.py", + "type": "stdio", + "allowed_extensions": ["browserextension@jabref.org", "@jabfox"] +} diff --git a/buildres/macos/Runtime-Info.plist b/buildres/macos/Runtime-Info.plist new file mode 100644 index 0000000..76fb7ee --- /dev/null +++ b/buildres/macos/Runtime-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + libjli.dylib + CFBundleIdentifier + CF_BUNDLE_IDENTIFIER + CFBundleInfoDictionaryVersion + 7.0 + CFBundleName + CF_BUNDLE_NAME + CFBundlePackageType + BNDL + CFBundleShortVersionString + CF_BUNDLE_SHORT_VERSION_STRING + CFBundleSignature + ???? + CFBundleVersion + CF_BUNDLE_VERSION + NSSupportsAutomaticGraphicsSwitching + + + diff --git a/buildres/macos/Runtime-Info.plist.template b/buildres/macos/Runtime-Info.plist.template new file mode 100644 index 0000000..76fb7ee --- /dev/null +++ b/buildres/macos/Runtime-Info.plist.template @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + libjli.dylib + CFBundleIdentifier + CF_BUNDLE_IDENTIFIER + CFBundleInfoDictionaryVersion + 7.0 + CFBundleName + CF_BUNDLE_NAME + CFBundlePackageType + BNDL + CFBundleShortVersionString + CF_BUNDLE_SHORT_VERSION_STRING + CFBundleSignature + ???? + CFBundleVersion + CF_BUNDLE_VERSION + NSSupportsAutomaticGraphicsSwitching + + + diff --git a/buildres/macos/bibtexAssociations.properties b/buildres/macos/bibtexAssociations.properties new file mode 100644 index 0000000..a083986 --- /dev/null +++ b/buildres/macos/bibtexAssociations.properties @@ -0,0 +1,3 @@ +extension=bib +mime-type=text/x-bibtex +description=BibTeX File diff --git a/buildres/macos/info-lite.plist b/buildres/macos/info-lite.plist new file mode 100644 index 0000000..509eb84 --- /dev/null +++ b/buildres/macos/info-lite.plist @@ -0,0 +1,39 @@ + + + + + LSMinimumSystemVersion + 10.9 + CFBundleDevelopmentRegion + English + CFBundleAllowMixedLocalizations + + CFBundleExecutable + DEPLOY_LAUNCHER_NAME + CFBundleIconFile + DEPLOY_ICON_FILE + CFBundleIdentifier + DEPLOY_BUNDLE_IDENTIFIER + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + DEPLOY_BUNDLE_NAME + CFBundlePackageType + APPL + CFBundleShortVersionString + DEPLOY_BUNDLE_SHORT_VERSION + CFBundleSignature + ???? + + LSApplicationCategoryType + Unknown + CFBundleVersion + DEPLOY_BUNDLE_CFBUNDLE_VERSION + NSHumanReadableCopyright + DEPLOY_BUNDLE_COPYRIGHTDEPLOY_FILE_ASSOCIATIONS + NSHighResolutionCapable + true + NSSupportsAutomaticGraphicsSwitching + + + diff --git a/buildres/macos/jabref.entitlements b/buildres/macos/jabref.entitlements new file mode 100644 index 0000000..56f6d63 --- /dev/null +++ b/buildres/macos/jabref.entitlements @@ -0,0 +1,24 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.server + + com.apple.security.network.client + + com.apple.security.files.user-selected.read-write + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-executable-page-protection + + com.apple.security.cs.disable-library-validation + + com.apple.security.cs.allow-dyld-environment-variables + + + diff --git a/buildres/macos/jabref.icns b/buildres/macos/jabref.icns new file mode 100644 index 0000000..e231e8d Binary files /dev/null and b/buildres/macos/jabref.icns differ diff --git a/buildres/macos/launcher.icns b/buildres/macos/launcher.icns new file mode 100644 index 0000000..e231e8d Binary files /dev/null and b/buildres/macos/launcher.icns differ diff --git a/buildres/macos/postinstall b/buildres/macos/postinstall new file mode 100644 index 0000000..3b99d57 --- /dev/null +++ b/buildres/macos/postinstall @@ -0,0 +1,20 @@ +#!/bin/sh + +chown root:wheel "INSTALL_LOCATION" +chmod a+rX "INSTALL_LOCATION" +chmod +r "APP_LOCATION/"*.jar +# Trigger an auto-install of the browser addon for chrome/chromium browsers +# First create the necessary path, then copy the autoinstall file. +install -d /Library/Application\ Support/Google/Chrome/External\ Extensions/ +install -m0644 /Applications/JabRef.app/Contents/Resources/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json /Library/Application\ Support/Google/Chrome/External\ Extensions/bifehkofibaamoeaopjglfkddgkijdlh.json +# Install the native-messaging host script for firefox/chrome/chromium +install -d /Library/Application\ Support/Mozilla/NativeMessagingHosts/ +install -m0755 /Applications/JabRef.app/Contents/Resources/native-messaging-host/firefox/org.jabref.jabref.json /Library/Application\ Support/Mozilla/NativeMessagingHosts/org.jabref.jabref.json +install -d /Library/Application\ Support/Chromium/NativeMessagingHosts/ +install -m0755 /Applications/JabRef.app/Contents/Resources/chromium/org.jabref.jabref.json /Library/Application\ Support/Chromium/NativeMessagingHosts/org.jabref.jabref.json +install -d /Library/Google/Chrome/NativeMessagingHosts/ +install -m0755 /Applications/JabRef.app/Contents/Resources/chromium/org.jabref.jabref.json /Library/Google/Chrome/NativeMessagingHosts/org.jabref.jabref.json +install -d /Library/Microsoft/Edge/NativeMessagingHosts/ +install -m0755 /Applications/JabRef.app/Contents/Resources/chromium/org.jabref.jabref.json /Library/Microsoft/Edge/NativeMessagingHosts/org.jabref.jabref.json + +exit 0