Merge pull request #12121 from EricFromCanada/restore-repology

bump: add `--start-with` option to retrieve a subset of results
This commit is contained in:
Mike McQuaid 2021-10-20 09:02:48 +01:00 committed by GitHub
commit b77b08cf00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 87 additions and 46 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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)

View File

@ -437,6 +437,7 @@ _brew_bump() {
--limit
--no-pull-requests
--quiet
--start-with
--verbose
"
return

View File

@ -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)'

View File

@ -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]' \

View File

@ -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`*

View File

@ -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\.
.