gitlab-dangerfiles 0.6.1 → 1.0.0

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