Skip to content

Commit

Permalink
build mac FORCE app with applescript launcher
Browse files Browse the repository at this point in the history
  • Loading branch information
j-bryan committed Jun 24, 2024
1 parent a91046f commit b6eff91
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 37 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ romMeta.xml

# Ignore built executables
build
force_install
*.app

# Ignore certain GUI files
.forceuirc
Expand Down
55 changes: 21 additions & 34 deletions package/build_force_mac.sh
Original file line number Diff line number Diff line change
@@ -1,45 +1,32 @@
# Freeze the FORCE app using cx_Freeze. We require a suitable python environment to be active.
# set -e
# python setup.py install_exe --install-dir force_install

# Set up the FORCE application bundle
# We'll set up the app so that some FORCE launcher script is the main executable, and the RAVEN,
# HERON, and TEAL executables are in the Resources directory.
# Build the initial app from the force_launcher.scpt AppleScript
osacompile -o FORCE.app force_launcher.scpt
# Now copy over the force_install directory contents to the application's Resources directory
cp -R force_install/* FORCE.app/Contents/Resources/
# Overwrite the app's icon with the FORCE icon
cp FORCE.icns FORCE.app/Contents/Resources/applet.icns

# Create a new disk image
hdiutil create -size 3g -fs HFS+ -volname "FORCE" -o force_build.dmg

# Mount the new disk image
hdiutil attach force_build.dmg -mountpoint /Volumes/FORCE

# Mount the existing .dmg files
hdiutil attach Workbench-5.4.1.dmg -mountpoint /Volumes/Workbench

# Copy the contents of the force_install directory and the Workbench .dmg file to the new disk image.
mkdir -p FORCE.app/Contents/MacOS
mkdir -p FORCE.app/Contents/Resources
# TODO: move icons to Resources?
cp -R force_install/* FORCE.app/Contents/MacOS/
cp -R force_install/* /Volumes/FORCE/
cp -R /Volumes/Workbench/* /Volumes/FORCE/

# Create the info.plist file with app metadata
# TODO: Which app do we point to?
cat <<EOF > FORCE.app/Contents/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>FORCE</string>
<key>CFBundleDisplayName</key>
<string>FORCE</string>
<key>CFBundleIdentifier</key>
<string></string>
<key>CFBundleVersion</key>
<string>0.1</string>
<key>CFBundleExecutable</key>
<string>my_script.sh</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
</dict>
</plist>
EOF
# Mount the existing .dmg file file Workbench
# hdiutil attach Workbench-5.4.1.dmg -mountpoint /Volumes/Workbench

# Move the FORCE app to the disk image
cp -R FORCE.app /Volumes/FORCE/
# cp -R /Volumes/Workbench/* /Volumes/FORCE/

# Unmount all the disk images
hdiutil detach /Volumes/Workbench
# hdiutil detach /Volumes/Workbench
hdiutil detach /Volumes/FORCE

# Convert to read-only compressed image
Expand Down
23 changes: 23 additions & 0 deletions package/force_launcher.scpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
set options to {"HERON", "RAVEN", "TEAL", "Quit"}

set resourceName to "heron"
set filePathName to quoted form of POSIX path of (path to resource resourceName) as text

set selectedOption to choose from list options with title "FORCE Launcher" with prompt "Which FORCE application woudl you like to use?" default items {"HERON"}

if selectedOption is false then
display dialog "No option selected. Exiting..." buttons {"OK"} default button "OK"
else
set selectedOption to item 1 of selectedOption
if selectedOption is "HERON" then
set resourceName to "heron"
else if selectedOption is "RAVEN" then
set resourceName to "raven_framework"
else if selectedOption is "TEAL" then
set resourceName to "teal"
else if selectedOption is "Quit" then
display dialog "Exiting..." buttons {"OK"} default button "OK"
end if
set filePathName to quoted form of POSIX path of (path to resource resourceName) as text
do shell script filePathName
end if
Binary file added package/force_logo.icns
Binary file not shown.
3 changes: 0 additions & 3 deletions package/ui/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
from ui.controllers import Controller
from ui.views import View

from typing import Optional
import argparse


def run_from_gui(func: Callable, **kwargs):
"""
Expand Down
74 changes: 74 additions & 0 deletions package/ui/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import xml.etree.ElementTree as ET
import os
import subprocess
import platform
import shutil


def check_parallel(path) -> bool:
"""
Checks if a ravenframework input file uses parallel processing. This poses a problem for the executable
on MacOS and possibly Linux.
@In, path, str, path to the input file
@Out, is_parallel, bool, True if parallel processing is used, False otherwise
"""
is_parallel = False

tree = ET.parse(path)
tree.find()

return is_parallel


def find_workbench():
"""
Finds the NEAMS Workbench executable
"""
workbench_path = None
if platform.system() == "Windows":
if os.environ.get('WORKBENCH_PATH'):
workbench_path = os.environ['WORKBENCH_PATH']
else:
workbench_path = shutil.which('workbench')
elif platform.system() == "Darwin":
# Look in the /Applications directory for a directory starting with "Workbench"
for app in os.listdir("/Applications"):
if app.startswith("Workbench") and os.path:
workbench_path = os.path.join("/Applications", app, "Contents/MacOS/Workbench")
break
else:
print("ERROR: Could not find the NEAMS Workbench application in the /Applications directory. "
"Has Workbench been installed?")
else: # Linux, not yet supported
print("Automatic connection of FORCE tools to the NEAMS Workbench is not yet supported on Linux.")
return workbench_path


def run_in_workbench(file: str | None = None):
"""
Opens the given file in the NEAMS Workbench
@ In, file, str, optional, the file to open in NEAMS Workbench
"""
# Find the workbench executable
workbench_path = find_workbench()
if workbench_path is None:
print("ERROR: Could not find the NEAMS Workbench executable. Please set the "
"WORKBENCH_PATH environment variable or add it to the system path.")
raise RuntimeError

# Open the file in the workbench
command = workbench_path
# Currently, we're only able to open the MacOS version of Workbench by opening the app itself.
# This does not accept a file as an argument, so users will need to open Workbench, then open
# the desired file manually from within the app.
if file is not None and platform.system() == "Windows":
command += ' ' + file

if platform.system() == "Windows":
os.system(command)
elif platform.system() == "Darwin":
subprocess.call(["/usr/bin/open", "-n", "-a", workbench_path])
else:
print("ERROR: Automatic connection of FORCE tools to the NEAMS Workbench is only supported "
"on Windows and MacOS. Please open Workbench manually and open the desired file.")

0 comments on commit b6eff91

Please sign in to comment.