Merge branch 'master' into delay-loading-from-cask-source-api

This commit is contained in:
apainintheneck 2023-02-26 14:50:13 -08:00
commit fdc2e9f3f5
9 changed files with 91 additions and 26 deletions

View File

@ -14,7 +14,7 @@ module Cask
# Loads a cask from a string. # Loads a cask from a string.
class FromContentLoader class FromContentLoader
attr_reader :content attr_reader :content, :tap
def self.can_load?(ref) def self.can_load?(ref)
return false unless ref.respond_to?(:to_str) return false unless ref.respond_to?(:to_str)
@ -32,8 +32,9 @@ module Cask
content.match?(@regex) content.match?(@regex)
end end
def initialize(content) def initialize(content, tap: nil)
@content = content.force_encoding("UTF-8") @content = content.force_encoding("UTF-8")
@tap = tap
end end
def load(config:) def load(config:)

View File

@ -39,7 +39,7 @@ module Homebrew
description: "A GitHub username or email address of a specific person to find contribution data for." description: "A GitHub username or email address of a specific person to find contribution data for."
switch "--csv", switch "--csv",
description: "Print a CSV of a user's contributions across repositories over the time period." description: "Print a CSV of contributions across repositories over the time period."
end end
end end
@ -48,6 +48,7 @@ module Homebrew
args = contributions_args.parse args = contributions_args.parse
results = {} results = {}
grand_totals = {}
all_repos = args.repositories.nil? || args.repositories.include?("all") all_repos = args.repositories.nil? || args.repositories.include?("all")
repos = if all_repos repos = if all_repos
@ -61,13 +62,13 @@ module Homebrew
if args.user if args.user
user = args.user user = args.user
results[user] = scan_repositories(repos, user, args) results[user] = scan_repositories(repos, user, args)
puts "#{user} contributed #{total(results[user])} times #{time_period(args)}." grand_totals[user] = total(results[user])
puts generate_csv(T.must(user), results[user]) if args.csv?
puts "#{user} contributed #{grand_totals[user].values.sum} times #{time_period(args)}."
puts generate_csv(T.must(user), results[user], grand_totals[user]) if args.csv?
return return
end end
odie "CSVs not yet supported for the full list of maintainers at once." if args.csv?
maintainers = GitHub.members_by_team("Homebrew", "maintainers") maintainers = GitHub.members_by_team("Homebrew", "maintainers")
maintainers.each do |username, _| maintainers.each do |username, _|
# TODO: Using the GitHub username to scan the `git log` undercounts some # TODO: Using the GitHub username to scan the `git log` undercounts some
@ -76,8 +77,12 @@ module Homebrew
# TODO: Switch to using the GitHub APIs instead of `git log` if # TODO: Switch to using the GitHub APIs instead of `git log` if
# they ever support trailers. # they ever support trailers.
results[username] = scan_repositories(repos, username, args) results[username] = scan_repositories(repos, username, args)
puts "#{username} contributed #{total(results[username])} times #{time_period(args)}." grand_totals[username] = total(results[username])
puts "#{username} contributed #{grand_totals[username].values.sum} times #{time_period(args)}."
end end
puts generate_maintainers_csv(grand_totals) if args.csv?
end end
sig { params(repo: String).returns(Pathname) } sig { params(repo: String).returns(Pathname) }
@ -100,10 +105,21 @@ module Homebrew
end end
end end
sig { params(user: String, results: Hash).returns(String) } sig { params(totals: Hash).returns(String) }
def generate_csv(user, results) def generate_maintainers_csv(totals)
CSV.generate do |csv| CSV.generate do |csv|
csv << %w[user repo commits coauthorships signoffs total] csv << %w[user repo commits coauthorships signoffs reviews total]
totals.sort_by { |_, v| -v.values.sum }.each do |user, total|
csv << grand_total_row(user, total)
end
end
end
sig { params(user: String, results: Hash, grand_total: Hash).returns(String) }
def generate_csv(user, results, grand_total)
CSV.generate do |csv|
csv << %w[user repo commits coauthorships signoffs reviews total]
results.each do |repo, counts| results.each do |repo, counts|
csv << [ csv << [
user, user,
@ -111,13 +127,27 @@ module Homebrew
counts[:commits], counts[:commits],
counts[:coauthorships], counts[:coauthorships],
counts[:signoffs], counts[:signoffs],
counts[:reviews],
counts.values.sum, counts.values.sum,
] ]
end end
csv << [user, "*", "*", "*", "*", total(results)] csv << grand_total_row(user, grand_total)
end end
end end
sig { params(user: String, grand_total: Hash).returns(Array) }
def grand_total_row(user, grand_total)
[
user,
"all",
grand_total[:commits],
grand_total[:coauthorships],
grand_total[:signoffs],
grand_total[:reviews],
grand_total.values.sum,
]
end
def scan_repositories(repos, person, args) def scan_repositories(repos, person, args)
data = {} data = {}
@ -145,18 +175,28 @@ module Homebrew
commits: GitHub.repo_commit_count_for_user(repo_full_name, person, args), commits: GitHub.repo_commit_count_for_user(repo_full_name, person, args),
coauthorships: git_log_trailers_cmd(T.must(repo_path), person, "Co-authored-by", args), coauthorships: git_log_trailers_cmd(T.must(repo_path), person, "Co-authored-by", args),
signoffs: git_log_trailers_cmd(T.must(repo_path), person, "Signed-off-by", args), signoffs: git_log_trailers_cmd(T.must(repo_path), person, "Signed-off-by", args),
reviews: GitHub.count_issues("", is: "pr", repo: repo_full_name, reviewed_by: person),
} }
end end
data data
end end
sig { params(results: Hash).returns(Integer) } sig { params(results: Hash).returns(Hash) }
def total(results) def total(results)
results totals = { commits: 0, coauthorships: 0, signoffs: 0, reviews: 0 }
.values # [{:commits=>1, :coauthorships=>0, :signoffs=>3}, {:commits=>500, :coauthorships=>2, :signoffs=>450}]
.map(&:values) # [[1, 0, 3], [500, 2, 450]] # {
.sum(&:sum) # 956 # "brew"=>{:commits=>9,:coauthorships=>6,:signoffs=>3,:reviews=>1},
# "core"=>{:commits=>15,:coauthorships=>10,:signoffs=>5,:reviews=>2}
# }
results.each_value do |counts|
counts.each do |kind, count|
totals[kind] += count
end
end
totals # {:commits=>24,:coauthorships=>16,:signoffs=>8,:reviews=>3}
end end
sig { params(repo_path: Pathname, person: String, trailer: String, args: Homebrew::CLI::Args).returns(Integer) } sig { params(repo_path: Pathname, person: String, trailer: String, args: Homebrew::CLI::Args).returns(Integer) }

View File

@ -5339,6 +5339,9 @@ class Object
HOMEBREW_LOGS = ::T.let(nil, ::T.untyped) HOMEBREW_LOGS = ::T.let(nil, ::T.untyped)
HOMEBREW_MACOS_ARM_DEFAULT_PREFIX = ::T.let(nil, ::T.untyped) HOMEBREW_MACOS_ARM_DEFAULT_PREFIX = ::T.let(nil, ::T.untyped)
HOMEBREW_MACOS_ARM_DEFAULT_REPOSITORY = ::T.let(nil, ::T.untyped) HOMEBREW_MACOS_ARM_DEFAULT_REPOSITORY = ::T.let(nil, ::T.untyped)
HOMEBREW_MACOS_NEWEST_UNSUPPORTED = ::T.let(nil, ::T.untyped)
HOMEBREW_MACOS_OLDEST_ALLOWED = ::T.let(nil, ::T.untyped)
HOMEBREW_MACOS_OLDEST_SUPPORTED = ::T.let(nil, ::T.untyped)
HOMEBREW_MAIN_TAP_CASK_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_MAIN_TAP_CASK_REGEX = ::T.let(nil, ::T.untyped)
HOMEBREW_OFFICIAL_REPO_PREFIXES_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_OFFICIAL_REPO_PREFIXES_REGEX = ::T.let(nil, ::T.untyped)
HOMEBREW_PHYSICAL_PROCESSOR = ::T.let(nil, ::T.untyped) HOMEBREW_PHYSICAL_PROCESSOR = ::T.let(nil, ::T.untyped)

View File

@ -39,7 +39,7 @@ describe Homebrew::Search do
], ],
} }
allow(GitHub::API).to receive(:open_rest).and_yield(json_response) allow(GitHub::API).to receive(:open_rest).and_return(json_response)
expect(described_class.search_taps("some-formula")) expect(described_class.search_taps("some-formula"))
.to match(formulae: ["homebrew/foo/some-formula"], casks: ["homebrew/bar/some-cask"]) .to match(formulae: ["homebrew/foo/some-formula"], casks: ["homebrew/bar/some-cask"])

View File

@ -37,7 +37,11 @@ module GitHub
end end
def search_issues(query, **qualifiers) def search_issues(query, **qualifiers)
search("issues", query, **qualifiers) search_results_items("issues", query, **qualifiers)
end
def count_issues(query, **qualifiers)
search_results_count("issues", query, **qualifiers)
end end
def create_gist(files, description, private:) def create_gist(files, description, private:)
@ -57,7 +61,14 @@ module GitHub
end end
def search_code(repo: nil, user: "Homebrew", path: ["Formula", "Casks", "."], filename: nil, extension: "rb") def search_code(repo: nil, user: "Homebrew", path: ["Formula", "Casks", "."], filename: nil, extension: "rb")
matches = search("code", user: user, path: path, filename: filename, extension: extension, repo: repo) matches = search_results_items(
"code",
user: user,
path: path,
filename: filename,
extension: extension,
repo: repo,
)
return matches if matches.blank? return matches if matches.blank?
matches.map do |match| matches.map do |match|
@ -163,7 +174,7 @@ module GitHub
params = main_params params = main_params
params += qualifiers.flat_map do |key, value| params += qualifiers.flat_map do |key, value|
Array(value).map { |v| "#{key}:#{v}" } Array(value).map { |v| "#{key.to_s.tr("_", "-")}:#{v}" }
end end
"q=#{URI.encode_www_form_component(params.join(" "))}&per_page=100" "q=#{URI.encode_www_form_component(params.join(" "))}&per_page=100"
@ -176,7 +187,17 @@ module GitHub
def search(entity, *queries, **qualifiers) def search(entity, *queries, **qualifiers)
uri = url_to "search", entity uri = url_to "search", entity
uri.query = search_query_string(*queries, **qualifiers) uri.query = search_query_string(*queries, **qualifiers)
API.open_rest(uri) { |json| json.fetch("items", []) } API.open_rest(uri)
end
def search_results_items(entity, *queries, **qualifiers)
json = search(entity, *queries, **qualifiers)
json.fetch("items", [])
end
def search_results_count(entity, *queries, **qualifiers)
json = search(entity, *queries, **qualifiers)
json.fetch("total_count", 0)
end end
def approved_reviews(user, repo, pr, commit: nil) def approved_reviews(user, repo, pr, commit: nil)

View File

@ -537,7 +537,7 @@ __fish_brew_complete_arg 'config' -l verbose -d 'Make some output more verbose'
__fish_brew_complete_cmd 'contributions' 'Contributions to Homebrew repos' __fish_brew_complete_cmd 'contributions' 'Contributions to Homebrew repos'
__fish_brew_complete_arg 'contributions' -l csv -d 'Print a CSV of a user\'s contributions across repositories over the time period' __fish_brew_complete_arg 'contributions' -l csv -d 'Print a CSV of contributions across repositories over the time period'
__fish_brew_complete_arg 'contributions' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'contributions' -l debug -d 'Display any debugging information'
__fish_brew_complete_arg 'contributions' -l from -d 'Date (ISO-8601 format) to start searching contributions' __fish_brew_complete_arg 'contributions' -l from -d 'Date (ISO-8601 format) to start searching contributions'
__fish_brew_complete_arg 'contributions' -l help -d 'Show this message' __fish_brew_complete_arg 'contributions' -l help -d 'Show this message'

View File

@ -666,7 +666,7 @@ _brew_config() {
# brew contributions # brew contributions
_brew_contributions() { _brew_contributions() {
_arguments \ _arguments \
'--csv[Print a CSV of a user'\''s contributions across repositories over the time period]' \ '--csv[Print a CSV of contributions across repositories over the time period]' \
'--debug[Display any debugging information]' \ '--debug[Display any debugging information]' \
'--from[Date (ISO-8601 format) to start searching contributions]' \ '--from[Date (ISO-8601 format) to start searching contributions]' \
'--help[Show this message]' \ '--help[Show this message]' \

View File

@ -1124,7 +1124,7 @@ Contributions to Homebrew repos.
* `--user`: * `--user`:
A GitHub username or email address of a specific person to find contribution data for. A GitHub username or email address of a specific person to find contribution data for.
* `--csv`: * `--csv`:
Print a CSV of a user's contributions across repositories over the time period. Print a CSV of contributions across repositories over the time period.
### `create` [*`options`*] *`URL`* ### `create` [*`options`*] *`URL`*

View File

@ -1619,7 +1619,7 @@ A GitHub username or email address of a specific person to find contribution dat
. .
.TP .TP
\fB\-\-csv\fR \fB\-\-csv\fR
Print a CSV of a user\'s contributions across repositories over the time period\. Print a CSV of contributions across repositories over the time period\.
. .
.SS "\fBcreate\fR [\fIoptions\fR] \fIURL\fR" .SS "\fBcreate\fR [\fIoptions\fR] \fIURL\fR"
Generate a formula or, with \fB\-\-cask\fR, a cask for the downloadable file at \fIURL\fR and open it in the editor\. Homebrew will attempt to automatically derive the formula name and version, but if it fails, you\'ll have to make your own template\. The \fBwget\fR formula serves as a simple example\. For the complete API, see: \fIhttps://rubydoc\.brew\.sh/Formula\fR Generate a formula or, with \fB\-\-cask\fR, a cask for the downloadable file at \fIURL\fR and open it in the editor\. Homebrew will attempt to automatically derive the formula name and version, but if it fails, you\'ll have to make your own template\. The \fBwget\fR formula serves as a simple example\. For the complete API, see: \fIhttps://rubydoc\.brew\.sh/Formula\fR