| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  | # typed: true | 
					
						
							|  |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | require "cli/parser" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Homebrew | 
					
						
							|  |  |  |   extend T::Sig | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   module_function | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 21:20:16 +01:00
										 |  |  |   SUPPORTED_REPOS = [ | 
					
						
							|  |  |  |     %w[brew core cask], | 
					
						
							|  |  |  |     OFFICIAL_CMD_TAPS.keys.map { |t| t.delete_prefix("homebrew/") }, | 
					
						
							| 
									
										
										
										
											2022-08-03 16:48:40 +01:00
										 |  |  |     OFFICIAL_CASK_TAPS.reject { |t| t == "cask" }, | 
					
						
							| 
									
										
										
										
											2022-07-29 21:20:16 +01:00
										 |  |  |   ].flatten.freeze | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   sig { returns(CLI::Parser) } | 
					
						
							|  |  |  |   def contributions_args | 
					
						
							|  |  |  |     Homebrew::CLI::Parser.new do | 
					
						
							| 
									
										
										
										
											2022-08-03 17:43:24 +01:00
										 |  |  |       usage_banner "`contributions` <email|name> [<--repositories>`=`]" | 
					
						
							| 
									
										
										
										
											2022-07-28 12:50:04 +01:00
										 |  |  |       description <<~EOS | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  |         Contributions to Homebrew repos for a user. | 
					
						
							| 
									
										
										
										
											2022-07-31 21:25:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 17:38:56 +01:00
										 |  |  |         The first argument is a name (e.g. "BrewTestBot") or an email address (e.g. "brewtestbot@brew.sh"). | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  |       EOS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-03 17:01:52 +01:00
										 |  |  |       comma_array "--repositories", | 
					
						
							|  |  |  |                   description: "Specify a comma-separated (no spaces) list of repositories to search. " \ | 
					
						
							| 
									
										
										
										
											2022-08-03 18:26:30 +01:00
										 |  |  |                                "Supported repositories: #{SUPPORTED_REPOS.map { |t| "`#{t}`" }.to_sentence}." \ | 
					
						
							| 
									
										
										
										
											2022-08-03 17:01:52 +01:00
										 |  |  |                                "Omitting this flag, or specifying `--repositories=all`, will search all repositories." | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  |       flag "--from=", | 
					
						
							|  |  |  |            description: "Date (ISO-8601 format) to start searching contributions." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       flag "--to=", | 
					
						
							|  |  |  |            description: "Date (ISO-8601 format) to stop searching contributions." | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-03 17:43:24 +01:00
										 |  |  |       named_args number: 1
 | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-03 10:19:03 +01:00
										 |  |  |   sig { void } | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  |   def contributions | 
					
						
							|  |  |  |     args = contributions_args.parse | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     commits = 0
 | 
					
						
							|  |  |  |     coauthorships = 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-03 17:01:52 +01:00
										 |  |  |     all_repos = args.repositories.nil? || args.repositories.include?("all") | 
					
						
							|  |  |  |     repos = all_repos ? SUPPORTED_REPOS : args.repositories | 
					
						
							| 
									
										
										
										
											2022-07-31 21:25:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-28 11:28:14 +01:00
										 |  |  |     repos.each do |repo| | 
					
						
							| 
									
										
										
										
											2022-07-28 12:00:27 +01:00
										 |  |  |       if SUPPORTED_REPOS.exclude?(repo) | 
					
						
							| 
									
										
										
										
											2022-07-29 21:19:42 +01:00
										 |  |  |         return ofail "Unsupported repository: #{repo}. Try one of #{SUPPORTED_REPOS.join(", ")}." | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-24 22:44:25 +01:00
										 |  |  |       repo_path = find_repo_path_for_repo(repo) | 
					
						
							| 
									
										
										
										
											2022-07-28 12:10:05 +01:00
										 |  |  |       unless repo_path.exist? | 
					
						
							| 
									
										
										
										
											2022-07-28 11:28:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 21:19:42 +01:00
										 |  |  |         opoo "Repository #{repo} not yet tapped! Tapping it now..." | 
					
						
							| 
									
										
										
										
											2022-07-29 21:49:59 +01:00
										 |  |  |         Tap.fetch("homebrew", repo).install | 
					
						
							| 
									
										
										
										
											2022-07-28 11:28:14 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2022-07-24 22:44:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-24 23:41:00 +01:00
										 |  |  |       commits += git_log_author_cmd(T.must(repo_path), args) | 
					
						
							|  |  |  |       coauthorships += git_log_coauthor_cmd(T.must(repo_path), args) | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-03 10:17:48 +01:00
										 |  |  |     sentence = "#{args.named.first} directly authored #{commits} commits " \ | 
					
						
							| 
									
										
										
										
											2022-07-25 10:52:32 +01:00
										 |  |  |                "and co-authored #{coauthorships} commits " \ | 
					
						
							| 
									
										
										
										
											2022-07-28 12:49:37 +01:00
										 |  |  |                "across #{all_repos ? "all Homebrew repos" : repos.to_sentence}" | 
					
						
							| 
									
										
										
										
											2022-07-30 00:36:31 +01:00
										 |  |  |     sentence += if args.from && args.to | 
					
						
							|  |  |  |       " between #{args.from} and #{args.to}" | 
					
						
							|  |  |  |     elsif args.from | 
					
						
							|  |  |  |       " after #{args.from}" | 
					
						
							|  |  |  |     elsif args.to | 
					
						
							|  |  |  |       " before #{args.to}" | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  |     else | 
					
						
							|  |  |  |       " in all time" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     sentence += "." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     puts sentence | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-24 23:41:00 +01:00
										 |  |  |   sig { params(repo: String).returns(Pathname) } | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  |   def find_repo_path_for_repo(repo) | 
					
						
							| 
									
										
										
										
											2022-07-24 23:18:27 +01:00
										 |  |  |     return HOMEBREW_REPOSITORY if repo == "brew" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Tap.fetch("homebrew", repo).path | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-24 23:41:00 +01:00
										 |  |  |   sig { params(repo_path: Pathname, args: Homebrew::CLI::Args).returns(Integer) } | 
					
						
							| 
									
										
										
										
											2022-07-24 23:24:52 +01:00
										 |  |  |   def git_log_author_cmd(repo_path, args) | 
					
						
							| 
									
										
										
										
											2022-07-28 11:20:04 +01:00
										 |  |  |     cmd = ["git", "-C", repo_path, "log", "--oneline", "--author=#{args.named.first}"] | 
					
						
							| 
									
										
										
										
											2022-07-30 00:36:31 +01:00
										 |  |  |     cmd << "--before=#{args.to}" if args.to | 
					
						
							|  |  |  |     cmd << "--after=#{args.from}" if args.from | 
					
						
							| 
									
										
										
										
											2022-07-24 23:24:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-28 11:20:04 +01:00
										 |  |  |     Utils.safe_popen_read(*cmd).lines.count | 
					
						
							| 
									
										
										
										
											2022-07-24 23:24:52 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-24 23:41:00 +01:00
										 |  |  |   sig { params(repo_path: Pathname, args: Homebrew::CLI::Args).returns(Integer) } | 
					
						
							| 
									
										
										
										
											2022-07-24 23:24:52 +01:00
										 |  |  |   def git_log_coauthor_cmd(repo_path, args) | 
					
						
							| 
									
										
										
										
											2022-07-28 11:20:04 +01:00
										 |  |  |     cmd = ["git", "-C", repo_path, "log", "--oneline"] | 
					
						
							|  |  |  |     cmd << "--format='%(trailers:key=Co-authored-by:)'" | 
					
						
							| 
									
										
										
										
											2022-07-30 00:36:31 +01:00
										 |  |  |     cmd << "--before=#{args.to}" if args.to | 
					
						
							|  |  |  |     cmd << "--after=#{args.from}" if args.from | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-28 12:10:05 +01:00
										 |  |  |     Utils.safe_popen_read(*cmd).lines.count { |l| l.include?(args.named.first) } | 
					
						
							| 
									
										
										
										
											2022-07-24 22:06:00 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | end |