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 +4 -4
- data/gitlab-dangerfiles.gemspec +1 -1
- data/lib/danger/helper.rb +79 -70
- data/lib/danger/roulette.rb +2 -1
- data/lib/gitlab/dangerfiles.rb +3 -0
- data/lib/gitlab/dangerfiles/base_linter.rb +2 -1
- data/lib/gitlab/dangerfiles/changes.rb +53 -0
- data/lib/gitlab/dangerfiles/commit_linter.rb +1 -0
- data/lib/gitlab/dangerfiles/spec_helper.rb +112 -0
- data/lib/gitlab/dangerfiles/teammate.rb +2 -0
- data/lib/gitlab/dangerfiles/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9f8e727ceb4fd8d6a8163b5c2637cb117426e30d3002ae5772b7031c83bc98a
|
4
|
+
data.tar.gz: 650de232d49a5cb7a022ed53e4607ddc8941ba0615e5cc73214da44d2e838967
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe6821b98e683ead18db025365f4efe6821ca92773f8baacfec88ab12131ab1597d735a1262d2cf65928d24b9b72182a1db2d2cb3435edd6c52248eb029ecd87
|
7
|
+
data.tar.gz: e984610303236d5d6f964ed04c61f924560cf2e29b04c1b485434f0755dc9dd676d486b879972f02b4463da4d499fd070e2a8629bfb570cee93e88b0e4eaf531
|
data/gitlab-dangerfiles.gemspec
CHANGED
@@ -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
|
-
# `
|
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(
|
119
|
-
.merge(
|
120
|
-
.merge(
|
121
|
-
.subtract(
|
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 =
|
144
|
+
diff = diff_for_file(changed_file)
|
136
145
|
return [] unless diff
|
137
146
|
|
138
|
-
diff.
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
250
|
+
return "" unless ci?
|
242
251
|
|
243
252
|
gitlab_helper.mr_json["target_branch"]
|
244
253
|
end
|
data/lib/danger/roulette.rb
CHANGED
@@ -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
|
|
data/lib/gitlab/dangerfiles.rb
CHANGED
@@ -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
|
@@ -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
|
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.
|
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-
|
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
|