gergich 0.2.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|