feat: generate stub .app bundle for Launchpad/Spotlight integration on macOS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-29 12:10:07 -04:00
parent 3f0451ccf7
commit ef4d6c73a8
2 changed files with 85 additions and 0 deletions
+71
View File
@@ -22,6 +22,77 @@ class GlabelsQt < Formula
*std_cmake_args
system "cmake", "--build", "build"
system "cmake", "--install", "build"
# Build a thin .app wrapper for Launchpad/Spotlight integration.
# Upstream's CMakeLists doesn't set MACOSX_BUNDLE, so we synthesize one.
# The launcher script execs the real CLI binary in #{bin}/glabels-qt.
on_macos do
app_bundle = prefix/"glabels-qt.app"
contents = app_bundle/"Contents"
macos_dir = contents/"MacOS"
resources = contents/"Resources"
macos_dir.mkpath
resources.mkpath
# Launcher script: 2-line shell that execs the real binary with all args.
launcher = macos_dir/"glabels-qt"
launcher.write <<~SH
#!/bin/bash
exec "#{bin}/glabels-qt" "$@"
SH
launcher.chmod 0755
# Info.plist: minimum keys for Launchpad/Spotlight to recognize the bundle.
(contents/"Info.plist").write <<~PLIST
<?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>gLabels</string>
<key>CFBundleDisplayName</key><string>gLabels</string>
<key>CFBundleIdentifier</key><string>org.glabels.glabels-qt</string>
<key>CFBundleExecutable</key><string>glabels-qt</string>
<key>CFBundleVersion</key><string>#{version}</string>
<key>CFBundleShortVersionString</key><string>#{version}</string>
<key>CFBundlePackageType</key><string>APPL</string>
<key>CFBundleIconFile</key><string>glabels-qt.icns</string>
<key>LSMinimumSystemVersion</key><string>10.13</string>
<key>NSHighResolutionCapable</key><true/>
</dict>
</plist>
PLIST
# Convert upstream PNG icon to .icns using sips (macOS built-in).
# Upstream installs hicolor PNGs at share/icons/hicolor/<size>/apps/glabels.png.
# Pick the largest available; fall back gracefully if none found.
candidate_pngs = Dir[share/"icons/hicolor/*/apps/glabels.png"].sort_by do |path|
size = path[%r{hicolor/(\d+)x\d+/}, 1].to_i
-size # largest first
end
if candidate_pngs.first
system "sips", "-s", "format", "icns",
candidate_pngs.first,
"--out", resources/"glabels-qt.icns"
else
opoo "No upstream PNG icon found; .app will use generic Mac icon."
end
end
end
def caveats
on_macos do
<<~CAVEATS
gLabels has been installed as a CLI binary at:
#{HOMEBREW_PREFIX}/bin/glabels-qt
#{HOMEBREW_PREFIX}/bin/glabels-batch-qt
For Launchpad / Spotlight / Dock integration, copy the .app bundle
to /Applications:
cp -R #{prefix}/glabels-qt.app /Applications/
(Re-run that command after each `brew upgrade glabels-qt` to refresh.)
CAVEATS
end
end
test do
+14
View File
@@ -13,6 +13,20 @@ The explicit URL form is required because Homebrew defaults to GitHub for tap
names. When this repo is mirrored to GitHub at the public-flip, the URL becomes
implicit and the tap command shortens to `brew tap seth/tap`.
### Launchpad / Spotlight integration (macOS)
`brew install` puts `glabels-qt` and `glabels-batch-qt` on your `$PATH` as CLI
binaries. To get a Launchpad icon (and Spotlight matches), copy the bundled
`.app` wrapper to `/Applications/`:
```
cp -R "$(brew --prefix glabels-qt)/glabels-qt.app" /Applications/
```
Re-run that one-liner after each `brew upgrade glabels-qt` so the wrapper
points at the latest version. (Brew formulas can't write to `/Applications/`
directly without elevation; the `cp` is the user's one-time step.)
## Formulae
| Formula | Description |