Skip to content

Instantly share code, notes, and snippets.

@javascripto
Last active September 26, 2024 23:05
Show Gist options
  • Select an option

  • Save javascripto/16d6fa85c14dafa81cb578ba1ae1d3b4 to your computer and use it in GitHub Desktop.

Select an option

Save javascripto/16d6fa85c14dafa81cb578ba1ae1d3b4 to your computer and use it in GitHub Desktop.
MacOS bash script app bundle generator (app name + icon path)
#!/bin/bash
if [ -z "$1" ]; then
echo "Use: $0 /path/to/AppBundle.app"
exit 1
fi
APP_PATH="$1"
APP_NAME=$(basename "$APP_PATH" .app)
TMP_DIR="/tmp/${APP_NAME}_dmg"
DMG_PATH="./${APP_NAME}.dmg"
VOL_NAME="$APP_NAME"
if [ ! -d "$APP_PATH" ]; then
echo "App bundle not found: $APP_PATH"
exit 1
fi
if [ -d "$TMP_DIR" ]; then
rm -rf "$TMP_DIR"
fi
mkdir "$TMP_DIR"
cp -R "$APP_PATH" "$TMP_DIR/$APP_NAME.app"
ln -s /Applications "$TMP_DIR/Applications"
echo "Creating DMG..."
hdiutil create -volname "$VOL_NAME" -srcfolder "$TMP_DIR" -ov -format UDZO "$DMG_PATH"
rm -rf "$TMP_DIR"
echo "DMG created successfully: $DMG_PATH"
#!/bin/bash
if [[ ! -z "${BASH_SOURCE[0]}" ]]; then
SCRIPT_DIR_NAME=$(dirname "${BASH_SOURCE[0]}")
cd "${SCRIPT_DIR_NAME}"
fi
read -p "App name: " app_name
read -p "Icon path (.png or .icns): " icon_path
if [ -z "$app_name" ]; then
app_name="MyAppBundle"
fi
mkdir -p ./AppBundle.temp/Contents/{MacOS,Resources}
if [[ -z "$icon_path" ]] || [[ ! -f "$icon_path" ]]; then
icon_path="/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericApplicationIcon.icns"
fi
if [[ "$icon_path" == *.icns ]]; then
cp "$icon_path" ./AppBundle.temp/icon.icns
elif [[ "$icon_path" == *.png ]]; then
mkdir ./AppBundle.temp/icon.iconset
cp "$icon_path" ./AppBundle.temp/icon.iconset/icon.png
sips -z 32 32 ./AppBundle.temp/icon.iconset/icon.png --out AppBundle.temp/icon.iconset/icon_16x16@2x.png > /dev/null
sips -z 32 32 ./AppBundle.temp/icon.iconset/icon.png --out AppBundle.temp/icon.iconset/icon_32x32.png > /dev/null
sips -z 64 64 ./AppBundle.temp/icon.iconset/icon.png --out AppBundle.temp/icon.iconset/icon_32x32@2x.png > /dev/null
sips -z 128 128 ./AppBundle.temp/icon.iconset/icon.png --out AppBundle.temp/icon.iconset/icon_128x128.png > /dev/null
sips -z 256 256 ./AppBundle.temp/icon.iconset/icon.png --out AppBundle.temp/icon.iconset/icon_128x128@2x.png > /dev/null
sips -z 256 256 ./AppBundle.temp/icon.iconset/icon.png --out AppBundle.temp/icon.iconset/icon_256x256.png > /dev/null
sips -z 512 512 ./AppBundle.temp/icon.iconset/icon.png --out AppBundle.temp/icon.iconset/icon_256x256@2x.png > /dev/null
sips -z 512 512 ./AppBundle.temp/icon.iconset/icon.png --out AppBundle.temp/icon.iconset/icon_512x512.png > /dev/null
sips -z 1024 1024 ./AppBundle.temp/icon.iconset/icon.png --out AppBundle.temp/icon.iconset/icon_512x512@2x.png > /dev/null
rm ./AppBundle.temp/icon.iconset/icon.png
iconutil -c icns ./AppBundle.temp/icon.iconset
rm -R ./AppBundle.temp/icon.iconset
fi
mv ./AppBundle.temp/icon.icns "./AppBundle.temp/Contents/Resources/${app_name}.icns"
cat > "./AppBundle.temp/Contents/MacOS/${app_name}" << EOF
#!/bin/bash
SCRIPT_DIR_NAME=\$(dirname "\${BASH_SOURCE[0]}")
CONTENTS_DIR=\$(dirname "\${SCRIPT_DIR_NAME}")
"\${CONTENTS_DIR}/Resources/${app_name}"
EOF
cat > "./AppBundle.temp/Contents/Resources/${app_name}" << EOF
#!/bin/bash
osascript -e 'display dialog "$app_name works!" buttons {"OK"} default button "OK"'
EOF
chmod +x "./AppBundle.temp/Contents/MacOS/${app_name}"
chmod +x "./AppBundle.temp/Contents/Resources/${app_name}"
echo "Place your app binary in ./${app_name}.app/Contents/MacOS/${app_name}"
cat > ./AppBundle.temp/Contents/Info.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>${app_name}</string>
<key>CFBundleExecutable</key>
<string>${app_name}</string>
<key>CFBundleIconFile</key>
<string>${app_name}</string>
<key>CFBundleIconName</key>
<string>${app_name}</string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.myapp</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
</dict>
</plist>
EOF
if [ -d "./${app_name}.app" ]; then
read -p "Do you want to replace ${app_name}.app? (y/n): " replace_file
if [ "$replace_file" == "y" ]; then
rm -r "./${app_name}.app"
mv ./AppBundle.temp "./${app_name}.app"
else
echo "Not replaced"
rm -r ./AppBundle.temp
fi
else
mv ./AppBundle.temp "./${app_name}.app"
fi
open "./${app_name}.app/Contents"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment