gitlab-dangerfiles 0.6.1 → 1.0.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: 1376c48a26c7b3a10cc3e649d1cf28f49fdf58fd7b317713b9ac9a0f3771e5a5
4
- data.tar.gz: 9ecd1d0db0f583740a73f96f6ffd14905f7a66157e427c6a11410a7bc7c70e55
3
+ metadata.gz: f9f8e727ceb4fd8d6a8163b5c2637cb117426e30d3002ae5772b7031c83bc98a
4
+ data.tar.gz: 650de232d49a5cb7a022ed53e4607ddc8941ba0615e5cc73214da44d2e838967
5
5
  SHA512:
6
- metadata.gz: e1684cb0a7b5367b37f099cad0dca796cdb5cf01fc71f36e4896268b4abc8c0ee59ed122459261f47ec1b873da8aa2355644c6074b92285ddd1b3f4215bbba86
7
- data.tar.gz: 8e8644fa64222def924524b8545397615f7335198e88d35f47fc07c450793879c0c710c380b496eb0c80a6bf856c855ec4bb58266670aff6a526ff3b9c84bc5a
6
+ metadata.gz: fe6821b98e683ead18db025365f4efe6821ca92773f8baacfec88ab12131ab1597d735a1262d2cf65928d24b9b72182a1db2d2cb3435edd6c52248eb029ecd87
7
+ data.tar.gz: e984610303236d5d6f964ed04c61f924560cf2e29b04c1b485434f0755dc9dd676d486b879972f02b4463da4d499fd070e2a8629bfb570cee93e88b0e4eaf531
@@ -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
@@ -3,6 +3,7 @@
3
3
  require "net/http"
4
4
  require "json"
5
5
  require "danger"
6
+ require_relative "../gitlab/dangerfiles/changes"
6
7
  require_relative "../gitlab/dangerfiles/teammate"
7
8
  require_relative "../gitlab/dangerfiles/title_linting"
8
9
 
@@ -22,52 +23,6 @@ module Danger
22
23
 
23
24
  HTTPError = Class.new(StandardError)
24
25
 
25
- Change = Struct.new(:file, :change_type, :category)
26
-
27
- class Changes < ::SimpleDelegator
28
- def added
29
- select_by_change_type(:added)
30
- end
31
-
32
- def modified
33
- select_by_change_type(:modified)
34
- end
35
-
36
- def deleted
37
- select_by_change_type(:deleted)
38
- end
39
-
40
- def renamed_before
41
- select_by_change_type(:renamed_before)
42
- end
43
-
44
- def renamed_after
45
- select_by_change_type(:renamed_after)
46
- end
47
-
48
- def has_category?(category)
49
- any? { |change| change.category == category }
50
- end
51
-
52
- def by_category(category)
53
- Changes.new(select { |change| change.category == category })
54
- end
55
-
56
- def categories
57
- map(&:category).uniq
58
- end
59
-
60
- def files
61
- map(&:file)
62
- end
63
-
64
- private
65
-
66
- def select_by_change_type(change_type)
67
- Changes.new(select { |change| change.change_type == change_type })
68
- end
69
- end
70
-
71
26
  def gitlab_helper
72
27
  # Unfortunately the following does not work:
73
28
  # - respond_to?(:gitlab)
@@ -96,8 +51,62 @@ module Danger
96
51
  JSON.parse(rsp.body)
97
52
  end
98
53
 
54
+ def added_files
55
+ @added_files ||= if changes_from_api
56
+ changes_from_api.select { |file| file["new_file"] }.map { |file| file["new_path"] }
57
+ else
58
+ git.added_files.to_a
59
+ end
60
+ end
61
+
62
+ def modified_files
63
+ @modified_files ||= if changes_from_api
64
+ changes_from_api.select { |file| !file["new_file"] && !file["deleted_file"] && !file["renamed_file"] }.map { |file| file["new_path"] }
65
+ else
66
+ git.modified_files.to_a
67
+ end
68
+ end
69
+
70
+ def renamed_files
71
+ @renamed_files ||= if changes_from_api
72
+ changes_from_api.select { |file| file["renamed_file"] }.each_with_object([]) do |file, memo|
73
+ memo << { before: file["old_path"], after: file["new_path"] }
74
+ end
75
+ else
76
+ git.renamed_files.to_a
77
+ end
78
+ end
79
+
80
+ def deleted_files
81
+ @deleted_files ||= if changes_from_api
82
+ changes_from_api.select { |file| file["deleted_file"] }.map { |file| file["new_path"] }
83
+ else
84
+ git.deleted_files.to_a
85
+ end
86
+ end
87
+
88
+ def diff_for_file(filename)
89
+ if changes_from_api
90
+ changes_hash = changes_from_api.find { |file| file["new_path"] == filename }
91
+ changes_hash["diff"] if changes_hash
92
+ else
93
+ git.diff_for_file(filename)&.patch
94
+ end
95
+ end
96
+
97
+ def changes_from_api
98
+ return nil unless ci?
99
+ return nil if defined?(@force_changes_from_git)
100
+
101
+ @changes_from_api ||= gitlab_helper.api.merge_request_changes(gitlab_helper.mr_json["project_id"], gitlab_helper.mr_json["iid"]).to_h["changes"]
102
+ rescue
103
+ # Fallback to the Git strategy in any case
104
+ @force_changes_from_git = true
105
+ nil
106
+ end
107
+
99
108
  # Returns a list of all files that have been added, modified or renamed.
100
- # `git.modified_files` might contain paths that already have been renamed,
109
+ # `modified_files` might contain paths that already have been renamed,
101
110
  # so we need to remove them from the list.
102
111
  #
103
112
  # Considering these changes:
@@ -115,10 +124,10 @@ module Danger
115
124
  # @return [Array<String>]
116
125
  def all_changed_files
117
126
  Set.new
118
- .merge(git.added_files.to_a)
119
- .merge(git.modified_files.to_a)
120
- .merge(git.renamed_files.map { |x| x[:after] })
121
- .subtract(git.renamed_files.map { |x| x[:before] })
127
+ .merge(added_files)
128
+ .merge(modified_files)
129
+ .merge(renamed_files.map { |x| x[:after] })
130
+ .subtract(renamed_files.map { |x| x[:before] })
122
131
  .to_a
123
132
  .sort
124
133
  end
@@ -132,10 +141,10 @@ module Danger
132
141
  # "+ # Test change",
133
142
  # "- # Old change" ]
134
143
  def changed_lines(changed_file)
135
- diff = git.diff_for_file(changed_file)
144
+ diff = diff_for_file(changed_file)
136
145
  return [] unless diff
137
146
 
138
- diff.patch.split("\n").select { |line| %r{^[+-]}.match?(line) }
147
+ diff.split("\n").select { |line| %r{^[+-]}.match?(line) }
139
148
  end
140
149
 
141
150
  def release_automation?
@@ -159,27 +168,27 @@ module Danger
159
168
  end
160
169
  end
161
170
 
162
- # @return [Changes]
171
+ # @return [Gitlab::Dangerfiles::Changes]
163
172
  def changes(categories)
164
- Changes.new([]).tap do |changes|
165
- git.added_files.each do |file|
166
- categories_for_file(file, categories).each { |category| changes << Change.new(file, :added, category) }
173
+ Gitlab::Dangerfiles::Changes.new([]).tap do |changes|
174
+ added_files.each do |file|
175
+ categories_for_file(file, categories).each { |category| changes << Gitlab::Dangerfiles::Change.new(file, :added, category) }
167
176
  end
168
177
 
169
- git.modified_files.each do |file|
170
- categories_for_file(file, categories).each { |category| changes << Change.new(file, :modified, category) }
178
+ modified_files.each do |file|
179
+ categories_for_file(file, categories).each { |category| changes << Gitlab::Dangerfiles::Change.new(file, :modified, category) }
171
180
  end
172
181
 
173
- git.deleted_files.each do |file|
174
- categories_for_file(file, categories).each { |category| changes << Change.new(file, :deleted, category) }
182
+ deleted_files.each do |file|
183
+ categories_for_file(file, categories).each { |category| changes << Gitlab::Dangerfiles::Change.new(file, :deleted, category) }
175
184
  end
176
185
 
177
- git.renamed_files.map { |x| x[:before] }.each do |file|
178
- categories_for_file(file, categories).each { |category| changes << Change.new(file, :renamed_before, category) }
186
+ renamed_files.map { |x| x[:before] }.each do |file|
187
+ categories_for_file(file, categories).each { |category| changes << Gitlab::Dangerfiles::Change.new(file, :renamed_before, category) }
179
188
  end
180
189
 
181
- git.renamed_files.map { |x| x[:after] }.each do |file|
182
- categories_for_file(file, categories).each { |category| changes << Change.new(file, :renamed_after, category) }
190
+ renamed_files.map { |x| x[:after] }.each do |file|
191
+ categories_for_file(file, categories).each { |category| changes << Gitlab::Dangerfiles::Change.new(file, :renamed_after, category) }
183
192
  end
184
193
  end
185
194
  end
@@ -214,31 +223,31 @@ module Danger
214
223
  end
215
224
 
216
225
  def mr_iid
217
- return "" unless gitlab_helper
226
+ return "" unless ci?
218
227
 
219
228
  gitlab_helper.mr_json["iid"]
220
229
  end
221
230
 
222
231
  def mr_title
223
- return "" unless gitlab_helper
232
+ return "" unless ci?
224
233
 
225
234
  gitlab_helper.mr_json["title"]
226
235
  end
227
236
 
228
237
  def mr_web_url
229
- return "" unless gitlab_helper
238
+ return "" unless ci?
230
239
 
231
240
  gitlab_helper.mr_json["web_url"]
232
241
  end
233
242
 
234
243
  def mr_labels
235
- return [] unless gitlab_helper
244
+ return [] unless ci?
236
245
 
237
246
  gitlab_helper.mr_labels
238
247
  end
239
248
 
240
249
  def mr_target_branch
241
- return "" unless gitlab_helper
250
+ return "" unless ci?
242
251
 
243
252
  gitlab_helper.mr_json["target_branch"]
244
253
  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
 
@@ -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]
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "title_linting"
4
+
5
+ module Gitlab
6
+ module Dangerfiles
7
+ Change = Struct.new(:file, :change_type, :category)
8
+
9
+ class Changes < ::SimpleDelegator
10
+ def added
11
+ select_by_change_type(:added)
12
+ end
13
+
14
+ def modified
15
+ select_by_change_type(:modified)
16
+ end
17
+
18
+ def deleted
19
+ select_by_change_type(:deleted)
20
+ end
21
+
22
+ def renamed_before
23
+ select_by_change_type(:renamed_before)
24
+ end
25
+
26
+ def renamed_after
27
+ select_by_change_type(:renamed_after)
28
+ end
29
+
30
+ def has_category?(category)
31
+ any? { |change| change.category == category }
32
+ end
33
+
34
+ def by_category(category)
35
+ Changes.new(select { |change| change.category == category })
36
+ end
37
+
38
+ def categories
39
+ map(&:category).uniq
40
+ end
41
+
42
+ def files
43
+ map(&:file)
44
+ end
45
+
46
+ private
47
+
48
+ def select_by_change_type(change_type)
49
+ Changes.new(select { |change| change.change_type == change_type })
50
+ end
51
+ end
52
+ end
53
+ end
@@ -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
 
@@ -0,0 +1,112 @@
1
+ require "danger"
2
+ require "gitlab/dangerfiles/changes"
3
+
4
+ module DangerSpecHelper
5
+ # These functions are a subset of https://github.com/danger/danger/blob/master/spec/spec_helper.rb
6
+ # If you are expanding these files, see if it's already been done ^.
7
+
8
+ # A silent version of the user interface
9
+ def self.testing_ui
10
+ Cork::Board.new(silent: true)
11
+ end
12
+
13
+ # Example environment (ENV) that would come from
14
+ # running a PR on TravisCI
15
+ def self.testing_env
16
+ {
17
+ "GITLAB_CI" => "true",
18
+ "DANGER_GITLAB_HOST" => "gitlab.example.com",
19
+ "CI_MERGE_REQUEST_IID" => 28_493,
20
+ "DANGER_GITLAB_API_TOKEN" => "123sbdq54erfsd3422gdfio",
21
+ }
22
+ end
23
+
24
+ # A stubbed out Dangerfile for use in tests
25
+ def self.testing_dangerfile
26
+ env = Danger::EnvironmentManager.new(testing_env)
27
+ Danger::Dangerfile.new(env, testing_ui)
28
+ end
29
+
30
+ def self.fake_danger
31
+ Class.new do
32
+ attr_reader :git, :gitlab, :helper
33
+
34
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
35
+ def initialize(git: nil, gitlab: nil, helper: nil)
36
+ @git = git
37
+ @gitlab = gitlab
38
+ @helper = helper
39
+ end
40
+
41
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
42
+ end
43
+ end
44
+ end
45
+
46
+ RSpec.shared_context "with dangerfile" do
47
+ let(:dangerfile) { DangerSpecHelper.testing_dangerfile }
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
+ let(:renamed_files) { [{ before: renamed_before_file, after: renamed_after_file }] }
54
+ let(:change_class) { Gitlab::Dangerfiles::Change }
55
+ let(:changes_class) { Gitlab::Dangerfiles::Changes }
56
+ let(:changes) { changes_class.new([]) }
57
+ let(:mr_title) { "Fake Title" }
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
105
+
106
+ let(:fake_git) { double("fake-git", added_files: added_files, modified_files: modified_files, deleted_files: deleted_files, renamed_files: renamed_files) }
107
+ let(:fake_helper) { double("fake-helper", changes: changes, mr_iid: 1234, mr_title: mr_title, mr_labels: mr_labels) }
108
+
109
+ before do
110
+ allow(dangerfile).to receive(:git).and_return(fake_git)
111
+ end
112
+ end
@@ -101,6 +101,8 @@ module Gitlab
101
101
  return true if capabilities(project).include?("#{kind} engineering_productivity")
102
102
 
103
103
  capabilities(project).include?("#{kind} backend")
104
+ when nil
105
+ capabilities(project).include?("#{kind}")
104
106
  else
105
107
  capabilities(project).include?("#{kind} #{category}")
106
108
  end
@@ -1,5 +1,5 @@
1
1
  module Gitlab
2
2
  module Dangerfiles
3
- VERSION = "0.6.1"
3
+ VERSION = "1.0.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.6.1
4
+ version: 1.0.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-03 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
  - - ">="
@@ -136,9 +136,11 @@ files:
136
136
  - lib/gitlab/Dangerfile
137
137
  - lib/gitlab/dangerfiles.rb
138
138
  - lib/gitlab/dangerfiles/base_linter.rb
139
+ - lib/gitlab/dangerfiles/changes.rb
139
140
  - lib/gitlab/dangerfiles/commit_linter.rb
140
141
  - lib/gitlab/dangerfiles/emoji_checker.rb
141
142
  - lib/gitlab/dangerfiles/merge_request_linter.rb
143
+ - lib/gitlab/dangerfiles/spec_helper.rb
142
144
  - lib/gitlab/dangerfiles/teammate.rb
143
145
  - lib/gitlab/dangerfiles/title_linting.rb
144
146
  - lib/gitlab/dangerfiles/version.rb