reviewlette 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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