From 2719c345abb109a1bed96075093b9e004b20c68c Mon Sep 17 00:00:00 2001 From: Issy Long Date: Wed, 15 Feb 2023 12:25:04 +0000 Subject: [PATCH 1/4] dev-cmd/contributions: CSV output of queried repos; shorter sentence - This gives users of this command a `--csv` option to pass to... you guessed it, generate a CSV that's `pbcopy`able elsewhere, for more granular breakdowns of where a person contributed. - Inspiration was taken from the mockup in https://github.com/Homebrew/brew/issues/13642#issuecomment-1254535251 but without the extra dependency of the TerminalTable gem. - Always print a condensed "total contributions" sentence. Output: ``` $ brew contributions issyl0 The user issyl0 has made 1201 contributions in all time. $ brew contributions issyl0 --csv user,repo,commits,coauthorships,signoffs issyl0,brew,331,13,0 issyl0,core,473,24,326 issyl0,cask,4,0,0 issyl0,aliases,0,0,0 issyl0,autoupdate,1,0,0 issyl0,bundle,14,2,0 issyl0,command-not-found,1,0,0 issyl0,test-bot,3,0,0 issyl0,services,9,0,0 issyl0,cask-drivers,0,0,0 issyl0,cask-fonts,0,0,0 issyl0,cask-versions,0,0,0 ``` --- Library/Homebrew/cli/args.rbi | 3 + Library/Homebrew/dev-cmd/contributions.rb | 68 +++++++++++++++-------- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/Library/Homebrew/cli/args.rbi b/Library/Homebrew/cli/args.rbi index b9768725ab..2e717c2646 100644 --- a/Library/Homebrew/cli/args.rbi +++ b/Library/Homebrew/cli/args.rbi @@ -335,6 +335,9 @@ module Homebrew sig { returns(T.nilable(T::Boolean)) } def force_auto_update?; end + + sig { returns(T::Boolean) } + def csv?; end end end end diff --git a/Library/Homebrew/dev-cmd/contributions.rb b/Library/Homebrew/dev-cmd/contributions.rb index b303d6574a..ed1cdf44e2 100755 --- a/Library/Homebrew/dev-cmd/contributions.rb +++ b/Library/Homebrew/dev-cmd/contributions.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "cli/parser" +require "csv" module Homebrew extend T::Sig @@ -17,7 +18,7 @@ module Homebrew sig { returns(CLI::Parser) } def contributions_args Homebrew::CLI::Parser.new do - usage_banner "`contributions` [<--repositories>`=`]" + usage_banner "`contributions` [<--repositories>`=`] [<--csv>]" description <<~EOS Contributions to Homebrew repos for a user. @@ -34,6 +35,9 @@ module Homebrew flag "--to=", description: "Date (ISO-8601 format) to stop searching contributions." + switch "--csv", + description: "Print a CSV of a user's contributions across repositories over the time period." + named_args number: 1 end end @@ -42,9 +46,7 @@ module Homebrew def contributions args = contributions_args.parse - commits = 0 - coauthorships = 0 - signoffs = 0 + results = {} all_repos = args.repositories.nil? || args.repositories.include?("all") repos = all_repos ? SUPPORTED_REPOS : args.repositories @@ -56,32 +58,19 @@ module Homebrew repo_path = find_repo_path_for_repo(repo) unless repo_path.exist? - opoo "Repository #{repo} not yet tapped! Tapping it now..." Tap.fetch("homebrew", repo).install end - commits += git_log_author_cmd(T.must(repo_path), args) - coauthorships += git_log_trailers_cmd(T.must(repo_path), "Co-authored-by", args) - signoffs += git_log_trailers_cmd(T.must(repo_path), "Signed-off-by", args) + results[repo] = { + commits: git_log_author_cmd(T.must(repo_path), args), + coauthorships: git_log_trailers_cmd(T.must(repo_path), "Co-authored-by", args), + signoffs: git_log_trailers_cmd(T.must(repo_path), "Signed-off-by", args), + } end - sentence = "#{args.named.first} directly authored #{commits} commits" \ - ", co-authored #{coauthorships} commits" \ - ", and signed-off #{signoffs} commits " \ - "across #{all_repos ? "all Homebrew repos" : repos.to_sentence}" - sentence += if args.from && args.to - " between #{args.from} and #{args.to}" - elsif args.from - " after #{args.from}" - elsif args.to - " before #{args.to}" - else - " in all time" - end - sentence += ". Total: #{commits + coauthorships + signoffs}." - - puts sentence + puts "The user #{args.named.first} has made #{total(results)} contributions #{time_period(args)}." + puts generate_csv(args.named.first, results) if args.csv? end sig { params(repo: String).returns(Pathname) } @@ -91,6 +80,37 @@ module Homebrew Tap.fetch("homebrew", repo).path end + sig { params(args: Homebrew::CLI::Args).returns(String) } + def time_period(args) + if args.from && args.to + "between #{args.from} and #{args.to}" + elsif args.from + "after #{args.from}" + elsif args.to + "before #{args.to}" + else + "in all time" + end + end + + sig { params(user: String, results: Hash).returns(String) } + def generate_csv(user, results) + CSV.generate do |csv| + csv << %w[user repo commits coauthorships signoffs] + results.each do |repo, counts| + csv << [user, repo, counts[:commits], counts[:coauthorships], counts[:signoffs]] + end + end + end + + sig { params(results: Hash).returns(Integer) } + def total(results) + results + .values # [{:commits=>1, :coauthorships=>0, :signoffs=>3}, {:commits=>500, :coauthorships=>2, :signoffs=>450}] + .map(&:values) # [[1, 0, 3], [500, 2, 450]] + .sum(&:sum) # 956 + end + sig { params(repo_path: Pathname, args: Homebrew::CLI::Args).returns(Integer) } def git_log_author_cmd(repo_path, args) cmd = ["git", "-C", repo_path, "log", "--oneline", "--author=#{args.named.first}"] From 9aad9d011be583c39620f4fd3de1bcf8ff34f30f Mon Sep 17 00:00:00 2001 From: Issy Long Date: Wed, 15 Feb 2023 13:56:37 +0000 Subject: [PATCH 2/4] dev-cmd/contributions: Add a per-repo total column to the CSV ``` $ brew contributions issyl0 --csv The user issyl0 has made 1202 contributions in all time. user,repo,commits,coauthorships,signoffs,total issyl0,brew,332,13,0,345 issyl0,core,473,24,326,823 issyl0,cask,4,0,0,4 issyl0,aliases,0,0,0,0 issyl0,autoupdate,1,0,0,1 issyl0,bundle,14,2,0,16 issyl0,command-not-found,1,0,0,1 issyl0,test-bot,3,0,0,3 issyl0,services,9,0,0,9 issyl0,cask-drivers,0,0,0,0 issyl0,cask-fonts,0,0,0,0 issyl0,cask-versions,0,0,0,0 ``` --- Library/Homebrew/dev-cmd/contributions.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/contributions.rb b/Library/Homebrew/dev-cmd/contributions.rb index ed1cdf44e2..84c1acd7f5 100755 --- a/Library/Homebrew/dev-cmd/contributions.rb +++ b/Library/Homebrew/dev-cmd/contributions.rb @@ -96,9 +96,16 @@ module Homebrew sig { params(user: String, results: Hash).returns(String) } def generate_csv(user, results) CSV.generate do |csv| - csv << %w[user repo commits coauthorships signoffs] + csv << %w[user repo commits coauthorships signoffs total] results.each do |repo, counts| - csv << [user, repo, counts[:commits], counts[:coauthorships], counts[:signoffs]] + csv << [ + user, + repo, + counts[:commits], + counts[:coauthorships], + counts[:signoffs], + counts.values.sum + ] end end end From 44edad85bc36483d10986ad4e31ea85c1b5a7169 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Wed, 15 Feb 2023 13:59:23 +0000 Subject: [PATCH 3/4] dev-cmd/contributions: Add a grand total row to the CSV ``` $ brew contributions issyl0 --csv The user issyl0 has made 1203 contributions in all time. user,repo,commits,coauthorships,signoffs,total issyl0,brew,333,13,0,346 issyl0,core,473,24,326,823 issyl0,cask,4,0,0,4 issyl0,aliases,0,0,0,0 issyl0,autoupdate,1,0,0,1 issyl0,bundle,14,2,0,16 issyl0,command-not-found,1,0,0,1 issyl0,test-bot,3,0,0,3 issyl0,services,9,0,0,9 issyl0,cask-drivers,0,0,0,0 issyl0,cask-fonts,0,0,0,0 issyl0,cask-versions,0,0,0,0 issyl0,*,*,*,*,1203 ``` --- Library/Homebrew/dev-cmd/contributions.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/Library/Homebrew/dev-cmd/contributions.rb b/Library/Homebrew/dev-cmd/contributions.rb index 84c1acd7f5..ed0c0f2ce1 100755 --- a/Library/Homebrew/dev-cmd/contributions.rb +++ b/Library/Homebrew/dev-cmd/contributions.rb @@ -107,6 +107,7 @@ module Homebrew counts.values.sum ] end + csv << [user, "*", "*", "*", "*", total(results)] end end From 43a88cbd972b0980c6e99d2f2bbb4cbcc40d72c1 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Wed, 15 Feb 2023 14:04:05 +0000 Subject: [PATCH 4/4] dev-cmd/contributions: Appease RuboCop --- Library/Homebrew/dev-cmd/contributions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/contributions.rb b/Library/Homebrew/dev-cmd/contributions.rb index ed0c0f2ce1..f8c1aebc40 100755 --- a/Library/Homebrew/dev-cmd/contributions.rb +++ b/Library/Homebrew/dev-cmd/contributions.rb @@ -104,7 +104,7 @@ module Homebrew counts[:commits], counts[:coauthorships], counts[:signoffs], - counts.values.sum + counts.values.sum, ] end csv << [user, "*", "*", "*", "*", total(results)]