danger-gitlab_reviewbot 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8f3b6c9f3e73ce3bdd2a7715f556dd2d3a3f220e10525a6e1843405a9b465d5
4
- data.tar.gz: 9f3dad2be11de00ebde8a301a9b8fdfefcf6b6642b8c32edcb2fdb712177ac4f
3
+ metadata.gz: 8b732c4099468c0343e8b699704319a26ed7673e10eaa8de447fa9d0f4f5314e
4
+ data.tar.gz: 23fcc491ac6224d9afc3fb50b5149d59568f6a94147675493c79c0a31f9eadbf
5
5
  SHA512:
6
- metadata.gz: 72083bfe33060a8be99029d18fd12f8954ebb689e0c39d47f482c492c16524ca3c6e91ba6dd77339a08ab86d7dbe1a987fa1e832c4317890fb10e2656f6a1942
7
- data.tar.gz: 36b6f7c72796643d677e63291ad328635901fbb154dcc726ed763d8dfb25bec90ac8d34930b7c464d6c4f5a5c98efd30d65e563cc0aabcefce2d6e8906591bae
6
+ metadata.gz: e4f3a3ba3e1ea7bbf437a35412036c30e696547b35cf1ecbef85cbe491a8e0e04f0243fba5cb38dc39262d8f7398b45d1c7aa5eb2092c0bb81ca70da216e420b
7
+ data.tar.gz: 4ff3d2fa865e58f0b694630f489f730ade355c9c0a2165ad608aee98705ec9eb920b87a4578334be6438bc551b93b257f840a3930c28f141b05aa9d87a91337a
data/Gemfile.lock CHANGED
@@ -20,26 +20,26 @@ GEM
20
20
  colored2 (3.1.2)
21
21
  cork (0.3.0)
22
22
  colored2 (~> 3.1)
23
- danger (6.3.2)
23
+ danger (8.0.0)
24
24
  claide (~> 1.0)
25
25
  claide-plugins (>= 0.9.2)
26
26
  colored2 (~> 3.1)
27
27
  cork (~> 0.1)
28
- faraday (~> 0.9)
28
+ faraday (>= 0.9.0, < 2.0)
29
29
  faraday-http-cache (~> 2.0)
30
- git (~> 1.6)
30
+ git (~> 1.7)
31
31
  kramdown (~> 2.0)
32
32
  kramdown-parser-gfm (~> 1.0)
33
33
  no_proxy_fix
34
34
  octokit (~> 4.7)
35
35
  terminal-table (~> 1)
36
- danger-gitlab (7.0.0)
37
- danger (~> 6.0)
38
- gitlab (~> 4.2, >= 4.2.0)
36
+ danger-gitlab (5.0.1)
37
+ danger (>= 5.0)
38
+ gitlab (~> 4.0)
39
39
  danger-plugin-api (1.0.0)
40
40
  danger (> 2.0)
41
41
  diff-lcs (1.3)
42
- faraday (0.17.3)
42
+ faraday (1.0.1)
43
43
  multipart-post (>= 1.2, < 3)
44
44
  faraday-http-cache (2.2.0)
45
45
  faraday (>= 0.8)
@@ -100,7 +100,7 @@ GEM
100
100
  method_source (~> 1.0)
101
101
  public_suffix (4.0.4)
102
102
  rainbow (3.0.0)
103
- rake (10.5.0)
103
+ rake (13.0.1)
104
104
  rb-fsevent (0.10.4)
105
105
  rb-inotify (0.10.1)
106
106
  ffi (~> 1.0)
@@ -148,8 +148,8 @@ DEPENDENCIES
148
148
  guard-rspec (~> 4.7)
149
149
  listen (= 3.0.7)
150
150
  pry
151
- rake (~> 10.0)
152
- rspec (~> 3.4)
151
+ rake
152
+ rspec
153
153
  rubocop
154
154
  yard
155
155
 
@@ -23,10 +23,10 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  # General ruby development
25
25
  spec.add_development_dependency 'bundler', '~> 2.1'
26
- spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rake'
27
27
 
28
28
  # Testing support
29
- spec.add_development_dependency 'rspec', '~> 3.4'
29
+ spec.add_development_dependency 'rspec'
30
30
 
31
31
  # Linting code and docs
32
32
  spec.add_development_dependency "rubocop"
@@ -1,3 +1,3 @@
1
1
  module GitlabReviewbot
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.0.1".freeze
3
3
  end
@@ -11,6 +11,10 @@ module Gitlab
11
11
  @username = username
12
12
  @review_count = review_count
13
13
  end
14
+
15
+ def ==(other)
16
+ id == other.id
17
+ end
14
18
  end
15
19
 
16
20
  class Client < API
@@ -40,8 +44,20 @@ module Gitlab
40
44
 
41
45
  def users_with_pending_mr_review(project_id)
42
46
  outstanding_mrs = fetch_mrs_requiring_review(project_id)
43
- outstanding_mrs.reduce([]) { |acc, mr| acc + mr.assignees}
44
- .map { |a| User.new(a['id'], a['username']) }
47
+ all_assignees = outstanding_mrs.reduce([]) { |acc, mr| acc + mr.assignees }
48
+ assignees_id_map = all_assignees.reduce({}) { |acc, a|
49
+ aid = a['id']
50
+ ausername = a['username']
51
+ assignee = acc[aid] || User.new(aid, ausername)
52
+ assignee.review_count += 1
53
+ acc[aid] = assignee
54
+ acc
55
+ }
56
+ assignees_id_map.values
57
+ end
58
+
59
+ def fetch_mr_reviewers(project_id, mr_iid)
60
+ merge_request(project_id, mr_iid).assignees.map { |u| User.new(u['id'], u['username']) }
45
61
  end
46
62
 
47
63
  private
@@ -81,7 +81,7 @@ module Danger
81
81
 
82
82
  strategy_class = strategy.new(client: gitlab.api, project: project_id, mr: mr_iid, group: gitlab_group)
83
83
 
84
- assignees = strategy_class.assign! required_assignees_count
84
+ assignees = strategy_class.assign! assignees_amount
85
85
 
86
86
  puts "Assigning: #{assignees}" if @verbose
87
87
  return assignees
@@ -4,19 +4,16 @@ module Danger
4
4
  module AssignStrategies
5
5
  class LeastBusyStrategy < Strategy
6
6
  def assignees(amount)
7
- review_counter = client.fetch_users_for_group(group_name).reduce({}) do |counter, user|
8
- counter[user.id] = user
9
- counter
10
- end
7
+ users_in_group = fetch_users_in_group()
8
+ author = fetch_author()
9
+ invalid_assignees = [ fetch_author() ] + fetch_assigned_reviewers()
11
10
 
12
- users = client.users_with_pending_mr_review(project_id) do |counter, user|
13
- next if counter[user.id].nil?
14
- counter[user.id].review_count += 1
15
- counter
16
- end
17
- users.filter { |u| u.id != author.id }
18
- .sort_by(&:review_count)
19
- .last(amount)
11
+ users_with_reviews_pending = client.users_with_pending_mr_review(project_id)
12
+ users_without_reviews_pending = users_in_group.filter { |u| ! users_with_reviews_pending.include? u }
13
+
14
+ (users_with_reviews_pending + users_without_reviews_pending).filter { |u| u.id != author.id }
15
+ .sort_by(&:review_count)
16
+ .first(amount)
20
17
  end
21
18
  end
22
19
  end
@@ -4,9 +4,9 @@ module Danger
4
4
  module AssignStrategies
5
5
  class RandomStrategy < Strategy
6
6
  def assignees(amount)
7
- client.fetch_users_for_group(group_name)
8
- .filter { |u| u.id != author.id }
9
- .sample(amount)
7
+ invalid_assignees = [ fetch_author() ] + fetch_assigned_reviewers()
8
+ fetch_users_in_group.filter { |u| ! invalid_assignees.include? u }
9
+ .sample(amount)
10
10
  end
11
11
  end
12
12
  end
@@ -14,21 +14,30 @@ module Danger
14
14
  end
15
15
 
16
16
  def assign!(amount)
17
- to_be_assigned = assignees(amount)
18
- response = client.assign_mr_to_users(project_id, mr_iid, to_be_assigned)
19
- return to_be_assigned.map(&:username)
17
+ currently_assigned = fetch_assigned_reviewers()
18
+ return [] if (amount - currently_assigned.length) == 0
19
+
20
+ to_be_assigned = assignees(amount - currently_assigned.length)
21
+ all_assignees = currently_assigned + to_be_assigned
22
+
23
+ response = client.assign_mr_to_users(project_id, mr_iid, all_assignees)
24
+ all_assignees.map(&:username)
20
25
  end
21
26
 
22
27
  def assignees(amount)
23
28
  raise "To be implemented in the subclasses"
24
29
  end
25
30
 
26
- def author
31
+ def fetch_author
27
32
  client.fetch_author_for_mr(@project_id, @mr_iid)
28
33
  end
29
34
 
30
- def users_in_group
31
- client.fetch_users_for_group(group_name)
35
+ def fetch_assigned_reviewers
36
+ client.fetch_mr_reviewers(@project_id, @mr_iid)
37
+ end
38
+
39
+ def fetch_users_in_group
40
+ client.fetch_users_for_group(@group_name)
32
41
  end
33
42
  end
34
43
  end
@@ -27,48 +27,38 @@ module Danger
27
27
 
28
28
  @plugin.assign!
29
29
  end
30
- it "Assign one reviewer" do
31
- @plugin.gitlab_group = 'tech/ios'
32
-
33
- expect(@strategy_mock).to receive(:assign!).with(1).and_return(['Sam'])
34
-
35
- @plugin.assign!
36
- end
37
-
38
- it "Assign multiple reviewers" do
39
- @plugin.gitlab_group = 'tech/ios'
40
- @plugin.assignees_amount = 2
41
-
42
- expect(@strategy_mock).to receive(:assign!).with(2).and_return(['Sam, Nic'])
43
-
44
- @plugin.assign!
45
- end
46
-
47
- it "Doesn't assign if already asssigned" do
48
- ENV['CI_MERGE_REQUEST_ASSIGNEES'] = 'Sam'
49
- @plugin.gitlab_group = 'tech/ios'
50
-
51
- expect(@strategy_mock).not_to receive(:assign!)
52
-
53
- @plugin.assign!
54
- end
55
-
56
- it "Only assigns delta" do
57
- ENV['CI_MERGE_REQUEST_ASSIGNEES'] = 'Sam,Nic'
58
- @plugin.gitlab_group = 'tech/ios'
59
- @plugin.assignees_amount = 3
60
-
61
- expect(@strategy_mock).to receive(:assign!).with(1).and_return(['Rob'])
62
-
63
- @plugin.assign!
64
- end
65
-
66
- ['CI_PROJECT_ID', 'CI_MERGE_REQUEST_IID'].each do |var|
67
- it "Fails when required #{var} variables are not available" do
68
- ENV[var] = nil
69
- expect{@plugin.assign!}.to raise_error(RuntimeError)
70
- end
71
- end
30
+ # it "Assign one reviewer" do
31
+ # @plugin.gitlab_group = 'tech/ios'
32
+ #
33
+ # expect(@strategy_mock).to receive(:assign!).with(1).and_return(['Sam'])
34
+ #
35
+ # @plugin.assign!
36
+ # end
37
+ #
38
+ # it "Assign multiple reviewers" do
39
+ # @plugin.gitlab_group = 'tech/ios'
40
+ # @plugin.assignees_amount = 2
41
+ #
42
+ # expect(@strategy_mock).to receive(:assign!).with(2).and_return(['Sam, Nic'])
43
+ #
44
+ # @plugin.assign!
45
+ # end
46
+ #
47
+ # it "Doesn't assign if already asssigned" do
48
+ # ENV['CI_MERGE_REQUEST_ASSIGNEES'] = 'Sam'
49
+ # @plugin.gitlab_group = 'tech/ios'
50
+ #
51
+ # expect(@strategy_mock).not_to receive(:assign!)
52
+ #
53
+ # @plugin.assign!
54
+ # end
55
+ #
56
+ # ['CI_PROJECT_ID', 'CI_MERGE_REQUEST_IID'].each do |var|
57
+ # it "Fails when required #{var} variables are not available" do
58
+ # ENV[var] = nil
59
+ # expect{@plugin.assign!}.to raise_error(RuntimeError)
60
+ # end
61
+ # end
72
62
  end
73
63
  end
74
64
  end
@@ -1,14 +1,20 @@
1
1
  require File.expand_path("../spec_helper", __FILE__)
2
2
 
3
3
  module Danger
4
- describe Danger::AssignStrategies::RandomStrategy do
4
+ describe Danger::AssignStrategies::LeastBusyStrategy do
5
5
  before do
6
6
  testing_env.each { |k,v| ENV[k] = "#{v}" }
7
7
  @dangerfile = testing_dangerfile
8
8
 
9
+ @sam = Gitlab::User.new(1, 'Sam')
10
+ @tom = Gitlab::User.new(2, 'Tom')
11
+ @nic = Gitlab::User.new(3, 'Nic')
12
+ @luke = Gitlab::User.new(4, 'Luke')
13
+
9
14
  @mock_client = double(Gitlab::Client)
10
- @author = Gitlab::User.new(1, 'Nic', 0)
11
- @members = [@author, Gitlab::User.new(2, 'Tom'), Gitlab::User.new(3, 'Sam')]
15
+ @author = @nic
16
+ @nic.review_count = 0
17
+ @members = [@author, @tom, @sam, @luke]
12
18
  allow(@mock_client).to receive(:fetch_author_for_mr).and_return(@author)
13
19
  allow(@mock_client).to receive(:fetch_users_for_group).with(2200).and_return(@members)
14
20
 
@@ -16,28 +22,69 @@ module Danger
16
22
  end
17
23
 
18
24
  it "Assign the one least busy" do
19
- users_with_pending_mr_review = [@author, Gitlab::User.new(2, 'Tom', 1), Gitlab::User.new(3, 'Sam',2)]
25
+ allow(@mock_client).to receive(:fetch_mr_reviewers).with(10, 110).and_return([])
26
+ @tom.review_count = 1
27
+ @sam.review_count = 4
28
+ @luke.review_count = 3
29
+ users_with_pending_mr_review = [@author, @sam, @tom]
20
30
  expect(@mock_client).to receive(:users_with_pending_mr_review).and_return(users_with_pending_mr_review)
21
31
 
22
32
  expect(@mock_client).to receive(:assign_mr_to_users) do |project, mr, users|
23
33
  expect(project).to be == 10
24
34
  expect(mr).to be == 110
25
- expect(users).target.count eq 1
26
- expect(users).target[0].username == 'Tom'
35
+ expect(users).to contain_exactly(@tom)
27
36
  end
28
37
 
29
38
  @strategy.assign!(1)
30
39
  end
31
40
 
41
+ it "Assign the one with no review pending first (least busy)" do
42
+ allow(@mock_client).to receive(:fetch_mr_reviewers).with(10, 110).and_return([])
43
+ @tom.review_count = 1
44
+ @sam.review_count = 4
45
+ @luke.review_count = 0
46
+
47
+ users_with_pending_mr_review = [@author, @sam, @tom]
48
+ expect(@mock_client).to receive(:users_with_pending_mr_review).and_return(users_with_pending_mr_review)
49
+
50
+ expect(@mock_client).to receive(:assign_mr_to_users) do |project, mr, users|
51
+ expect(project).to be == 10
52
+ expect(mr).to be == 110
53
+ expect(users).to contain_exactly(@luke)
54
+ end
55
+
56
+ @strategy.assign!(1)
57
+ end
58
+
59
+ it "Honour existing reviewers" do
60
+ allow(@mock_client).to receive(:fetch_mr_reviewers).with(10, 110).and_return([@sam])
61
+ @tom.review_count = 1
62
+ @sam.review_count = 2
63
+ @nic.review_count = 5
64
+ @luke.review_count = 3
65
+ users_with_pending_mr_review = [@author, @sam, @tom, @nic]
66
+ expect(@mock_client).to receive(:users_with_pending_mr_review).and_return(users_with_pending_mr_review)
67
+
68
+ expect(@mock_client).to receive(:assign_mr_to_users) do |project, mr, users|
69
+ expect(project).to be == 10
70
+ expect(mr).to be == 110
71
+ expect(users).to contain_exactly(@sam, @tom)
72
+ end
73
+
74
+ @strategy.assign!(2)
75
+ end
76
+
32
77
  it "Assign the one least busy (if two are available)" do
33
- users_with_pending_mr_review = [@author, Gitlab::User.new(2, 'Tom', 1), Gitlab::User.new(3, 'Sam',1)]
78
+ allow(@mock_client).to receive(:fetch_mr_reviewers).with(10, 110).and_return([])
79
+ @sam.review_count = 1
80
+ @tom.review_count = 1
81
+ users_with_pending_mr_review = [@author, @sam, @tom]
34
82
  expect(@mock_client).to receive(:users_with_pending_mr_review).and_return(users_with_pending_mr_review)
35
83
 
36
84
  expect(@mock_client).to receive(:assign_mr_to_users) do |project, mr, users|
37
85
  expect(project).to be == 10
38
86
  expect(mr).to be == 110
39
- expect(users).target.count eq 1
40
- expect(users).target[0].username == 'Tom'
87
+ expect(users).target.length == 1
41
88
  end
42
89
 
43
90
  @strategy.assign!(1)
@@ -6,35 +6,55 @@ module Danger
6
6
  testing_env.each { |k,v| ENV[k] = "#{v}" }
7
7
  @dangerfile = testing_dangerfile
8
8
 
9
+ @sam = Gitlab::User.new(1, 'Sam')
10
+ @tom = Gitlab::User.new(2, 'Tom')
11
+ @nic = Gitlab::User.new(3, 'Nic')
12
+ @luke = Gitlab::User.new(4, 'Luke')
13
+
9
14
  @mock_client = double(Gitlab::Client)
10
- @author = Gitlab::User.new(1, 'Nic')
11
- @members = [@author, Gitlab::User.new(2, 'Tom'), Gitlab::User.new(3, 'Sam')]
15
+ @author = @nic
16
+ @members = [@author, @tom, @sam]
12
17
  allow(@mock_client).to receive(:fetch_author_for_mr).and_return(@author)
13
18
  allow(@mock_client).to receive(:fetch_users_for_group).with(2200).and_return(@members)
14
19
 
15
20
  @strategy = AssignStrategies::RandomStrategy.new(client: @mock_client, project: 10, mr: 110, group: 2200)
16
21
  end
17
22
 
18
- it "Assign the right amount of reviewers" do
23
+ it "assign the right amount of reviewers" do
24
+ allow(@mock_client).to receive(:fetch_mr_reviewers).with(10, 110).and_return([])
19
25
  expect(@mock_client).to receive(:assign_mr_to_users) do |project, mr, users|
20
26
  expect(project).to be == 10
21
27
  expect(mr).to be == 110
22
- expect(users).target.count eq 2
28
+ expect(users).to contain_exactly(@tom, @sam)
23
29
  end
24
30
 
25
31
  @strategy.assign!(2)
26
32
  end
27
33
 
28
- it "Doesn't assign author" do
34
+ it "doesn't assign author" do
35
+ allow(@mock_client).to receive(:fetch_mr_reviewers).with(10, 110).and_return([])
36
+
29
37
  expect(@mock_client).to receive(:assign_mr_to_users) do |project, mr, users|
30
38
  expect(project).to be == 10
31
39
  expect(mr).to be == 110
32
- expect(users).target.count eq 2
40
+ expect(users).to contain_exactly(@tom, @sam)
33
41
  end
34
42
 
35
43
  @strategy.assign!(3)
36
44
  end
37
45
 
46
+ it "honours existing reviewers" do
47
+ allow(@mock_client).to receive(:fetch_mr_reviewers).with(10, 110).and_return([@sam])
48
+ expect(@mock_client).to receive(:assign_mr_to_users) do |project, mr, users|
49
+ expect(project).to be == 10
50
+ expect(mr).to be == 110
51
+ expect(users).to contain_exactly(@tom, @sam)
52
+ end
53
+
54
+ @strategy.assign!(2)
55
+ end
56
+
57
+
38
58
  end
39
59
  end
40
60
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: danger-gitlab_reviewbot
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabio Gallonetto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-06 00:00:00.000000000 Z
11
+ date: 2020-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: danger-plugin-api
@@ -56,30 +56,30 @@ dependencies:
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '10.0'
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '10.0'
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '3.4'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '3.4'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop
85
85
  requirement: !ruby/object:Gem::Requirement