Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Livecheck: Use Homebrew curl based on root domain #13292

Merged
merged 1 commit into from
May 17, 2022

Conversation

samford
Copy link
Member

@samford samford commented May 17, 2022

  • 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 style with your changes locally?
  • Have you successfully run brew typecheck with your changes locally?
  • Have you successfully run brew tests with your changes locally?

At the moment, #use_homebrew_curl? can only be true for a homepage or stable/cask url with using: :homebrew_curl. If the checked URL differs from these URLs, livecheck won't use brewed curl. This limitation prevents livecheck from using brewed curl for a livecheck block URL that's a string literal (not a symbol for a #checkable_url like :stable, :head, :url). libzip was the original formula referenced in the related brew issue and it meets this criterion, so it doesn't appear to be handled by the existing #use_homebrew_curl? implementation.

Additionally, the existing behavior can cause livecheck to unnecessarily use brewed curl for a completely different website (e.g., cubelib, otf2). For example, if the stable URL has using: :homebrew_curl and the livecheck block has url :homepage, livecheck will use brewed curl when checking the homepage. If these are completely different domains/servers, it's unlikely that we would need to use brewed curl when checking the homepage, so this particular behavior may not be beneficial.

This commit reimplements use_homebrew_curl? to apply brewed curl when the checked URL's root domain is the same as the root domain of an aforementioned formula/cask URL with using: :homebrew_curl. For example, this looser approach would allow a livecheck block checking https://www.example.com/downloads/ to use brewed curl if the stable URL was https://downloads.example.com/example.zip with using: :homebrew_curl. These could be different servers but, based on related formulae, this looseness is necessary for the moment.

This approach aims to resolve both issues, allowing brewed curl to be applied to a slightly broader range of URLs (i.e., not limited to just the #checkable_urls) while also helping to avoid unnecessarily applying brewed curl when it's less likely to be useful (completely different domains). Neither approach is perfect but this one may be more useful in the interim time.

Besides that, this reworks, expands, and reorganizes the related tests a bit. There's still some room for improvement here and I may take another pass at it but I wanted to get this PR up in the interim time, as there's an open PR in homebrew/core that fails CI due to a related livecheck situation and it should be resolved by this.


One thing to note is that this implementation uses addressable to identify the root domain of a URL. Doing this accurately requires a TLD-aware approach, as some top-level domains use more than one part (e.g., co.uk), so we can't simply assume that the last two parts (e.g., example.com) are the root domain.

This gem is already in our dependency tree and this simply adds it to our Gemfile. There's a feature that I plan to implement eventually where this would also be useful, so I hope using this gem in brew is amenable. If not, do let me know of any alternatives, as the implementation relies on being able to identify the root domain (and matching the full host doesn't meet the same needs).


Depending on how this looser approach works in practice, we may want to consider returning to a stricter approach once we have something like using: :homebrew_curl in livecheck blocks (this is forthcoming). Being explicit in a livecheck block is the most reliable approach (i.e., only use brewed curl when needed), so we could favor that and pare down the automated approach to only what's needed to support implicit checks (i.e., with no livecheck block). Of course, it's also possible to drop the automated approach entirely and simply require a livecheck block in this scenario but we can decide on how to handle this when the time comes.

At the moment, `#use_homebrew_curl?` can only be true for a
`homepage` or `stable`/cask `url` with `using: :homebrew_curl`. If
the checked URL differs from these URLs, livecheck won't use brewed
curl. This limitation prevents livecheck from using brewed curl for a
`livecheck` block URL that's a string literal (not a symbol for a
`#checkable_url` like `:stable`, `:head`, `:url`). `libzip` was the
original formula referenced in the related brew issue and it meets
this criterion, so it doesn't appear to be handled by the existing
`#use_homebrew_curl?` implementation.

Additionally, the existing behavior can cause livecheck to
unnecessarily use brewed curl for a completely different website
(e.g., `cubelib`, `otf2`). For example, if the `stable` URL has
`using: :homebrew_curl` and the `livecheck` block has `url
:homepage`, livecheck will use brewed curl when checking the
`homepage`. If these are completely different domains/servers, it's
unlikely that we would need to use brewed curl when checking the
`homepage`, so this particular behavior may not be beneficial.

This commit reimplements `use_homebrew_curl?` to apply brewed curl
when the checked URL's root domain is the same as the root domain of
an aforementioned formula/cask URL with `using: :homebrew_curl`. For
example, this looser approach would allow a `livecheck` block
checking `https://www.example.com/downloads/` to use brewed curl if
the `stable` URL was `https://downloads.example.com/example.zip` with
`using: :homebrew_curl`. These could be different servers but, based
on related formulae, this looseness is necessary for the moment.

This approach aims to resolve both issues, allowing brewed curl to be
applied to a slightly broader range of URLs (i.e., not limited to
just the `#checkable_urls`) while also helping to avoid unnecessarily
applying brewed curl when it's less likely to be useful (completely
different domains). Neither approach is perfect but this one may be
more useful in the interim time.

Depending on how this looser approach works in practice, we may want
to consider returning to a stricter approach once we have something
like `using: :homebrew_curl` in `livecheck` blocks (this is
forthcoming). Being explicit in a `livecheck` block is the most
reliable approach (i.e., only use brewed curl when needed), so we
could favor that and pare down the automated approach to only what's
needed to support implicit checks (i.e., with no `livecheck` block).
Of course, it's also possible to drop the automated approach entirely
and simply require a `livecheck` block in this scenario but we can
decide on how to handle this when the time comes.
@BrewTestBot
Copy link
Member

Review period will end on 2022-05-18 at 04:54:12 UTC.

@BrewTestBot BrewTestBot added the waiting for feedback Merging is blocked until sufficient time has passed for review label May 17, 2022
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, nice work!

@MikeMcQuaid MikeMcQuaid added the critical Critical change which should be shipped as soon as possible. label May 17, 2022
@BrewTestBot BrewTestBot removed the waiting for feedback Merging is blocked until sufficient time has passed for review label May 17, 2022
@BrewTestBot
Copy link
Member

Review period skipped due to critical label.

@SMillerDev
Copy link
Member

@MikeMcQuaid @samford i think this means brew is missing some vendored gems now. See the last linked ticket.

@MikeMcQuaid
Copy link
Member

@SMillerDev Reverted now.

@samford
Copy link
Member Author

samford commented May 18, 2022

I certainly missed something here. addressable looks to be in my vendored gems, so I didn't encounter this error in testing. What's the correct way to handle this situation?

I know we usually have Homebrew.install_bunder_gems! calls in places where we use third-party gems (that was an oversight here and I've been working on a follow-up PR since I saw that issue around an hour ago) but I imagine something more may be needed.

Potentially affected areas that I'm aware of:

  • cask/audit: require "livecheck/livecheck"
  • dev-cmd/bump: require "livecheck/livecheck"
  • dev-cmd/livecheck: require "livecheck/livecheck"`
  • dev-cmd/bump-cask-pr: require "cask" (this requires cask/audit)
  • dev-cmd/irb: require "cask" (this requires cask/audit)
  • livecheck/skip_conditions: require "livecheck/livecheck" (SkipConditions only uses some livecheck utility methods and we may want to move those to a livecheck/utils module)

@MikeMcQuaid
Copy link
Member

I certainly missed something here. addressable looks to be in my vendored gems, so I didn't encounter this error in testing. What's the correct way to handle this situation?

@samford don't worry about it, it happens!

vendored-gems:
name: vendored gems (Linux)
runs-on: ubuntu-latest
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master
- name: Configure Git user
uses: Homebrew/actions/git-user-config@master
with:
username: BrewTestBot
# Can't cache this because we need to check that it doesn't fail the
# "uncommitted RubyGems" step with a cold cache.
- name: Install Bundler RubyGems
run: brew install-bundler-gems --groups=sorbet
- name: Check for uncommitted RubyGems
run: git diff --stat --exit-code Library/Homebrew/vendor/bundle/ruby
should have caught this, I'm surprised it didn't.

The fix here I think is adjusting .gitignore and unignoring and committing the relevant stuff.

Stretch goals: figure out why that test didn't work right and fix that too 😅

@samford
Copy link
Member Author

samford commented May 18, 2022

The fix here I think is adjusting .gitignore and unignoring and committing the relevant stuff.

Makes sense (and good to know going forward). Are we thinking !**/vendor/bundle/ruby/*/gems/addressable-*/* (in the # Unignore vendored gems section) or do we need to be more selective?

@MikeMcQuaid
Copy link
Member

MikeMcQuaid commented May 18, 2022

@samford unless the gem is such huge (like active_support): that seems totally fine 👍🏻

@MikeMcQuaid
Copy link
Member

such

huge, sorry!

@samford
Copy link
Member Author

samford commented May 18, 2022

From what I'm seeing, we should only need the lib and data directories (e.g., not spec or tasks). lib is already covered by !**/vendor/bundle/ruby/*/gems/*/lib, so it should be as simple as !**/vendor/bundle/ruby/*/gems/addressable-*/data. The unicode.data file is found in the data directory, so that tracks with the error users have been seeing.

To be sure, I removed everything from my local addressable-2.8.0 directory except for the data and lib directories and brew livecheck worked as expected. It predictably fails if you remove the data directory, which is basically what users were experiencing.

I'll get a PR up shortly to reinstate this (with related fixes), so the reversion hopefully doesn't affect FX's GCC work in homebrew/core.

@github-actions github-actions bot added the outdated PR was locked due to age label Jun 18, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
critical Critical change which should be shipped as soon as possible. outdated PR was locked due to age
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants