Skip to content

feat: cask support with unified command interface#10

Merged
dipankar merged 15 commits intoneul-labs:mainfrom
jhult:feat/cask-unified
Apr 13, 2026
Merged

feat: cask support with unified command interface#10
dipankar merged 15 commits intoneul-labs:mainfrom
jhult:feat/cask-unified

Conversation

@jhult
Copy link
Copy Markdown
Contributor

@jhult jhult commented Apr 2, 2026

Add cask (application) support with Homebrew-compatible --cask/--formula flags on all top-level commands, replacing the separate stout cask namespace.

  • Cask index integration (downloads and merges cask index during stout update)
  • Install casks via stout install with auto-detection or --cask
  • Cask upgrade detection in stout upgrade and stout outdated
  • Cask sync/drift detection in stout sync
  • --cask/--formula flags on install, uninstall, upgrade, outdated, list, info, and search
  • stout outdated and stout list show both formulas and casks by default
  • stout cask <cmd> deprecated with warning, delegates to top-level commands

@jhult jhult force-pushed the feat/cask-unified branch 2 times, most recently from 74cd079 to daf5a45 Compare April 3, 2026 03:26
Add sync_cask_index method to download the cask database from stout-index and merge it into the local index database. The casks table was previously empty because only the formula index was being downloaded.

Also adds import_casks_from method to Database for merging casks from a source database, handling schema differences gracefully.
@jhult jhult force-pushed the feat/cask-unified branch from daf5a45 to 18cc748 Compare April 4, 2026 20:50
jhult added 11 commits April 4, 2026 16:17
The two-pass approach stored tar entries in a Vec for deferred processing, but tar entries read from a streaming gzip decoder. Once an entry was iterated past in the first pass, its data was consumed and invalidated — the second pass read truncated data.

Switched to single-pass: regular entries extract immediately, hardlinks are collected and resolved in a post-pass. Use create_dir_all for directory entries instead of entry.unpack() to avoid restrictive permissions from tar headers (e.g. 0555) that prevented child file writes.
Support installing casks via `stout install <cask>` with automatic detection of whether a package is a formula or cask. Add --cask flag to explicitly treat packages as casks.

Show a conflict message when a name exists as both formula and cask, and provide "did you mean?" suggestions for both formulas and casks when a package is not found.

Use a two-phase approach: download all artifacts in parallel with FuturesUnordered for streaming results, then install sequentially with full terminal access for sudo and DMG license dialogs.
Detect upgradable casks by comparing installed versions from casks.json against the cask index. Auto-update the index if outdated before checking for upgrades.

Extract the new bottle before removing the old version to avoid breaking the system if extraction fails. Continue on individual upgrade failures and report all errors at the end.

Fix "Upgraded N packages" summary to exclude packages that were already up-to-date before stout ran.
Add CaskVersionChanged drift type that detects when a cask has been upgraded externally (e.g. via Homebrew directly). The drift is detected by comparing the installed version in casks.json against the actual version reported by brew.

The apply action updates the version in state to match reality.
Auto-detect formula vs cask uninstallation. Add --cask and --formula flags for explicit type, and --zap for thorough cask cleanup. Extract formula and cask logic into helpers.
Show both formulas and casks by default. Wire up the existing but unused --formula/--cask flags as filters. Cask output uses magenta color for consistency with other cask commands.
Show both formulas and casks by default. Add --cask and --formula flags to filter. Cask section uses magenta color. Add --json flag for cask output.
Add --cask and --formula flags to restrict upgrade scope. Default behavior unchanged: upgrades both formulas and casks.
Add --formula flag for explicit formula lookup. Replace placeholder cask install status with actual InstalledCasks state check.
Replace duplicated cask handlers with a thin delegation layer that prints a deprecation warning and calls the corresponding top-level command with --cask. Removes ~430 lines of duplicated logic.
Replace stout cask examples with --cask flag equivalents. Add deprecation notes for stout cask namespace. Document new --formula and --cask flags on install, uninstall, outdated, list, upgrade, info, and search commands.
@jhult jhult force-pushed the feat/cask-unified branch 2 times, most recently from 46a23bc to 23cf450 Compare April 4, 2026 21:33
jhult added 3 commits April 4, 2026 16:37
stout install/upgrade saved cask versions to casks.json but never updated the Caskroom directory. This caused sync to detect stale versions from the original brew install and report false "upgraded externally" drift.

Now register_cask_in_caskroom creates the version directory after each successful install/upgrade, and unregister_cask_from_caskroom removes it on uninstall.
link_package now detects symlinks pointing into the same package's Cellar directory (but an older version) and replaces them instead of skipping. Previously, if symlinks were orphaned from a prior version (e.g., due to an interrupted upgrade or external Homebrew activity), they would remain broken indefinitely since unlink only removed links matching the tracked version.
DMGs with embedded Software License Agreements (e.g. calhash) would freeze for 5 minutes because hdiutil printed the license text to captured stdout while waiting for stdin input the user couldn't see. Now stdout is inherited so SLA prompts are visible and interactive.
@jhult jhult force-pushed the feat/cask-unified branch from 23cf450 to 6eefc4c Compare April 4, 2026 21:40
@jhult
Copy link
Copy Markdown
Contributor Author

jhult commented Apr 10, 2026

@dipankar - can you please review?

@dipankar dipankar merged commit 1835f6e into neul-labs:main Apr 13, 2026
4 checks passed
@jhult jhult deleted the feat/cask-unified branch April 13, 2026 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants