Formula-Cookbook: improve download strategy info

This commit is contained in:
Eric Knibbe 2025-07-04 10:09:41 -04:00
parent 727804bb08
commit bb372b2665
No known key found for this signature in database
2 changed files with 77 additions and 44 deletions

View File

@ -11,11 +11,12 @@ module Cask
T.any(URI::Generic, String, [T.any(URI::Generic, String), T::Hash[Symbol, T.untyped]])
end
# Methods for the `url` stanza.
class DSL
sig { returns(T.any(URI::Generic, String)) }
attr_reader :uri
sig { returns(T.nilable(T::Array[String])) }
sig { returns(T.nilable(T::Hash[T.any(Symbol, String), String])) }
attr_reader :revisions
sig { returns(T.nilable(T::Boolean)) }
@ -57,7 +58,7 @@ module Cask
# @api public
branch: T.nilable(String),
# @api public
revisions: T.nilable(T::Array[String]),
revisions: T.nilable(T::Hash[T.any(Symbol, String), String]),
# @api public
revision: T.nilable(String),
# @api public
@ -87,7 +88,7 @@ module Cask
specs[:using] = @using = T.let(using, T.any(T::Class[AbstractDownloadStrategy], Symbol, NilClass))
specs[:tag] = @tag = T.let(tag, T.nilable(String))
specs[:branch] = @branch = T.let(branch, T.nilable(String))
specs[:revisions] = @revisions = T.let(revisions, T.nilable(T::Array[String]))
specs[:revisions] = @revisions = T.let(revisions, T.nilable(T::Hash[T.any(Symbol, String), String]))
specs[:revision] = @revision = T.let(revision, T.nilable(String))
specs[:trust_cert] = @trust_cert = T.let(trust_cert, T.nilable(T::Boolean))
specs[:cookies] = @cookies = T.let(cookies, T.nilable(T::Hash[String, String]))
@ -101,6 +102,7 @@ module Cask
end
end
# Allow passing a block to the `url` stanza.
class BlockDSL
# Allow accessing the URL associated with page contents.
class PageWithURL < SimpleDelegator
@ -197,7 +199,7 @@ module Cask
using: T.any(T::Class[AbstractDownloadStrategy], Symbol, NilClass),
tag: T.nilable(String),
branch: T.nilable(String),
revisions: T.nilable(T::Array[String]),
revisions: T.nilable(T::Hash[T.any(Symbol, String), String]),
revision: T.nilable(String),
trust_cert: T.nilable(T::Boolean),
cookies: T.nilable(T::Hash[String, String]),

View File

@ -780,35 +780,9 @@ no_autobump! because: "some unique reason"
More information about the autobump process can be found on the [Autobump](Autobump.md) page.
### Unstable versions (`head`)
Formulae can specify an alternate download for the upstream projects development cutting-edge source (e.g. `main`/`master`/`trunk`) using [`head`](https://rubydoc.brew.sh/Formula#head-class_method), which can be activated by passing `--HEAD` when installing. Specifying it is done in the same manner as [`url`](https://rubydoc.brew.sh/Formula#url-class_method):
```ruby
class Foo < Formula
# ...
head "https://github.com/some/package.git", branch: "main" # the default is "master"
end
```
You can also bundle the URL and any `head`-specific dependencies and resources in a `head do` block.
```ruby
class Foo < Formula
# ...
head do
url "https://svn.code.sf.net/p/project/code/trunk"
depends_on "pkg-config" => :build
end
end
```
You can test whether the [`head`](https://rubydoc.brew.sh/Formula#head-class_method) is being built with `build.head?` in the `install` method.
### URL download strategies
When parsing a download URL, Homebrew auto-detects the resource type it points to, whether archive (e.g. tarball, zip) or version control repository (e.g. Git, SVN, Mercurial) and chooses an appropriate download strategy. Some strategies can be passed additional options to alter what's downloaded. For example, to use a specific commit, tag, or branch from a repository, specify [`url`](https://rubydoc.brew.sh/Formula#url-class_method) or [`head`](https://rubydoc.brew.sh/Formula#head-class_method) with the `:tag` and `:revision`, `:revision`, or `:branch` options, like so:
When parsing a download URL, Homebrew auto-detects the resource type it points to, whether archive (e.g. tarball, zip) or version control repository (e.g. Git, Subversion, Mercurial) and chooses an appropriate download strategy. Some strategies can be passed additional options to alter what's downloaded. For example, to fetch a formula's source code and infer its version number from a specific tag in a Git repository (useful for packages that rely on Git submodules), specify [`url`](https://rubydoc.brew.sh/Formula#url-class_method) with the `:tag` and `:revision` options, like so:
```ruby
class Foo < Formula
@ -819,7 +793,28 @@ class Foo < Formula
end
```
If not inferable, specify which of Homebrews built-in download strategies to use with the `using:` option. For example:
If fetching from a Subversion or Mercurial repository, specify `revision` and `version` separately:
```ruby
class Bar < Formula
# ...
url "https://svn.code.sf.net/p/package/code/stable", revision: "4687"
version "12.1.8"
end
```
To fetch specific revisions of Subversion externals, specify `revisions`:
```ruby
class Baz < Formula
# ...
url "svn://source.something.org/package/trunk/",
revisions: { trunk: "22916", "libsomething" => "31045" }
version "7.2.11"
end
```
If not inferable, specify which of Homebrew's built-in download strategies to use with the `using:` option. For example:
```ruby
class Nginx < Formula
@ -833,18 +828,18 @@ end
Homebrew offers these anonymous download strategies.
| `:using` value | download strategy |
| ---------------- | ----------------------------- |
| `:bzr` | `BazaarDownloadStrategy` |
| `:curl` | `CurlDownloadStrategy` |
| `:cvs` | `CVSDownloadStrategy` |
| `:fossil` | `FossilDownloadStrategy` |
| `:git` | `GitDownloadStrategy` |
| `:hg` | `MercurialDownloadStrategy` |
| `:homebrew_curl` | `HomebrewCurlDownloadStrategy` |
| `:nounzip` | `NoUnzipCurlDownloadStrategy` |
| `:post` | `CurlPostDownloadStrategy` |
| `:svn` | `SubversionDownloadStrategy` |
| `using:` value | download strategy | requirements |
| ---------------- | -------------------------------- | ------------ |
| `:bzr` | fetch from Bazaar repository | `breezy` installed |
| `:curl` | download using `curl` (default) | |
| `:cvs` | fetch from CVS repository | `cvs` installed |
| `:fossil` | fetch from Fossil repository | `fossil` installed |
| `:git` | fetch from Git repository | `git` installed |
| `:hg` | fetch from Mercurial repository | `hg` installed |
| `:homebrew_curl` | download using brewed `curl` | `curl` installed |
| `:nounzip` | download without decompressing | |
| `:post` | download using `curl` via POST | `data:` [hash of parameters](Cask-Cookbook.md#additional-url-parameters) |
| `:svn` | fetch from Subversion repository | `svn` installed |
If you need more control over the way files are downloaded and staged, you can create a custom download strategy and specify it with the `:using` option:
@ -862,6 +857,42 @@ class Foo < Formula
end
```
### Unstable versions (`head`)
Formulae can specify an alternate download for the upstream project's development/cutting-edge source (e.g. `master`/`main`/`trunk`) using [`head`](https://rubydoc.brew.sh/Formula#head-class_method), which can be activated by passing `--HEAD` when installing. Specifying it is done in the same manner as [`url`](https://rubydoc.brew.sh/Formula#url-class_method), with added conventions for fetching from version control repositories:
* Git repositories need `branch:` specified to fetch a branch other than "master". If the repository is very large, specify `only_path` to [limit the checkout to one path](Cask-Cookbook.md#git-urls).
```sh
head "https://github.com/some/package.git", branch: "main"
```
* Mercurial repositories need `branch:` specified to fetch a branch other than "default".
* Subversion repositories can specify `trust_cert: true` to [skip interactive certificate prompts](Cask-Cookbook.md#subversion-urls).
* CVS repositories can specify `module:` to check out a specific module.
You can also bundle the URL and any `head`-specific dependencies and resources in a `head do` block.
```ruby
class Foo < Formula
# ...
head do
url "https://hg.sr.ht/~user/foo", using: :hg, branch: "develop"
depends_on "pkg-config" => :build
resource "package" do
url "https://github.com/other/package.git", branch: "main"
end
end
end
```
You can test whether the [`head`](https://rubydoc.brew.sh/Formula#head-class_method) is being built with `build.head?` in the `install` method.
### Compiler selection
Sometimes a package fails to build when using a certain compiler. Since recent [Xcode versions](Xcode.md) no longer include a GCC compiler we cannot simply force the use of GCC. Instead, the correct way to declare this is with the [`fails_with`](https://rubydoc.brew.sh/Formula#fails_with-class_method) DSL method. A properly constructed [`fails_with`](https://rubydoc.brew.sh/Formula#fails_with-class_method) block documents the latest compiler build version known to cause compilation to fail, and the cause of the failure. For example: