Skip to content

Conversation

@samford
Copy link
Member

@samford samford commented Nov 19, 2025

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same change?
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) with your changes locally?

The min_os cask audit uses the cask_bundle_min_os method to identify minimum OS requirements from an app bundle but this doesn't always produce the expected output for universal apps. If an app doesn't specify a minimum system version in the Info.plist file, the method checks binaries for requirements but it picks the highest version regardless of architecture and that can be inaccurate.

For example, if a universal app without a minimum system version in the Info.plist has a binary with a macOS requirement of 10.13 or later for Intel and 11 or later for ARM, cask_bundle_min_os will incorrectly return 11 as the minimum OS version on Intel. If the cask doesn't have a depends_on macos: value, the audit will error with "Artifact defined :big_sur as the minimum macOS version but the cask declared no minimum macOS version". However, this error only applies to ARM, as Intel can rely on the implicit macOS requirement (currently >= :catalina). Adding a top-level depends_on macos: ">= :big_sur" value resolves the error but it's technically incorrect for Intel.

We can accurately address this in casks with separate ARM/Intel apps by calling depends_on macos: in an on_arm block, though we also have to make the implicit macOS requirement explicit in an on_intel block to pass brew style (as it won't allow depends_on to only be called in one on_arch block). However, that approach doesn't work for a universal app like the previous example, as cask_bundle_min_os incorrectly returns the [higher] ARM requirement on Intel.

This addresses the issue by modifying cask_bundle_min_os to respect the current architecture (i.e., the hardware arch or the arch we're simulating) when identifying OS requirements from binaries. The existing approach lumped all the requirements together and returned the highest version, so this does the same thing for a given arch. This can return an incorrect requirement if the binary covers more than one ARM/Intel arch and the requirements differ but I didn't want to unnecessarily complicate this when we currently only distinguish between general arch types like ARM or Intel. If this ambiguity becomes a problem in the future, we can always modify this setup again.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR modifies the cask_bundle_min_os method to respect the current architecture when determining minimum macOS version requirements from universal app binaries. Previously, the method returned the highest version requirement across all architectures, which could be incorrect for Intel when the ARM requirement was higher.

Key Changes:

  • Architecture-specific requirement collection for universal (fat) binaries
  • Returns minimum OS requirement based on the current/simulated architecture instead of the global maximum
  • Preserves existing behavior for single-architecture (MachO) binaries

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@samford samford force-pushed the cask/audit_min_os-respect-arch-for-universal-apps branch from 3b59f8c to 8ceffdb Compare November 19, 2025 00:13
Copy link
Member

@p-linnane p-linnane left a comment

Choose a reason for hiding this comment

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

Excellent nerd snipe!

The `min_os` cask audit uses the `cask_bundle_min_os` method to
identify minimum OS requirements from an app bundle but this doesn't
always produce the expected output for universal apps. If an app
doesn't specify a minimum system version in the `Info.plist` file, the
method checks binaries for requirements but it picks the highest
version regardless of architecture and that can be inaccurate.

For example, if a universal app without a minimum system version in
the `Info.plist` has a binary with a macOS requirement of 10.13 or
later for Intel and 11 or later for ARM, `cask_bundle_min_os` will
incorrectly return 11 as the minimum OS version on Intel. If the cask
doesn't have a `depends_on macos:` value, the audit will error with
"Artifact defined :big_sur as the minimum macOS version but the cask
declared no minimum macOS version". However, this error only applies
to ARM, as Intel can rely on the implicit macOS requirement
(currently `>= :catalina`). Adding a top-level `depends_on macos:
">= :big_sur"` value resolves the error but it's technically incorrect
for Intel.

We can accurately address this in casks with separate ARM/Intel apps
by calling `depends_on macos:` in an `on_arm` block, though we also
have to make the implicit macOS requirement explicit in an `on_intel`
block to pass `brew style` (as it won't allow `depends_on` to only
be called in one on_arch block). However, that approach doesn't work
for a universal app like the previous example, as `cask_bundle_min_os`
incorrectly returns the [higher] ARM requirement on Intel.

This addresses the issue by modifying `cask_bundle_min_os` to respect
the current architecture (i.e., the hardware arch or the arch we're
simulating) when identifying OS requirements from binaries. The
existing approach lumped all the requirements together and returned
the highest version, so this does the same thing for a given arch.
This can return an incorrect requirement if the binary covers more
than one ARM/Intel arch and the requirements differ but I didn't want
to unnecessarily complicate this when we currently only distinguish
between general arch types like ARM or Intel. If this ambiguity
becomes a problem in the future, we can always modify this setup
again.
Copilot AI review requested due to automatic review settings November 19, 2025 04:16
@samford samford force-pushed the cask/audit_min_os-respect-arch-for-universal-apps branch from 8ceffdb to 6c3c5f9 Compare November 19, 2025 04:16
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

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

Makes sense, thanks!

@MikeMcQuaid MikeMcQuaid added this pull request to the merge queue Nov 19, 2025
Merged via the queue into main with commit 43ba00f Nov 19, 2025
43 checks passed
@MikeMcQuaid MikeMcQuaid deleted the cask/audit_min_os-respect-arch-for-universal-apps branch November 19, 2025 08:52
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.

5 participants