On macOS 13 (Ventura) and later, installation could fail if Gatekeeper blocks app modifications. Note this is only applicable for external updaters like sparkle-cli where the updater and target bundle to update have different team identifiers.
When the framework or sparkle-cli is run as root, we always launch the installer (Autoupdate) in the system domain.
For the progress tool agent, we chown() the copied Updater.app so the Updater app has proper ownership of it (and clean it up later). The progress tool app may not be able to clean up the parent directory, but that's okay and will be garbage collected on a later run.
To get the username and home directory for the user session when running the framework as root, we use the SecurityConfiguration framework. Sparkle needs and depends on an active GUI user login session. If a user ssh's in to install an update, that user must be the same as the active logged in user.
Installing interactive based package updates as root is not supported. For sparkle-cli, we disallow using --interactive when running as root.
An additional error exit code is added for sparkle-cli when ran as root and trying to install a interactive based package update, which is unsupported.
In some cases for shared headers in downloader XPC Service or generate_appcast / sign_update tools, I had to do a little dance for using double quote imports.
This may be useful if user defaults can't be relied on for the feed URL.
For example, if an app is sandboxed, its user defaults may differ from the defaults sparkle-cli looks up.
Assume that the updater will be run as a logged in user.
The command line driver and progress app aren't completely root safe anyway, and running the progress app under a different user could be quite awkward from root
This allows installation by requesting the user to enter a password when elevated privileges are necessary. This only works if the application is alive before installation begins.
If an update permission request comes up, this alows us to make a decision.
Also I renamed the defer and checknow flags to defer-install and check-immediately
What is new is that we can now disable checking for updates immediately.
sparkle-cli is not intended to be run for a long time, so if the next update check is not soon, we exit.
A client can now launch sparkle-cli without having to necessarily check for updates, so that they don't check for updates too soon.
I added an application target but it's really intended to be used as a command line tool. The reason being was that it was the easiest way to bundle the Sparkle framework, I've found.
Note this doesn't work perfectly yet, but it's a good start. Trying to update anything that's not Sparkle based will crash for instance. And it will use the installer progress tool which may be undesirable.