gergich 0.2.2 → 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 +5 -5
- data/bin/check_coverage +2 -1
- data/bin/gergich +1 -0
- data/bin/master_bouncer +1 -1
- data/bin/run_tests.sh +0 -5
- data/lib/gergich.rb +17 -23
- data/lib/gergich/capture.rb +6 -2
- data/lib/gergich/capture/androidlint_capture.rb +4 -0
- data/lib/gergich/capture/brakeman_capture.rb +4 -2
- data/lib/gergich/capture/eslint_capture.rb +2 -0
- data/lib/gergich/capture/flake8_capture.rb +2 -0
- data/lib/gergich/capture/i18nliner_capture.rb +2 -0
- data/lib/gergich/capture/rubocop_capture.rb +2 -0
- data/lib/gergich/capture/shellcheck_capture.rb +2 -0
- data/lib/gergich/capture/stylelint_capture.rb +6 -4
- data/lib/gergich/capture/swiftlint_capture.rb +4 -0
- data/lib/gergich/cli.rb +4 -2
- data/lib/gergich/cli/gergich.rb +119 -118
- data/lib/gergich/cli/master_bouncer.rb +16 -14
- data/spec/gergich/capture/androidlint_capture_spec.rb +14 -9
- data/spec/gergich/capture/brakeman_capture_spec.rb +43 -41
- data/spec/gergich/capture/custom_capture_spec.rb +4 -2
- data/spec/gergich/capture/eslint_capture_spec.rb +6 -4
- data/spec/gergich/capture/flake8_capture_spec.rb +4 -2
- data/spec/gergich/capture/i18nliner_capture_spec.rb +6 -4
- data/spec/gergich/capture/rubocop_capture_spec.rb +24 -22
- data/spec/gergich/capture/shellcheck_capture_spec.rb +45 -43
- data/spec/gergich/capture/stylelint_capture_spec.rb +9 -7
- data/spec/gergich/capture/swiftlint_capture_spec.rb +7 -4
- data/spec/gergich/capture_spec.rb +6 -4
- data/spec/gergich_spec.rb +43 -4
- data/spec/spec_helper.rb +2 -0
- data/spec/support/capture_shared_examples.rb +2 -0
- metadata +35 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c35e56070c32b0ee9d3ae02336e3d27eb4831b5f4f04dc6b73e75d9e87f02908
|
4
|
+
data.tar.gz: 45ee0f9e2b95996903267e298c2347c5f6d234e86516af7677dafa999910c895
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93c5d49b94710befacbaa40b05af12a530b1dd6dbcda69349e45731ce2d8d628109390d34432b3a12f5132eec5b3b368c316c88d5b075ea81fd226d46294d507
|
7
|
+
data.tar.gz: 442c992f4077b79da2666d350d0f803ef55a40e401c0e6b79cabaff4ca5cd807380ea1cb3b99c37bc5aa7b2305323508e9017faa0d0ef0473c4cd9ef66c94b17
|
data/bin/check_coverage
CHANGED
data/bin/gergich
CHANGED
data/bin/master_bouncer
CHANGED
data/bin/run_tests.sh
CHANGED
@@ -49,9 +49,4 @@ fi
|
|
49
49
|
|
50
50
|
run_command bin/check_coverage
|
51
51
|
|
52
|
-
if [[ "$GEMNASIUM_TOKEN" && "$GEMNASIUM_ENABLED" ]]; then
|
53
|
-
# Push our dependency specification files to gemnasium for analysis
|
54
|
-
run_command gemnasium dependency_files push -f=gergich.gemspec
|
55
|
-
fi
|
56
|
-
|
57
52
|
clean_up_and_exit
|
data/lib/gergich.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "erb"
|
2
4
|
require "sqlite3"
|
3
5
|
require "json"
|
@@ -105,18 +107,9 @@ module Gergich
|
|
105
107
|
|
106
108
|
API.post(generate_url, generate_payload)
|
107
109
|
|
108
|
-
# because why not
|
109
|
-
if change_name?
|
110
|
-
API.put("/accounts/self/name", { name: whats_his_face }.to_json)
|
111
|
-
end
|
112
|
-
|
113
110
|
review_info
|
114
111
|
end
|
115
112
|
|
116
|
-
def change_name?
|
117
|
-
ENV["GERGICH_CHANGE_NAME"] != "0" && rand < 0.01 && GERGICH_USER == "gergich"
|
118
|
-
end
|
119
|
-
|
120
113
|
def anything_to_publish?
|
121
114
|
!review_info[:comments].empty? ||
|
122
115
|
!review_info[:cover_message_parts].empty? ||
|
@@ -202,7 +195,7 @@ module Gergich
|
|
202
195
|
end
|
203
196
|
|
204
197
|
def my_messages
|
205
|
-
@
|
198
|
+
@my_messages ||= API.get("/changes/#{commit.change_id}/detail")["messages"]
|
206
199
|
.select { |message| message["author"] && message["author"]["username"] == GERGICH_USER }
|
207
200
|
end
|
208
201
|
|
@@ -227,6 +220,7 @@ module Gergich
|
|
227
220
|
# then grab the comment's revision.
|
228
221
|
def current_label_revision
|
229
222
|
return nil if my_messages.empty?
|
223
|
+
|
230
224
|
@current_label_revision ||= begin
|
231
225
|
date = current_label_date
|
232
226
|
comment_for_current_label = my_messages.find { |message| message["date"] == date } ||
|
@@ -254,17 +248,13 @@ module Gergich
|
|
254
248
|
score = upcoming_score
|
255
249
|
prefix_parts = []
|
256
250
|
prefix_parts << unique_comment_prefix if multi_build_setup?
|
257
|
-
prefix_parts << score if score
|
251
|
+
prefix_parts << score if score.negative?
|
258
252
|
prefix_parts.join(":")
|
259
253
|
# [].join(":") => ""
|
260
254
|
# [-2].join(":") => "-2"
|
261
255
|
# ["some build prefix", -2].join(":") => "some build prefix:-2"
|
262
256
|
end
|
263
257
|
|
264
|
-
def whats_his_face
|
265
|
-
"#{%w[Garry Larry Terry Jerry].sample} Gergich (Bot)"
|
266
|
-
end
|
267
|
-
|
268
258
|
def review_info
|
269
259
|
@review_info ||= draft.info
|
270
260
|
end
|
@@ -306,7 +296,8 @@ module Gergich
|
|
306
296
|
ret = HTTParty.send(method, url, options).body
|
307
297
|
return ret if options[:raw]
|
308
298
|
|
309
|
-
|
299
|
+
ret = ret.sub(/\A\)\]\}'\n/, "")
|
300
|
+
if ret && ret =~ /\A("|\[|\{)/
|
310
301
|
JSON.parse("[#{ret}]")[0] # array hack so we can parse a string literal
|
311
302
|
elsif ret =~ /Not found: (?<change_id>.*)/i
|
312
303
|
raise("Cannot find Change-Id: #{Regexp.last_match[:change_id]} at #{url}.\n"\
|
@@ -321,7 +312,7 @@ module Gergich
|
|
321
312
|
end
|
322
313
|
|
323
314
|
def base_uri
|
324
|
-
@
|
315
|
+
@base_uri ||= \
|
325
316
|
ENV["GERRIT_BASE_URL"] ||
|
326
317
|
ENV.key?("GERRIT_HOST") && "https://#{ENV['GERRIT_HOST']}" ||
|
327
318
|
raise(GergichError, "need to set GERRIT_BASE_URL or GERRIT_HOST")
|
@@ -452,13 +443,16 @@ module Gergich
|
|
452
443
|
# severe comment will be used to determine the overall
|
453
444
|
# Code-Review score (0, -1, or -2 respectively)
|
454
445
|
def add_comment(path, position, message, severity)
|
446
|
+
stripped_path = path.strip
|
447
|
+
|
455
448
|
raise GergichError, "invalid position `#{position}`" unless valid_position?(position)
|
449
|
+
|
456
450
|
position = position.to_json if position.is_a?(Hash)
|
457
451
|
raise GergichError, "invalid severity `#{severity}`" unless SEVERITY_MAP.key?(severity)
|
458
452
|
raise GergichError, "no message specified" unless message.is_a?(String) && !message.empty?
|
459
453
|
|
460
454
|
db.execute "INSERT INTO comments (path, position, message, severity) VALUES (?, ?, ?, ?)",
|
461
|
-
[
|
455
|
+
[stripped_path, position, message, severity]
|
462
456
|
end
|
463
457
|
|
464
458
|
POSITION_KEYS = %w[end_character end_line start_character start_line].freeze
|
@@ -478,7 +472,7 @@ module Gergich
|
|
478
472
|
labels[row["name"]] = row["score"]
|
479
473
|
end
|
480
474
|
score = min_comment_score
|
481
|
-
labels[GERGICH_REVIEW_LABEL] = score if score < 0
|
475
|
+
labels[GERGICH_REVIEW_LABEL] = score if score < [0, labels[GERGICH_REVIEW_LABEL]].min
|
482
476
|
labels
|
483
477
|
end
|
484
478
|
end
|
@@ -535,21 +529,21 @@ module Gergich
|
|
535
529
|
end
|
536
530
|
|
537
531
|
def orphaned_message
|
538
|
-
|
532
|
+
messages = ["NOTE: I couldn't create inline comments for everything. " \
|
539
533
|
"Although this isn't technically part of your commit, you " \
|
540
534
|
"should still check it out (i.e. side effects or auto-" \
|
541
|
-
"generated from stuff you *did* change):"
|
535
|
+
"generated from stuff you *did* change):"]
|
542
536
|
|
543
537
|
other_comments.each do |file|
|
544
538
|
file.comments.each do |position, comments|
|
545
539
|
comments.each do |comment|
|
546
540
|
line = position.is_a?(Integer) ? position : position["start_line"]
|
547
|
-
|
541
|
+
messages << "#{file.path}:#{line}: #{comment}"
|
548
542
|
end
|
549
543
|
end
|
550
544
|
end
|
551
545
|
|
552
|
-
|
546
|
+
messages.join("\n\n")
|
553
547
|
end
|
554
548
|
|
555
549
|
def cover_message_parts
|
data/lib/gergich/capture.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "../gergich"
|
2
4
|
require "English"
|
3
5
|
|
@@ -35,6 +37,7 @@ module Gergich
|
|
35
37
|
if add_comments
|
36
38
|
comments.each do |comment|
|
37
39
|
next if skip_paths.any? { |path| comment[:path].start_with?(path) }
|
40
|
+
|
38
41
|
draft.add_comment comment[:path], comment[:position],
|
39
42
|
comment[:message], comment[:severity]
|
40
43
|
end
|
@@ -67,12 +70,12 @@ module Gergich
|
|
67
70
|
end
|
68
71
|
|
69
72
|
def wiretap(io, suppress_output)
|
70
|
-
output =
|
73
|
+
output = []
|
71
74
|
io.each do |line|
|
72
75
|
$stdout.puts line unless suppress_output
|
73
76
|
output << line
|
74
77
|
end
|
75
|
-
output
|
78
|
+
output.join("")
|
76
79
|
end
|
77
80
|
|
78
81
|
def load_captor(format)
|
@@ -81,6 +84,7 @@ module Gergich
|
|
81
84
|
else
|
82
85
|
captor = captors[format]
|
83
86
|
raise GergichError, "Unrecognized format `#{format}`" unless captor
|
87
|
+
|
84
88
|
captor
|
85
89
|
end
|
86
90
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Gergich
|
2
4
|
module Capture
|
3
5
|
class AndroidlintCapture < BaseCapture
|
@@ -23,6 +25,8 @@ module Gergich
|
|
23
25
|
# /path/to/values.xml:5: Warning: For language "fr" (French) the following quantities are not relevant: few, zero [UnusedQuantity]
|
24
26
|
# <plurals name="number">
|
25
27
|
# ^
|
28
|
+
#
|
29
|
+
# rubocop:enable Metrics/LineLength
|
26
30
|
pattern = /
|
27
31
|
^([^:\n]+):(\d+)?:?\s(\w+):\s(.*?)\n
|
28
32
|
([^\n]+\n
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Gergich
|
2
4
|
module Capture
|
3
5
|
class BrakemanCapture < BaseCapture
|
4
6
|
# Map Brakeman "confidence level" to severity.
|
5
7
|
# http://brakemanscanner.org/docs/confidence/
|
6
8
|
SEVERITY_MAP = {
|
7
|
-
"Weak"
|
9
|
+
"Weak" => "warn",
|
8
10
|
"Medium" => "warn",
|
9
|
-
"High"
|
11
|
+
"High" => "error"
|
10
12
|
}.freeze
|
11
13
|
|
12
14
|
def run(output)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Gergich
|
2
4
|
module Capture
|
3
5
|
class StylelintCapture < BaseCapture
|
@@ -14,7 +16,7 @@ module Gergich
|
|
14
16
|
# 2:15 ✖ Unexpected invalid hex color "#2D3B4" color-no-invalid-hex
|
15
17
|
# 30:15 ⚠ Expected "#2d3b4a" to be "#2D3B4A" color-hex-case
|
16
18
|
|
17
|
-
MESSAGE_PREFIX = "[stylelint]"
|
19
|
+
MESSAGE_PREFIX = "[stylelint]"
|
18
20
|
|
19
21
|
SEVERITY_MAP = {
|
20
22
|
"✖" => "error",
|
@@ -23,14 +25,14 @@ module Gergich
|
|
23
25
|
|
24
26
|
# example file line:
|
25
27
|
# app/stylesheets/base/_variables.scss
|
26
|
-
FILE_PATH_PATTERN = /([^\n]+)\n
|
28
|
+
FILE_PATH_PATTERN = /([^\n]+)\n/.freeze
|
27
29
|
|
28
30
|
# example error line:
|
29
31
|
# 1:15 ✖ Unexpected invalid hex color "#2D3B4" color-no-invalid-hex
|
30
|
-
ERROR_PATTERN = /^\s+(\d+):\d+\s+(✖|⚠)\s+(.*?)\s\s+[^\n]+\n
|
32
|
+
ERROR_PATTERN = /^\s+(\d+):\d+\s+(✖|⚠)\s+(.*?)\s\s+[^\n]+\n/.freeze
|
31
33
|
# rubocop:enable Style/AsciiComments
|
32
34
|
|
33
|
-
PATTERN = /#{FILE_PATH_PATTERN}((#{ERROR_PATTERN})+)
|
35
|
+
PATTERN = /#{FILE_PATH_PATTERN}((#{ERROR_PATTERN})+)/.freeze
|
34
36
|
|
35
37
|
def run(output)
|
36
38
|
output.scan(PATTERN).map { |file, errors|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Gergich
|
2
4
|
module Capture
|
3
5
|
class SwiftlintCapture < BaseCapture
|
@@ -15,6 +17,8 @@ module Gergich
|
|
15
17
|
# Example:
|
16
18
|
# /path/to/My.swift:13:22: warning: Colon Violation: Colons should be next to the identifier when specifying a type. (colon)
|
17
19
|
# /path/to/Fail.swift:80: warning: Line Length Violation: Line should be 100 characters or less: currently 108 characters (line_length)
|
20
|
+
#
|
21
|
+
# rubocop:enable Metrics/LineLength
|
18
22
|
pattern = /
|
19
23
|
^([^:\n]+):(\d+)(?::\d+)?:\s(\w+):\s(.*?)\n
|
20
24
|
/mx
|
data/lib/gergich/cli.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "shellwords"
|
2
4
|
require "English"
|
3
5
|
|
@@ -38,7 +40,7 @@ def help_command(commands)
|
|
38
40
|
end
|
39
41
|
},
|
40
42
|
help: -> {
|
41
|
-
indentation = commands.keys.map(&:size).
|
43
|
+
indentation = commands.keys.map(&:size).max
|
42
44
|
commands_help = commands
|
43
45
|
.to_a
|
44
46
|
.sort_by(&:first)
|
@@ -73,7 +75,7 @@ def run_app(commands)
|
|
73
75
|
run_command(action)
|
74
76
|
rescue GergichError
|
75
77
|
error $ERROR_INFO.message
|
76
|
-
rescue
|
78
|
+
rescue StandardError
|
77
79
|
error "Unhandled exception: #{$ERROR_INFO}\n#{$ERROR_INFO.backtrace.join("\n")}"
|
78
80
|
end
|
79
81
|
else
|
data/lib/gergich/cli/gergich.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "../cli"
|
4
4
|
require_relative "../../gergich"
|
@@ -14,11 +14,11 @@ CI_TEST_ARGS = {
|
|
14
14
|
],
|
15
15
|
"label" => ["Code-Review", 1],
|
16
16
|
"message" => ["this is a test"],
|
17
|
-
"capture" => ["rubocop", "echo #{Shellwords.escape(
|
18
|
-
bin/gergich:47:8: C: Prefer double-quoted strings
|
19
|
-
if ENV['DEBUG']
|
20
|
-
|
21
|
-
OUTPUT
|
17
|
+
"capture" => ["rubocop", "echo #{Shellwords.escape(<<~OUTPUT)}"]
|
18
|
+
bin/gergich:47:8: C: Prefer double-quoted strings
|
19
|
+
if ENV['DEBUG']
|
20
|
+
^^^^^^^
|
21
|
+
OUTPUT
|
22
22
|
}.freeze
|
23
23
|
|
24
24
|
def run_ci_test!(all_commands)
|
@@ -27,13 +27,14 @@ def run_ci_test!(all_commands)
|
|
27
27
|
commands_to_test << "status" # put it at the end, so we maximize the stuff it tests
|
28
28
|
|
29
29
|
commands = commands_to_test.map { |command| [command, CI_TEST_ARGS[command] || []] }
|
30
|
-
commands.concat
|
30
|
+
commands.concat(all_commands.map { |command| ["help", [command]] })
|
31
31
|
|
32
32
|
# after running our test commands, reset and publish frd:
|
33
33
|
commands << ["reset"]
|
34
|
-
|
35
|
-
|
36
|
-
commands << ["label", ["
|
34
|
+
# Note that while gergich should always be able to vote on these labels, he may be used to
|
35
|
+
# vone on other branches depending on project usage and project-specific permissions
|
36
|
+
commands << ["label", ["Lint-Review", 1]]
|
37
|
+
commands << ["label", ["Code-Review", 1]] # Not all projects have Lint-Review
|
37
38
|
commands << ["message", ["\`gergich citest\` checks out :thumbsup: :mj:"]]
|
38
39
|
commands << ["publish"]
|
39
40
|
|
@@ -50,21 +51,21 @@ commands = {}
|
|
50
51
|
|
51
52
|
commands["reset"] = {
|
52
53
|
summary: "Clear out pending comments/labels/messages for this patchset",
|
53
|
-
action: ->
|
54
|
+
action: -> {
|
54
55
|
Gergich::Draft.new.reset!
|
55
56
|
},
|
56
57
|
help: -> {
|
57
|
-
|
58
|
-
gergich reset
|
58
|
+
<<~TEXT
|
59
|
+
gergich reset
|
59
60
|
|
60
|
-
Clear out the draft for this patchset. Useful for testing.
|
61
|
-
TEXT
|
61
|
+
Clear out the draft for this patchset. Useful for testing.
|
62
|
+
TEXT
|
62
63
|
}
|
63
64
|
}
|
64
65
|
|
65
66
|
commands["publish"] = {
|
66
67
|
summary: "Publish the draft for this patchset",
|
67
|
-
action: ->
|
68
|
+
action: -> {
|
68
69
|
if (data = Gergich::Review.new.publish!)
|
69
70
|
puts "Published #{data[:total_comments]} comments, set score to #{data[:score]}"
|
70
71
|
else
|
@@ -72,33 +73,33 @@ commands["publish"] = {
|
|
72
73
|
end
|
73
74
|
},
|
74
75
|
help: -> {
|
75
|
-
|
76
|
-
gergich publish
|
76
|
+
<<~TEXT
|
77
|
+
gergich publish
|
77
78
|
|
78
|
-
Publish all draft comments/labels/messages for this patchset. no-op if
|
79
|
-
there are none.
|
79
|
+
Publish all draft comments/labels/messages for this patchset. no-op if
|
80
|
+
there are none.
|
80
81
|
|
81
|
-
The cover message and Code-Review label (e.g. -2) are inferred from the
|
82
|
-
comments, but labels and messages may be manually set (via `gergich
|
83
|
-
message` and `gergich labels`)
|
84
|
-
TEXT
|
82
|
+
The cover message and Code-Review label (e.g. -2) are inferred from the
|
83
|
+
comments, but labels and messages may be manually set (via `gergich
|
84
|
+
message` and `gergich labels`)
|
85
|
+
TEXT
|
85
86
|
}
|
86
87
|
}
|
87
88
|
|
88
89
|
commands["status"] = {
|
89
90
|
summary: "Show the current draft for this patchset",
|
90
|
-
action: ->
|
91
|
+
action: -> {
|
91
92
|
Gergich::Review.new.status
|
92
93
|
},
|
93
94
|
help: -> {
|
94
|
-
|
95
|
-
gergich status
|
95
|
+
<<~TEXT
|
96
|
+
gergich status
|
96
97
|
|
97
|
-
Show the current draft for this patchset
|
98
|
+
Show the current draft for this patchset
|
98
99
|
|
99
|
-
Display any labels, cover messages and inline comments that will be set
|
100
|
-
as part of this review.
|
101
|
-
TEXT
|
100
|
+
Display any labels, cover messages and inline comments that will be set
|
101
|
+
as part of this review.
|
102
|
+
TEXT
|
102
103
|
}
|
103
104
|
}
|
104
105
|
|
@@ -107,8 +108,8 @@ commands["comment"] = {
|
|
107
108
|
action: ->(comment_data) {
|
108
109
|
comment_data = begin
|
109
110
|
JSON.parse(comment_data)
|
110
|
-
|
111
|
-
|
111
|
+
rescue JSON::ParserError
|
112
|
+
error("Unable to parse <comment_data> json", "comment")
|
112
113
|
end
|
113
114
|
comment_data = [comment_data] unless comment_data.is_a?(Array)
|
114
115
|
|
@@ -120,36 +121,36 @@ commands["comment"] = {
|
|
120
121
|
comment["severity"]
|
121
122
|
end
|
122
123
|
},
|
123
|
-
help: ->
|
124
|
-
|
125
|
-
gergich comment <comment_data>
|
126
|
-
|
127
|
-
<comment_data> is a JSON object (or array of objects). Each comment object
|
128
|
-
should have the following properties:
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
Note that a cover message and Code-Review score will be inferred from the
|
143
|
-
most severe comment.
|
144
|
-
|
145
|
-
Examples
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
TEXT
|
124
|
+
help: -> {
|
125
|
+
<<~TEXT
|
126
|
+
gergich comment <comment_data>
|
127
|
+
|
128
|
+
<comment_data> is a JSON object (or array of objects). Each comment object
|
129
|
+
should have the following properties:
|
130
|
+
path - the relative file path, e.g. "app/models/user.rb"
|
131
|
+
position - either a number (line) or an object (range). If an object,
|
132
|
+
must have the following numeric properties:
|
133
|
+
* start_line
|
134
|
+
* start_character
|
135
|
+
* end_line
|
136
|
+
* end_character
|
137
|
+
message - the text of the comment
|
138
|
+
severity - "info"|"warn"|"error" - this will automatically prefix the
|
139
|
+
comment (e.g. "[ERROR] message here"), and the most severe
|
140
|
+
comment will be used to determine the overall Code-Review
|
141
|
+
score (0, -1, or -2 respectively)
|
142
|
+
|
143
|
+
Note that a cover message and Code-Review score will be inferred from the
|
144
|
+
most severe comment.
|
145
|
+
|
146
|
+
Examples
|
147
|
+
gergich comment '{"path":"foo.rb","position":3,"severity":"error",
|
148
|
+
"message":"ಠ_ಠ"}'
|
149
|
+
gergich comment '{"path":"bar.rb","severity":"warn",
|
150
|
+
"position":{"start_line":3,"start_character":5,...},
|
151
|
+
"message":"¯\\_(ツ)_/¯"}'
|
152
|
+
gergich comment '[{"path":"baz.rb",...}, {...}, {...}]'
|
153
|
+
TEXT
|
153
154
|
}
|
154
155
|
}
|
155
156
|
|
@@ -159,13 +160,13 @@ commands["message"] = {
|
|
159
160
|
draft = Gergich::Draft.new
|
160
161
|
draft.add_message message
|
161
162
|
},
|
162
|
-
help: ->
|
163
|
-
|
164
|
-
gergich message <message>
|
163
|
+
help: -> {
|
164
|
+
<<~TEXT
|
165
|
+
gergich message <message>
|
165
166
|
|
166
|
-
<message> will be appended to existing cover messages (inferred or manually
|
167
|
-
added) for this patchset.
|
168
|
-
TEXT
|
167
|
+
<message> will be appended to existing cover messages (inferred or manually
|
168
|
+
added) for this patchset.
|
169
|
+
TEXT
|
169
170
|
}
|
170
171
|
}
|
171
172
|
|
@@ -174,16 +175,16 @@ commands["label"] = {
|
|
174
175
|
action: ->(label, score) {
|
175
176
|
Gergich::Draft.new.add_label label, score
|
176
177
|
},
|
177
|
-
help: ->
|
178
|
-
|
179
|
-
gergich label <label> <score>
|
178
|
+
help: -> {
|
179
|
+
<<~TEXT
|
180
|
+
gergich label <label> <score>
|
180
181
|
|
181
|
-
Add a draft label to this patchset. If the same label is set multiple
|
182
|
-
times, the lowest score will win.
|
182
|
+
Add a draft label to this patchset. If the same label is set multiple
|
183
|
+
times, the lowest score will win.
|
183
184
|
|
184
|
-
<label> - a valid label (e.g. "Code-Review")
|
185
|
-
<score> - a valid score (e.g. -1)
|
186
|
-
TEXT
|
185
|
+
<label> - a valid label (e.g. "Code-Review")
|
186
|
+
<score> - a valid score (e.g. -1)
|
187
|
+
TEXT
|
187
188
|
}
|
188
189
|
}
|
189
190
|
|
@@ -194,63 +195,63 @@ commands["capture"] = {
|
|
194
195
|
status, = Gergich::Capture.run(format, command)
|
195
196
|
exit status
|
196
197
|
},
|
197
|
-
help: ->
|
198
|
-
|
199
|
-
gergich capture <format> <command>
|
198
|
+
help: -> {
|
199
|
+
<<~TEXT
|
200
|
+
gergich capture <format> <command>
|
200
201
|
|
201
|
-
For common linting formats, `gergich capture` can be used to automatically
|
202
|
-
do `gergich comment` calls so you don't have to wire it up yourself.
|
202
|
+
For common linting formats, `gergich capture` can be used to automatically
|
203
|
+
do `gergich comment` calls so you don't have to wire it up yourself.
|
203
204
|
|
204
|
-
<format> - One of the following:
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
205
|
+
<format> - One of the following:
|
206
|
+
* brakeman
|
207
|
+
* rubocop
|
208
|
+
* eslint
|
209
|
+
* i18nliner
|
210
|
+
* flake8
|
211
|
+
* stylelint
|
212
|
+
* custom:<path>:<class_name> - file path and ruby
|
213
|
+
class_name of a custom formatter.
|
213
214
|
|
214
|
-
<command> - The command to run whose output conforms to <format>.
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
215
|
+
<command> - The command to run whose output conforms to <format>.
|
216
|
+
Output from the command will still go to STDOUT, and
|
217
|
+
Gergich will preserve its exit status.
|
218
|
+
If command is "-", Gergich will simply read from STDIN
|
219
|
+
and the exit status will always be 0.
|
219
220
|
|
220
|
-
Examples:
|
221
|
-
|
221
|
+
Examples:
|
222
|
+
gergich capture rubocop "bundle exec rubocop"
|
222
223
|
|
223
|
-
|
224
|
+
gergich capture eslint eslint
|
224
225
|
|
225
|
-
|
226
|
+
gergich capture i18nliner "rake i18nliner:check"
|
226
227
|
|
227
|
-
|
228
|
+
gergich capture custom:./gergich/xss:Gergich::XSS "node script/xsslint"
|
228
229
|
|
229
|
-
|
230
|
-
|
231
|
-
TEXT
|
230
|
+
docker-compose run --rm web eslint | gergich capture eslint -
|
231
|
+
# you might be interested in $PIPESTATUS[0]
|
232
|
+
TEXT
|
232
233
|
}
|
233
234
|
}
|
234
235
|
|
235
236
|
commands["citest"] = {
|
236
237
|
summary: "Do a full gergich test based on the current commit",
|
237
|
-
action: ->
|
238
|
+
action: -> {
|
238
239
|
# automagically test any new command that comes along
|
239
240
|
run_ci_test!(commands.keys)
|
240
241
|
},
|
241
|
-
help: ->
|
242
|
-
|
243
|
-
gergich citest
|
244
|
-
|
245
|
-
You shouldn't need to run this locally, it runs on jenkins. It does the
|
246
|
-
following:
|
247
|
-
|
248
|
-
1. runs all the gergich commands (w/ dummy data)
|
249
|
-
2. ensure all `help` commands work
|
250
|
-
3. ensures gergich status is correct
|
251
|
-
4. resets
|
252
|
-
5. posts an actual +1
|
253
|
-
6. publishes
|
242
|
+
help: -> {
|
243
|
+
<<~TEXT
|
244
|
+
gergich citest
|
245
|
+
|
246
|
+
You shouldn't need to run this locally, it runs on jenkins. It does the
|
247
|
+
following:
|
248
|
+
|
249
|
+
1. runs all the gergich commands (w/ dummy data)
|
250
|
+
2. ensure all `help` commands work
|
251
|
+
3. ensures gergich status is correct
|
252
|
+
4. resets
|
253
|
+
5. posts an actual +1
|
254
|
+
6. publishes
|
254
255
|
TEXT
|
255
256
|
}
|
256
257
|
}
|