danger-gitlab_reviewbot 1.0.2 → 1.1.5

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: 78868b60ea86cc9289c4a13598fe7807228c548190c02769f6a7007144c25bb9
4
- data.tar.gz: c4a7efe442933e89acb1efdca5602ca5bc3742c51f8874b0d220a7fd0988cae0
3
+ metadata.gz: a87855f2af8575497c523339ced8070408e9e2191bbf1eec2b4cf1ef0e431376
4
+ data.tar.gz: 5d30b4bde8ad0ce2ccf8e95c5efb75899f1e3acf40cc8e806211da79e518acdd
5
5
  SHA512:
6
- metadata.gz: 72813a9d97245481c458864a9478e0641200e529c072adb9ab4e245954c250c3ab88d64147e23d3a82896cbdadfaa0f7463454fe1db45e4072f6ab898b4090ad
7
- data.tar.gz: 56a3308398621751ce1bed2efb53a1b4f82ddf29bf105a00bd5197b06210276f0cd270b273125da66ad4ecb86e3671ba61cc67c1eb05ab12f557384ffbbfd142
6
+ metadata.gz: 90895467fe4e12bf949f2bdc38bc72e2885aa0c77ec73cd3b7d47c4cfb0fe07f1f14641e159b47dc64fdbbd17b59d29bb49805794521305d077ae726c1063953
7
+ data.tar.gz: 39ab6152e3916f0ab1e473c06ca5514608906174bf416a28d3ebe4be8ac249414020effbc57a61375335d5eee864bd122eb0b425fe01ef18bc07e2566a80bd7f
@@ -0,0 +1,34 @@
1
+ image: "ruby:2.6"
2
+
3
+ cache:
4
+ paths:
5
+ - vendor/bundle/
6
+
7
+ stages:
8
+ - test
9
+ - deploy
10
+
11
+ test:
12
+ stage: test
13
+ script:
14
+ - gem install bundler
15
+ - bundle --path vendor/bundle
16
+ - bundle exec rake spec
17
+ artifacts:
18
+ paths:
19
+ - rspec.xml
20
+ reports:
21
+ junit: rspec.xml
22
+
23
+ deploy:
24
+ stage: deploy
25
+ only:
26
+ - tags
27
+ before_script:
28
+ - 'mkdir ~/.gem && echo -e "---\r\n:rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials && chmod 0600 ~/.gem/credentials'
29
+ script:
30
+ - gem install bundler
31
+ - bundle --path vendor/bundle
32
+ - bundle exec rake build
33
+ - gem push pkg/danger-gitlab_reviewbot-${CI_COMMIT_TAG}.gem
34
+
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- danger-gitlab_reviewbot (1.0.2)
4
+ danger-gitlab_reviewbot (1.1.5)
5
5
  danger-gitlab
6
6
  danger-plugin-api (~> 1.0)
7
7
 
@@ -11,6 +11,7 @@ GEM
11
11
  addressable (2.7.0)
12
12
  public_suffix (>= 2.0.2, < 5.0)
13
13
  ast (2.4.0)
14
+ awesome_print (1.8.0)
14
15
  claide (1.0.3)
15
16
  claide-plugins (0.9.2)
16
17
  cork
@@ -20,7 +21,7 @@ GEM
20
21
  colored2 (3.1.2)
21
22
  cork (0.3.0)
22
23
  colored2 (~> 3.1)
23
- danger (8.0.0)
24
+ danger (8.0.1)
24
25
  claide (~> 1.0)
25
26
  claide-plugins (>= 0.9.2)
26
27
  colored2 (~> 3.1)
@@ -33,9 +34,9 @@ GEM
33
34
  no_proxy_fix
34
35
  octokit (~> 4.7)
35
36
  terminal-table (~> 1)
36
- danger-gitlab (5.0.1)
37
- danger (>= 5.0)
38
- gitlab (~> 4.0)
37
+ danger-gitlab (8.0.0)
38
+ danger
39
+ gitlab (~> 4.2, >= 4.2.0)
39
40
  danger-plugin-api (1.0.0)
40
41
  danger (> 2.0)
41
42
  diff-lcs (1.3)
@@ -47,7 +48,7 @@ GEM
47
48
  formatador (0.2.5)
48
49
  git (1.7.0)
49
50
  rchardet (~> 1.8)
50
- gitlab (4.14.1)
51
+ gitlab (4.15.0)
51
52
  httparty (~> 0.14, >= 0.14.0)
52
53
  terminal-table (~> 1.5, >= 1.5.1)
53
54
  guard (2.16.2)
@@ -64,10 +65,9 @@ GEM
64
65
  guard (~> 2.1)
65
66
  guard-compat (~> 1.1)
66
67
  rspec (>= 2.99.0, < 4.0)
67
- httparty (0.18.0)
68
+ httparty (0.18.1)
68
69
  mime-types (~> 3.0)
69
70
  multi_xml (>= 0.5.2)
70
- jaro_winkler (1.5.4)
71
71
  kramdown (2.2.1)
72
72
  rexml
73
73
  kramdown-parser-gfm (1.1.0)
@@ -76,7 +76,7 @@ GEM
76
76
  rb-fsevent (>= 0.9.3)
77
77
  rb-inotify (>= 0.9.7)
78
78
  lumberjack (1.2.4)
79
- method_source (1.0.0)
79
+ method_source (0.9.2)
80
80
  mime-types (3.3.1)
81
81
  mime-types-data (~> 3.2015)
82
82
  mime-types-data (3.2020.0512)
@@ -95,9 +95,11 @@ GEM
95
95
  parallel (1.19.1)
96
96
  parser (2.7.1.2)
97
97
  ast (~> 2.4.0)
98
- pry (0.13.1)
99
- coderay (~> 1.1)
100
- method_source (~> 1.0)
98
+ pry (0.12.2)
99
+ coderay (~> 1.1.0)
100
+ method_source (~> 0.9.0)
101
+ pry-nav (0.3.0)
102
+ pry (>= 0.9.10, < 0.13.0)
101
103
  public_suffix (4.0.5)
102
104
  rainbow (3.0.0)
103
105
  rake (13.0.1)
@@ -112,15 +114,14 @@ GEM
112
114
  rspec-mocks (~> 3.9.0)
113
115
  rspec-core (3.9.2)
114
116
  rspec-support (~> 3.9.3)
115
- rspec-expectations (3.9.1)
117
+ rspec-expectations (3.9.2)
116
118
  diff-lcs (>= 1.2.0, < 2.0)
117
119
  rspec-support (~> 3.9.0)
118
120
  rspec-mocks (3.9.1)
119
121
  diff-lcs (>= 1.2.0, < 2.0)
120
122
  rspec-support (~> 3.9.0)
121
123
  rspec-support (3.9.3)
122
- rubocop (0.82.0)
123
- jaro_winkler (~> 1.5.1)
124
+ rubocop (0.83.0)
124
125
  parallel (~> 1.10)
125
126
  parser (>= 2.7.0.1)
126
127
  rainbow (>= 2.2.2, < 4.0)
@@ -142,12 +143,14 @@ PLATFORMS
142
143
  ruby
143
144
 
144
145
  DEPENDENCIES
146
+ awesome_print
145
147
  bundler (~> 2.1)
146
148
  danger-gitlab_reviewbot!
147
- guard (~> 2.14)
148
- guard-rspec (~> 4.7)
149
+ guard
150
+ guard-rspec
149
151
  listen (= 3.0.7)
150
152
  pry
153
+ pry-nav
151
154
  rake
152
155
  rspec
153
156
  rubocop
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ['fabio.gallonetto@curve.com']
11
11
  spec.description = %q{A review raffle bot for Gitlab }
12
12
  spec.summary = %q{A review raffle bot for Gitlab.}
13
- spec.homepage = 'https://github.com/curve-technology/danger-gitlab_reviewbot'
13
+ spec.homepage = 'https://git.curve.tools/fabio.gallonetto/danger-gitlab_reviewbot'
14
14
  spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -33,8 +33,8 @@ Gem::Specification.new do |spec|
33
33
  spec.add_development_dependency "yard"
34
34
 
35
35
  # Makes testing easy via `bundle exec guard`
36
- spec.add_development_dependency 'guard', '~> 2.14'
37
- spec.add_development_dependency 'guard-rspec', '~> 4.7'
36
+ spec.add_development_dependency 'guard'
37
+ spec.add_development_dependency 'guard-rspec'
38
38
 
39
39
  # If you want to work on older builds of ruby
40
40
  spec.add_development_dependency 'listen', '3.0.7'
@@ -47,4 +47,7 @@ Gem::Specification.new do |spec|
47
47
  #
48
48
  # This will stop test execution and let you inspect the results
49
49
  spec.add_development_dependency 'pry'
50
+ spec.add_development_dependency 'pry-nav'
51
+ spec.add_development_dependency 'awesome_print'
52
+
50
53
  end
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gitlab_reviewbot/gem_version"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gitlab_reviewbot/plugin"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GitlabReviewbot
2
- VERSION = "1.0.2".freeze
4
+ VERSION = "1.1.5"
3
5
  end
@@ -1,4 +1,6 @@
1
- require 'gitlab'
1
+ # frozen_string_literal: true
2
+
3
+ require "gitlab"
2
4
 
3
5
  module Gitlab
4
6
  class User
@@ -25,12 +27,12 @@ module Gitlab
25
27
  res = group_members(group_id)
26
28
 
27
29
  developer_access_level = 30
28
- res.select { |u| u.state == 'active' && u.access_level >= developer_access_level }.map { |u| User.new(u.id, u.username) }
30
+ res.select { |u| u.state == "active" && u.access_level >= developer_access_level }.map { |u| User.new(u.id, u.username) }
29
31
  end
30
32
 
31
33
  def assign_mr_to_users(project_id, mr_iid, users)
32
34
  user_ids = users.map(&:id)
33
- update_merge_request(project_id, mr_iid, 'assignee_ids' => user_ids)
35
+ update_merge_request(project_id, mr_iid, "assignee_ids" => user_ids)
34
36
  end
35
37
 
36
38
  def fetch_author_for_mr(project_id, mr_iid)
@@ -39,30 +41,34 @@ module Gitlab
39
41
  end
40
42
 
41
43
  def fetch_mrs_requiring_review(project_id)
42
- merge_requests(project_id, :state => 'opened', :per_page => '100').select { |mr| mr.merge_status != 'can_be_merged' }
44
+ merge_requests(project_id, state: "opened", per_page: "100").reject { |mr| mr.merge_status == "can_be_merged" }
45
+ end
46
+
47
+ def find_user_with_username(username)
48
+ users({ username: username }).map { |u| User.new(u.id, u.username) }
43
49
  end
44
50
 
45
51
  def users_with_pending_mr_review(project_id)
46
52
  outstanding_mrs = fetch_mrs_requiring_review(project_id)
47
53
  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']
54
+ assignees_id_map = all_assignees.each_with_object({}) do |a, acc|
55
+ aid = a["id"]
56
+ ausername = a["username"]
51
57
  assignee = acc[aid] || User.new(aid, ausername)
52
58
  assignee.review_count += 1
53
59
  acc[aid] = assignee
54
- acc
55
- }
60
+ end
56
61
  assignees_id_map.values
57
62
  end
58
63
 
59
64
  def fetch_mr_reviewers(project_id, mr_iid)
60
- merge_request(project_id, mr_iid).assignees.map { |u| User.new(u['id'], u['username']) }
65
+ merge_request(project_id, mr_iid).assignees.map { |u| User.new(u["id"], u["username"]) }
61
66
  end
62
67
 
63
68
  private
69
+
64
70
  def search_group(group_name)
65
- short_name = group_name.split('/').last
71
+ short_name = group_name.split("/").last
66
72
  res = group_search(short_name)
67
73
  res = res.find { |i| i.full_path == group_name }
68
74
 
@@ -74,4 +80,3 @@ module Gitlab
74
80
  end
75
81
  end
76
82
  end
77
-
@@ -1,5 +1,6 @@
1
- require 'gitlab_reviewbot/strategies'
1
+ # frozen_string_literal: true
2
2
 
3
+ require "gitlab_reviewbot/strategies"
3
4
 
4
5
  module Danger
5
6
  # This is your plugin class. Any attributes or methods you expose here will
@@ -20,8 +21,7 @@ module Danger
20
21
  # @tags monday, weekends, time, rattata
21
22
  #
22
23
  class DangerGitlabReviewbot < Plugin
23
-
24
- # Define the group to take the reviewers from.
24
+ # Define the group to take the reviewers from.
25
25
  # NOTE: This is the group full path as in 'tech/iOS' instead of just the group name
26
26
  #
27
27
  # @return String
@@ -32,7 +32,7 @@ module Danger
32
32
  # NOTE: The plugin won't remove existing assigned reviewers
33
33
  #
34
34
  # @return Int
35
- attr_accessor :assignees_amount
35
+ attr_writer :assignees_amount
36
36
  def assignees_amount
37
37
  @assignees_amount || 1
38
38
  end
@@ -44,17 +44,15 @@ module Danger
44
44
  # * Danger::AssignStrategies::LeastBusyStrategy - assign the N users with the least amount of open MRs
45
45
  # to review
46
46
  #
47
- attr_accessor :strategy
48
- def strategy
49
- @strategy || Danger::AssignStrategies::RandomStrategy
47
+ def strategy=(klass)
48
+ @strategy = klass.new(client: gitlab.api, project: project_id, mr_iid: mr_iid)
50
49
  end
51
50
 
51
+
52
52
  # Call this method from the Dangerfile to assign reviewers to your merge requests
53
53
  # @return The usernames list of assigned reviewes [Array<String>]
54
54
  #
55
55
  def assign!
56
- project_id = ENV['CI_PROJECT_ID']
57
- mr_iid = ENV['CI_MERGE_REQUEST_IID']
58
56
  if mr_iid.nil?
59
57
  raise "Env variable CI_MERGE_REQUEST_IID doesn't point to a valid merge request iid"
60
58
  end
@@ -63,27 +61,52 @@ module Danger
63
61
  raise "Env variable CI_PROJECT_ID doesn't point to a valid project id"
64
62
  end
65
63
 
66
- current_assignees = (ENV['CI_MERGE_REQUEST_ASSIGNEES'] || '').split(',') #buggy?
67
- already_assigned_count = current_assignees.length
68
- required_assignees_count = [assignees_amount - already_assigned_count, 0].max
64
+ current_assignees = (ENV["CI_MERGE_REQUEST_ASSIGNEES"] || "").split(",") # buggy?
65
+ # already_assigned_count = current_assignees.length
66
+ # required_assignees_count = [assignees_amount - already_assigned_count, 0].max
69
67
 
70
- puts "Project ID: #{project_id}" if verbose
71
- puts "MR IID: #{mr_iid}" if verbose
72
- puts "Currently assigned: #{current_assignees}" if verbose
73
- # puts "Required: #{required_assignees_count}" if @verbose
68
+ ui.puts "Project ID: #{project_id}" if verbose
69
+ ui.puts "MR IID: #{mr_iid}" if verbose
70
+ ui.puts "Currently assigned: #{current_assignees}" if verbose
71
+ # puts "Required: #{required_assignees_count}" if @verbose
74
72
 
75
73
  # if required_assignees_count == 0
76
- # puts "Nothing to do" if @verbose
74
+ # puts "Nothing to do" if verbose
77
75
  # return
78
76
  # end
79
77
 
80
- strategy_class = strategy.new(client: gitlab.api, project: project_id, mr: mr_iid, group: gitlab_group)
78
+ @strategy.group_name = gitlab_group
81
79
 
82
- assignees = strategy_class.assign! assignees_amount
80
+ assignees = @strategy.assign! assignees_amount
83
81
 
84
- puts "Assigning: #{assignees}" if verbose
82
+ ui.puts "Assigning: #{assignees}" if verbose
85
83
  return assignees
86
84
  end
85
+
86
+ private
87
+
88
+ attr_reader :strategy
89
+
90
+ def project_id
91
+ ENV["CI_PROJECT_ID"]
92
+ end
93
+
94
+ def mr_iid
95
+ ENV["CI_MERGE_REQUEST_IID"]
96
+ end
97
+
98
+ # Once a strategy is in place, adopt the conf methods
99
+ def method_missing(method, *args)
100
+ super unless method.to_s.start_with? "strategy_"
101
+ if strategy.respond_to? method.to_s.delete_prefix("strategy_")
102
+ strategy.send(method.to_s.delete_prefix("strategy_"), *args)
103
+ else
104
+ super
105
+ end
106
+ end
107
+
108
+ def respond_to_missing?(method_name, include_private = false)
109
+ method_name.to_s.start_with?("strategy_") || super
110
+ end
87
111
  end
88
112
  end
89
-
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Danger
2
4
  module AssignStrategies
3
- require 'gitlab_reviewbot/strategies/strategy'
4
- require 'gitlab_reviewbot/strategies/random'
5
- require 'gitlab_reviewbot/strategies/least_busy'
5
+ require "gitlab_reviewbot/strategies/strategy"
6
+ require "gitlab_reviewbot/strategies/random"
7
+ require "gitlab_reviewbot/strategies/least_busy"
6
8
  end
7
9
  end
8
-
@@ -1,21 +1,21 @@
1
- require 'gitlab_reviewbot/gitlab'
1
+ # frozen_string_literal: true
2
+
3
+ require "gitlab_reviewbot/gitlab"
2
4
 
3
5
  module Danger
4
6
  module AssignStrategies
5
7
  class LeastBusyStrategy < Strategy
6
8
  def assignees(amount)
7
- users_in_group = fetch_users_in_group()
8
- author = fetch_author()
9
- invalid_assignees = [ fetch_author() ] + fetch_assigned_reviewers()
9
+ # This doesn't fetch the review count for the users so we need to fetch it separately later
10
+ users_in_group = fetch_users_in_group
11
+ invalid_assignees = [fetch_author] + fetch_assigned_reviewers
10
12
 
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
+ group_users_with_reviews_pending = client.users_with_pending_mr_review(project_id).filter { |u| users_in_group.include? u }
14
+ group_users_without_reviews_pending = users_in_group.filter { |u| !group_users_with_reviews_pending.include? u }
13
15
 
14
- (users_with_reviews_pending + users_without_reviews_pending).filter { |u| u.id != author.id }
15
- .sort_by(&:review_count)
16
- .first(amount)
16
+ candidates = (group_users_with_reviews_pending + group_users_without_reviews_pending).filter { |u| !invalid_assignees.include? u }
17
+ candidates.shuffle.sort_by(&:review_count).first(amount)
17
18
  end
18
19
  end
19
20
  end
20
21
  end
21
-
@@ -1,12 +1,14 @@
1
- require 'gitlab_reviewbot/gitlab'
1
+ # frozen_string_literal: true
2
+
3
+ require "gitlab_reviewbot/gitlab"
2
4
 
3
5
  module Danger
4
6
  module AssignStrategies
5
7
  class RandomStrategy < Strategy
6
8
  def assignees(amount)
7
- invalid_assignees = [ fetch_author() ] + fetch_assigned_reviewers()
8
- fetch_users_in_group.filter { |u| ! invalid_assignees.include? u }
9
- .sample(amount)
9
+ invalid_assignees = [fetch_author] + fetch_assigned_reviewers
10
+ fetch_users_in_group.filter { |u| !invalid_assignees.include? u }
11
+ .sample(amount)
10
12
  end
11
13
  end
12
14
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Danger
2
4
  module AssignStrategies
3
5
  class Strategy
@@ -5,26 +7,27 @@ module Danger
5
7
  attr_accessor :project_id
6
8
  attr_accessor :group_name
7
9
  attr_accessor :client
10
+ attr_accessor :excluded_users
8
11
 
9
- def initialize(client:, project:, mr:, group:)
12
+ def initialize(client:, project:, mr_iid:)
10
13
  @client = client
11
14
  @project_id = project
12
- @mr_iid = mr
13
- @group_name = group
15
+ @mr_iid = mr_iid
16
+ @excluded_users = []
14
17
  end
15
18
 
16
19
  def assign!(amount)
17
- currently_assigned = fetch_assigned_reviewers()
18
- return [] if (amount - currently_assigned.length) == 0
20
+ currently_assigned = fetch_assigned_reviewers
21
+ return [] if (amount - currently_assigned.length) <= 0
19
22
 
20
23
  to_be_assigned = assignees(amount - currently_assigned.length)
21
24
  all_assignees = currently_assigned + to_be_assigned
22
25
 
23
- response = client.assign_mr_to_users(project_id, mr_iid, all_assignees)
26
+ client.assign_mr_to_users(project_id, mr_iid, all_assignees)
24
27
  all_assignees.map(&:username)
25
28
  end
26
29
 
27
- def assignees(amount)
30
+ def assignees(_amount)
28
31
  raise "To be implemented in the subclasses"
29
32
  end
30
33
 
@@ -37,9 +40,13 @@ module Danger
37
40
  end
38
41
 
39
42
  def fetch_users_in_group
40
- client.fetch_users_for_group(@group_name)
43
+ excluded = @excluded_users.map do |u|
44
+ server_user = client.find_user_with_username(u).first
45
+ raise "ERROR: Invalid username #{u} among excluded_users" if server_user.nil?
46
+ server_user
47
+ end
48
+ client.fetch_users_for_group(@group_name).filter { |u| !excluded.include? u }
41
49
  end
42
50
  end
43
51
  end
44
52
  end
45
-
@@ -1,4 +1,6 @@
1
- require File.expand_path("../spec_helper", __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("spec_helper", __dir__)
2
4
 
3
5
  module Danger
4
6
  describe Danger::DangerGitlabReviewbot do
@@ -11,46 +13,50 @@ module Danger
11
13
  #
12
14
  describe "with Dangerfile" do
13
15
  before do
14
- testing_env.each { |k,v| ENV[k] = "#{v}" }
16
+ testing_env.each { |k, v| ENV[k] = v.to_s }
15
17
 
16
18
  @dangerfile = testing_dangerfile
17
19
  @plugin = @dangerfile.gitlab_reviewbot
18
- @plugin.strategy = Danger::AssignStrategies::RandomStrategy
19
20
  @strategy_mock = instance_double(Danger::AssignStrategies::Strategy)
20
21
  allow(Danger::AssignStrategies::RandomStrategy).to receive(:new).and_return(@strategy_mock)
22
+ allow(@strategy_mock).to receive(:group_name=).with("tech/ios")
23
+ @plugin.strategy = Danger::AssignStrategies::RandomStrategy
24
+ @plugin.gitlab_group = "tech/ios"
21
25
  end
22
26
 
23
27
  it "Assign one reviewer" do
24
- @plugin.gitlab_group = 'tech/ios'
25
-
26
- expect(@strategy_mock).to receive(:assign!).with(1).and_return(['Sam'])
28
+ expect(@strategy_mock).to receive(:assign!).with(1).and_return(["Sam"])
27
29
 
28
30
  @plugin.assign!
29
31
  end
30
32
  it "Assign one reviewer" do
31
- @plugin.gitlab_group = 'tech/ios'
32
-
33
- expect(@strategy_mock).to receive(:assign!).with(1).and_return(['Sam'])
33
+ expect(@strategy_mock).to receive(:assign!).with(1).and_return(["Sam"])
34
34
 
35
35
  @plugin.assign!
36
36
  end
37
37
 
38
38
  it "Assign multiple reviewers" do
39
- @plugin.gitlab_group = 'tech/ios'
40
39
  @plugin.assignees_amount = 2
41
40
 
42
- expect(@strategy_mock).to receive(:assign!).with(2).and_return(['Sam, Nic'])
41
+ expect(@strategy_mock).to receive(:assign!).with(2).and_return(["Sam, Nic"])
43
42
 
44
43
  @plugin.assign!
45
44
  end
46
45
 
47
- ['CI_PROJECT_ID', 'CI_MERGE_REQUEST_IID'].each do |var|
46
+ it "Correctly sets strategy options" do
47
+ expect(@strategy_mock).to receive(:excluded_users=)
48
+ expect(@strategy_mock).to receive(:excluded_users).and_return([])
49
+
50
+ @plugin.strategy_excluded_users = ["Tom"]
51
+ @plugin.strategy_excluded_users << "Sam"
52
+ end
53
+
54
+ ["CI_PROJECT_ID", "CI_MERGE_REQUEST_IID"].each do |var|
48
55
  it "Fails when required #{var} variables are not available" do
49
56
  ENV[var] = nil
50
- expect{@plugin.assign!}.to raise_error(RuntimeError)
57
+ expect { @plugin.assign! }.to raise_error(RuntimeError)
51
58
  end
52
59
  end
53
60
  end
54
61
  end
55
62
  end
56
-
@@ -1,24 +1,27 @@
1
- require File.expand_path("../spec_helper", __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("spec_helper", __dir__)
2
4
 
3
5
  module Danger
4
6
  describe Danger::AssignStrategies::LeastBusyStrategy do
5
7
  before do
6
- testing_env.each { |k,v| ENV[k] = "#{v}" }
8
+ testing_env.each { |k, v| ENV[k] = v.to_s }
7
9
  @dangerfile = testing_dangerfile
8
10
 
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')
11
+ @sam = Gitlab::User.new(1, "Sam")
12
+ @tom = Gitlab::User.new(2, "Tom")
13
+ @nic = Gitlab::User.new(3, "Nic")
14
+ @luke = Gitlab::User.new(4, "Luke")
13
15
 
14
16
  @mock_client = double(Gitlab::Client)
15
17
  @author = @nic
16
18
  @nic.review_count = 0
17
19
  @members = [@author, @tom, @sam, @luke]
18
20
  allow(@mock_client).to receive(:fetch_author_for_mr).and_return(@author)
19
- allow(@mock_client).to receive(:fetch_users_for_group).with(2200).and_return(@members)
21
+ allow(@mock_client).to receive(:fetch_users_for_group).with("tech/ios").and_return(@members)
20
22
 
21
- @strategy = AssignStrategies::LeastBusyStrategy.new(client: @mock_client, project: 10, mr: 110, group: 2200)
23
+ @strategy = AssignStrategies::LeastBusyStrategy.new(client: @mock_client, project: 10, mr_iid: 110)
24
+ @strategy.group_name = "tech/ios"
22
25
  end
23
26
 
24
27
  it "Assign the one least busy" do
@@ -89,6 +92,44 @@ module Danger
89
92
 
90
93
  @strategy.assign!(1)
91
94
  end
95
+
96
+ # TODO: This should go up to the superclass for testing
97
+ it "honours excluded users" do
98
+ allow(@mock_client).to receive(:fetch_mr_reviewers).with(10, 110).and_return([])
99
+ @tom.review_count = 0
100
+ @sam.review_count = 4
101
+ @luke.review_count = 3
102
+ users_with_pending_mr_review = [@author, @sam, @luke]
103
+ expect(@mock_client).to receive(:users_with_pending_mr_review).and_return(users_with_pending_mr_review)
104
+
105
+ allow(@mock_client).to receive(:find_user_with_username).with("Tom").and_return([@tom])
106
+ @strategy.excluded_users = ["Tom"]
107
+
108
+ expect(@mock_client).to receive(:assign_mr_to_users) do |project, mr, users|
109
+ expect(project).to be == 10
110
+ expect(mr).to be == 110
111
+ expect(users).to contain_exactly(@luke)
112
+ end
113
+
114
+ @strategy.assign!(1)
115
+ end
116
+
117
+ it "Raises error when excluded_user is invalid" do
118
+ allow(@mock_client).to receive(:fetch_mr_reviewers).with(10, 110).and_return([])
119
+
120
+ allow(@mock_client).to receive(:find_user_with_username).with("WrongTom").and_return([])
121
+ @strategy.excluded_users = ["WrongTom"]
122
+
123
+ expect { @strategy.assign!(1) }.to raise_error("ERROR: Invalid username WrongTom among excluded_users")
124
+ end
125
+
126
+ # it "test" do
127
+ # strategy = AssignStrategies::LeastBusyStrategy.new(client: @dangerfile.gitlab.api, project: 346, mr_iid: 960)
128
+ # strategy.excluded_users << 'fabio.gallonetto'
129
+ # strategy.group_name = 'tech/ios'
130
+ # require 'pry'
131
+ # binding.pry
132
+ # puts strategy.assign!(2)
133
+ # end
92
134
  end
93
135
  end
94
-
@@ -1,23 +1,27 @@
1
- require File.expand_path("../spec_helper", __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("spec_helper", __dir__)
2
4
 
3
5
  module Danger
4
6
  describe Danger::AssignStrategies::RandomStrategy do
5
7
  before do
6
- testing_env.each { |k,v| ENV[k] = "#{v}" }
8
+ testing_env.each { |k, v| ENV[k] = v.to_s }
7
9
  @dangerfile = testing_dangerfile
8
10
 
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')
11
+ @sam = Gitlab::User.new(1, "Sam")
12
+ @tom = Gitlab::User.new(2, "Tom")
13
+ @nic = Gitlab::User.new(3, "Nic")
14
+ @luke = Gitlab::User.new(4, "Luke")
15
+ @lei = Gitlab::User.new(5, "Lei")
13
16
 
14
17
  @mock_client = double(Gitlab::Client)
15
- @author = @nic
18
+ @author = @lei
16
19
  @members = [@author, @tom, @sam]
17
20
  allow(@mock_client).to receive(:fetch_author_for_mr).and_return(@author)
18
- allow(@mock_client).to receive(:fetch_users_for_group).with(2200).and_return(@members)
21
+ allow(@mock_client).to receive(:fetch_users_for_group).with("tech/ios").and_return(@members)
19
22
 
20
- @strategy = AssignStrategies::RandomStrategy.new(client: @mock_client, project: 10, mr: 110, group: 2200)
23
+ @strategy = AssignStrategies::RandomStrategy.new(client: @mock_client, project: 10, mr_iid: 110)
24
+ @strategy.group_name = "tech/ios"
21
25
  end
22
26
 
23
27
  it "assign the right amount of reviewers" do
@@ -53,8 +57,5 @@ module Danger
53
57
 
54
58
  @strategy.assign!(2)
55
59
  end
56
-
57
-
58
60
  end
59
61
  end
60
-
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "pathname"
2
- ROOT = Pathname.new(File.expand_path("../../", __FILE__))
4
+ ROOT = Pathname.new(File.expand_path("..", __dir__))
3
5
  $:.unshift((ROOT + "lib").to_s)
4
6
  $:.unshift((ROOT + "spec").to_s)
5
7
 
@@ -9,7 +11,7 @@ require "pry"
9
11
  require "rspec"
10
12
  require "danger"
11
13
 
12
- if `git remote -v` == ''
14
+ if `git remote -v` == ""
13
15
  puts "You cannot run tests without setting a local git remote on this repo"
14
16
  puts "It's a weird side-effect of Danger's internals."
15
17
  exit(0)
@@ -50,12 +52,12 @@ end
50
52
  # running a PR on TravisCI
51
53
  def testing_env
52
54
  {
53
- 'CI_MERGE_REQUEST_IID' => '549',
54
- 'CI_MERGE_REQUEST_PROJECT_PATH' => '...',
55
- 'CI_MERGE_REQUEST_PROJECT_URL' => '...',
56
- 'DANGER_GITLAB_HOST' => 'github.com', # This needs to be the same as where the repo is stored due to Danger internals :facepalm:
57
- 'CI_API_V4_URL' => "https://gitlab.com/api/v4",
58
- 'CI_PROJECT_ID' => '346',
55
+ "CI_MERGE_REQUEST_IID" => "549",
56
+ "CI_MERGE_REQUEST_PROJECT_PATH" => "...",
57
+ "CI_MERGE_REQUEST_PROJECT_URL" => "...",
58
+ "DANGER_GITLAB_HOST" => "git.curve.tools", # This needs to be the same as where the repo is stored due to Danger internals :facepalm:
59
+ "CI_API_V4_URL" => "https://git.curve.tools/api/v4",
60
+ "CI_PROJECT_ID" => "346",
59
61
  "GITLAB_CI" => true,
60
62
  "DANGER_GITLAB_API_TOKEN" => "token-token-token"
61
63
  }
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.2
4
+ version: 1.1.5
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-13 00:00:00.000000000 Z
11
+ date: 2020-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: danger-plugin-api
@@ -112,30 +112,30 @@ dependencies:
112
112
  name: guard
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: '2.14'
117
+ version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
- version: '2.14'
124
+ version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: guard-rspec
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - "~>"
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
- version: '4.7'
131
+ version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - "~>"
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
- version: '4.7'
138
+ version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: listen
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +164,34 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: pry-nav
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: awesome_print
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
167
195
  description: 'A review raffle bot for Gitlab '
168
196
  email:
169
197
  - fabio.gallonetto@curve.com
@@ -172,6 +200,7 @@ extensions: []
172
200
  extra_rdoc_files: []
173
201
  files:
174
202
  - ".gitignore"
203
+ - ".gitlab-ci.yml"
175
204
  - ".rubocop.yml"
176
205
  - Gemfile
177
206
  - Gemfile.lock
@@ -193,7 +222,7 @@ files:
193
222
  - spec/least_busy_strategy_spec.rb
194
223
  - spec/random_strategy_spec.rb
195
224
  - spec/spec_helper.rb
196
- homepage: https://github.com/curve-technology/danger-gitlab_reviewbot
225
+ homepage: https://git.curve.tools/fabio.gallonetto/danger-gitlab_reviewbot
197
226
  licenses:
198
227
  - MIT
199
228
  metadata: {}