Skip to content

Application support path - #150

Merged
p-linnane merged 4 commits into
mainfrom
application-support-path
Sep 7, 2026
Merged

p-linnane merged 4 commits into
mainfrom
application-support-path

Conversation

@graeme

@graeme graeme commented Sep 7, 2026 •

Copy link
Copy Markdown
Collaborator

PR: Namespace on-disk storage by bundle identifier

Summary

The app is unsandboxed, so it writes into the shared ~/Library with no container
to namespace it, and every store resolved its own path into a folder called Brew.
That name collides with anything else using it and reads as the brew CLI's. This
namespaces the paths as sh.brew.app and moves each store into the root matching
whether its data can be rebuilt.

Changes

  • Catalogue and Discover analytics caches move to ~/Library/Caches/sh.brew.app.
    Both hold ETag-validated HTTP bodies: a purge costs one refetch, and the
    catalogue leaves Time Machine backups.
  • Crash reports move to ~/Library/Application Support/sh.brew.app/CrashReports.
    A pending report cannot be regenerated, so it must not be purgeable.
  • The "attach the full crash log from ..." note in the pre-filled GitHub issue is
    updated to match.
  • Each store keeps resolving its own path; only the return value changed. The three
    default-path helpers lose private so the new tests can assert them.

Nothing is released yet, so there is no migration: pre-1.0 installs lose a cached
catalogue and refetch it. Convention followed is Apple's File System Programming
Guide, macOS Library Directory Details.

Testing

  • scripts/test: 955 tests pass, up from 949.
  • SwiftFormat lint, SwiftLint --strict, and BrewUILint all clean.
  • xcodebuild scheme Brew builds.
  • Package tests re-run against git archive HEAD, so nothing depends on an
    untracked file.
  • scripts/test-ui was not run: UI tests cannot run in this sandbox. No app
    code changed, so the exposure is limited to the two cache stores at launch.

PR checklist

  • Have you followed this repository's contribution and workflow guidance?
  • Have you explained what changed and why this should land now?
  • Have you run relevant local checks for the changed scope?
  • Are changes scoped and free of unrelated modifications?

  • AI was used to generate or assist with generating this PR.
  • Claude Code wrote the code, tests, and this description from a discussion of
    which directory each store belongs in. Verification is the automated runs above;
    the app was not run by hand.

Follow-ups (optional)

sh.brew.app is written in three places, matching how Brew was. Worth a shared
constant only once something else needs it. Rationale is in .ai/memory.md.

graeme and others added 4 commits September 7, 2026 19:57
Both stores hold raw HTTP response bodies validated by an ETag, so losing
them costs one refetch and nothing else. That belongs in Caches, which the
system may purge and which is excluded from Time Machine; the catalogue is
the largest thing the app writes and has no business in a backup.

The app is unsandboxed, so the folder name is not cosmetic: "Brew" sat
directly in the shared ~/Library, where it collides with anything else of
that name and reads as if it belonged to the brew CLI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pitCmmVCCRVwpUvPgDDoy
Reports are the opposite of the API caches: a pending report cannot be
regenerated, and a purge would destroy one before the user ever saw the
prompt to file it. So they stay in Application Support and only pick up the
bundle-identifier namespace.

The "attach the full crash log from ..." note in the pre-filled GitHub issue
named the old path, and is updated to match.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pitCmmVCCRVwpUvPgDDoy
Which root each store writes to looks arbitrary later and invites someone
to merge the two back together.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pitCmmVCCRVwpUvPgDDoy
Drop the three-line note on each cache's init explaining that its directory
and defaults prefix are test seams. Injecting a directory for a test is an
ordinary pattern and does not need narrating, and the block was longer than
the initialiser it sat on.

Shorten the one-line note on each default path to state the decision
(which root, and why) rather than restate the return value.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019pitCmmVCCRVwpUvPgDDoy

@p-linnane p-linnane left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice improvement. Will definitely make it easier to separate from brew itself.

@p-linnane
p-linnane merged commit 6a11296 into main Sep 7, 2026
11 checks passed
@p-linnane
p-linnane deleted the application-support-path branch September 7, 2026 16:07
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.

3 participants