-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmonkey.rb
More file actions
executable file
·131 lines (108 loc) · 3.21 KB
/
Copy pathmonkey.rb
File metadata and controls
executable file
·131 lines (108 loc) · 3.21 KB
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
#!/usr/bin/env ruby
require "date"
require "logger"
require "optparse"
require "thread"
require "pry" # for debugging
require_relative "lib/github_client"
require_relative "lib/make_pull_request"
require_relative "lib/random_gaussian"
WORK_HOURS = 9..18
DAY_LENGTH = WORK_HOURS.last - WORK_HOURS.first
Thread.abort_on_exception = true
$logger = Logger.new(STDOUT)
$logger.level = Logger::DEBUG
$opts = {
ludicrous_mode: false,
repo: nil,
token: nil,
api_host: "https://api.github.com/",
daily_prs: 35..45,
merge_rate: 0.85,
files_per_pr: 1..20,
commits_per_pr: 1..8,
comments_per_pr: 0..10,
}
OptionParser.new do |opts|
opts.banner = "Usage: ./monkey.rb --repo=/dir --token=GH_TOKEN"
opts.on("-rPATH", "--repo=PATH", "repo directory") do |v|
$opts[:repo] = v
end
opts.on("-tTOKEN", "--token=TOKEN", "auth token") do |v|
$opts[:token] = v
end
opts.on("--api_host=URL", "Github API Host") do |v|
$opts[:api_host] = v
end
# just churn out PRs as fast as possible in series, no time sensitivity
opts.on("--ludicrous", "Ludicrous mode") do |v|
$opts[:ludicrous_mode] = true
end
end.parse!
if $opts.fetch(:repo).nil? || $opts.fetch(:token).nil?
raise ArgumentError, "repo and token are required args"
end
$repo_lock = Mutex.new # so multiple threads can work on multiple PRs at the same time
Dir.chdir($opts.fetch(:repo))
$logger.debug "Current directory is #{Dir.pwd}"
def schedule_days_prs
pr_count = $opts.fetch(:daily_prs).to_a.sample
# scale pr count if script is started in middle of day
day_pct_left = (DAY_LENGTH - (Time.now.hour - WORK_HOURS.first)).to_f / DAY_LENGTH
pr_count = (pr_count * day_pct_left).round
$logger.debug "[main] Going to generate #{pr_count} pull requests on #{Date.today}"
pr_count.times.map { |idx| schedule_pr(idx) }.map(&:join)
end
def end_of_day
now = Time.now
Time.new(now.year, now.month, now.day, WORK_HOURS.last, 0, 0)
end
def schedule_pr(idx)
secs_left_in_day = end_of_day - Time.now
Thread.new do
MakePullRequest.new(
index: idx,
duration_secs: rand(secs_left_in_day),
will_merge: rand <= $opts.fetch(:merge_rate),
commit_count: RandomGaussian.from_range($opts.fetch(:commits_per_pr)),
comment_count: RandomGaussian.from_range($opts.fetch(:comments_per_pr)),
files_count: RandomGaussian.from_range($opts.fetch(:files_per_pr)),
).run
end
end
def simulate_team
while true
schedule_days_prs
now = Time.now
next_morning = Time.new(
now.year,
now.month,
now.day + 1,
WORK_HOURS.first,
0,
0,
)
sleep_time = (next_morning - now).round
$logger.info "[main] sleeping #{sleep_time} seconds until #{next_morning}"
sleep sleep_time
end
end
def run_ludicrous_mode
idx = 0
while true
MakePullRequest.new(
index: idx,
duration_secs: 0,
will_merge: rand <= $opts.fetch(:merge_rate),
commit_count: RandomGaussian.from_range($opts.fetch(:commits_per_pr)),
comment_count: RandomGaussian.from_range($opts.fetch(:comments_per_pr)),
files_count: RandomGaussian.from_range($opts.fetch(:files_per_pr)),
).run
idx += 1
end
end
if $opts.fetch(:ludicrous_mode)
run_ludicrous_mode
else
simulate_team
end