Port Homebrew::DevCmd::Contributions

This commit is contained in:
Douglas Eichelberger 2024-03-19 11:57:54 -07:00
parent 777ee12258
commit 0373e0dc29
2 changed files with 189 additions and 188 deletions

View File

@ -5,8 +5,8 @@ require "cli/parser"
require "csv"
module Homebrew
module_function
module DevCmd
class Contributions < AbstractCommand
PRIMARY_REPOS = %w[brew core cask].freeze
SUPPORTED_REPOS = [
PRIMARY_REPOS,
@ -15,9 +15,7 @@ module Homebrew
].flatten.freeze
MAX_REPO_COMMITS = 1000
sig { returns(CLI::Parser) }
def contributions_args
Homebrew::CLI::Parser.new do
cmd_args do
usage_banner "`contributions` [--user=<email|username>] [<--repositories>`=`] [<--csv>]"
description <<~EOS
Summarise contributions to Homebrew repositories.
@ -43,18 +41,15 @@ module Homebrew
switch "--csv",
description: "Print a CSV of contributions across repositories over the time period."
end
end
sig { void }
def contributions
args = contributions_args.parse
sig { override.void }
def run
results = {}
grand_totals = {}
repos = if args.repositories.blank? || args.repositories.include?("primary")
repos = if args.repositories.blank? || T.must(args.repositories).include?("primary")
PRIMARY_REPOS
elsif args.repositories.include?("all")
elsif T.must(args.repositories).include?("all")
SUPPORTED_REPOS
else
args.repositories
@ -71,7 +66,7 @@ module Homebrew
# committer details to match the ones on GitHub.
# TODO: Switch to using the GitHub APIs instead of `git log` if
# they ever support trailers.
results[username] = scan_repositories(repos, username, args, from:)
results[username] = scan_repositories(repos, username, from:)
grand_totals[username] = total(results[username])
contributions = contribution_types.filter_map do |type|
@ -80,7 +75,8 @@ module Homebrew
"#{Utils.pluralize("time", type_count, include_count: true)} (#{type})"
end
contributions << "#{Utils.pluralize("time", grand_totals[username].values.sum, include_count: true)} (total)"
contributions << "#{Utils.pluralize("time", grand_totals[username].values.sum,
include_count: true)} (total)"
puts [
"#{username} contributed",
@ -95,6 +91,8 @@ module Homebrew
puts generate_csv(grand_totals)
end
private
sig { params(repo: String).returns(Pathname) }
def find_repo_path_for_repo(repo)
return HOMEBREW_REPOSITORY if repo == "brew"
@ -139,7 +137,7 @@ module Homebrew
]
end
def scan_repositories(repos, person, args, from:)
def scan_repositories(repos, person, from:)
data = {}
repos.each do |repo|
@ -168,7 +166,7 @@ module Homebrew
author: author_commits,
committer: committer_commits,
coauthorship: git_log_trailers_cmd(T.must(repo_path), person, "Co-authored-by", from:, to: args.to),
review: count_reviews(repo_full_name, person, args),
review: count_reviews(repo_full_name, person),
}
end
@ -201,8 +199,8 @@ module Homebrew
Utils.safe_popen_read(*cmd).lines.count { |l| l.include?(person) }
end
sig { params(repo_full_name: String, person: String, args: Homebrew::CLI::Args).returns(Integer) }
def count_reviews(repo_full_name, person, args)
sig { params(repo_full_name: String, person: String).returns(Integer) }
def count_reviews(repo_full_name, person)
GitHub.count_issues("", is: "pr", repo: repo_full_name, reviewed_by: person, review: "approved", args:)
rescue GitHub::API::ValidationFailedError
if args.verbose?
@ -210,4 +208,6 @@ module Homebrew
end
0 # Users who have made their contributions private are not searchable to determine counts.
end
end
end
end

View File

@ -1,7 +1,8 @@
# frozen_string_literal: true
require "cmd/shared_examples/args_parse"
require "dev-cmd/contributions"
RSpec.describe "brew contributions" do
RSpec.describe Homebrew::DevCmd::Contributions do
it_behaves_like "parseable arguments"
end