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