app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 6492564a3007fe20ef83c1b8676c486b0603838a
parent 92c4051d65f247312fe3428835f524beba66f4ae
Author: triesap <tyson@radroots.org>
Date:   Fri, 17 Apr 2026 23:00:44 +0000

app: add macos app icon

Diffstat:
Mplatforms/macos/App/Resources/Info.plist | 2++
Mplatforms/macos/Scripts/build-macos-host.sh | 2++
Aplatforms/macos/Scripts/generate-macos-app-icon.sh | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mplatforms/macos/Scripts/test-macos-host.sh | 8++++++++
4 files changed, 92 insertions(+), 0 deletions(-)

diff --git a/platforms/macos/App/Resources/Info.plist b/platforms/macos/App/Resources/Info.plist @@ -8,6 +8,8 @@ <string>Radroots</string> <key>CFBundleIdentifier</key> <string>org.radroots.app.macos</string> + <key>CFBundleIconFile</key> + <string>AppIcon</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> diff --git a/platforms/macos/Scripts/build-macos-host.sh b/platforms/macos/Scripts/build-macos-host.sh @@ -13,6 +13,7 @@ resources_root="${contents_root}/Resources" plist_template="${platform_root}/App/Resources/Info.plist" plist_path="${contents_root}/Info.plist" binary_target="${executable_root}/Radroots" +app_icon_path="${resources_root}/AppIcon.icns" require_command() { if command -v "$1" >/dev/null 2>&1; then @@ -65,6 +66,7 @@ mkdir -p "${executable_root}" "${resources_root}" cp "${plist_template}" "${plist_path}" cp "${binary_source}" "${binary_target}" chmod +x "${binary_target}" +"${script_dir}/generate-macos-app-icon.sh" "${app_icon_path}" /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $(workspace_version)" "${plist_path}" /usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${RADROOTS_APP_BUILD:-1}" "${plist_path}" diff --git a/platforms/macos/Scripts/generate-macos-app-icon.sh b/platforms/macos/Scripts/generate-macos-app-icon.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +set -euo pipefail + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" +repo_root="$(git -C "${script_dir}" rev-parse --show-toplevel)" +superproject_root="$(git -C "${script_dir}" rev-parse --show-superproject-working-tree || true)" +output_path="${1:-}" + +require_command() { + if command -v "$1" >/dev/null 2>&1; then + return + fi + echo "missing required command: $1" >&2 + exit 1 +} + +require_command git +require_command sips +require_command iconutil + +if [[ -n "${superproject_root}" && -f "${superproject_root}/logo.png" ]]; then + source_artwork="${superproject_root}/logo.png" +else + source_artwork="${repo_root}/logo.png" +fi + +if [[ -z "${output_path}" ]]; then + echo "usage: $0 <output-icns-path>" >&2 + exit 1 +fi + +if [[ ! -f "${source_artwork}" ]]; then + echo "missing source artwork: ${source_artwork}" >&2 + exit 1 +fi + +tmp_dir="$(mktemp -d)" +cleanup() { + rm -rf "${tmp_dir}" +} +trap cleanup EXIT + +normalized_png="${tmp_dir}/logo.normalized.png" +iconset_dir="${tmp_dir}/AppIcon.iconset" + +mkdir -p "${iconset_dir}" "$(dirname "${output_path}")" +sips -s format png "${source_artwork}" --out "${normalized_png}" >/dev/null + +source_width="$( + sips -g pixelWidth "${normalized_png}" | awk '/pixelWidth/ {print $2}' +)" +source_height="$( + sips -g pixelHeight "${normalized_png}" | awk '/pixelHeight/ {print $2}' +)" + +if [[ "${source_width}" -lt 1024 || "${source_height}" -lt 1024 ]]; then + printf '%s\n' \ + "warning: macos icon source is ${source_width}x${source_height}; 1024x1024 is recommended for crisp AppIcon.icns output" \ + >&2 +fi + +generate_icon() { + local filename="$1" + local size_px="$2" + sips -z "${size_px}" "${size_px}" "${normalized_png}" \ + --out "${iconset_dir}/${filename}" >/dev/null +} + +generate_icon "icon_16x16.png" 16 +generate_icon "icon_16x16@2x.png" 32 +generate_icon "icon_32x32.png" 32 +generate_icon "icon_32x32@2x.png" 64 +generate_icon "icon_128x128.png" 128 +generate_icon "icon_128x128@2x.png" 256 +generate_icon "icon_256x256.png" 256 +generate_icon "icon_256x256@2x.png" 512 +generate_icon "icon_512x512.png" 512 +generate_icon "icon_512x512@2x.png" 1024 + +iconutil -c icns "${iconset_dir}" -o "${output_path}" diff --git a/platforms/macos/Scripts/test-macos-host.sh b/platforms/macos/Scripts/test-macos-host.sh @@ -24,6 +24,9 @@ bundle_name="$( bundle_id="$( /usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "${plist_path}" )" +icon_name="$( + /usr/libexec/PlistBuddy -c 'Print :CFBundleIconFile' "${plist_path}" +)" [[ "${bundle_name}" == "Radroots" ]] || { echo "unexpected CFBundleName: ${bundle_name}" >&2 @@ -39,3 +42,8 @@ bundle_id="$( echo "missing bundle executable: ${app_path}/Contents/MacOS/${executable_name}" >&2 exit 1 } + +[[ -f "${app_path}/Contents/Resources/${icon_name}.icns" ]] || { + echo "missing bundle icon: ${app_path}/Contents/Resources/${icon_name}.icns" >&2 + exit 1 +}