brew livecheck

The brew livecheck command finds the newest version of a formula or cask’s software by checking upstream. Livecheck has strategies to identify versions from various sources, such as Git repositories, websites, etc.

Behavior

When livecheck isn’t given instructions for how to check for upstream versions, it does the following by default:

  1. For formulae: Collect the head, stable, and homepage URLs, in that order. For casks: Collect the url and homepage URLs, in that order.
  2. Determine if any strategies apply to the first URL. If not, try the next URL.
  3. If a strategy can be applied, use it to check for new versions.
  4. Return the newest version (or an error if versions could not be found at any available URLs).

It’s sometimes necessary to override this default behavior to create a working check. If a source doesn’t provide the newest version, we need to check a different one. If livecheck doesn’t correctly match version text, we need to provide an appropriate regex or strategy block.

This can be accomplished by adding a livecheck block to the formula/cask. For more information on the available methods, please refer to the Livecheck class documentation.

Creating a check

  1. Use the debug output to understand the situation. brew livecheck --debug <formula>|<cask> provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc.

  2. Research available sources to select a URL. Try removing the file name from stable/url, to see if this is a directory listing page. If that doesn’t work, try to find a page that links to the file (e.g. a download page). If it’s not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask.

  3. Create a regex, if necessary. If the check works without a regex and wouldn’t benefit from having one, it’s usually fine to omit it. More information on creating regexes can be found in the regex guidelines section.

General guidelines

URL guidelines

Regex guidelines

The livecheck block regex restricts matches to a subset of the fetched content and uses a capture group around the version text.

Example livecheck blocks

The following examples cover a number of patterns that you may encounter. These are intended to be representative samples and can be easily adapted.

When in doubt, start with one of these examples instead of copy-pasting a livecheck block from a random formula/cask.

File names

When matching the version from a file name on an HTML page, we often restrict matching to href attributes. href=.*? will match the opening delimiter (", ') as well as any part of the URL before the file name.

livecheck do
  url "https://www.example.com/downloads/"
  regex(/href=.*?example[._-]v?(\d+(?:\.\d+)+)\.t/i)
end

We sometimes make this more explicit to exclude unwanted matches. URLs with a preceding path can use href=.*?/ and others can use href=["']?. For example, this is necessary when the page also contains unwanted files with a longer prefix (another-example-1.2.tar.gz).

Version directories

When checking a directory listing page, sometimes files are separated into version directories (e.g. 1.2.3/). In this case, we must identify versions from the directory names.

livecheck do
  url "https://www.example.com/releases/example/"
  regex(%r{href=["']?v?(\d+(?:\.\d+)+)/?["' >]}i)
end

Git tags

When the stable URL uses the Git strategy, the following example will only match tags like 1.2/v1.2, etc.

livecheck do
  url :stable
  regex(/^v?(\d+(?:\.\d+)+)$/i)
end

If tags include the software name as a prefix (e.g. example-1.2.3), it’s easy to modify the regex accordingly: /^example[._-]v?(\d+(?:\.\d+)+)$/i

Referenced formula/cask

A formula/cask can use the same check as another by using formula or cask.

livecheck do
  formula "another-formula"
end

The referenced formula/cask should be in the same tap, as a reference to a formula/cask from another tap will generate an error if the user doesn’t already have it tapped.

strategy blocks

If the upstream version format needs to be manipulated to match the formula/cask format, a strategy block can be used instead of a regex.

PageMatch strategy block

In the example below, we’re converting a date format like 2020-01-01 into 20200101.

livecheck do
  url :homepage
  strategy :page_match do |page|
    page.scan(/href=.*?example[._-]v?(\d{4}-\d{2}-\d{2})\.t/i)
        .map { |match| match&.first&.gsub(/\D/, "") }
  end
end

The PageMatch strategy block style seen here also applies to any strategy that uses PageMatch internally.

Git strategy block

A strategy block for Git is a bit different, as the block receives an array of tag strings instead of a page content string. Similar to the PageMatch example, this is converting tags with a date format like 2020-01-01 into 20200101.

livecheck do
  url :stable
  strategy :git do |tags|
    tags.map { |tag| tag[/^(\d{4}-\d{2}-\d{2})$/i, 1]&.gsub(/\D/, "") }.compact
  end
end

Sparkle strategy block

A strategy block for Sparkle receives an item which has methods for the short_version, version, url and title.

The default pattern for the Sparkle strategy is "#{item.short_version},#{item.version}" if both are set. In the example below, the url also includes a download ID which is needed:

livecheck do
  url "https://www.example.com/example.xml"
  strategy :sparkle do |item|
    "#{item.short_version},#{item.version}:#{item.url[%r{/(\d+)/[^/]+\.zip}i, 1]}"
  end
end

skip

Livecheck automatically skips some formulae/casks for a number of reasons (deprecated, disabled, discontinued, etc.). However, on rare occasions we need to use a livecheck block to do a manual skip. The skip method takes a string containing a very brief reason for skipping.

livecheck do
  skip "No version information available"
end
Fork me on GitHub