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.
For bottle uploads that would be skipped due to preupload_check warning about
skipped uploads and returning early, the old code errored out due to JSON schema
validation failure since the upload was allowed to resume:
"error"=>"value at /manifests/0/annotations/org.opencontainers.image.ref.name is not a string"
This change ensures that the upload is effectively skipped if preupload_check
returns no result.
- Previously I thought that comments were fine to discourage people from
wasting their time trying to bump things that used `undef` that Sorbet
didn't support. But RuboCop is better at this since it'll complain if
the comments are unnecessary.
- Suggested in https://github.com/Homebrew/brew/pull/18018#issuecomment-2283369501.
- I've gone for a mixture of `rubocop:disable` for the files that can't
be `typed: strict` (use of undef, required before everything else, etc)
and `rubocop:todo` for everything else that should be tried to make
strictly typed. There's no functional difference between the two as
`rubocop:todo` is `rubocop:disable` with a different name.
- And I entirely disabled the cop for the docs/ directory since
`typed: strict` isn't going to gain us anything for some Markdown
linting config files.
- This means that now it's easier to track what needs to be done rather
than relying on checklists of files in our big Sorbet issue:
```shell
$ git grep 'typed: true # rubocop:todo Sorbet/StrictSigil' | wc -l
268
```
- And this is confirmed working for new files:
```shell
$ git status
On branch use-rubocop-for-sorbet-strict-sigils
Untracked files:
(use "git add <file>..." to include in what will be committed)
Library/Homebrew/bad.rb
Library/Homebrew/good.rb
nothing added to commit but untracked files present (use "git add" to track)
$ brew style
Offenses:
bad.rb:1:1: C: Sorbet/StrictSigil: Sorbet sigil should be at least strict got true.
^^^^^^^^^^^^^
1340 files inspected, 1 offense detected
```
This provides an extra field to the GitHub Packages manifest about the
executable files in `bin` or `sbin` directories of the bottle.
It also provides an extra GitHub Packages JSON file with the list of all
files.
This would allow us (post a large rebottling effort) to start providing
this information in the Homebrew JSON API.
It also provides a much nicer information source for e.g.
homebrew-command-not-found that doesn't involve downloading actual
bottles.
Co-authored-by: Carlo Cabrera <30379873+carlocab@users.noreply.github.com>
We have a bunch of versions we've been meaning to adjust to not use
invalid GitHub Packages characters for a while. Let's audit for them
and plan for deprecating their use in future.
Some bottles are quite large, and the copies can make us run out of
space rather quickly. Let's try to avoid that by using hard links
instead of copies.
The retry behaviour in `publish_commit_bottles.yml` [1] is often
successful after the second try, so it's likely that we're not waiting
long enough in between retries here.
Let's fix that by retrying with exponential backoff instead of adding a
fixed interval of five seconds after each failure.
[1] 3241035b2a/.github/workflows/publish-commit-bottles.yml (L431-L443)
Erroring out in the middle of uploading multiple bottles results in a
state that is tedious to recover from.
Let's try to avoid these situations by performing checks for all the
bottles first before trying to upload any.
This will reduce the number of requests necessary to ascertain the size
of formulas' bottle archives for analysis purposes.
Currently, getting the size of each bottle requires 1 request for the
formula.json and followed by N requests per formula-version, which
for most formulae is 7— more than 47k requests!
After this change, size retrieval can ascertain all bottle sizes for a
formula-version in a single request, at the cost of one additional
request per formula-version if that formula-version has not been
rebuilt since this change was introduced.
To start, size retrieval will incur an additional P requests where
P is the number of packages. Over the next few weeks and months,
the retrieval will go a lot faster as all new and updated packages will
require only one request.