Merge branch 'mlh-outdated-packages' of github.com:MLH-Fellowship/brew into mlh-outdated-packages
This commit is contained in:
commit
af117fab25
@ -314,7 +314,7 @@ module Homebrew
|
||||
|
||||
new_formula_version = formula_version(formula, requested_spec, new_contents)
|
||||
|
||||
check_for_duplicate_pull_requests(formula, tap_full_name, new_formula_version.to_s)
|
||||
GitHub.check_for_duplicate_pull_requests(formula, tap_full_name, new_formula_version.to_s)
|
||||
|
||||
if !new_mirrors && !formula_spec.mirrors.empty?
|
||||
if args.force?
|
||||
@ -469,41 +469,6 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def fetch_pull_requests(query, tap_full_name, state: nil)
|
||||
GitHub.issues_for_formula(query, tap_full_name: tap_full_name, state: state).select do |pr|
|
||||
pr["html_url"].include?("/pull/") &&
|
||||
/(^|\s)#{Regexp.quote(query)}(:|\s|$)/i =~ pr["title"]
|
||||
end
|
||||
rescue GitHub::RateLimitExceededError => e
|
||||
opoo e.message
|
||||
[]
|
||||
end
|
||||
|
||||
def check_for_duplicate_pull_requests(formula, tap_full_name, version)
|
||||
# check for open requests
|
||||
pull_requests = fetch_pull_requests(formula.name, tap_full_name, state: "open")
|
||||
|
||||
# if we haven't already found open requests, try for an exact match across all requests
|
||||
pull_requests = fetch_pull_requests("#{formula.name} #{version}", tap_full_name) if pull_requests.blank?
|
||||
return if pull_requests.blank?
|
||||
|
||||
duplicates_message = <<~EOS
|
||||
These pull requests may be duplicates:
|
||||
#{pull_requests.map { |pr| "#{pr["title"]} #{pr["html_url"]}" }.join("\n")}
|
||||
EOS
|
||||
error_message = "Duplicate PRs should not be opened. Use --force to override this error."
|
||||
if args.force? && !args.quiet?
|
||||
opoo duplicates_message
|
||||
elsif !args.force? && args.quiet?
|
||||
odie error_message
|
||||
elsif !args.force?
|
||||
odie <<~EOS
|
||||
#{duplicates_message.chomp}
|
||||
#{error_message}
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
def alias_update_pair(formula, new_formula_version)
|
||||
versioned_alias = formula.aliases.grep(/^.*@\d+(\.\d+)?$/).first
|
||||
return if versioned_alias.nil?
|
||||
|
||||
108
Library/Homebrew/dev-cmd/bump.rb
Normal file
108
Library/Homebrew/dev-cmd/bump.rb
Normal file
@ -0,0 +1,108 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cli/parser"
|
||||
|
||||
module Homebrew
|
||||
module_function
|
||||
|
||||
def bump_args
|
||||
Homebrew::CLI::Parser.new do
|
||||
usage_banner <<~EOS
|
||||
`bump`
|
||||
|
||||
Display out-of-date brew formulae, the latest version available, and whether a pull request has been opened.
|
||||
EOS
|
||||
switch :verbose
|
||||
switch :debug
|
||||
end
|
||||
end
|
||||
|
||||
def bump
|
||||
bump_args.parse
|
||||
|
||||
outdated_repology_packages = Repology.parse_api_response
|
||||
outdated_packages = validate_and_format_packages(outdated_repology_packages)
|
||||
|
||||
display(outdated_packages)
|
||||
end
|
||||
|
||||
def validate_and_format_packages(outdated_repology_packages)
|
||||
ohai "Verifying outdated repology packages as Homebrew formulae"
|
||||
|
||||
packages = {}
|
||||
outdated_repology_packages.each do |_name, repositories|
|
||||
# identify homebrew repo
|
||||
repology_homebrew_repo = repositories.find do |repo|
|
||||
repo["repo"] == "homebrew"
|
||||
end
|
||||
|
||||
next if repology_homebrew_repo.blank?
|
||||
|
||||
latest_version = repositories.find { |repo| repo["status"] == "newest" }["version"]
|
||||
|
||||
packages[repology_homebrew_repo["srcname"]] = format_package(repology_homebrew_repo["srcname"], latest_version)
|
||||
end
|
||||
packages
|
||||
end
|
||||
|
||||
def format_package(package_name, latest_version)
|
||||
formula = get_formula_details(package_name)
|
||||
|
||||
return if formula.blank?
|
||||
|
||||
tap_full_name = formula.tap&.full_name
|
||||
current_version = current_formula_version(formula)
|
||||
livecheck_response = livecheck_formula(package_name)
|
||||
pull_requests = GitHub.check_for_duplicate_pull_requests(formula, tap_full_name, latest_version, true)
|
||||
|
||||
{
|
||||
repology_latest_version: latest_version,
|
||||
current_formula_version: current_version.to_s,
|
||||
livecheck_latest_version: livecheck_response[:livecheck_version],
|
||||
open_pull_requests: pull_requests,
|
||||
}
|
||||
end
|
||||
|
||||
def get_formula_details(formula_name)
|
||||
Formula[formula_name]
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
|
||||
def current_formula_version(formula)
|
||||
formula.version.to_s
|
||||
end
|
||||
|
||||
def livecheck_formula(formula)
|
||||
ohai "Checking livecheck formula: #{formula}" if Homebrew.args.verbose?
|
||||
|
||||
response = Utils.popen_read(HOMEBREW_BREW_FILE, "livecheck", formula, "--quiet").chomp
|
||||
|
||||
parse_livecheck_response(response)
|
||||
end
|
||||
|
||||
def parse_livecheck_response(response)
|
||||
output = response.delete(" ").split(/:|==>/)
|
||||
|
||||
# e.g. ["openclonk", "7.0", "8.1"]
|
||||
package_name, brew_version, latest_version = output
|
||||
|
||||
{
|
||||
name: package_name,
|
||||
formula_version: brew_version,
|
||||
livecheck_version: latest_version,
|
||||
}
|
||||
end
|
||||
|
||||
def display(outdated_packages)
|
||||
ohai "Outdated formulae\n"
|
||||
|
||||
outdated_packages.each do |formula, package_details|
|
||||
ohai formula
|
||||
puts "Current formula version: #{package_details[:current_formula_version]}"
|
||||
puts "Latest repology version: #{package_details[:repology_latest_version]}"
|
||||
puts "Latest livecheck version: #{package_details[:livecheck_latest_version]}"
|
||||
puts "Open pull requests: #{package_details[:open_pull_requests]}"
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -10,8 +10,10 @@ require "utils/github"
|
||||
require "utils/inreplace"
|
||||
require "utils/link"
|
||||
require "utils/popen"
|
||||
require "utils/repology"
|
||||
require "utils/svn"
|
||||
require "utils/tty"
|
||||
require "utils/repology"
|
||||
require "tap_constants"
|
||||
require "time"
|
||||
|
||||
|
||||
@ -346,6 +346,43 @@ module GitHub
|
||||
prs.each { |i| puts "#{i["title"]} (#{i["html_url"]})" }
|
||||
end
|
||||
|
||||
def fetch_pull_requests(query, tap_full_name, state: nil)
|
||||
issues_for_formula(query, tap_full_name: tap_full_name, state: state).select do |pr|
|
||||
pr["html_url"].include?("/pull/") &&
|
||||
/(^|\s)#{Regexp.quote(query)}(:|\s|$)/i =~ pr["title"]
|
||||
end
|
||||
rescue GitHub::RateLimitExceededError => e
|
||||
opoo e.message
|
||||
[]
|
||||
end
|
||||
|
||||
def check_for_duplicate_pull_requests(formula, tap_full_name, version, fetch_pr = false)
|
||||
# check for open requests
|
||||
pull_requests = fetch_pull_requests(formula.name, tap_full_name, state: "open")
|
||||
|
||||
# if we haven't already found open requests, try for an exact match across all requests
|
||||
pull_requests = fetch_pull_requests("#{formula.name} #{version}", tap_full_name) if pull_requests.blank?
|
||||
return if pull_requests.blank?
|
||||
|
||||
return pull_requests.map { |pr| { title: pr["title"], url: pr["html_url"] } } if fetch_pr
|
||||
|
||||
duplicates_message = <<~EOS
|
||||
These pull requests may be duplicates:
|
||||
#{pull_requests.map { |pr| "#{pr["title"]} #{pr["html_url"]}" }.join("\n")}
|
||||
EOS
|
||||
error_message = "Duplicate PRs should not be opened. Use --force to override this error."
|
||||
if Homebrew.args.force? && !Homebrew.args.quiet?
|
||||
opoo duplicates_message
|
||||
elsif !Homebrew.args.force? && Homebrew.args.quiet?
|
||||
odie error_message
|
||||
elsif !Homebrew.args.force?
|
||||
odie <<~EOS
|
||||
#{duplicates_message.chomp}
|
||||
#{error_message}
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
def create_fork(repo)
|
||||
url = "#{API_URL}/repos/#{repo}/forks"
|
||||
data = {}
|
||||
|
||||
42
Library/Homebrew/utils/repology.rb
Normal file
42
Library/Homebrew/utils/repology.rb
Normal file
@ -0,0 +1,42 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/curl"
|
||||
|
||||
module Repology
|
||||
module_function
|
||||
|
||||
MAX_PAGINATION = 15
|
||||
|
||||
def query_api(last_package_in_response = "")
|
||||
last_package_in_response += "/" if last_package_in_response.present?
|
||||
url = "https://repology.org/api/v1/projects/#{last_package_in_response}?inrepo=homebrew&outdated=1"
|
||||
|
||||
output, _errors, _status = curl_output(url.to_s)
|
||||
JSON.parse(output)
|
||||
end
|
||||
|
||||
def parse_api_response
|
||||
ohai "Querying outdated packages from Repology"
|
||||
|
||||
outdated_packages = query_api
|
||||
last_package_index = outdated_packages.size - 1
|
||||
response_size = outdated_packages.size
|
||||
page_no = 1
|
||||
|
||||
while response_size > 1 && page_no <= MAX_PAGINATION
|
||||
odebug "Paginating Repology API page: #{page_no}"
|
||||
|
||||
last_package_in_response = outdated_packages.keys[last_package_index]
|
||||
response = query_api(last_package_in_response)
|
||||
|
||||
response_size = response.size
|
||||
outdated_packages.merge!(response)
|
||||
last_package_index = outdated_packages.size - 1
|
||||
page_no += 1
|
||||
end
|
||||
|
||||
ohai "#{outdated_packages.size} outdated #{"package".pluralize(outdated_packages.size)} identified"
|
||||
|
||||
outdated_packages
|
||||
end
|
||||
end
|
||||
@ -12,6 +12,7 @@ abv
|
||||
analytics
|
||||
audit
|
||||
bottle
|
||||
bump
|
||||
bump-formula-pr
|
||||
bump-revision
|
||||
cask
|
||||
|
||||
@ -696,6 +696,11 @@ at its original value, while `--no-rebuild` will remove it.
|
||||
* `--root-url`:
|
||||
Use the specified *`URL`* as the root of the bottle's URL instead of Homebrew's default.
|
||||
|
||||
### `bump`
|
||||
|
||||
Display out-of-date brew formulae, the latest version available, and whether a
|
||||
pull request has been opened.
|
||||
|
||||
### `bump-formula-pr` [*`options`*] [*`formula`*]
|
||||
|
||||
Create a pull request to update *`formula`* with a new URL or a new tag.
|
||||
|
||||
@ -906,6 +906,9 @@ When passed with \fB\-\-write\fR, a new commit will not generated after writing
|
||||
\fB\-\-root\-url\fR
|
||||
Use the specified \fIURL\fR as the root of the bottle\'s URL instead of Homebrew\'s default\.
|
||||
.
|
||||
.SS "\fBbump\fR"
|
||||
Display out\-of\-date brew formulae, the latest version available, and whether a pull request has been opened\.
|
||||
.
|
||||
.SS "\fBbump\-formula\-pr\fR [\fIoptions\fR] [\fIformula\fR]"
|
||||
Create a pull request to update \fIformula\fR with a new URL or a new tag\.
|
||||
.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user