audition 0.2.0 → 0.2.2

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.
@@ -34,6 +34,10 @@ module Audition
34
34
  @hyperlinks = hyperlinks
35
35
  end
36
36
 
37
+ def color?
38
+ @color
39
+ end
40
+
37
41
  def glyph(kind)
38
42
  GLYPHS.fetch(kind)[@color ? 0 : 1]
39
43
  end
@@ -135,7 +139,12 @@ module Audition
135
139
  else
136
140
  acc[f.severity] += 1
137
141
  end
138
- acc[:fixable] += 1 if f.fixable?
142
+ # Only safe autofixes count: `--fix` alone would not
143
+ # touch an unsafe-only finding, so advertising it as
144
+ # fixable would send users in circles.
145
+ if f.autofix && !f.autofix.unsafe?
146
+ acc[:fixable] += 1
147
+ end
139
148
  end
140
149
  end
141
150
  end
@@ -160,8 +169,10 @@ module Audition
160
169
  level = GITHUB_LEVELS.fetch(f.severity)
161
170
  location = f.line ? ",line=#{f.line}" : ""
162
171
  body = workflow_escape("#{f.message}. #{f.why}")
163
- "::#{level} file=#{f.path}#{location}," \
164
- "title=audition #{f.check}::#{body}"
172
+ file = property_escape(f.path)
173
+ title = property_escape("audition #{f.check}")
174
+ "::#{level} file=#{file}#{location}," \
175
+ "title=#{title}::#{body}"
165
176
  end
166
177
  lines << "audition verdict: #{VERDICTS.fetch(verdict)}"
167
178
  lines.join("\n")
@@ -208,6 +219,12 @@ module Audition
208
219
  text.gsub("%", "%25").gsub("\r", "%0D").gsub("\n", "%0A")
209
220
  end
210
221
 
222
+ # Workflow command properties additionally reserve `:` and `,`;
223
+ # an unescaped comma in a path would end the property early.
224
+ def property_escape(text)
225
+ workflow_escape(text).gsub(":", "%3A").gsub(",", "%2C")
226
+ end
227
+
211
228
  public
212
229
 
213
230
  # Text renderer, kept separate from the data so styles stay
@@ -276,8 +293,11 @@ module Audition
276
293
  wrapped.map { |line| " #{@style.dim(line)}" }
277
294
  end
278
295
 
296
+ # Tokens longer than the width (long URLs) cannot end before
297
+ # whitespace, so the first alternative would drop their head;
298
+ # the second hard-slices them instead.
279
299
  def wrap(text, width)
280
- text.scan(/\S.{0,#{width - 1}}(?=\s|\z)/m)
300
+ text.scan(/\S.{0,#{width - 1}}(?=\s|\z)|\S{#{width}}/m)
281
301
  end
282
302
 
283
303
  def dynamic_section
@@ -298,16 +318,24 @@ module Audition
298
318
  [lines.join("\n") + "\n"]
299
319
  end
300
320
 
321
+ def pluralize(count, noun)
322
+ (count == 1) ? "#{count} #{noun}" : "#{count} #{noun}s"
323
+ end
324
+
301
325
  def summary
302
326
  s = @style
303
327
  c = @report.counts
304
328
  parts = []
305
- parts << s.red("#{c[:error]} errors") if c[:error].positive?
329
+ if c[:error].positive?
330
+ parts << s.red(pluralize(c[:error], "error"))
331
+ end
306
332
  if c[:dep_error].positive?
307
- parts << s.magenta("#{c[:dep_error]} dependency errors")
333
+ parts << s.magenta(
334
+ pluralize(c[:dep_error], "dependency error")
335
+ )
308
336
  end
309
337
  if c[:warning].positive?
310
- parts << s.yellow("#{c[:warning]} warnings")
338
+ parts << s.yellow(pluralize(c[:warning], "warning"))
311
339
  end
312
340
  parts << s.cyan("#{c[:info]} info") if c[:info].positive?
313
341
  if c[:fixable].positive?
@@ -318,7 +346,8 @@ module Audition
318
346
  end
319
347
  if @report.unsafe_fixes.positive?
320
348
  parts << s.cyan(
321
- "#{@report.unsafe_fixes} more with --fix-unsafe"
349
+ pluralize(@report.unsafe_fixes, "edit") +
350
+ " with --fix-unsafe"
322
351
  )
323
352
  end
324
353
  if @report.baselined.positive?