## Checklist - [X] I have searched the issue tracker for relevant or duplicate issues. ## Erroneous Behavior The Sparkle step always fails silently and does not update any apps. ## Steps to reproduce Run the following command: ```shell topgrade --only sparkle ``` The Sparkle step will fail silently and will not update any apps. ## Expected Behavior The Sparkle step should update all apps using Sparkle with updates available. ## Cause [The following command is being executed to check for updates](https://github.com/topgrade-rs/topgrade/blob/9ec8e83f410fead45e3b7ce3169a854e338e276a/src/steps/os/macos.rs#L80-L82): ```shell /path/to/sparkle --probe --application /Applications/Example.app ``` Which `sparkle` reports as incorrect usage. The correct usage is: ```shell /path/to/sparkle /Applications/Example.app --probe ``` If updates to the app are available, [the following command would be executed to install the update](https://github.com/topgrade-rs/topgrade/blob/9ec8e83f410fead45e3b7ce3169a854e338e276a/src/steps/os/macos.rs#L85-L87): ```shell /path/to/sparkle bundle --check-immediately --application /Applications/Example.app ``` Which `sparkle` would again report as incorrect usage. The correct usage is: ```shell /path/to/sparkle /Applications/Example.app --check-immediately ``` ## Problem persists without calling from Topgrade Yes, when executing `sparkle` with the same, incorrect usage ## Ran through `Remote Execution` No ## Configuration file None ## Additional Details - macOS Tahoe 26.1 (`25B78`) - Topgrade 16.2.1 installed via Homebrew - Sparkle 2.8.1 installed via Homebrew ## Verbose Output <details> ```shell topgrade --only sparkle --verbose DEBUG Current system locale is en-US DEBUG Configuration directory /Users/f1248/.config/ does not exist DEBUG Version: 16.2.1 DEBUG OS: aarch64-apple-darwin DEBUG Args { inner: ["topgrade", "--only", "sparkle", "--verbose"] } DEBUG Binary path: Ok("/opt/homebrew/bin/topgrade") DEBUG self-update Feature Enabled: false DEBUG Configuration: Config { opt: CommandLineArgs { edit_config: false, show_config_reference: false, run_in_tmux: false, no_tmux: false, cleanup: false, dry_run: false, run_type: Wet, no_retry: false, disable: [], only: [Sparkle], custom_commands: [], env: [], verbose: true, keep_at_end: false, skip_notify: false, yes: None, disable_predefined_git_repos: false, config: None, remote_host_limit: None, show_skipped: false, allow_root: false, log_filter: "warn", gen_completion: None, gen_manpage: false, no_self_update: false }, config_file: ConfigFile { include: None, misc: None, pre_commands: None, post_commands: None, commands: None, conda: None, python: None, composer: None, brew: None, linux: None, mandb: None, git: None, containers: None, windows: None, npm: None, yarn: None, deno: None, vim: None, firmware: None, vagrant: None, flatpak: None, pixi: None, distrobox: None, lensfun: None, julia: None, zigup: None, vscode: None, doom: None, rustup: None, pkgfile: None }, allowed_steps: [Sparkle] } DEBUG Running with euid: 501 DEBUG Cannot find "doas" DEBUG Detected "/usr/bin/sudo" as "sudo" DEBUG Sudo: Ok(Sudo { path: Some("/usr/bin/sudo"), kind: Sudo }) DEBUG Step "Sparkle" DEBUG Detected "/opt/homebrew/bin/sparkle" as "sparkle" ── 15:00:16 - Sparkle ────────────────────────────────────────────────────────── DEBUG Executing command `/opt/homebrew/bin/sparkle --probe --application /Applications/NetNewsWire.app` DEBUG Command failed: Err( 0: \x1b[91mCommand failed: `/opt/homebrew/bin/sparkle --probe --application /Applications/NetNewsWire.app` Stderr: Usage: /opt/homebrew/bin/sparkle bundle [--application app-path] [--check-immediately] [--probe] [--channels chan1,chan2,…] [--feed-url feed-url] [--user-agent-name display-name] [--grant-automatic-checks] [--send-profile] [--defer-install] [--interactive] [--allow-major-upgrades] [--verbose] Description: Check if any new updates for a Sparkle supported bundle need to be installed. If any new updates need to be installed, the user application is terminated and the update is installed immediately unless --defer-install is specified. If the application was alive, then it will be relaunched after. To check if an update is available without installing, use --probe. if no updates are available now, or if the last update check was recently (unless --check-immediately is specified) then nothing is done. If update permission is requested and --grant-automatic-checks is not specified, then checking for updates is aborted. Unless --interactive is specified, this tool will not request for escalated authorization. Alternatively, this tool can be run as root under an active user login session, which will not require (and disallow) interaction. If --defer-install is specified, this tool will exit leaving a spawned process for finishing the installation after the target application terminates. If update installation fails due to not having permission (e.g. from Gatekeeper) to replace the old bundle, an exit status of 8 is returned. Please specify --user-agent-name if you intend to use this tool in an automated way. Options: --application Path to the application to watch for termination and to relaunch. If not provided, this is assumed to be the same as the bundle. --check-immediately Immediately checks for updates to install. Without this, updates are checked only when needed on a scheduled basis. --probe Probe for updates. Check if any updates are available but do not install. An exit status of 0 is returned if a new update is available. --allow-major-upgrades Allows probing and installing major upgrades. Without passing this, an exit status of 2 is returned if a major upgrade is found. --channels List of allowed Sparkle channels to look for updates in. By default, only the default channel is used. --feed-url URL for appcast feed. This URL will be used for the feed instead of the one in the bundle's Info.plist or in the bundle's user defaults. --user-agent-name Display name that will be included as a part of the User-Agent string. We encourage setting this so developers know what is querying their feed. Otherwise, this value may be set and inferred automatically. --interactive Allows prompting the user for an authorization dialog prompt if the installer needs elevated privileges, or allows performing an interactive installer package. Without passing this, an exit status of 3 is returned if an update requires user interaction. An exit status of 5 is returned if the user cancels the authorization prompt. --grant-automatic-checks If update permission is requested, this enables automatic update checks. Note that this behavior may overwrite the user's defaults for the bundle. This option has no effect if --check-immediately is passed, or if the user has replied to this request already, or if the developer configured to skip it. Without passing this, an exit status of 6 is returned if permission is needed. --send-profile Choose to send system profile information if update permission is requested. This option can only take effect if --grant-automatic-checks is passed. --defer-install Defer installation until after the application terminates on its own. The application will not be relaunched unless the installation is resumed later. --verbose Enable verbose logging.\x1b[0m 1: \x1b[91m`/opt/homebrew/bin/sparkle` failed: exit status: 1 with Usage: /opt/homebrew/bin/sparkle bundle [--application app-path] [--check-immediately] [--probe] [--channels chan1,chan2,…] [--feed-url feed-url] [--user-agent-name display-name] [--grant-automatic-checks] [--send-profile] [--defer-install] [--interactive] [--allow-major-upgrades] [--verbose] Description: Check if any new updates for a Sparkle supported bundle need to be installed. If any new updates need to be installed, the user application is terminated and the update is installed immediately unless --defer-install is specified. If the application was alive, then it will be relaunched after. To check if an update is available without installing, use --probe. if no updates are available now, or if the last update check was recently (unless --check-immediately is specified) then nothing is done. If update permission is requested and --grant-automatic-checks is not specified, then checking for updates is aborted. Unless --interactive is specified, this tool will not request for escalated authorization. Alternatively, this tool can be run as root under an active user login session, which will not require (and disallow) interaction. If --defer-install is specified, this tool will exit leaving a spawned process for finishing the installation after the target application terminates. If update installation fails due to not having permission (e.g. from Gatekeeper) to replace the old bundle, an exit status of 8 is returned. Please specify --user-agent-name if you intend to use this tool in an automated way. Options: --application Path to the application to watch for termination and to relaunch. If not provided, this is assumed to be the same as the bundle. --check-immediately Immediately checks for updates to install. Without this, updates are checked only when needed on a scheduled basis. --probe Probe for updates. Check if any updates are available but do not install. An exit status of 0 is returned if a new update is available. --allow-major-upgrades Allows probing and installing major upgrades. Without passing this, an exit status of 2 is returned if a major upgrade is found. --channels List of allowed Sparkle channels to look for updates in. By default, only the default channel is used. --feed-url URL for appcast feed. This URL will be used for the feed instead of the one in the bundle's Info.plist or in the bundle's user defaults. --user-agent-name Display name that will be included as a part of the User-Agent string. We encourage setting this so developers know what is querying their feed. Otherwise, this value may be set and inferred automatically. --interactive Allows prompting the user for an authorization dialog prompt if the installer needs elevated privileges, or allows performing an interactive installer package. Without passing this, an exit status of 3 is returned if an update requires user interaction. An exit status of 5 is returned if the user cancels the authorization prompt. --grant-automatic-checks If update permission is requested, this enables automatic update checks. Note that this behavior may overwrite the user's defaults for the bundle. This option has no effect if --check-immediately is passed, or if the user has replied to this request already, or if the developer configured to skip it. Without passing this, an exit status of 6 is returned if permission is needed. --send-profile Choose to send system profile information if update permission is requested. This option can only take effect if --grant-automatic-checks is passed. --defer-install Defer installation until after the application terminates on its own. The application will not be relaunched unless the installation is resumed later. --verbose Enable verbose logging. 1: \x1b[0m Location: \x1b[35msrc/steps/os/macos.rs\x1b[0m:\x1b[35m83\x1b[0m) ── 15:00:16 - Summary ────────────────────────────────────────────────────────── Sparkle: OK DEBUG Desktop notification: Topgrade finished successfully ``` </details>