-
Notifications
You must be signed in to change notification settings - Fork 28
/
pull_requests.rb
executable file
·142 lines (118 loc) · 5.1 KB
/
pull_requests.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'optparse'
require_relative 'octokit_utils'
options = {}
options[:oauth] = ENV['GITHUB_COMMUNITY_TOKEN'] if ENV['GITHUB_COMMUNITY_TOKEN']
parser = OptionParser.new do |opts|
opts.banner = 'Usage: pull_requests.rb [options]'
opts.on('-a', '--after DAYS', 'Pull requests that were last updated after DAYS days ago.') { |v| options[:after] = v.to_i }
opts.on('-b', '--before DAYS', 'Pull requests that were last updated before DAYS days ago.') { |v| options[:before] = v.to_i }
opts.on('-c', '--count', 'Only print the count of pull requests.') { options[:count] = true }
opts.on('-e', '--show-empty', 'List repos with no pull requests') { options[:empty] = true }
opts.on('-s', '--sort', 'Sort output based on number of pull requests') { options[:sort] = true }
opts.on('-f', '--file NAME', String, 'Module file list') { |v| options[:file] = v }
opts.on('-t', '--oauth-token TOKEN', 'OAuth token. Required.') { |v| options[:oauth] = v }
opts.on('-v', '--verbose', 'More output') { options[:verbose] = true }
opts.on('--no-response', 'Select PRs which had no response in the last 30 days') do
options[:before] = 30
end
opts.on('--needs-closing', 'Select PRs where the last response is from an owner, but no further activity for the last 30 days') do
options[:before] = 30
options[:last_comment] = :owner
end
opts.on('--bad-status', 'Select PRs where the status is bad') do
options[:bad_status] = 1
end
opts.on('--needs-squashed', 'Select PRs that need squashed') do
options[:needs_squashed] = 1
end
opts.on('--needs-rebase', 'Select PRs where they need a rebase') do
options[:needs_rebase] = 1
end
opts.on('--no-comments', 'Select PRs where there are no comments') do
options[:no_comments] = 1
end
opts.on('--no-puppet-comments', 'Select PRs where there are no comments from puppet members') do
options[:no_puppet_comments] = 1
end
opts.on('--last-comment-mention-member', 'Select PRs where the last comment mentions a puppet members') do
options[:comment_mention_member] = 1
end
opts.on('--no-activity-40-days', 'Select PRs where there has been no activity in 40 days') do
options[:no_activity_40] = 1
end
end
parser.parse!
options[:file] = 'modules.json' if options[:file].nil?
missing = []
missing << '-t' if options[:oauth].nil?
unless missing.empty?
puts "Missing options: #{missing.join(', ')}"
puts parser
exit
end
if options[:before] && options[:after]
puts 'Only one of -a and -b can be specified'
exit
end
util = OctokitUtils.new(options[:oauth])
parsed = util.load_module_list(options[:file])
repo_data = []
parsed.each do |m|
pr_information_cache = util.fetch_async("#{m['github_namespace']}/#{m['repo_name']}")
begin
pulls = if options[:last_comment] == :owner
util.fetch_pull_requests_with_last_owner_comment(pr_information_cache)
elsif options[:needs_rebase]
util.fetch_pull_requests_which_need_rebase(pr_information_cache)
elsif options[:bad_status]
util.fetch_pull_requests_with_bad_status(pr_information_cache)
elsif options[:needs_squashed]
util.fetch_pull_requests_which_need_squashed(pr_information_cache)
elsif options[:no_comments]
util.fetch_uncommented_pull_requests(pr_information_cache)
elsif options[:comment_mention_member]
util.fetch_pull_requests_mention_member(pr_information_cache)
elsif options[:no_puppet_comments]
util.fetch_pull_requests_with_no_puppet_personnel_comments(pr_information_cache)
elsif options[:no_activity_40]
util.fetch_pull_requests_with_no_activity_40_days(pr_information_cache)
else
util.fetch_pull_requests("#{m['github_namespace']}/#{m['repo_name']}")
end
if options[:before]
opts = { pulls: pulls }
start_time = (DateTime.now - options[:before]).to_time
pulls = util.pulls_older_than(start_time, opts)
elsif options[:after]
opts = { pulls: pulls }
end_time = (DateTime.now - options[:after]).to_time
pulls = util.pulls_newer_than(end_time, opts)
end
next if !(options[:empty]) && pulls.empty?
repo_data << if options[:count]
{ 'repo' => "#{m['github_namespace']}/#{m['repo_name']}", 'pulls' => nil, 'pull_count' => pulls.length }
else
{ 'repo' => "#{m['github_namespace']}/#{m['repo_name']}", 'pulls' => pulls, 'pull_count' => pulls.length }
end
rescue StandardError
puts "Unable to fetch pull requests for #{m['github_namespace']}/#{m['repo_name']}" if options[:verbose]
end
end
repo_data.sort_by! { |x| -x['pull_count'] } if options[:sort]
repo_data.each do |entry|
puts "=== #{entry['repo']} ==="
case entry['pull_count']
when 0
puts ' no open pull requests'
when 1
puts ' 1 open pull request'
else
puts " #{entry['pull_count']} open pull requests"
end
next if options[:count]
entry['pulls'].each do |pull|
puts " #{pull[:html_url]} - #{pull[:title]}"
end
end