gitlab-dangerfiles 0.7.0 → 1.1.0

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: d8a22cec902c95d63352af51b2b0460e7cb761ddda7ee7ab2833077686ee5428
4
- data.tar.gz: 1eb6288e842695e9811d6f8ba88cf43d8c75caa1c441a3419aed3f5988c11864
3
+ metadata.gz: f299245a993fb11dfa01fb1f8c3a09167c0fd327c07c7580368f0b7fbd0c4da5
4
+ data.tar.gz: 18b3be58359757bd1587106ddcce00d80f4ce25d6179b3ce394505449ca3fda4
5
5
  SHA512:
6
- metadata.gz: 81214e30c00e1b8c3f164a8b3bdfbc135902b5292a1064a8f4acbcd26ef5f9d9b0e83ebea83c51621e1742b2b6df13af1e81732fb4c9256bb254cac153370170
7
- data.tar.gz: dd5be048537a4604d21774622effdb3e02d82aa3aefaaecb5bdcf598a96efcbff9ade89100c753cb26cff12b85b7cded1fdde71bbae10035ea341717b9704c67
6
+ metadata.gz: 6916956a8eedeef8ef292e10a7a31ea4269648f1136c3dca198f0567f563f0534d3fa5c75e37bb66b451e817067971b62390334e4f2060988f83b611d51b6c49
7
+ data.tar.gz: e20cc032bcff74bc423d2d0b50c6026b4ea05f99fde5b053a9941249b52bf799e34cea420028d5411fe4646b52a409d886baaca2da56289e739f53fc9a9b8e61
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
- spec.add_dependency "danger"
30
+ spec.add_dependency "danger-gitlab"
31
31
 
32
32
  spec.add_development_dependency "rspec", "~> 3.0"
33
33
  spec.add_development_dependency "rspec-parameterized"
data/lib/danger/helper.rb CHANGED
@@ -19,6 +19,7 @@ module Danger
19
19
  test: "~test ~Quality for `spec/features/*`",
20
20
  engineering_productivity: '~"Engineering Productivity" for CI, Danger',
21
21
  ci_template: '~"ci::templates"',
22
+ product_intelligence: '~"product intelligence"',
22
23
  }.freeze
23
24
 
24
25
  HTTPError = Class.new(StandardError)
@@ -51,8 +52,62 @@ module Danger
51
52
  JSON.parse(rsp.body)
52
53
  end
53
54
 
55
+ def added_files
56
+ @added_files ||= if changes_from_api
57
+ changes_from_api.select { |file| file["new_file"] }.map { |file| file["new_path"] }
58
+ else
59
+ git.added_files.to_a
60
+ end
61
+ end
62
+
63
+ def modified_files
64
+ @modified_files ||= if changes_from_api
65
+ changes_from_api.select { |file| !file["new_file"] && !file["deleted_file"] && !file["renamed_file"] }.map { |file| file["new_path"] }
66
+ else
67
+ git.modified_files.to_a
68
+ end
69
+ end
70
+
71
+ def renamed_files
72
+ @renamed_files ||= if changes_from_api
73
+ changes_from_api.select { |file| file["renamed_file"] }.each_with_object([]) do |file, memo|
74
+ memo << { before: file["old_path"], after: file["new_path"] }
75
+ end
76
+ else
77
+ git.renamed_files.to_a
78
+ end
79
+ end
80
+
81
+ def deleted_files
82
+ @deleted_files ||= if changes_from_api
83
+ changes_from_api.select { |file| file["deleted_file"] }.map { |file| file["new_path"] }
84
+ else
85
+ git.deleted_files.to_a
86
+ end
87
+ end
88
+
89
+ def diff_for_file(filename)
90
+ if changes_from_api
91
+ changes_hash = changes_from_api.find { |file| file["new_path"] == filename }
92
+ changes_hash["diff"] if changes_hash
93
+ else
94
+ git.diff_for_file(filename)&.patch
95
+ end
96
+ end
97
+
98
+ def changes_from_api
99
+ return nil unless ci?
100
+ return nil if defined?(@force_changes_from_git)
101
+
102
+ @changes_from_api ||= gitlab_helper.api.merge_request_changes(gitlab_helper.mr_json["project_id"], gitlab_helper.mr_json["iid"]).to_h["changes"]
103
+ rescue
104
+ # Fallback to the Git strategy in any case
105
+ @force_changes_from_git = true
106
+ nil
107
+ end
108
+
54
109
  # Returns a list of all files that have been added, modified or renamed.
55
- # `git.modified_files` might contain paths that already have been renamed,
110
+ # `modified_files` might contain paths that already have been renamed,
56
111
  # so we need to remove them from the list.
57
112
  #
58
113
  # Considering these changes:
@@ -70,10 +125,10 @@ module Danger
70
125
  # @return [Array<String>]
71
126
  def all_changed_files
72
127
  Set.new
73
- .merge(git.added_files.to_a)
74
- .merge(git.modified_files.to_a)
75
- .merge(git.renamed_files.map { |x| x[:after] })
76
- .subtract(git.renamed_files.map { |x| x[:before] })
128
+ .merge(added_files)
129
+ .merge(modified_files)
130
+ .merge(renamed_files.map { |x| x[:after] })
131
+ .subtract(renamed_files.map { |x| x[:before] })
77
132
  .to_a
78
133
  .sort
79
134
  end
@@ -87,10 +142,10 @@ module Danger
87
142
  # "+ # Test change",
88
143
  # "- # Old change" ]
89
144
  def changed_lines(changed_file)
90
- diff = git.diff_for_file(changed_file)
145
+ diff = diff_for_file(changed_file)
91
146
  return [] unless diff
92
147
 
93
- diff.patch.split("\n").select { |line| %r{^[+-]}.match?(line) }
148
+ diff.split("\n").select { |line| %r{^[+-]}.match?(line) }
94
149
  end
95
150
 
96
151
  def release_automation?
@@ -117,23 +172,23 @@ module Danger
117
172
  # @return [Gitlab::Dangerfiles::Changes]
118
173
  def changes(categories)
119
174
  Gitlab::Dangerfiles::Changes.new([]).tap do |changes|
120
- git.added_files.each do |file|
175
+ added_files.each do |file|
121
176
  categories_for_file(file, categories).each { |category| changes << Gitlab::Dangerfiles::Change.new(file, :added, category) }
122
177
  end
123
178
 
124
- git.modified_files.each do |file|
179
+ modified_files.each do |file|
125
180
  categories_for_file(file, categories).each { |category| changes << Gitlab::Dangerfiles::Change.new(file, :modified, category) }
126
181
  end
127
182
 
128
- git.deleted_files.each do |file|
183
+ deleted_files.each do |file|
129
184
  categories_for_file(file, categories).each { |category| changes << Gitlab::Dangerfiles::Change.new(file, :deleted, category) }
130
185
  end
131
186
 
132
- git.renamed_files.map { |x| x[:before] }.each do |file|
187
+ renamed_files.map { |x| x[:before] }.each do |file|
133
188
  categories_for_file(file, categories).each { |category| changes << Gitlab::Dangerfiles::Change.new(file, :renamed_before, category) }
134
189
  end
135
190
 
136
- git.renamed_files.map { |x| x[:after] }.each do |file|
191
+ renamed_files.map { |x| x[:after] }.each do |file|
137
192
  categories_for_file(file, categories).each { |category| changes << Gitlab::Dangerfiles::Change.new(file, :renamed_after, category) }
138
193
  end
139
194
  end
@@ -169,31 +224,31 @@ module Danger
169
224
  end
170
225
 
171
226
  def mr_iid
172
- return "" unless gitlab_helper
227
+ return "" unless ci?
173
228
 
174
229
  gitlab_helper.mr_json["iid"]
175
230
  end
176
231
 
177
232
  def mr_title
178
- return "" unless gitlab_helper
233
+ return "" unless ci?
179
234
 
180
235
  gitlab_helper.mr_json["title"]
181
236
  end
182
237
 
183
238
  def mr_web_url
184
- return "" unless gitlab_helper
239
+ return "" unless ci?
185
240
 
186
241
  gitlab_helper.mr_json["web_url"]
187
242
  end
188
243
 
189
244
  def mr_labels
190
- return [] unless gitlab_helper
245
+ return [] unless ci?
191
246
 
192
247
  gitlab_helper.mr_labels
193
248
  end
194
249
 
195
250
  def mr_target_branch
196
- return "" unless gitlab_helper
251
+ return "" unless ci?
197
252
 
198
253
  gitlab_helper.mr_json["target_branch"]
199
254
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "helper"
3
4
  require_relative "../gitlab/dangerfiles/teammate"
4
5
  require_relative "../gitlab/dangerfiles/weightage/maintainers"
5
6
  require_relative "../gitlab/dangerfiles/weightage/reviewers"
@@ -25,7 +26,7 @@ module Danger
25
26
  # for each change category that a Merge Request contains.
26
27
  #
27
28
  # @return [Array<Spin>]
28
- def spin(project, categories, timezone_experiment: false)
29
+ def spin(project, categories = [nil], timezone_experiment: false)
29
30
  spins = categories.sort.map do |category|
30
31
  including_timezone = INCLUDE_TIMEZONE_FOR_CATEGORY.fetch(category, timezone_experiment)
31
32
 
@@ -59,6 +60,8 @@ module Danger
59
60
  # Fetch an already picked backend maintainer, or pick one otherwise
60
61
  spin.maintainer = backend_spin&.maintainer || spin_for_category(project, :backend, timezone_experiment: including_timezone).maintainer
61
62
  end
63
+ when :product_intelligence
64
+ spin.optional_role = :maintainer
62
65
  end
63
66
  end
64
67
 
@@ -2,5 +2,8 @@ require "gitlab/dangerfiles/version"
2
2
 
3
3
  module Gitlab
4
4
  module Dangerfiles
5
+ def self.import_plugins(danger)
6
+ danger.import_plugin(File.expand_path("../danger/*.rb", __dir__))
7
+ end
5
8
  end
6
9
  end
@@ -59,7 +59,7 @@ module Gitlab
59
59
  private
60
60
 
61
61
  def subject
62
- TitleLinting.remove_draft_flag(message_parts[0])
62
+ @subject ||= TitleLinting.remove_draft_flag(message_parts[0])
63
63
  end
64
64
 
65
65
  def subject_too_short?
@@ -75,6 +75,7 @@ module Gitlab
75
75
  end
76
76
 
77
77
  def subject_starts_with_lowercase?
78
+ return false if subject.empty?
78
79
  return false if ("A".."Z").cover?(subject[0])
79
80
 
80
81
  first_char = subject.sub(/\A(\[.+\]|\w+:)\s/, "")[0]
@@ -6,6 +6,7 @@ require_relative "emoji_checker"
6
6
  module Gitlab
7
7
  module Dangerfiles
8
8
  class CommitLinter < BaseLinter
9
+ MAX_CHANGED_FILES_IN_COMMIT = 3
9
10
  MAX_CHANGED_LINES_IN_COMMIT = 30
10
11
  SHORT_REFERENCE_REGEX = %r{([\w\-\/]+)?(?<!`)(#|!|&|%)\d+(?<!`)}.freeze
11
12
 
@@ -45,17 +45,63 @@ end
45
45
 
46
46
  RSpec.shared_context "with dangerfile" do
47
47
  let(:dangerfile) { DangerSpecHelper.testing_dangerfile }
48
- let(:added_files) { %w[added1] }
49
- let(:modified_files) { %w[modified1] }
50
- let(:deleted_files) { %w[deleted1] }
51
- let(:renamed_before_file) { "renamed_before" }
52
- let(:renamed_after_file) { "renamed_after" }
48
+ let(:added_files) { %w[added-from-git] }
49
+ let(:modified_files) { %w[modified-from-git] }
50
+ let(:deleted_files) { %w[deleted-from-git] }
51
+ let(:renamed_before_file) { "renamed_before-from-git" }
52
+ let(:renamed_after_file) { "renamed_after-from-git" }
53
53
  let(:renamed_files) { [{ before: renamed_before_file, after: renamed_after_file }] }
54
54
  let(:change_class) { Gitlab::Dangerfiles::Change }
55
55
  let(:changes_class) { Gitlab::Dangerfiles::Changes }
56
56
  let(:changes) { changes_class.new([]) }
57
57
  let(:mr_title) { "Fake Title" }
58
58
  let(:mr_labels) { [] }
59
+ let(:mr_changes_from_api) do
60
+ {
61
+ "changes" => [
62
+ {
63
+ "old_path" => "added-from-api",
64
+ "new_path" => "added-from-api",
65
+ "a_mode" => "100644",
66
+ "b_mode" => "100644",
67
+ "new_file" => true,
68
+ "renamed_file" => false,
69
+ "deleted_file" => false,
70
+ "diff" => "@@ -49,6 +49,14 @@\n- vendor/ruby/\n policy: pull\n \n+.danger-review-cache:\n",
71
+ },
72
+ {
73
+ "old_path" => "modified-from-api",
74
+ "new_path" => "modified-from-api",
75
+ "a_mode" => "100644",
76
+ "b_mode" => "100644",
77
+ "new_file" => false,
78
+ "renamed_file" => false,
79
+ "deleted_file" => false,
80
+ "diff" => "@@ -49,6 +49,14 @@\n- vendor/ruby/\n policy: pull\n \n+.danger-review-cache:\n",
81
+ },
82
+ {
83
+ "old_path" => "renamed_before-from-api",
84
+ "new_path" => "renamed_after-from-api",
85
+ "a_mode" => "100644",
86
+ "b_mode" => "100644",
87
+ "new_file" => false,
88
+ "renamed_file" => true,
89
+ "deleted_file" => false,
90
+ "diff" => "@@ -49,6 +49,14 @@\n- vendor/ruby/\n policy: pull\n \n+.danger-review-cache:\n",
91
+ },
92
+ {
93
+ "old_path" => "deleted-from-api",
94
+ "new_path" => "deleted-from-api",
95
+ "a_mode" => "100644",
96
+ "b_mode" => "100644",
97
+ "new_file" => false,
98
+ "renamed_file" => false,
99
+ "deleted_file" => true,
100
+ "diff" => "@@ -49,6 +49,14 @@\n- vendor/ruby/\n policy: pull\n \n+.danger-review-cache:\n",
101
+ },
102
+ ],
103
+ }
104
+ end
59
105
 
60
106
  let(:fake_git) { double("fake-git", added_files: added_files, modified_files: modified_files, deleted_files: deleted_files, renamed_files: renamed_files) }
61
107
  let(:fake_helper) { double("fake-helper", changes: changes, mr_iid: 1234, mr_title: mr_title, mr_labels: mr_labels) }
@@ -101,6 +101,13 @@ module Gitlab
101
101
  return true if capabilities(project).include?("#{kind} engineering_productivity")
102
102
 
103
103
  capabilities(project).include?("#{kind} backend")
104
+ when :product_intelligence
105
+ return false unless role[/Engineer, Product Intelligence/]
106
+
107
+ # any reviewer of project from Product Intelligence team can review MR
108
+ kind == :reviewer && capabilities(project).any?
109
+ when nil
110
+ capabilities(project).include?("#{kind}")
104
111
  else
105
112
  capabilities(project).include?("#{kind} #{category}")
106
113
  end
@@ -1,5 +1,5 @@
1
1
  module Gitlab
2
2
  module Dangerfiles
3
- VERSION = "0.7.0"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-dangerfiles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rémy Coutable
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-04 00:00:00.000000000 Z
11
+ date: 2021-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: danger
14
+ name: danger-gitlab
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="