Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions cmd/maintained-apps/validate/darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,18 @@ func appExists(ctx context.Context, logger *slog.Logger, appName, uniqueAppIdent
}
}

// Logi Tune: the installer URL always serves the latest release, while the Homebrew
// cask version lags behind (its livecheck scrapes a Logitech support article that is
// updated less often than the download). The installed version is therefore newer
// than the manifest version. If version doesn't match but app is installed, fall
// back to existence-only validation.
if uniqueAppIdentifier == "com.logitech.logitune" {
if !checkVersionMatch(appVersion, result.Version, result.BundledVersion) {
logger.InfoContext(ctx, "Logi Tune detected - version mismatch but app is installed, falling back to existence-only validation")
return true, nil
}
}

// Check various version matching strategies
if checkVersionMatch(appVersion, result.Version, result.BundledVersion) {
return true, nil
Expand Down
12 changes: 12 additions & 0 deletions ee/maintained-apps/ingesters/homebrew/external_refs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var Funcs = map[string][]func(*maintained_apps.FMAManifestApp) (*maintained_apps
"mysqlworkbench/darwin": {MySQLWorkbenchVersionTransformer},
"lens/darwin": {LensVersionTransformer},
"grammarly-desktop/darwin": {GrammarlyDesktopVersionShortener},
"logitune/darwin": {LogiTunePKGInstaller},
"anka-virtualization/darwin": {AnkaVersionShortener},
"pd/darwin": {PdVersionTransformer},
}
Expand Down Expand Up @@ -83,6 +84,17 @@ func ZoomPKGInstaller(app *maintained_apps.FMAManifestApp) (*maintained_apps.FMA
return app, nil
}

func LogiTunePKGInstaller(app *maintained_apps.FMAManifestApp) (*maintained_apps.FMAManifestApp, error) {
// Override installer URL to use Logitech's enterprise PKG installer instead of Homebrew's DMG,
// which only contains a GUI installer app with no silent mode.
// Version is kept from Homebrew (not set to "latest")
app.InstallerURL = "https://software.vc.logitech.com/downloads/tune/LogiTuneInstaller.pkg"
// Set SHA256 to "no_check" since we're using a different installer URL than Homebrew
app.SHA256 = "no_check"

return app, nil
}

func WhatsAppInstallerURL(app *maintained_apps.FMAManifestApp) (*maintained_apps.FMAManifestApp, error) {
// Override installer URL to always use the specified URL
app.InstallerURL = "https://web.whatsapp.com/desktop/mac_native/release/?configuration=Release&src=whatsapp_downloads_page"
Expand Down
10 changes: 10 additions & 0 deletions ee/maintained-apps/inputs/homebrew/logitune.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "Logi Tune",
"unique_identifier": "com.logitech.logitune",
"token": "logitune",
"installer_format": "pkg",
"slug": "logitune/darwin",
"default_categories": ["Communication"],
"install_script_path": "ee/maintained-apps/inputs/homebrew/scripts/logitune-install.sh",
"uninstall_script_path": "ee/maintained-apps/inputs/homebrew/scripts/logitune-uninstall.sh"
}
43 changes: 43 additions & 0 deletions ee/maintained-apps/inputs/homebrew/scripts/logitune-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/bash

quit_application() {
local bundle_id="$1"
local console_user="$2"
local timeout_duration=10

if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
return
fi

echo "Quitting application '$bundle_id'..."

# try to quit the application within the timeout period
local quit_success=false
SECONDS=0
while (( SECONDS < timeout_duration )); do
if osascript -e "tell application id \"$bundle_id\" to quit" >/dev/null 2>&1; then
if ! pgrep -f "$bundle_id" >/dev/null 2>&1; then
echo "Application '$bundle_id' quit successfully."
quit_success=true
break
fi
fi
sleep 1
done

if [[ "$quit_success" = false ]]; then
echo "Application '$bundle_id' did not quit."
fi
}

CONSOLE_USER=$(stat -f "%Su" /dev/console 2>/dev/null || echo "")

# Quit Logi Tune gracefully before the PKG's preinstall force-kills it. The
# PKG's default RUNAPP choice relaunches the app for logged-in console users
# after installation, so no relaunch step is needed here.
if osascript -e "application id \"com.logitech.logitune\" is running" 2>/dev/null; then
quit_application 'com.logitech.logitune' "$CONSOLE_USER"
fi
Comment thread
allenhouchins marked this conversation as resolved.

installer -pkg "$INSTALLER_PATH" -target /
48 changes: 48 additions & 0 deletions ee/maintained-apps/inputs/homebrew/scripts/logitune-uninstall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash

# Logi Tune installs a vendor uninstall script that unloads its launchd
# services, kills running processes, removes the RightSight daemon, and
# deletes the app bundle, support files, and pkg receipts. Prefer it when
# present (any install of Logi Tune 3.4+ has it).
VENDOR_UNINSTALLER="/Library/Application Support/logitune/uninstall_app.sh"

if [ -f "$VENDOR_UNINSTALLER" ]; then
sh "$VENDOR_UNINSTALLER"
exit $?
fi

# Fallback cleanup for installs missing the vendor uninstaller.

# stop and remove per-user launch agents
for agent in com.logitech.logitune.launcher com.logitech.logitune.agent; do
for user in $(who | grep console | awk '{print $1}'); do
user_id=$(id -u "$user")
launchctl asuser "$user_id" launchctl unload "/Library/LaunchAgents/${agent}.plist" 2>/dev/null
done
rm -f "/Library/LaunchAgents/${agent}.plist"
done

# stop and remove launch daemons (incl. the bundled RightSight daemon)
for daemon in com.logitech.logitune.updater com.logitech.logitune.crashpad com.logitech.LogiRightSight; do
launchctl unload "/Library/LaunchDaemons/${daemon}.plist" 2>/dev/null
rm -f "/Library/LaunchDaemons/${daemon}.plist"
done
Comment thread
allenhouchins marked this conversation as resolved.

# kill any remaining processes
for process in LogiTune LogiTuneAgent LogiTuneUpdater LogiTuneCrashpadHandler; do
pkill -9 -x "$process" 2>/dev/null
done

# remove the app bundle (current and legacy install paths) and support files
rm -rf "/Applications/Logi Tune.app"
rm -rf "/Applications/LogiTune.app"
rm -rf "/Applications/LogiTuneInstaller.app"
rm -rf "/Library/Application Support/logitune"
rm -rf "/Users/Shared/logitune"
rm -f "/Users/Shared/LogiTuneInstallerStarted.txt"

# forget pkg receipts
pkgutil --forget com.logitech.pkg.logitune 2>/dev/null
pkgutil --forget com.logitech.logitune.installer 2>/dev/null

exit 0
7 changes: 7 additions & 0 deletions ee/maintained-apps/outputs/apps.json
Original file line number Diff line number Diff line change
Expand Up @@ -2878,6 +2878,13 @@
"unique_identifier": "Logi Options+",
"description": "Logi Options+ is software for managing Logitech devices."
},
{
"name": "Logi Tune",
"slug": "logitune/darwin",
"platform": "darwin",
"unique_identifier": "com.logitech.logitune",
"description": "Logi Tune is software for managing Logitech webcams, headsets, and docks for video meetings."
},
{
"name": "Loom",
"slug": "loom/darwin",
Expand Down
22 changes: 22 additions & 0 deletions ee/maintained-apps/outputs/logitune/darwin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"versions": [
{
"version": "3.11.89",
"queries": {
"exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.logitech.logitune';",
"patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.logitech.logitune' AND version_compare(bundle_short_version, '3.11.89') < 0);"
},
"installer_url": "https://software.vc.logitech.com/downloads/tune/LogiTuneInstaller.pkg",
"install_script_ref": "584e269e",
"uninstall_script_ref": "8a23a81e",
"sha256": "no_check",
"default_categories": [
"Communication"
]
}
],
"refs": {
"584e269e": "#!/bin/bash\n\nquit_application() {\n local bundle_id=\"$1\"\n local console_user=\"$2\"\n local timeout_duration=10\n\n if [[ $EUID -eq 0 && \"$console_user\" == \"root\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\nCONSOLE_USER=$(stat -f \"%Su\" /dev/console 2>/dev/null || echo \"\")\n\n# Quit Logi Tune gracefully before the PKG's preinstall force-kills it. The\n# PKG's default RUNAPP choice relaunches the app for logged-in console users\n# after installation, so no relaunch step is needed here.\nif osascript -e \"application id \\\"com.logitech.logitune\\\" is running\" 2>/dev/null; then\n quit_application 'com.logitech.logitune' \"$CONSOLE_USER\"\nfi\n\ninstaller -pkg \"$INSTALLER_PATH\" -target /\n",
"8a23a81e": "#!/bin/bash\n\n# Logi Tune installs a vendor uninstall script that unloads its launchd\n# services, kills running processes, removes the RightSight daemon, and\n# deletes the app bundle, support files, and pkg receipts. Prefer it when\n# present (any install of Logi Tune 3.4+ has it).\nVENDOR_UNINSTALLER=\"/Library/Application Support/logitune/uninstall_app.sh\"\n\nif [ -f \"$VENDOR_UNINSTALLER\" ]; then\n sh \"$VENDOR_UNINSTALLER\"\n exit $?\nfi\n\n# Fallback cleanup for installs missing the vendor uninstaller.\n\n# stop and remove per-user launch agents\nfor agent in com.logitech.logitune.launcher com.logitech.logitune.agent; do\n for user in $(who | grep console | awk '{print $1}'); do\n user_id=$(id -u \"$user\")\n launchctl asuser \"$user_id\" launchctl unload \"/Library/LaunchAgents/${agent}.plist\" 2>/dev/null\n done\n rm -f \"/Library/LaunchAgents/${agent}.plist\"\ndone\n\n# stop and remove launch daemons (incl. the bundled RightSight daemon)\nfor daemon in com.logitech.logitune.updater com.logitech.logitune.crashpad com.logitech.LogiRightSight; do\n launchctl unload \"/Library/LaunchDaemons/${daemon}.plist\" 2>/dev/null\n rm -f \"/Library/LaunchDaemons/${daemon}.plist\"\ndone\n\n# kill any remaining processes\nfor process in LogiTune LogiTuneAgent LogiTuneUpdater LogiTuneCrashpadHandler; do\n pkill -9 -x \"$process\" 2>/dev/null\ndone\n\n# remove the app bundle (current and legacy install paths) and support files\nrm -rf \"/Applications/Logi Tune.app\"\nrm -rf \"/Applications/LogiTune.app\"\nrm -rf \"/Applications/LogiTuneInstaller.app\"\nrm -rf \"/Library/Application Support/logitune\"\nrm -rf \"/Users/Shared/logitune\"\nrm -f \"/Users/Shared/LogiTuneInstallerStarted.txt\"\n\n# forget pkg receipts\npkgutil --forget com.logitech.pkg.logitune 2>/dev/null\npkgutil --forget com.logitech.logitune.installer 2>/dev/null\n\nexit 0\n"
Comment thread
allenhouchins marked this conversation as resolved.
}
}
Loading
Loading