danger-gitlab_reviewbot 1.0.0 → 1.0.1

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.
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