docscribe 1.4.2 → 1.5.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 +4 -4
- data/README.md +465 -130
- data/lib/docscribe/cli/check_for_comments.rb +183 -0
- data/lib/docscribe/cli/config_builder.rb +107 -53
- data/lib/docscribe/cli/formatters/json.rb +294 -0
- data/lib/docscribe/cli/formatters/sarif.rb +235 -0
- data/lib/docscribe/cli/formatters/text.rb +208 -0
- data/lib/docscribe/cli/formatters.rb +26 -0
- data/lib/docscribe/cli/generate.rb +45 -45
- data/lib/docscribe/cli/init.rb +14 -6
- data/lib/docscribe/cli/options.rb +190 -88
- data/lib/docscribe/cli/rbs_gen.rb +529 -0
- data/lib/docscribe/cli/run.rb +210 -152
- data/lib/docscribe/cli/sigs.rb +366 -0
- data/lib/docscribe/cli/update_types.rb +103 -0
- data/lib/docscribe/cli.rb +21 -13
- data/lib/docscribe/config/defaults.rb +5 -1
- data/lib/docscribe/config/emit.rb +17 -0
- data/lib/docscribe/config/filtering.rb +18 -25
- data/lib/docscribe/config/loader.rb +15 -11
- data/lib/docscribe/config/plugin.rb +1 -1
- data/lib/docscribe/config/rbs.rb +41 -9
- data/lib/docscribe/config/sorbet.rb +9 -12
- data/lib/docscribe/config/sorting.rb +1 -1
- data/lib/docscribe/config/template.rb +9 -1
- data/lib/docscribe/config/utils.rb +11 -9
- data/lib/docscribe/config.rb +2 -4
- data/lib/docscribe/infer/ast_walk.rb +1 -1
- data/lib/docscribe/infer/literals.rb +6 -11
- data/lib/docscribe/infer/names.rb +2 -3
- data/lib/docscribe/infer/params.rb +15 -17
- data/lib/docscribe/infer/raises.rb +3 -5
- data/lib/docscribe/infer/returns.rb +542 -140
- data/lib/docscribe/infer.rb +22 -23
- data/lib/docscribe/inline_rewriter/collector.rb +159 -164
- data/lib/docscribe/inline_rewriter/doc_block.rb +145 -115
- data/lib/docscribe/inline_rewriter/doc_builder.rb +1026 -723
- data/lib/docscribe/inline_rewriter/source_helpers.rb +49 -49
- data/lib/docscribe/inline_rewriter/tag_sorter.rb +82 -85
- data/lib/docscribe/inline_rewriter.rb +495 -492
- data/lib/docscribe/parsing.rb +29 -10
- data/lib/docscribe/plugin/base/collector_plugin.rb +2 -1
- data/lib/docscribe/plugin/base/tag_plugin.rb +0 -1
- data/lib/docscribe/plugin/context.rb +28 -18
- data/lib/docscribe/plugin/registry.rb +26 -27
- data/lib/docscribe/plugin/tag.rb +9 -14
- data/lib/docscribe/plugin.rb +17 -16
- data/lib/docscribe/types/provider_chain.rb +4 -2
- data/lib/docscribe/types/rbs/collection_loader.rb +2 -2
- data/lib/docscribe/types/rbs/provider.rb +60 -44
- data/lib/docscribe/types/rbs/type_formatter.rb +224 -83
- data/lib/docscribe/types/signature.rb +22 -42
- data/lib/docscribe/types/sorbet/base_provider.rb +24 -19
- data/lib/docscribe/types/sorbet/rbi_provider.rb +3 -3
- data/lib/docscribe/types/sorbet/source_provider.rb +3 -2
- data/lib/docscribe/types/yard/formatter.rb +100 -0
- data/lib/docscribe/types/yard/parser.rb +240 -0
- data/lib/docscribe/types/yard/types.rb +52 -0
- data/lib/docscribe/version.rb +1 -1
- metadata +33 -1
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'docscribe/version'
|
|
5
|
+
|
|
6
|
+
module Docscribe
|
|
7
|
+
module CLI
|
|
8
|
+
module Formatters
|
|
9
|
+
# Output formatter producing RuboCop-compatible JSON.
|
|
10
|
+
#
|
|
11
|
+
# stdout: complete JSON document with all findings.
|
|
12
|
+
# stderr: progress markers only (same as text mode).
|
|
13
|
+
class Json
|
|
14
|
+
SEVERITY_MAP = {
|
|
15
|
+
missing_param: 'convention',
|
|
16
|
+
missing_return: 'convention',
|
|
17
|
+
missing_raise: 'convention',
|
|
18
|
+
missing_visibility: 'convention',
|
|
19
|
+
missing_module_function_note: 'convention',
|
|
20
|
+
insert_full_doc_block: 'convention',
|
|
21
|
+
unsorted_tags: 'convention',
|
|
22
|
+
updated_param: 'warning',
|
|
23
|
+
updated_return: 'warning'
|
|
24
|
+
}.freeze
|
|
25
|
+
|
|
26
|
+
COP_NAME_MAP = {
|
|
27
|
+
missing_param: 'Docscribe/MissingParam',
|
|
28
|
+
missing_return: 'Docscribe/MissingReturn',
|
|
29
|
+
missing_raise: 'Docscribe/MissingRaise',
|
|
30
|
+
missing_visibility: 'Docscribe/MissingVisibility',
|
|
31
|
+
missing_module_function_note: 'Docscribe/MissingModuleFunctionNote',
|
|
32
|
+
insert_full_doc_block: 'Docscribe/MissingDocBlock',
|
|
33
|
+
unsorted_tags: 'Docscribe/UnsortedTags',
|
|
34
|
+
updated_param: 'Docscribe/UpdatedParam',
|
|
35
|
+
updated_return: 'Docscribe/UpdatedReturn'
|
|
36
|
+
}.freeze
|
|
37
|
+
|
|
38
|
+
# Output JSON check summary.
|
|
39
|
+
#
|
|
40
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
41
|
+
# @param [Docscribe::CLI::Formatters::opts] options runtime options hash
|
|
42
|
+
# @return [void]
|
|
43
|
+
def format_check_summary(state:, options:)
|
|
44
|
+
puts JSON.generate(build_document(state, options))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Output JSON write summary.
|
|
48
|
+
#
|
|
49
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
50
|
+
# @param [Docscribe::CLI::Formatters::opts] options runtime options hash
|
|
51
|
+
# @return [void]
|
|
52
|
+
def format_write_summary(state:, options:)
|
|
53
|
+
puts JSON.generate(build_document(state, options))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
# Build full JSON document.
|
|
59
|
+
#
|
|
60
|
+
# @private
|
|
61
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
62
|
+
# @param [Docscribe::CLI::Formatters::opts] _options runtime options hash
|
|
63
|
+
# @return [Hash<Symbol, Object>]
|
|
64
|
+
def build_document(state, _options)
|
|
65
|
+
document_hash(build_files(state), state)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Build document hash structure.
|
|
69
|
+
#
|
|
70
|
+
# @private
|
|
71
|
+
# @param [Array<Hash<Symbol, Object>>] files files offenses array
|
|
72
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
73
|
+
# @return [Hash<Symbol, Object>]
|
|
74
|
+
def document_hash(files, state)
|
|
75
|
+
{
|
|
76
|
+
metadata: metadata_hash,
|
|
77
|
+
files: files,
|
|
78
|
+
summary: summary_hash(files, state)
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Build tool metadata hash.
|
|
83
|
+
#
|
|
84
|
+
# @private
|
|
85
|
+
# @return [Hash<Symbol, String>]
|
|
86
|
+
def metadata_hash
|
|
87
|
+
{
|
|
88
|
+
docscribe_version: Docscribe::VERSION,
|
|
89
|
+
ruby_version: RUBY_VERSION
|
|
90
|
+
}
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Build summary statistics hash.
|
|
94
|
+
#
|
|
95
|
+
# @private
|
|
96
|
+
# @param [Array<Hash<Symbol, Object>>] files files offenses array
|
|
97
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
98
|
+
# @return [Hash<Symbol, Integer>]
|
|
99
|
+
def summary_hash(files, state)
|
|
100
|
+
{
|
|
101
|
+
offense_count: files.sum { |f| f[:offenses].size },
|
|
102
|
+
target_file_count: files.size,
|
|
103
|
+
inspected_file_count: inspected_count(state),
|
|
104
|
+
error_count: state[:error_paths].size
|
|
105
|
+
}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Build files array from state.
|
|
109
|
+
#
|
|
110
|
+
# @private
|
|
111
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
112
|
+
# @return [Array<Hash<Symbol, Object>>]
|
|
113
|
+
def build_files(state)
|
|
114
|
+
files = [] #: Array[Hash[untyped, untyped]]
|
|
115
|
+
|
|
116
|
+
append_check_files(state, files) if state[:fail_paths].any? || state[:type_mismatch_paths].any?
|
|
117
|
+
append_corrected_files(state, files) if state[:corrected_paths].any?
|
|
118
|
+
append_error_files(state, files) if state[:error_paths].any?
|
|
119
|
+
|
|
120
|
+
files
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Append check file entries.
|
|
124
|
+
#
|
|
125
|
+
# @private
|
|
126
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
127
|
+
# @param [Array<Hash<Symbol, Object>>] files files offenses array
|
|
128
|
+
# @return [void]
|
|
129
|
+
def append_check_files(state, files)
|
|
130
|
+
state[:fail_paths].each do |path|
|
|
131
|
+
files << file_entry(path, state[:fail_changes][path] || [])
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
state[:type_mismatch_paths].each do |path|
|
|
135
|
+
files << file_entry(path, state[:type_mismatch_changes][path] || [], severity: 'warning')
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Append corrected file entries.
|
|
140
|
+
#
|
|
141
|
+
# @private
|
|
142
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
143
|
+
# @param [Array<Hash<Symbol, Object>>] files files offenses array
|
|
144
|
+
# @return [void]
|
|
145
|
+
def append_corrected_files(state, files)
|
|
146
|
+
state[:corrected_paths].each do |path|
|
|
147
|
+
merge_or_append(files, path, state[:corrected_changes][path] || [])
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Append error file entries.
|
|
152
|
+
#
|
|
153
|
+
# @private
|
|
154
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
155
|
+
# @param [Array<Hash<Symbol, Object>>] files files offenses array
|
|
156
|
+
# @return [void]
|
|
157
|
+
def append_error_files(state, files)
|
|
158
|
+
state[:error_paths].each do |path|
|
|
159
|
+
merge_or_append(files, path, [error_offense(state, path)])
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Merge or append file offenses.
|
|
164
|
+
#
|
|
165
|
+
# @private
|
|
166
|
+
# @param [Array<Hash<Symbol, Object>>] files files offenses array
|
|
167
|
+
# @param [String] path file path string
|
|
168
|
+
# @param [Array<Hash<Symbol, Object>>] offenses offense objects array
|
|
169
|
+
# @return [void]
|
|
170
|
+
def merge_or_append(files, path, offenses)
|
|
171
|
+
existing = files.find { |f| f[:path] == path }
|
|
172
|
+
|
|
173
|
+
if existing
|
|
174
|
+
existing[:offenses].concat(offenses)
|
|
175
|
+
else
|
|
176
|
+
files << { path: path, offenses: offenses }
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Build single file entry hash.
|
|
181
|
+
#
|
|
182
|
+
# @private
|
|
183
|
+
# @param [String] path file path string
|
|
184
|
+
# @param [Array<Docscribe::CLI::Formatters::change>] changes changes info array
|
|
185
|
+
# @param [String?] severity offense severity level
|
|
186
|
+
# @return [Hash<Symbol, Object>]
|
|
187
|
+
def file_entry(path, changes, severity: nil)
|
|
188
|
+
{ path: path, offenses: build_offenses(changes, severity: severity) }
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Build error offense entry.
|
|
192
|
+
#
|
|
193
|
+
# @private
|
|
194
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
195
|
+
# @param [String] path file path string
|
|
196
|
+
# @return [Hash<Symbol, Object>]
|
|
197
|
+
def error_offense(state, path)
|
|
198
|
+
error_offense_hash(state[:error_messages][path] || 'Unknown error')
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Format error offense hash.
|
|
202
|
+
#
|
|
203
|
+
# @private
|
|
204
|
+
# @param [String] message error message string
|
|
205
|
+
# @return [Hash<Symbol, Object>]
|
|
206
|
+
def error_offense_hash(message)
|
|
207
|
+
{ severity: 'fatal', cop_name: 'Docscribe/ProcessingError', message: message,
|
|
208
|
+
corrected: false, correctable: false, location: default_location }
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Default location hash value.
|
|
212
|
+
#
|
|
213
|
+
# @private
|
|
214
|
+
# @return [Hash<Symbol, Integer>]
|
|
215
|
+
def default_location
|
|
216
|
+
{ start_line: 1, start_column: 1, last_line: 1, last_column: 1 }
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Build offense array from changes.
|
|
220
|
+
#
|
|
221
|
+
# @private
|
|
222
|
+
# @param [Array<Docscribe::CLI::Formatters::change>] changes changes info array
|
|
223
|
+
# @param [String?] severity offense severity level
|
|
224
|
+
# @return [Array<Hash<Symbol, Object>>]
|
|
225
|
+
def build_offenses(changes, severity: nil)
|
|
226
|
+
changes.map { |change| build_offense(change, severity) }
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Build single offense hash.
|
|
230
|
+
#
|
|
231
|
+
# @private
|
|
232
|
+
# @param [Docscribe::CLI::Formatters::change] change change info hash
|
|
233
|
+
# @param [String?] severity offense severity level
|
|
234
|
+
# @return [Hash<Symbol, Object>]
|
|
235
|
+
def build_offense(change, severity)
|
|
236
|
+
{
|
|
237
|
+
severity: severity || SEVERITY_MAP[change[:type]] || 'convention',
|
|
238
|
+
cop_name: COP_NAME_MAP[change[:type]] || cop_name_fallback(change),
|
|
239
|
+
message: build_message(change),
|
|
240
|
+
corrected: false,
|
|
241
|
+
correctable: true,
|
|
242
|
+
location: location_for(change)
|
|
243
|
+
}
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Build location hash from change.
|
|
247
|
+
#
|
|
248
|
+
# @private
|
|
249
|
+
# @param [Docscribe::CLI::Formatters::change] change change info hash
|
|
250
|
+
# @return [Hash<Symbol, Integer>]
|
|
251
|
+
def location_for(change)
|
|
252
|
+
line = change[:line] || 1
|
|
253
|
+
{ start_line: line, start_column: 1, last_line: line, last_column: 1 }
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Fallback cop name from type.
|
|
257
|
+
#
|
|
258
|
+
# @private
|
|
259
|
+
# @param [Docscribe::CLI::Formatters::change] change change info hash
|
|
260
|
+
# @return [String]
|
|
261
|
+
def cop_name_fallback(change)
|
|
262
|
+
name = change[:type].to_s.tr('_', '_').capitalize
|
|
263
|
+
"Docscribe/#{name}"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Build human-readable message.
|
|
267
|
+
#
|
|
268
|
+
# @private
|
|
269
|
+
# @param [Docscribe::CLI::Formatters::change] change change info hash
|
|
270
|
+
# @return [String]
|
|
271
|
+
def build_message(change)
|
|
272
|
+
method = change[:method] ? " for #{change[:method]}" : ''
|
|
273
|
+
line = change[:line] ? " at line #{change[:line]}" : ''
|
|
274
|
+
|
|
275
|
+
return "unsorted tags#{line}" if change[:type] == :unsorted_tags
|
|
276
|
+
|
|
277
|
+
msg = change[:message] || change[:type].to_s.tr('_', ' ')
|
|
278
|
+
"#{msg}#{method}#{line}"
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# Count inspected file total.
|
|
282
|
+
#
|
|
283
|
+
# @private
|
|
284
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
285
|
+
# @return [Integer]
|
|
286
|
+
def inspected_count(state)
|
|
287
|
+
total = state[:checked_ok] + state[:checked_fail] + state[:type_mismatch_paths].size
|
|
288
|
+
total = state[:corrected] if total.zero? && state[:corrected].positive?
|
|
289
|
+
total + state[:error_paths].size
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'docscribe/version'
|
|
5
|
+
|
|
6
|
+
module Docscribe
|
|
7
|
+
module CLI
|
|
8
|
+
module Formatters
|
|
9
|
+
# Output formatter producing SARIF 2.1 JSON.
|
|
10
|
+
#
|
|
11
|
+
# SARIF (Static Analysis Results Interchange Format) is a standard
|
|
12
|
+
# format for static analysis tools. This formatter produces output
|
|
13
|
+
# compatible with GitHub Code Scanning, VS Code SARIF viewer, etc.
|
|
14
|
+
#
|
|
15
|
+
# stdout: complete SARIF 2.1 document with all findings.
|
|
16
|
+
# stderr: progress markers only (same as text mode).
|
|
17
|
+
class Sarif
|
|
18
|
+
SEVERITY_MAP = {
|
|
19
|
+
missing_param: 'note',
|
|
20
|
+
missing_return: 'note',
|
|
21
|
+
missing_raise: 'note',
|
|
22
|
+
missing_visibility: 'note',
|
|
23
|
+
missing_module_function_note: 'note',
|
|
24
|
+
insert_full_doc_block: 'note',
|
|
25
|
+
unsorted_tags: 'note',
|
|
26
|
+
updated_param: 'warning',
|
|
27
|
+
updated_return: 'warning'
|
|
28
|
+
}.freeze
|
|
29
|
+
|
|
30
|
+
COP_NAME_MAP = {
|
|
31
|
+
missing_param: 'Docscribe/MissingParam',
|
|
32
|
+
missing_return: 'Docscribe/MissingReturn',
|
|
33
|
+
missing_raise: 'Docscribe/MissingRaise',
|
|
34
|
+
missing_visibility: 'Docscribe/MissingVisibility',
|
|
35
|
+
missing_module_function_note: 'Docscribe/MissingModuleFunctionNote',
|
|
36
|
+
insert_full_doc_block: 'Docscribe/MissingDocBlock',
|
|
37
|
+
unsorted_tags: 'Docscribe/UnsortedTags',
|
|
38
|
+
updated_param: 'Docscribe/UpdatedParam',
|
|
39
|
+
updated_return: 'Docscribe/UpdatedReturn'
|
|
40
|
+
}.freeze
|
|
41
|
+
|
|
42
|
+
SARIF_SCHEMA = 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/' \
|
|
43
|
+
'master/Schemata/sarif-schema-2.1.0.json'
|
|
44
|
+
|
|
45
|
+
# @param [Docscribe::CLI::Formatters::state] state
|
|
46
|
+
# @param [Docscribe::CLI::Formatters::opts] options
|
|
47
|
+
# @return [void]
|
|
48
|
+
def format_check_summary(state:, options:)
|
|
49
|
+
puts JSON.generate(build_sarif_document(state, options[:format]))
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @param [Docscribe::CLI::Formatters::state] state
|
|
53
|
+
# @param [Docscribe::CLI::Formatters::opts] options
|
|
54
|
+
# @return [void]
|
|
55
|
+
def format_write_summary(state:, options:)
|
|
56
|
+
puts JSON.generate(build_sarif_document(state, options[:format]))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
# @private
|
|
62
|
+
# @param [Docscribe::CLI::Formatters::state] state
|
|
63
|
+
# @param [Object] _format
|
|
64
|
+
# @return [Hash<String, Symbol, Object>]
|
|
65
|
+
def build_sarif_document(state, _format)
|
|
66
|
+
{
|
|
67
|
+
'$schema' => SARIF_SCHEMA,
|
|
68
|
+
version: '2.1.0',
|
|
69
|
+
runs: [build_run(state)]
|
|
70
|
+
}
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @private
|
|
74
|
+
# @param [Docscribe::CLI::Formatters::state] state
|
|
75
|
+
# @return [Hash<Symbol, Object>]
|
|
76
|
+
def build_run(state)
|
|
77
|
+
{
|
|
78
|
+
tool: build_tool,
|
|
79
|
+
results: build_results(state),
|
|
80
|
+
invocations: [build_invocation(state)]
|
|
81
|
+
}
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @private
|
|
85
|
+
# @return [Hash<Symbol, Object>]
|
|
86
|
+
def build_tool
|
|
87
|
+
{
|
|
88
|
+
driver: {
|
|
89
|
+
name: 'docscribe',
|
|
90
|
+
version: Docscribe::VERSION,
|
|
91
|
+
informationUri: 'https://github.com/unurgunite/docscribe'
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# @private
|
|
97
|
+
# @param [Docscribe::CLI::Formatters::state] state
|
|
98
|
+
# @return [Array<Hash<Symbol, Object>>]
|
|
99
|
+
def build_results(state)
|
|
100
|
+
results = [] #: Array[Hash[Symbol, top]]
|
|
101
|
+
|
|
102
|
+
append_check_results(state, results)
|
|
103
|
+
append_corrected_results(state, results)
|
|
104
|
+
append_error_results(state, results)
|
|
105
|
+
|
|
106
|
+
results
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# @private
|
|
110
|
+
# @param [Docscribe::CLI::Formatters::state] state
|
|
111
|
+
# @param [Array<Hash<Symbol, Object>>] results
|
|
112
|
+
# @return [void]
|
|
113
|
+
def append_check_results(state, results)
|
|
114
|
+
append_changes(state[:fail_paths], state[:fail_changes], results)
|
|
115
|
+
append_changes(state[:type_mismatch_paths], state[:type_mismatch_changes], results, level: 'warning')
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# @private
|
|
119
|
+
# @param [Array<String>] paths
|
|
120
|
+
# @param [Hash<String, Array<Docscribe::CLI::Formatters::change>>] changes_map
|
|
121
|
+
# @param [Array<Hash<Symbol, Object>>] results
|
|
122
|
+
# @param [String?] level
|
|
123
|
+
# @return [void]
|
|
124
|
+
def append_changes(paths, changes_map, results, level: nil)
|
|
125
|
+
paths.each do |path|
|
|
126
|
+
(changes_map[path] || []).each do |change|
|
|
127
|
+
results << build_result(change, path, level: level)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# @private
|
|
133
|
+
# @param [Docscribe::CLI::Formatters::state] state
|
|
134
|
+
# @param [Array<Hash<Symbol, Object>>] results
|
|
135
|
+
# @return [void]
|
|
136
|
+
def append_corrected_results(state, results)
|
|
137
|
+
state[:corrected_paths].each do |path|
|
|
138
|
+
changes = state[:corrected_changes][path] || []
|
|
139
|
+
changes.each do |change|
|
|
140
|
+
results << build_result(change, path)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# @private
|
|
146
|
+
# @param [Docscribe::CLI::Formatters::state] state
|
|
147
|
+
# @param [Array<Hash<Symbol, Object>>] results
|
|
148
|
+
# @return [void]
|
|
149
|
+
def append_error_results(state, results)
|
|
150
|
+
state[:error_paths].each do |path|
|
|
151
|
+
msg = state[:error_messages][path] || 'Unknown error'
|
|
152
|
+
results << build_error_result(msg, path)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# @private
|
|
157
|
+
# @param [Docscribe::CLI::Formatters::change] change
|
|
158
|
+
# @param [String] path
|
|
159
|
+
# @param [String?] level
|
|
160
|
+
# @return [Hash<Symbol, Object>]
|
|
161
|
+
def build_result(change, path, level: nil)
|
|
162
|
+
{
|
|
163
|
+
ruleId: cop_name_for(change),
|
|
164
|
+
level: level || SEVERITY_MAP[change[:type]] || 'note',
|
|
165
|
+
message: { text: message_for(change) },
|
|
166
|
+
locations: [location(path, change[:line] || 1)]
|
|
167
|
+
}
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# @private
|
|
171
|
+
# @param [String] message
|
|
172
|
+
# @param [String] path
|
|
173
|
+
# @return [Hash<Symbol, Object>]
|
|
174
|
+
def build_error_result(message, path)
|
|
175
|
+
{
|
|
176
|
+
ruleId: 'Docscribe/ProcessingError',
|
|
177
|
+
level: 'error',
|
|
178
|
+
message: { text: message },
|
|
179
|
+
locations: [location(path, 1)]
|
|
180
|
+
}
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# @private
|
|
184
|
+
# @param [String] path
|
|
185
|
+
# @param [Integer] line
|
|
186
|
+
# @return [Hash<Symbol, Object>]
|
|
187
|
+
def location(path, line)
|
|
188
|
+
{
|
|
189
|
+
physicalLocation: {
|
|
190
|
+
artifactLocation: { uri: path },
|
|
191
|
+
region: { startLine: line }
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# @private
|
|
197
|
+
# @param [Docscribe::CLI::Formatters::change] change
|
|
198
|
+
# @return [String]
|
|
199
|
+
def cop_name_for(change)
|
|
200
|
+
COP_NAME_MAP[change[:type]] || fallback_cop_name(change)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# @private
|
|
204
|
+
# @param [Docscribe::CLI::Formatters::change] change
|
|
205
|
+
# @return [String]
|
|
206
|
+
def fallback_cop_name(change)
|
|
207
|
+
name = change[:type].to_s.tr('_', ' ').split.map(&:capitalize).join
|
|
208
|
+
"Docscribe/#{name}"
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# @private
|
|
212
|
+
# @param [Docscribe::CLI::Formatters::change] change
|
|
213
|
+
# @return [String]
|
|
214
|
+
def message_for(change)
|
|
215
|
+
method = change[:method] ? " for #{change[:method]}" : ''
|
|
216
|
+
line = change[:line] ? " at line #{change[:line]}" : ''
|
|
217
|
+
|
|
218
|
+
return "unsorted tags#{line}" if change[:type] == :unsorted_tags
|
|
219
|
+
|
|
220
|
+
msg = change[:message] || change[:type].to_s.tr('_', ' ')
|
|
221
|
+
"#{msg}#{method}#{line}"
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# @private
|
|
225
|
+
# @param [Docscribe::CLI::Formatters::state] state
|
|
226
|
+
# @return [Hash<Symbol, Object>]
|
|
227
|
+
def build_invocation(state)
|
|
228
|
+
{
|
|
229
|
+
executionSuccessful: !state[:had_errors]
|
|
230
|
+
}
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|