Updating

Check for Updates

The menu item Check for Updates… opens Settings → Updates and runs a check immediately. A check never installs anything and never stops playback — it only reports.

Here is what a check actually does:

  1. Reads the version of the running bundle from its own Info.plist, requiring the bundle identifier to be com.walzmedia.ultimatevj. A copy with no readable release version reports that it cannot receive updates.
  2. Downloads the published tap manifest from https://raw.githubusercontent.com/weswalz/homebrew-ultimatevj/main/Casks/ultimatevj.rb.
  3. Parses the single version "X.Y.Z,BUILD" line, then compares it against the running version component by component — the build number participates, so 0.2.1 (3) is newer than 0.2.1 (2).

Automatic checks also run in the background while the app is open, on a six-hour loop, with a minimum gap of one hour between them. The default is on.

Managed installation

Update and Restart only works on a copy that Homebrew manages. The app decides this by checking that all three hold true:

If any check fails, Settings → Updates shows "Update and Restart requires the copy installed through the official Homebrew tap." and installation refuses with "This copy isn't managed by Homebrew. Install UltimateVJ through the official Homebrew tap first."

If Homebrew manages a different copy than the one you are running, updating is refused with "Homebrew manages a different copy of UltimateVJ." — open that other copy to update it.

A self-built or manually copied app can still check for updates. It simply cannot install them.

What Update and Restart does

Update between shows. The documented behaviour is explicit: installing stops playback.

The sequence is deliberately defensive:

  1. Recording must be stopped first, or installing is refused.
  2. The current set is saved as Recovery.uvj into a private per-run folder under ~/Library/Application Support/ULTIMATEVJ/Updates/.
  3. The folder requires at least 512 MiB of free space, and is created with private permissions.
  4. The bundled ULTIMATEVJUpdateHelper is copied alongside, and the request is validated — the bundle must be unsymlinked, the brew path must be one of the two standard locations, and the run folder must not live inside the app itself.
  5. The app terminates and the helper waits up to 120 seconds for it to exit.
  6. The helper runs brew upgrade --cask pinned to the directory holding your running app, then verifies the result by code signature and Gatekeeper assessment. If the installed version is still behind what was expected, it runs a brew reinstall --cask repair pass.
  7. On failure, the bad package is moved aside rather than deleted, your previous app is restored from a backup copy and re-verified, and you are told your previous app and set were retained.
  8. The app relaunches, restores your set from the recovery copy, and marks the restore complete so it can never repeat.

Every brew subprocess runs with a pinned PATH and the HOMEBREW_NO_AUTO_UPDATE, HOMEBREW_NO_INSTALL_CLEANUP and HOMEBREW_NO_ANALYTICS settings, so the update cannot trigger unrelated Homebrew maintenance work.

Updating from the terminal

For a terminal update (this does not provide the in-app helper's recovery/relaunch sequence):

sh
brew update
brew upgrade --cask ultimatevj

Quit UltimateVJ first. Moving from a build without the in-app updater to one with it requires a terminal upgrade once.

Troubleshooting

Symptom Meaning
"This copy isn't managed by Homebrew." The app was not installed by the tap, or is not named ULTIMATEVJ.app
"Homebrew manages a different copy of UltimateVJ." Another ULTIMATEVJ.app is the one Homebrew installed
"This copy has no release version." The bundle has no readable version — usually a local build
Update appears to do nothing Check that you are not recording, and that another copy is not the managed one

Not verified