gergich 0.2.2 → 1.2.1

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.
Files changed (36) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +2 -2
  3. data/README.md +0 -1
  4. data/bin/check_coverage +2 -1
  5. data/bin/gergich +1 -0
  6. data/bin/master_bouncer +1 -1
  7. data/bin/run_tests.sh +8 -43
  8. data/lib/gergich.rb +20 -24
  9. data/lib/gergich/capture.rb +8 -4
  10. data/lib/gergich/capture/androidlint_capture.rb +5 -1
  11. data/lib/gergich/capture/brakeman_capture.rb +4 -2
  12. data/lib/gergich/capture/eslint_capture.rb +2 -0
  13. data/lib/gergich/capture/flake8_capture.rb +2 -0
  14. data/lib/gergich/capture/i18nliner_capture.rb +2 -0
  15. data/lib/gergich/capture/rubocop_capture.rb +2 -0
  16. data/lib/gergich/capture/shellcheck_capture.rb +2 -0
  17. data/lib/gergich/capture/stylelint_capture.rb +8 -5
  18. data/lib/gergich/capture/swiftlint_capture.rb +5 -1
  19. data/lib/gergich/cli.rb +4 -2
  20. data/lib/gergich/cli/gergich.rb +119 -118
  21. data/lib/gergich/cli/master_bouncer.rb +16 -14
  22. data/spec/gergich/capture/androidlint_capture_spec.rb +15 -10
  23. data/spec/gergich/capture/brakeman_capture_spec.rb +43 -41
  24. data/spec/gergich/capture/custom_capture_spec.rb +4 -2
  25. data/spec/gergich/capture/eslint_capture_spec.rb +6 -4
  26. data/spec/gergich/capture/flake8_capture_spec.rb +4 -2
  27. data/spec/gergich/capture/i18nliner_capture_spec.rb +6 -4
  28. data/spec/gergich/capture/rubocop_capture_spec.rb +24 -22
  29. data/spec/gergich/capture/shellcheck_capture_spec.rb +45 -43
  30. data/spec/gergich/capture/stylelint_capture_spec.rb +16 -7
  31. data/spec/gergich/capture/swiftlint_capture_spec.rb +8 -5
  32. data/spec/gergich/capture_spec.rb +6 -4
  33. data/spec/gergich_spec.rb +58 -4
  34. data/spec/spec_helper.rb +2 -0
  35. data/spec/support/capture_shared_examples.rb +2 -0
  36. metadata +39 -40
@@ -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).sort.last
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
@@ -1,4 +1,4 @@
1
- # encoding=utf-8
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(<<-OUTPUT)}"]
18
- bin/gergich:47:8: C: Prefer double-quoted strings
19
- if ENV['DEBUG']
20
- ^^^^^^^
21
- OUTPUT
17
+ "capture" => ["rubocop", format("echo %<output>s", output: 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 all_commands.map { |command| ["help", [command]] }
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
- commands << ["label", ["QA-Review", 1]]
35
- commands << ["label", ["Product-Review", 1]]
36
- commands << ["label", ["Code-Review", 1]]
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
- <<-TEXT
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
- <<-TEXT
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
- <<-TEXT
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
- rescue JSON::ParserError
111
- error("Unable to parse <comment_data> json", "comment")
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
- <<-TEXT
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
- path - the relative file path, e.g. "app/models/user.rb"
130
- position - either a number (line) or an object (range). If an object,
131
- must have the following numeric properties:
132
- * start_line
133
- * start_character
134
- * end_line
135
- * end_character
136
- message - the text of the comment
137
- severity - "info"|"warn"|"error" - this will automatically prefix the
138
- comment (e.g. "[ERROR] message here"), and the most severe
139
- comment will be used to determine the overall Code-Review
140
- score (0, -1, or -2 respectively)
141
-
142
- Note that a cover message and Code-Review score will be inferred from the
143
- most severe comment.
144
-
145
- Examples
146
- gergich comment '{"path":"foo.rb","position":3,"severity":"error",
147
- "message":"ಠ_ಠ"}'
148
- gergich comment '{"path":"bar.rb","severity":"warn",
149
- "position":{"start_line":3,"start_character":5,...},
150
- "message":"¯\\_(ツ)_/¯"}'
151
- gergich comment '[{"path":"baz.rb",...}, {...}, {...}]'
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
- <<-TEXT
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
- <<-TEXT
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
- <<-TEXT
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
- * brakeman
206
- * rubocop
207
- * eslint
208
- * i18nliner
209
- * flake8
210
- * stylelint
211
- * custom:<path>:<class_name> - file path and ruby
212
- class_name of a custom formatter.
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
- Output from the command will still go to STDOUT, and
216
- Gergich will preserve its exit status.
217
- If command is "-", Gergich will simply read from STDIN
218
- and the exit status will always be 0.
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
- gergich capture rubocop "bundle exec rubocop"
221
+ Examples:
222
+ gergich capture rubocop "bundle exec rubocop"
222
223
 
223
- gergich capture eslint eslint
224
+ gergich capture eslint eslint
224
225
 
225
- gergich capture i18nliner "rake i18nliner:check"
226
+ gergich capture i18nliner "rake i18nliner:check"
226
227
 
227
- gergich capture custom:./gergich/xss:Gergich::XSS "node script/xsslint"
228
+ gergich capture custom:./gergich/xss:Gergich::XSS "node script/xsslint"
228
229
 
229
- docker-compose run --rm web eslint | gergich capture eslint -
230
- # you might be interested in $PIPESTATUS[0]
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
- <<-TEXT
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
  }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "../cli"
2
4
 
3
5
  ENV["GERGICH_USER"] = ENV.fetch("MASTER_BOUNCER_USER", "master_bouncer")
@@ -19,7 +21,7 @@ def potentially_mergeable_changes
19
21
  "branch:master" \
20
22
  "&o=CURRENT_REVISION"
21
23
  changes = Gergich::API.get(url)
22
- changes.select { |c| c["subject"] !~ /\Awip($|\W)/i }
24
+ changes.reject { |c| c["subject"] =~ /\Awip($|\W)/i }
23
25
  end
24
26
 
25
27
  def maybe_bounce_commit!(commit)
@@ -67,22 +69,22 @@ commands = {}
67
69
 
68
70
  commands["check"] = {
69
71
  summary: "Check the current commit's age",
70
- action: ->() {
72
+ action: -> {
71
73
  maybe_bounce_commit! Gergich::Commit.new
72
74
  },
73
- help: ->() {
74
- <<-TEXT
75
- master_bouncer check
75
+ help: -> {
76
+ <<~TEXT
77
+ master_bouncer check
76
78
 
77
- Check the current commit's age, and bounce it if it's too old (-1 or -2,
78
- depending on the threshold)
79
- TEXT
79
+ Check the current commit's age, and bounce it if it's too old (-1 or -2,
80
+ depending on the threshold)
81
+ TEXT
80
82
  }
81
83
  }
82
84
 
83
85
  commands["check_all"] = {
84
86
  summary: "Check the age of all potentially mergeable changes",
85
- action: ->() {
87
+ action: -> {
86
88
  Gergich.git("fetch")
87
89
  gerrit_host = ENV["GERRIT_HOST"] || error("No GERRIT_HOST set")
88
90
 
@@ -102,12 +104,12 @@ commands["check_all"] = {
102
104
  sleep 1
103
105
  end
104
106
  },
105
- help: ->() {
106
- <<-TEXT
107
- master_bouncer check_all
107
+ help: -> {
108
+ <<~TEXT
109
+ master_bouncer check_all
108
110
 
109
- Check all open Verified+1 patchsets and bounce any that are too old.
110
- TEXT
111
+ Check all open Verified+1 patchsets and bounce any that are too old.
112
+ TEXT
111
113
  }
112
114
  }
113
115
 
@@ -1,24 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "../../support/capture_shared_examples"
2
4
 
3
5
  RSpec.describe Gergich::Capture::AndroidlintCapture do
4
- # rubocop:disable Metrics/LineLength
6
+ # rubocop:disable Layout/LineLength
5
7
  let(:rtl_hardcoded) { 'Consider adding android:drawableStart="@drawable/a_media" to better support right-to-left layouts [RtlHardcoded]' }
6
8
  let(:rtl_enabled) { "The project references RTL attributes, but does not explicitly enable or disable RTL support with android:supportsRtl in the manifest [RtlEnabled]" }
7
9
  let(:lint_error) { 'No .class files were found in project "0.0.2", so none of the classfile based checks could be run. Does the project need to be built first? [LintError]' }
8
10
  let(:unused_quantity) { 'For language "fr" (French) the following quantities are not relevant: few, zero [UnusedQuantity]' }
11
+ # rubocop:enable Layout/LineLength
9
12
  let(:output) do
10
- <<-OUTPUT
11
- /path/to/some.xml:27: Warning: #{rtl_hardcoded}
12
- android:drawableLeft="@drawable/ic_cv_media"/>
13
- ~~~~~~~~~~~~~~~~~~~~
13
+ <<~OUTPUT
14
+ /path/to/some.xml:27: Warning: #{rtl_hardcoded}
15
+ android:drawableLeft="@drawable/ic_cv_media"/>
16
+ ~~~~~~~~~~~~~~~~~~~~
14
17
 
15
- /path/to/AndroidManifest.xml: Warning: #{rtl_enabled}
18
+ /path/to/AndroidManifest.xml: Warning: #{rtl_enabled}
16
19
 
17
- /path/to/library/0.0.2: Error: #{lint_error}
20
+ /path/to/library/0.0.2: Error: #{lint_error}
18
21
 
19
- /path/to/values.xml:5: Warning: #{unused_quantity}
20
- <plurals name="number">
21
- ^
22
+ /path/to/values.xml:5: Warning: #{unused_quantity}
23
+ <plurals name="number">
24
+ ^
22
25
 
23
26
  OUTPUT
24
27
  end
@@ -28,7 +31,9 @@ RSpec.describe Gergich::Capture::AndroidlintCapture do
28
31
  {
29
32
  path: "/path/to/some.xml",
30
33
  position: 27,
34
+ # rubocop:disable Layout/LineLength
31
35
  message: "[androidlint] #{rtl_hardcoded}\n\n android:drawableLeft=\"@drawable/ic_cv_media\"/>\n ~~~~~~~~~~~~~~~~~~~~",
36
+ # rubocop:enable Layout/LineLength
32
37
  severity: "warn"
33
38
  },
34
39
  {