mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Merge pull request #12121 from EricFromCanada/restore-repology
bump: add `--start-with` option to retrieve a subset of results
This commit is contained in:
commit
b77b08cf00
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@ -309,6 +309,8 @@ jobs:
|
||||
brew sh -c "svn --homebrew=print-path"
|
||||
which svn
|
||||
which svnadmin
|
||||
brew install curl
|
||||
which curl
|
||||
|
||||
- name: Create parallel test log directory
|
||||
run: mkdir tests
|
||||
|
@ -192,6 +192,9 @@ module Homebrew
|
||||
sig { returns(T.nilable(String)) }
|
||||
def limit; end
|
||||
|
||||
sig { returns(T.nilable(String)) }
|
||||
def start_with; end
|
||||
|
||||
sig { returns(T.nilable(String)) }
|
||||
def message; end
|
||||
|
||||
|
@ -13,8 +13,9 @@ module Homebrew
|
||||
def bump_args
|
||||
Homebrew::CLI::Parser.new do
|
||||
description <<~EOS
|
||||
Display out-of-date brew formulae and the latest version available.
|
||||
Also displays whether a pull request has been opened with the URL.
|
||||
Display out-of-date brew formulae and the latest version available. If the
|
||||
returned current and livecheck versions differ or when querying specific
|
||||
formulae, also displays whether a pull request has been opened with the URL.
|
||||
EOS
|
||||
switch "--full-name",
|
||||
description: "Print formulae/casks with fully-qualified names."
|
||||
@ -26,6 +27,8 @@ module Homebrew
|
||||
description: "Check only casks."
|
||||
flag "--limit=",
|
||||
description: "Limit number of package results returned."
|
||||
flag "--start-with=",
|
||||
description: "Letter or word that the list of package results should alphabetically follow."
|
||||
|
||||
conflicts "--cask", "--formula"
|
||||
|
||||
@ -53,6 +56,18 @@ module Homebrew
|
||||
|
||||
limit = args.limit.to_i if args.limit.present?
|
||||
|
||||
unless quiet_system(HOMEBREW_SHIMS_PATH/"shared/curl", "--tlsv1.3", "--head", "https://repology.org/")
|
||||
begin
|
||||
brewed_curl = Formula["curl"]
|
||||
unless brewed_curl.any_version_installed?
|
||||
ohai "Installing `curl` for Repology queries..."
|
||||
safe_system HOMEBREW_BREW_FILE, "install", "--formula", brewed_curl.full_name
|
||||
end
|
||||
rescue FormulaUnavailableError
|
||||
opoo "A `curl` with TLS 1.3 support is required for Repology queries"
|
||||
end
|
||||
end
|
||||
|
||||
if formulae_and_casks.present?
|
||||
Livecheck.load_other_tap_strategies(formulae_and_casks)
|
||||
|
||||
@ -104,21 +119,25 @@ module Homebrew
|
||||
api_response = {}
|
||||
unless args.cask?
|
||||
api_response[:formulae] =
|
||||
Repology.parse_api_response(limit, repository: Repology::HOMEBREW_CORE)
|
||||
Repology.parse_api_response(limit, args.start_with, repository: Repology::HOMEBREW_CORE)
|
||||
end
|
||||
unless args.formula?
|
||||
api_response[:casks] =
|
||||
Repology.parse_api_response(limit, repository: Repology::HOMEBREW_CASK)
|
||||
Repology.parse_api_response(limit, args.start_with, repository: Repology::HOMEBREW_CASK)
|
||||
end
|
||||
|
||||
api_response.each do |package_type, outdated_packages|
|
||||
api_response.each_with_index do |(package_type, outdated_packages), idx|
|
||||
repository = if package_type == :formulae
|
||||
Repology::HOMEBREW_CORE
|
||||
else
|
||||
Repology::HOMEBREW_CASK
|
||||
end
|
||||
puts if idx.positive?
|
||||
oh1 package_type.capitalize if api_response.size > 1
|
||||
|
||||
outdated_packages.each_with_index do |(_name, repositories), i|
|
||||
break if limit && i >= limit
|
||||
|
||||
homebrew_repo = repositories.find do |repo|
|
||||
repo["repo"] == repository
|
||||
end
|
||||
@ -143,8 +162,6 @@ module Homebrew
|
||||
|
||||
puts if i.positive?
|
||||
retrieve_and_display_info(formula_or_cask, name, repositories, args: args, ambiguous_cask: ambiguous_cask)
|
||||
|
||||
break if limit && i >= limit
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -180,7 +197,7 @@ module Homebrew
|
||||
|
||||
return "unable to get versions" if latest.blank?
|
||||
|
||||
latest.to_s
|
||||
Version.new(latest)
|
||||
rescue => e
|
||||
"error: #{e}"
|
||||
end
|
||||
@ -211,22 +228,24 @@ module Homebrew
|
||||
end
|
||||
|
||||
livecheck_latest = livecheck_result(formula_or_cask)
|
||||
pull_requests = retrieve_pull_requests(formula_or_cask, name) unless args.no_pull_requests?
|
||||
pull_requests = if !args.no_pull_requests? && (args.named.present? || livecheck_latest != current_version)
|
||||
retrieve_pull_requests(formula_or_cask, name)
|
||||
end
|
||||
|
||||
name += " (cask)" if ambiguous_cask
|
||||
title = if current_version == repology_latest &&
|
||||
current_version == livecheck_latest
|
||||
"#{name} is up to date!"
|
||||
"#{name} #{Tty.green}is up to date!#{Tty.reset}"
|
||||
else
|
||||
name
|
||||
end
|
||||
|
||||
ohai title
|
||||
puts <<~EOS
|
||||
Current formula version: #{current_version}
|
||||
Latest Repology version: #{repology_latest}
|
||||
Current #{formula_or_cask.is_a?(Formula) ? "formula version:" : "cask version: "} #{current_version}
|
||||
Latest livecheck version: #{livecheck_latest}
|
||||
Latest Repology version: #{repology_latest}
|
||||
EOS
|
||||
puts "Open pull requests: #{pull_requests}" unless args.no_pull_requests?
|
||||
puts "Open pull requests: #{pull_requests}" unless pull_requests.nil?
|
||||
end
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ require "cmd/shared_examples/args_parse"
|
||||
describe "brew bump" do
|
||||
it_behaves_like "parseable arguments"
|
||||
|
||||
describe "formula", :integration_test, :needs_network do
|
||||
describe "formula", :integration_test, :needs_network, :needs_tls13 do
|
||||
it "returns data for single valid specified formula" do
|
||||
install_test_formula "testball"
|
||||
|
||||
|
@ -169,6 +169,15 @@ RSpec.configure do |config|
|
||||
.append(svnadmin.dirname)
|
||||
end
|
||||
|
||||
config.before(:each, :needs_tls13) do
|
||||
begin
|
||||
curl = Utils::Curl.curl_executable(use_homebrew_curl: OS.mac?)
|
||||
rescue FormulaUnavailableError
|
||||
skip "curl formula not available"
|
||||
end
|
||||
skip "Requires curl with TLS 1.3 support." unless quiet_system curl, "--tlsv1.3", "--head", "https://brew.sh/"
|
||||
end
|
||||
|
||||
config.before(:each, :needs_unzip) do
|
||||
skip "Unzip is not installed." unless which("unzip")
|
||||
end
|
||||
|
@ -4,7 +4,7 @@
|
||||
require "utils/repology"
|
||||
|
||||
describe Repology do
|
||||
describe "single_package_query", :needs_network do
|
||||
describe "single_package_query", :needs_network, :needs_tls13 do
|
||||
it "returns nil for non-existent package" do
|
||||
response = described_class.single_package_query("invalidName", repository: "homebrew")
|
||||
|
||||
@ -14,15 +14,12 @@ describe Repology do
|
||||
it "returns a hash for existing package" do
|
||||
response = described_class.single_package_query("openclonk", repository: "homebrew")
|
||||
|
||||
expect(response).to be_nil
|
||||
# TODO: uncomment (and remove line above) when we have a fix for Repology
|
||||
# `curl` issues
|
||||
# expect(response).not_to be_nil
|
||||
# expect(response).to be_a(Hash)
|
||||
expect(response).not_to be_nil
|
||||
expect(response).to be_a(Hash)
|
||||
end
|
||||
end
|
||||
|
||||
describe "parse_api_response", :needs_network do
|
||||
describe "parse_api_response", :needs_network, :needs_tls13 do
|
||||
it "returns a hash of data" do
|
||||
limit = 1
|
||||
response = described_class.parse_api_response(limit, repository: "homebrew")
|
||||
|
@ -357,6 +357,12 @@ module Utils
|
||||
file.unlink
|
||||
end
|
||||
|
||||
def homebrew_curl_available?
|
||||
Formulary.factory("curl").present?
|
||||
rescue FormulaUnavailableError
|
||||
false
|
||||
end
|
||||
|
||||
def http_status_ok?(status)
|
||||
(100..299).cover?(status.to_i)
|
||||
end
|
||||
|
@ -15,33 +15,29 @@ module Repology
|
||||
MAX_PAGINATION = 15
|
||||
private_constant :MAX_PAGINATION
|
||||
|
||||
def query_api(_last_package_in_response = "", repository:)
|
||||
{}
|
||||
# TODO: uncomment (and remove lines above) when we have a fix for Repology
|
||||
# `curl` issues
|
||||
# last_package_in_response += "/" if last_package_in_response.present?
|
||||
# url = "https://repology.org/api/v1/projects/#{last_package_in_response}?inrepo=#{repository}&outdated=1"
|
||||
def query_api(last_package_in_response = "", repository:)
|
||||
last_package_in_response += "/" if last_package_in_response.present?
|
||||
url = "https://repology.org/api/v1/projects/#{last_package_in_response}?inrepo=#{repository}&outdated=1"
|
||||
|
||||
# output, _errors, _status = curl_output(url.to_s)
|
||||
# JSON.parse(output)
|
||||
output, _errors, _status = curl_output(url.to_s, use_homebrew_curl: OS.mac?)
|
||||
JSON.parse(output)
|
||||
end
|
||||
|
||||
def single_package_query(name, repository:)
|
||||
# TODO: uncomment when we have a fix for Repology `curl` issues
|
||||
# url = "https://repology.org/tools/project-by?repo=#{repository}&" \
|
||||
# "name_type=srcname&target_page=api_v1_project&name=#{name}"
|
||||
url = "https://repology.org/tools/project-by?repo=#{repository}&" \
|
||||
"name_type=srcname&target_page=api_v1_project&name=#{name}"
|
||||
|
||||
# output, _errors, _status = curl_output("--location", url.to_s)
|
||||
output, _errors, _status = curl_output("--location", url.to_s, use_homebrew_curl: OS.mac?)
|
||||
|
||||
# begin
|
||||
# data = JSON.parse(output)
|
||||
# { name => data }
|
||||
# rescue
|
||||
# nil
|
||||
# end
|
||||
begin
|
||||
data = JSON.parse(output)
|
||||
{ name => data }
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def parse_api_response(limit = nil, repository:)
|
||||
def parse_api_response(limit = nil, last_package = "", repository:)
|
||||
package_term = case repository
|
||||
when HOMEBREW_CORE
|
||||
"formula"
|
||||
@ -55,14 +51,13 @@ module Repology
|
||||
|
||||
page_no = 1
|
||||
outdated_packages = {}
|
||||
last_package = ""
|
||||
|
||||
while page_no <= MAX_PAGINATION
|
||||
odebug "Paginating Repology API page: #{page_no}"
|
||||
|
||||
response = query_api(last_package, repository: repository)
|
||||
outdated_packages.merge!(response)
|
||||
last_package = response.keys.last
|
||||
last_package = response.keys.max
|
||||
|
||||
page_no += 1
|
||||
break if (limit && outdated_packages.size >= limit) || response.size <= 1
|
||||
@ -71,7 +66,7 @@ module Repology
|
||||
puts "#{outdated_packages.size} outdated #{package_term.pluralize(outdated_packages.size)} found"
|
||||
puts
|
||||
|
||||
outdated_packages
|
||||
outdated_packages.sort.to_h
|
||||
end
|
||||
|
||||
def latest_version(repositories)
|
||||
|
@ -437,6 +437,7 @@ _brew_bump() {
|
||||
--limit
|
||||
--no-pull-requests
|
||||
--quiet
|
||||
--start-with
|
||||
--verbose
|
||||
"
|
||||
return
|
||||
|
@ -389,6 +389,7 @@ __fish_brew_complete_arg 'bump' -l help -d 'Show this message'
|
||||
__fish_brew_complete_arg 'bump' -l limit -d 'Limit number of package results returned'
|
||||
__fish_brew_complete_arg 'bump' -l no-pull-requests -d 'Do not retrieve pull requests from GitHub'
|
||||
__fish_brew_complete_arg 'bump' -l quiet -d 'Make some output more quiet'
|
||||
__fish_brew_complete_arg 'bump' -l start-with -d 'Letter or word that the list of package results should alphabetically follow'
|
||||
__fish_brew_complete_arg 'bump' -l verbose -d 'Make some output more verbose'
|
||||
__fish_brew_complete_arg 'bump; and not __fish_seen_argument -l cask -l casks' -a '(__fish_brew_suggest_formulae_all)'
|
||||
__fish_brew_complete_arg 'bump; and not __fish_seen_argument -l formula -l formulae' -a '(__fish_brew_suggest_casks_all)'
|
||||
|
@ -479,6 +479,7 @@ _brew_bump() {
|
||||
'--limit[Limit number of package results returned]' \
|
||||
'--no-pull-requests[Do not retrieve pull requests from GitHub]' \
|
||||
'--quiet[Make some output more quiet]' \
|
||||
'--start-with[Letter or word that the list of package results should alphabetically follow]' \
|
||||
'--verbose[Make some output more verbose]' \
|
||||
- formula \
|
||||
'(--cask)--formula[Check only formulae]' \
|
||||
|
@ -901,8 +901,9 @@ value, while `--no-rebuild` will remove it.
|
||||
|
||||
### `bump` [*`options`*] [*`formula`*|*`cask`* ...]
|
||||
|
||||
Display out-of-date brew formulae and the latest version available.
|
||||
Also displays whether a pull request has been opened with the URL.
|
||||
Display out-of-date brew formulae and the latest version available. If the
|
||||
returned current and livecheck versions differ or when querying specific
|
||||
formulae, also displays whether a pull request has been opened with the URL.
|
||||
|
||||
* `--full-name`:
|
||||
Print formulae/casks with fully-qualified names.
|
||||
@ -914,6 +915,8 @@ Also displays whether a pull request has been opened with the URL.
|
||||
Check only casks.
|
||||
* `--limit`:
|
||||
Limit number of package results returned.
|
||||
* `--start-with`:
|
||||
Letter or word that the list of package results should alphabetically follow.
|
||||
|
||||
### `bump-cask-pr` [*`options`*] *`cask`*
|
||||
|
||||
|
@ -1265,7 +1265,7 @@ Use the specified \fIURL\fR as the root of the bottle\'s URL instead of Homebrew
|
||||
Use the specified download strategy class for downloading the bottle\'s URL instead of Homebrew\'s default\.
|
||||
.
|
||||
.SS "\fBbump\fR [\fIoptions\fR] [\fIformula\fR|\fIcask\fR \.\.\.]"
|
||||
Display out\-of\-date brew formulae and the latest version available\. Also displays whether a pull request has been opened with the URL\.
|
||||
Display out\-of\-date brew formulae and the latest version available\. If the returned current and livecheck versions differ or when querying specific formulae, also displays whether a pull request has been opened with the URL\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-full\-name\fR
|
||||
@ -1287,6 +1287,10 @@ Check only casks\.
|
||||
\fB\-\-limit\fR
|
||||
Limit number of package results returned\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-start\-with\fR
|
||||
Letter or word that the list of package results should alphabetically follow\.
|
||||
.
|
||||
.SS "\fBbump\-cask\-pr\fR [\fIoptions\fR] \fIcask\fR"
|
||||
Create a pull request to update \fIcask\fR with a new version\.
|
||||
.
|
||||
|
Loading…
x
Reference in New Issue
Block a user