reviewlette 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/lib/reviewlette.rb CHANGED
@@ -1,202 +1,53 @@
1
1
  require 'reviewlette/trello_connection'
2
2
  require 'reviewlette/github_connection'
3
- require 'reviewlette/database'
4
- require 'reviewlette/graph_gen'
5
3
  require 'reviewlette/vacations'
6
4
  require 'yaml'
7
- require 'octokit'
8
- require 'trello'
9
5
 
10
- class Trello::Card
6
+ VERSION = '0.0.7'
7
+ MEMBERS_CONFIG = YAML.load_file("#{File.dirname(__FILE__)}/../config/members.yml")
11
8
 
12
- def assignees
13
- @trello_connection = Reviewlette::TrelloConnection.new
14
- member_ids.map{|id| @trello_connection.find_member_by_id(id)}
15
- end
16
- end
17
-
18
- module Reviewlette
19
-
20
- attr_accessor :trello_connection, :github_connection, :repo, :board, :db
21
-
22
- TRELLO_CONFIG1 = YAML.load_file("#{File.dirname(__FILE__)}/../config/.trello.yml")
23
-
24
- class << self
25
-
26
- # Execute logic.
27
- def spin
28
- setup
29
- get_available_repos.each do |repo|
30
- @repo = repo
31
- get_unassigned_github_issues.each do |issue|
32
- @number = issue[:number]
33
- @title = issue[:title]
34
- @body = issue[:body]
35
- update_vacations
36
-
37
- if find_card(@title.to_s) and find_id
38
- if set_reviewer
39
- transform_name
40
- add_reviewer_on_github
41
- comment_on_github
42
- # add_to_trello_card
43
- comment_on_trello
44
- move_to_list
45
- @db.add_pr_to_db(@title, @reviewer.username)
46
- @reviewer = nil
47
- Reviewlette::Graphgenerator.new.write_to_graphs('graph.html',Reviewlette::Graphgenerator.new.model_graphs(Reviewlette::Database.new.conscruct_line_data.to_json, Reviewlette::Database.new.conscruct_graph_struct.to_json, 'Donut'))
48
- else
49
- comment_on_error
50
- end
51
- end
52
- puts 'No new issues.' unless @issues.present?
53
- end
54
- end
55
- end
56
-
57
- def get_available_repos
58
- @repos = Reviewlette::GithubConnection::GITHUB_CONFIG['repo']
59
- end
60
-
61
- # Finds card based on title of Github Issue.
62
- # Or by branch name if title does not include the trello number.
63
- # Happens if the pullrequest consists of only one commit.
64
- def find_card(title)
65
- begin
66
- match_pr_id_with_issue_id
67
- @id = title.split('_').last.to_i
68
- @id = fetch_branch if @id == 0 && !(@pullreq_ids.values.index(@number)).nil?
69
- raise NoTrelloCardException, "Could not find a Trello card. Found #{title.split('_').last} instead, maybe the naming of your pullrequest is wrong? And/or you dont have a branch?" if @id == 0
70
- true
71
- rescue NoTrelloCardException => e
72
- @logger.error e.message
73
- puts (e.message)
74
- false
75
- end
76
- end
9
+ class Reviewlette
77
10
 
78
- def update_vacations
79
- @db.get_users_tel_entries.each do |name|
80
- @vacations = Reviewlette::Vacations.find_vacations(name) #tel_name
81
- evaluate_vacations(name)
82
- end
83
- end
11
+ def initialize
12
+ @github = GithubConnection.new
13
+ @trello = TrelloConnection.new
14
+ end
84
15
 
85
- def evaluate_vacations(reviewer)
86
- parse_vacations.each do |check|
87
- check[1] = check[0] unless check[1] # Rewrite if statement with catch to prevent this error?
88
- if (check[0]..check[1]).cover?(Date.today)
89
- @db.set_vacation_flag(reviewer, 'true')
90
- break
16
+ def run
17
+ @github.unassigned_pull_requests.each do |issue|
18
+ issue_id = issue[:number]
19
+ issue_title = issue[:title]
20
+ puts "*** Checking unassigned github pull request: #{issue_title}"
21
+ card_id = issue_title.split(/[_ -#\.]/).last.to_i
22
+ if card = @trello.find_card_by_id(card_id)
23
+ puts "Found matching trello card: #{card.name}"
24
+ reviewer = select_reviewer(issue, card)
25
+ if reviewer
26
+ @github.add_assignee(issue_id, reviewer['github_username'])
27
+ @github.reviewer_comment(issue_id, reviewer['github_username'], card)
28
+ comment = "@#{reviewer['trello_username']} will review https://github.com/#{@github.repo}/issues/#{issue_id}"
29
+ @trello.comment_on_card(comment, card)
30
+ @trello.move_card_to_list(card, 'In review')
91
31
  else
92
- @db.set_vacation_flag(reviewer, 'false') # hopefully not to_bool?
32
+ puts "Could not find a reviewer for card: #{card.name}"
93
33
  end
94
- end
95
- end
96
-
97
- def parse_vacations
98
- split = @vacations.map { |x| x.split(' - ') }
99
- split.map { |x| x.map { |b| Date.parse(b) } }
100
- end
101
-
102
- # gets the branchname from github pullrequest
103
- def fetch_branch
104
- pr_id = @pullreq_ids.values.index(@number)
105
- branch_name = @github_connection.get_branch_name(pr_id, @repo)
106
- branch_name.split('_').last.to_i
107
- end
108
-
109
- # Matches Pull Request IDs with the respective Order of PullRequests
110
- # to call them and get the branch name.
111
- def match_pr_id_with_issue_id
112
- @pullreq_ids = {}
113
- @counter = 0
114
- @github_connection.list_pulls(@repo).each do |x|
115
- @pullreq_ids[@counter] = x.number
116
- @counter +=1
117
- end
118
- end
119
-
120
- # TODO: Generic Error message.
121
- def comment_on_error
122
- @trello_connection.comment_on_card("Skipped Issue #{@number} because everyone on the team is assigned to the card", @card)
123
- end
124
-
125
- # Gets [Array(String, String)] all GitHub Issues that are not assigned to someone.
126
- def get_unassigned_github_issues
127
- @issues = @github_connection.list_issues(@repo).select{|issue| !issue[:assignee]}
128
- end
129
-
130
- # Sets instance variables.
131
- def setup
132
- @logger = Logger.new('review.log')
133
- @db = Reviewlette::Database.new
134
- @github_connection = Reviewlette::GithubConnection.new
135
- @trello_connection = Reviewlette::TrelloConnection.new
136
- @board = Trello::Board.find(TRELLO_CONFIG1['board_id'])
137
- end
138
-
139
- # Finds a sets card.
140
- def find_id
141
- if @id != 0
142
- @card = @trello_connection.find_card_by_id(@id)
143
- true
144
34
  else
145
- @logger.warn("Id not found, skipping Issue #{@title} with number #{@number}")
146
- false
147
- end
148
- end
149
-
150
- # Selects and sets reviewer.
151
- def set_reviewer
152
- begin
153
- while !(@reviewer)
154
- @reviewer = @trello_connection.determine_reviewer(@card) if @card
155
- end
156
- @trelloname = @reviewer.username
157
- puts "Selected #{@reviewer.username}"
158
- return true
159
- rescue AlreadyAssignedException => e
160
- @logger.warn("Skipped Issue #{@card.short_id} because #{e.message}")
161
- puts ("Skipped Issue #{@card.short_id} because #{e.message}")
162
- return false
35
+ puts "No matching card found (id #{card_id})"
163
36
  end
164
37
  end
165
38
 
166
- # Get Trelloname from configfile.
167
- def transform_name
168
- @githubname = @db.find_gh_name_by_trello_name(@trelloname)
169
- end
170
-
171
- # Adds Assignee on GitHub.
172
- def add_reviewer_on_github
173
- @github_connection.add_assignee(@repo, @number, @title, @body, @githubname) if @number && @githubname
174
- end
175
-
176
- # Comments on GitHub.
177
- def comment_on_github
178
- @github_connection.comment_on_issue(@repo, @number, @githubname, @card.url) if @number && @githubname
179
- end
180
- # Adds Reviewer on Trello Card.
181
- def add_to_trello_card
182
- @trello_connection.add_reviewer_to_card(@reviewer, @card)
183
- end
184
-
185
- # Comments on Trello Card.
186
- def comment_on_trello
187
- @full_comment = '@' + @trelloname + ' will review ' + 'https://github.com/'+ @repo+'/issues/'+@number.to_s
188
- @trello_connection.comment_on_card(@full_comment, @card) if @full_comment
189
- end
39
+ end
190
40
 
191
- # TODO: More generic 'Done' and 'in Review' are not present everywhere
192
- def move_to_list
193
- if @github_connection.pull_merged?(@repo, @id)
194
- @column = @trello_connection.find_column('Done')
195
- @trello_connection.move_card_to_list(@card, @column)
196
- else
197
- @column = @trello_connection.find_column('In review')
198
- @trello_connection.move_card_to_list(@card, @column)
199
- end
200
- end
41
+ def select_reviewer(issue, card)
42
+ reviewers = MEMBERS_CONFIG['members']
43
+ # remove people on vacation
44
+ members_on_vacation = Vacations.members_on_vacation
45
+ reviewers = reviewers.reject{|r| members_on_vacation.include? r['suse_username'] }
46
+ # remove trello card owner
47
+ reviewers = reviewers.reject{|r| card.members.map(&:username).include? r['trello_username'] }
48
+ reviewer = reviewers.sample
49
+ puts "Selected reviewer: #{reviewer['name']} from pool #{reviewers.map{|r| r['name']}}" if reviewer
50
+ reviewer
201
51
  end
52
+
202
53
  end
data/reviewlette.gemspec CHANGED
@@ -1,11 +1,11 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'reviewlette/version'
4
+ require 'reviewlette'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "reviewlette"
8
- spec.version = Reviewlette::VERSION
8
+ spec.version = VERSION
9
9
  spec.authors = ["jschmid1"]
10
10
  spec.email = ["jschmid@suse.de"]
11
11
  spec.summary = %q{Randomly assignes a reviewer to your Pullrequest and corresponding Trello Card.}
@@ -1,96 +1,41 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Reviewlette::GithubConnection do
3
+ describe GithubConnection do
4
4
 
5
- subject { Reviewlette::GithubConnection }
5
+ GITHUB_CONFIG = { token: '661', repo: 'SUSE/reviewlette' }
6
+ subject { GithubConnection }
7
+ let( :connection ) { subject.new }
6
8
 
7
9
  describe '.new' do
8
10
 
9
- it 'sets up Github connection' do
10
- config = Reviewlette::GithubConnection::GITHUB_CONFIG
11
- expect(Octokit::Client).to receive(:new).with(:access_token => config['token'])
12
- subject.new
13
- end
14
- end
15
-
16
- describe '#pull_merged?' do
17
- let( :connection ) { subject.new }
18
-
19
- it 'checks if the pull is merged' do
20
- allow(connection.client).to receive(:pull_merged?).with('true', 6).and_return true
21
- expect(connection.pull_merged?('true', 6)).to be true
22
- end
23
-
24
- it 'checks if the pull is not merged' do
25
- allow(connection.client).to receive(:pull_merged?).with('false', 5).and_return false
26
- expect(connection.pull_merged?('false', 5)).to be false
11
+ it 'initializes octokit client and repo' do
12
+ expect(Octokit::Client).to receive(:new).with(:access_token => GITHUB_CONFIG['token'])
13
+ connection = subject.new
14
+ expect(connection.repo).to eq(GITHUB_CONFIG['repo'])
27
15
  end
28
16
  end
29
17
 
30
18
  describe '#add_assignee' do
31
- let( :connection ) { subject.new }
32
-
33
19
  it 'adds an assignee to the gh issue' do
34
- params = [connection.repo, 4, 'title', 'body', 'name']
35
- params2 = [connection.repo, 4, 'title', 'body', :assignee => 'name']
36
- allow(connection.client).to receive(:update_issue).with(*params2).and_return true
37
- expect(connection.add_assignee(*params)).to eq true
38
- end
39
-
40
- it 'fails to add an assignee to the gh issue' do
41
- params = [connection.repo, 4, 'title', 'body', 'name']
42
- params2 = [connection.repo, 4, 'title', 'body', :assignee => 'name']
43
- allow(connection.client).to receive(:update_issue).with(*params2).and_return false
44
- expect(connection.add_assignee(*params)).to eq false
20
+ expect(connection.client).to receive(:update_issue).with(connection.repo, 11, :assignee => 'test')
21
+ connection.add_assignee(11, 'test')
45
22
  end
46
23
  end
47
24
 
48
- describe '#comment_on_issue' do
49
- let( :connection ) { subject.new }
50
-
25
+ describe '#reviewer_comment' do
51
26
  it 'comments on a given issue' do
52
- params = [connection.repo, 4, '@name is your reviewer :thumbsup: check url']
53
- params2 = [connection.repo, 4, 'name', 'url']
54
- allow(connection.client).to receive(:add_comment).with(*params).and_return true
55
- expect(connection.comment_on_issue(*params2)).to eq true
56
- end
57
-
58
- it 'fails to comment on a given issue and fails' do
59
- params = [connection.repo, 4, '@name is your reviewer :thumbsup: check url']
60
- params2 = [connection.repo, 4, 'name', 'url']
61
- allow(connection.client).to receive(:add_comment).with(*params).and_return false
62
- expect(connection.comment_on_issue(*params2)).to eq false
63
- end
64
- end
65
-
66
- describe '#list_issues' do
67
- let( :connection ) { subject.new }
68
-
69
- it 'fails to determine if an assignee is set' do
70
- allow(connection.client).to receive_message_chain(:list_issues)
71
- connection.list_issues(connection.repo)
27
+ card = Trello::Card.new
28
+ allow(card).to receive(:url).and_return('url')
29
+ expect(connection.client).to receive(:add_comment).with(connection.repo, 11, anything)
30
+ connection.reviewer_comment(11, 'test', card)
72
31
  end
73
32
  end
74
33
 
75
34
  describe '#list_pulls' do
76
- let( :connection ) { subject.new }
77
-
78
- it 'lists a pullrequests for a given repository' do
79
- expect(connection.client).to receive(:pull_requests)
80
- connection.list_pulls(connection.repo)
35
+ it 'lists all pullrequests for a given repository' do
36
+ expect(connection.client).to receive(:pull_requests).with(connection.repo)
37
+ connection.list_pulls
81
38
  end
82
39
  end
83
40
 
84
- describe '#get_branch_name' do
85
- let( :connection ) { subject.new }
86
-
87
- it 'get branch name based on a repo and a pullrequest id' do
88
- pulls = [double({ 'head' => double({ 'ref' => 'number'})})]
89
- pr = pulls.first
90
- expect(connection.client).to receive(:pull_requests).with(connection.repo).and_return pulls
91
- expect(pulls).to receive(:[]).with(3).and_return pr
92
- expect(pr).to receive(:head).and_return pr.head
93
- connection.get_branch_name(3, connection.repo)
94
- end
95
- end
96
41
  end