This adds more tests to `curl_spec.rb` to increase test coverage.
This brings almost all of the methods that don't make network
requests up to 100% line and branch coverage (the exception being
some guards in `parse_curl_output` that shouldn't happen under
normal circumstances).
In the process of writing more tests for `parse_curl_response`, I
made some tweaks to remove checks for conditions that shouldn't ever
be true (e.g., `match["code"]` isn't optional, so it will be present
if `HTTP_STATUS_LINE_REGEX` matches) and to refactor some others. I
contributed this method a while back (9171eb2), so this is me coming
back to clarify some behavior.
This upgrades `utils/curl.rb` to `typed: strict`, which requires
a number of changes to pass `brew typecheck`. The most
straightforward are adding type signatures to methods, adding type
annotations (e.g., `T.let`) to variables that need them, and ensuring
that methods always use the expected return type.
I had to refactor areas where we call a `Utils::Curl` method and use
array destructuring on a `SystemCommand::Result` return value
(e.g., `output, errors, status = curl_output(...)`), as Sorbet
doesn't understand implicit array conversion. As suggested by Markus,
I've switched these areas to use `#stdout`, `#stderr`, and `#status`.
This requires the use of an intermediate variable (`result`) in some
cases but this was a fairly straightforward substitution.
I also had to refactor how `Cask::URL::BlockDSL::PageWithURL` works.
It currently uses `page.extend PageWithURL` to add a `url` attribute
but this reworks it to subclass `SimpleDelegator` and use an
`initialize` method instead. This achieves the same goal but in a way
that Sorbet can understand.
We need a way to escape systemd command lines properly as systemd treats
unrecognised escape sequences as separate literal characters. This helper
function does that.
Our autobump workflow sets the author and committer to the user who
triggered the workflow, defaulting to @BrewTestBot for scheduled runs.
This can be confusing for maintainers when GitHub shows up as
"Unverified" because the commit is signed with @BrewTestBot's key.[^1]
Let's fix that by configuring our autobump workflow to always commit as
@BrewTestBot, so that the committer matches the GPG signature. To do
that, we need to add support for setting `GIT_COMMITTER_NAME` and
`GIT_COMMITTER_EMAIL`.
[^1]: See, for example, Homebrew/homebrew-core#197234.
`#curl_http_content_headers_and_checksum` contains code that works
with a `Content-Type` header in a response but it expects there to
always be only one header in the response. This is normally a
reasonable assumption but we've come across a server that is giving
a response with multiple `Content-Type` headers in the response, so
this produces an error and causes `brew audit` to fail when checking
the URL.
This works around the issue by naively using the last `Content-Type`
header in the response when there's more than one. It's not something
that should normally occur but this will handle the situation when it
does.
Calls to `opoo` and `onoe` produce duplicate `Warning:` and `Error:`
messages in CI logs because we print something to stdout and print an
annotation. Annotations also produce `Error:` and `Warning:` lines in
the log.
Let's fix this by skipping printing the message if we've already printed
an annotation.
The `curl --head --request GET` causes a full download to happen on
`curl` from 8.7.0 to 8.9.1[^1] which causes poor UX due to slow
Cask downloads that can take almost twice as long as they should.
[^1]: https://github.com/Homebrew/brew/issues/18213
- only use annotations for `opoo` and `onoe` if
`HOMEBREW_GITHUB_ACTIONS` is set. This will make using `brew` less
noisy in GitHub Actions for third parties. See
Homebrew/discussions#5602.
- if we've already called `puts_annotation_if_env_set`, then we no
longer need to print the message to `$stderr`. The message from the
annotation already show up in the GitHub Actions log, so printing to
`$stderr` just leads to duplicate messages in the log.
While we're here, let's make sure to forward the `file:` and `line:`
kwargs of `puts_annotation_if_env_set` to the `Annotation` constructor.
We currently generate invalid workflow commands when we create
annotations with a `title` but no `file`. Let's fix that.
While we're here, let's improve handling of `title`s with `:`s. We
cannot use `title`s with `::` since GitHub Actions uses this as a
separator for different fields between a workflow command.
Let's also make sure `metadata` never ends in a `:` to avoid confusing
the GitHub Actions command parser about where the `::` separator is
meant to be.
I previously added the 8 curl exit code (weird server reply) to the
list of non-success exit codes that `#curl_headers` will handle.
We're now seeing failures with a 56 exit code (failure in receiving
network data), where the server returns a 4xx response for a `HEAD`
request but the same request using `GET` works as expected (e.g.,
casks like `beeper`, `get-api`, `odrive`, `ui`, etc.).
This adds 56 to the list of exit codes in `#curl_headers`, so a
response with a 4xx HTTP status will be automatically retried using
`GET`.
$ brew update
==> Updating Homebrew...
To restore the stashed changes to /usr/local/Homebrew, run:
cd /usr/local/Homebrew && git stash pop
File "<string>", line 1
import fcntl; fcntl.flock(, fcntl.LOCK_EX | fcntl.LOCK_NB)
^
SyntaxError: invalid syntax
Introduced on May 2, 2024 with bc0f5ee62a