brew livecheck
brew livecheck
指令透過檢查上游來尋找公式或 cask 軟體的最新版本。Livecheck 具有 策略,可從各種來源(例如 Git 儲存庫、網站等)識別版本。
當 livecheck 未收到如何檢查上游版本的指示時,它會預設執行下列動作
stable
、head
和 homepage
URL(資源僅使用其 url
)。對於 cask:按順序收集 url
和 homepage
URL。有時需要覆寫此預設行為才能建立運作良好的檢查。如果來源未提供最新版本,我們需要檢查其他來源。如果 livecheck 無法正確比對版本文字,我們需要提供適當的正規表示法或 strategy
區塊。
這可透過將 livecheck
區塊新增至公式/cask/資源來達成。如需有關可用方法的更多資訊,請參閱 Livecheck
類別文件。
使用偵錯輸出了解情況。brew livecheck --debug <formula>|<cask>
提供有關 livecheck 嘗試的 URL、任何適用的策略、比對版本等資訊。
研究可用來源以選擇 URL。嘗試從 stable
/url
中移除檔案名稱,看看它是否提供目錄清單頁面。如果這不起作用,請嘗試尋找連結至檔案的頁面(例如下載頁面)。如果無法在網站上找到最新版本,請嘗試檢查公式/cask 中的其他來源。必要時,請在公式/cask 外搜尋其他來源。
必要時建立正規表示法。如果檢查在沒有正規表示法的情況下運作,而且不會從中受益,則通常可以省略它。有關建立正規表示法的更多資訊,請參閱 正規表示法指南 部分。
只有在必要時才使用 strategy
。例如,如果 livecheck 已對 URL 使用 Git
策略,則不需要使用 strategy :git
。但是,如果 Git
適用於 URL,但我們需要使用 PageMatch
,則必須指定 strategy :page_match
。
僅在必要且正確的情況下使用 GithubLatest
和 GithubReleases
策略。GitHub 速率限制 API 要求,因此我們僅在 Git
不夠用或不適當時使用這些策略。僅當上游儲存庫有適合版本的「最新」版本,且公式/cask 使用版本資產或 Git
策略無法正確識別最新版本時,才應使用 GithubLatest
。僅當上游儲存庫使用版本,且 Git
和 GithubLatest
策略都不合適時,才應使用 GithubReleases
。
livecheck
區塊中需要 url
。這可以是 URL 字串(例如 "https://www.example.com/downloads/"
),或公式/cask URL 符號(即 :stable
、:url
、:head
、:homepage
)。此規則的例外情況是僅使用 skip
的 livecheck
區塊。
盡可能在與穩定檔案相同的位置檢查版本.
盡可能避免檢查分頁版本頁面。例如,我們通常避免檢查 GitHub 專案的 release
頁面,因為最新穩定版本可能會因預發行版本而從第一頁推擠出去。在這種情況下,使用 Git
策略會更可靠,它會擷取儲存庫中的所有標籤。
livecheck
區塊 regex 將比對限制在擷取內容的子集,並在版本文字周圍使用擷取群組。
只要有可能,都應讓正規表示式不區分大小寫,方法是在結尾加上 i
(例如 /.../i
或 %r{...}i
)。這能提升可靠性,因為正規表示式會處理字母大小寫的變更,而無需修改。
正規表示式應只在版本文字周圍使用擷取群組。例如,在 /href=.*?example-v?(\d+(?:\.\d+)+)(?:-src)?\.t/i
中,我們只在版本文字周圍使用擷取群組(比對類似 1.2
、1.2.3
等的版本),而其他地方則使用非擷取群組(例如 (?:-src)?
)。
錨定正規表示式的開頭/結尾,以限制範圍。例如,在 HTML 頁面上,我們經常在 href
屬性 URL 中比對檔案名稱或版本目錄(例如 /href=.*?example[._-]v?(\d+(?:\.\d+)+)\.zip/i
)。一般來說,限制範圍有助於排除不需要的比對結果。
避免使用 .*
或 .+
等泛用的萬用字元,而改用非貪婪或符合情境的字元。例如,若要比對 HTML 屬性範圍內的字元,請使用 [^"' >]+?
。
在檔案名稱中軟體名稱和版本之間的句點/底線/連字號,請使用 [._-]
取代。對於名為 example-1.2.3.tar.gz
的檔案,如果上游檔案名稱格式變更為 example_1.2.3.tar.gz
或 example.1.2.3.tar.gz
,example[._-]v?(\d+(?:\.\d+)+)\.t
將會持續比對。
請使用 \.t
取代 \.tgz
、\.tar\.gz
等。tarball 有許多不同的檔案副檔名(例如 .tar.bz2
、tbz2
、.tar.gz
、.tgz
、.tar.xz
、.txz
等),而上游來源可能會隨著時間從一種壓縮格式切換到另一種。 \.t
透過比對以 t
開頭的現有和未來格式,來避免此問題。在 tarball 之外,我們在正規表示式中使用完整的檔案副檔名,例如 \.zip
、\.jar
等。
livecheck
區塊以下範例涵蓋您可能會遇到的許多模式。這些範例旨在成為具代表性的範例,而且可以輕鬆調整。
如果您有疑問,請從這些範例中挑選一個開始,而不是從隨機公式/cask 複製貼上 livecheck
區塊。
當從 HTML 頁面上的檔案名稱比對版本時,我們通常會將比對限制在 href
屬性。 href=.*?
會比對開啟分隔符號 ("
、'
) 以及檔案名稱之前的任何 URL 部分。
livecheck do
url "https://www.example.com/downloads/"
regex(/href=.*?example[._-]v?(\d+(?:\.\d+)+)\.t/i)
end
我們有時會更明確地排除不需要的比對。有前置路徑的 URL 可以使用 href=.*?/
,其他 URL 則可以使用 href=["']?
。例如,當頁面中也包含前綴較長的不要的檔案(another-example-1.2.tar.gz
)時,這是有必要的。
當檢查目錄清單頁面時,檔案有時會分隔到版本目錄中(例如 1.2.3/
)。在這種情況下,我們必須從目錄名稱中辨識版本。
livecheck do
url "https://www.example.com/releases/example/"
regex(%r{href=["']?v?(\d+(?:\.\d+)+)/?["' >]}i)
end
當 stable
URL 使用 Git
策略時,以下範例只會比對 1.2
/v1.2
等標籤。
livecheck do
url :stable
regex(/^v?(\d+(?:\.\d+)+)$/i)
end
如果標籤包含軟體名稱作為前綴(例如 example-1.2.3
),可以輕鬆地修改正規表示式:/^example[._-]v?(\d+(?:\.\d+)+)$/i
公式/cask 可以使用 formula
或 cask
來使用與另一個相同的檢查。
livecheck do
formula "another-formula"
end
參考的公式/cask 應該在同一個 tap 中,因為如果使用者尚未 tap 另一個 tap 中的公式/cask,參考會產生錯誤。
strategy
區塊如果上游版本格式需要經過處理才能與公式/cask 格式相符,可以使用 strategy
區塊,而不是 regex
。
PageMatch
strategy
區塊以下是一個基本範例,從頁面中擷取一個簡單的版本
livecheck do
url "https://example.org/my-app/download"
regex(%r{href=.*?/MyApp-(\d+(?:\.\d+)*)\.zip}i)
strategy :page_match
end
可以透過指定區塊來處理更複雜的版本。
livecheck do
url "https://example.org/my-app/download"
regex(%r{href=.*?/(\d+)/MyApp-(\d+(?:\.\d+)*)\.zip}i)
strategy :page_match do |page, regex|
match = page.match(regex)
next if match.blank?
"#{match[2]},#{match[1]}"
end
end
在以下範例中,我們會掃描首頁的內容,尋找 2020-01-01
等日期格式,並將其轉換成 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
這裡看到的 PageMatch
strategy
區塊樣式也適用於任何使用 PageMatch
的特定於網站的策略。
HeaderMatch
策略
區塊HeaderMatch
的 策略
區塊會嘗試從檔案名稱(在 Content-Disposition
標頭中)和最終 URL(在 Location
標頭中)解析版本。如果無法解析,則可以指定 regex
。
livecheck do
url "https://example.org/my-app/download/latest"
regex(/MyApp-(\d+(?:\.\d+)*)\.zip/i)
strategy :header_match
end
如果版本取決於多個標頭欄位,則可以指定一個區塊。
livecheck do
url "https://example.org/my-app/download/latest"
strategy :header_match do |headers|
v = headers["content-disposition"][/MyApp-(\d+(?:\.\d+)*)\.zip/i, 1]
id = headers["location"][%r{/(\d+)/download$}i, 1]
next if v.blank? || id.blank?
"#{v},#{id}"
end
end
Git
策略
區塊Git
的 策略
區塊有點不同,因為區塊接收標籤字串陣列,而不是頁面內容字串。類似於 PageMatch
範例,這會將日期格式為 2020-01-01
的標籤轉換為 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
GithubLatest
策略
區塊GithubLatest
的 策略
區塊會接收 GitHub API 解析的 JSON 資料,以取得儲存庫的「最新」版本,以及一個 regex。如果在 livecheck
區塊中未提供 regex,則會將策略的預設 regex 傳遞到 策略
區塊中。
預設情況下,策略會比對版本文字在版本標籤或標題中,但可以使用 策略
區塊來檢查版本 JSON 中的任何欄位。下列 策略
區塊中的邏輯類似於預設行為,但僅檢查版本標籤,以示範為目的
livecheck do
url :stable
regex(/^example[._-]v?(\d+(?:\.\d+)+)$/i)
strategy :github_latest do |json, regex|
match = json["tag_name"]&.match(regex)
next if match.blank?
match[1]
end
end
您可以在相關的 GitHub REST API 文件 中找到更多關於此 API 端點回應 JSON 的資訊。
GithubReleases
策略
區塊GithubReleases
的 策略
區塊會接收 GitHub API 解析的 JSON 資料,以取得儲存庫的最新版本,以及一個 regex。如果在 livecheck
區塊中未提供 regex,則會將策略的預設 regex 傳遞到 策略
區塊中。
預設情況下,策略會比對每個版本標籤或標題中的版本文字,但可以使用 strategy
區塊來檢查版本 JSON 中的任何欄位。下列 strategy
區塊中的邏輯與預設行為類似,但僅為了示範目的而檢查版本標籤
livecheck do
url :stable
regex(/^example[._-]v?(\d+(?:\.\d+)+)$/i)
strategy :github_releases do |json, regex|
json.map do |release|
next if release["draft"] || release["prerelease"]
match = release["tag_name"]&.match(regex)
next if match.blank?
match[1]
end
end
end
您可以在相關的 GitHub REST API 文件 中找到此 API 端點的回應 JSON 的更多資訊。
Crate
strategy
區塊針對 Crate
的 strategy
區塊會從登錄 API 的 versions
端點接收已剖析的 JSON 資料,以及提供的或預設的策略正規表示式。預設情況下,策略會使用下列邏輯,因此這個 strategy
區塊可能是修改後方法的良好起點
livecheck do
url :stable
strategy :crate do |json, regex|
json["versions"]&.map do |version|
next if version["yanked"]
next unless (match = version["num"]&.match(regex))
match[1]
end
end
end
ElectronBuilder
strategy
區塊針對 ElectronBuilder
的 strategy
區塊會擷取 URL 中的內容,並將其剖析為 YAML 格式的 electron-builder appcast。它用於使用 Electron 架構建置的 macOS 應用程式的 cask。
livecheck do
url "https://example.org/my-app/latest-mac.yml"
strategy :electron_builder
end
Json
strategy
區塊針對 Json
的 strategy
區塊會接收已剖析的 JSON 資料,以及如果提供的正規表示式。例如,如果我們有一個包含一組物件的物件,其中包含 version
字串,我們可以只選取符合正規表示式的成員,並將相關的版本文字隔離如下
livecheck do
url "https://www.example.com/example.json"
regex(/^v?(\d+(?:\.\d+)+)$/i)
strategy :json do |json, regex|
json["versions"].select { |item| item["version"]&.match?(regex) }
.map { |item| item["version"][regex, 1] }
end
end
Sparkle
strategy
區塊針對 Sparkle
的 strategy
區塊會接收一個 item
,其中有 version
、short_version
、nice_version
、url
、channel
和 title
的方法。它預期有一個 XML 饋送的 URL,提供版本資訊給使用 Sparkle 架構進行自我更新的 macOS 應用程式。這個 URL 可以從應用程式套件中找到,作為 Contents/Info.plist
中的 SUFeedURL
屬性,或使用 find-appcast
腳本。使用下列方式執行
"$(brew --repository homebrew/cask)/developer/bin/find-appcast" '/path/to/application.app'
針對 Sparkle
策略的預設模式是從 sparkle:shortVersionString
和 sparkle:version
產生 "#{item.short_version},#{item.version}"
,如果兩個都設定的話。在下列範例中,url
也包含一個需要的下載 ID
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
若要只使用一個,請指定 &:version
、&:short_version
或 &:nice_version
livecheck do
url "https://www.example.com/example.xml"
strategy :sparkle, &:short_version
end
Xml
策略
區塊Xml
的 策略
區塊會接收一個 REXML::Document
物件,以及一個正規表示式(如果提供的話)。例如,如果 XML 包含一個 versions
元素,其中嵌入了 version
元素,而其內部文字包含版本字串,我們可以使用正規表示式將其萃取出來,如下所示
livecheck do
url "https://www.example.com/example.xml"
regex(/v?(\d+(?:\.\d+)+)/i)
strategy :xml do |xml, regex|
xml.get_elements("versions//version").map { |item| item.text[regex, 1] }
end
end
有關如何使用 REXML::Document
物件的詳細資訊,請參閱 REXML::Document
和 REXML::Element
文件。
Yaml
策略
區塊Yaml
的 策略
區塊會接收已剖析的 YAML 資料,以及一個正規表示式(如果提供的話)。借用 Json
範例,如果我們有一個包含一個物件陣列的物件,而該陣列中的物件具有 version
字串,我們可以只選取符合正規表示式的成員,並將相關版本文字分離出來,如下所示
livecheck do
url "https://www.example.com/example.yaml"
regex(/^v?(\d+(?:\.\d+)+)$/i)
strategy :yaml do |yaml, regex|
yaml["versions"].select { |item| item["version"]&.match?(regex) }
.map { |item| item["version"][regex, 1] }
end
end
ExtractPlist
策略
區塊如果網路上沒有任何方法可以查看 macOS 套件的哪個版本是目前的,那麼作為最後的手段,:extract_plist
策略會讓 brew livecheck
下載成品,並從包含的 .plist
檔案中擷取其版本字串。
livecheck do
url :url
strategy :extract_plist
end
一個 strategy
區塊用於 ExtractPlist
接收一個雜湊,其中包含每個已找到的套件識別碼的鍵,以及具有每個 version
和 short_version
方法的 item
。
livecheck do
url :url
strategy :extract_plist do |items|
items["com.example.MyApp"].short_version
end
end
略過
Livecheck 會自動略過一些公式/木桶,原因有很多(已棄用、已停用等)。但是,在極少數情況下,我們需要使用 livecheck
區塊進行手動略過。 skip
方法會取得一個包含略過原因的簡短字串。
livecheck do
skip "No version information available"
end