docscribe 1.6.0 → 1.6.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.
- checksums.yaml +4 -4
- data/README.md +76 -193
- data/exe/docscribe-client +26 -7
- data/lib/docscribe/cli/config_builder.rb +37 -2
- data/lib/docscribe/cli/coverage.rb +5 -5
- data/lib/docscribe/cli/formatters/json.rb +74 -29
- data/lib/docscribe/cli/formatters/sarif.rb +20 -3
- data/lib/docscribe/cli/options.rb +17 -2
- data/lib/docscribe/cli/rbs_gen.rb +4 -4
- data/lib/docscribe/cli/run.rb +107 -24
- data/lib/docscribe/cli/update_types.rb +61 -17
- data/lib/docscribe/cli.rb +19 -13
- data/lib/docscribe/config/defaults.rb +1 -0
- data/lib/docscribe/config/rbs.rb +22 -1
- data/lib/docscribe/config/template.rb +3 -0
- data/lib/docscribe/config/validation.rb +19 -0
- data/lib/docscribe/config.rb +1 -0
- data/lib/docscribe/infer/behavior.rb +13 -13
- data/lib/docscribe/infer/params.rb +2 -2
- data/lib/docscribe/infer/raises.rb +5 -6
- data/lib/docscribe/infer/returns.rb +1612 -151
- data/lib/docscribe/infer.rb +7 -7
- data/lib/docscribe/inline_rewriter/doc_builder.rb +485 -102
- data/lib/docscribe/inline_rewriter.rb +263 -97
- data/lib/docscribe/plugin/registry.rb +1 -0
- data/lib/docscribe/server/base.rb +255 -0
- data/lib/docscribe/server/client.rb +95 -0
- data/lib/docscribe/server/daemon.rb +678 -0
- data/lib/docscribe/server/protocol.rb +50 -0
- data/lib/docscribe/server.rb +4 -835
- data/lib/docscribe/types/primitive.rb +160 -0
- data/lib/docscribe/types/sorbet/base_provider.rb +33 -1
- data/lib/docscribe/types/yard/formatter.rb +35 -6
- data/lib/docscribe/types/yard/parser.rb +25 -20
- data/lib/docscribe/types/yard/validator.rb +131 -0
- data/lib/docscribe/validator/generic_compatibility.rb +698 -0
- data/lib/docscribe/validator/type_mismatch_validator.rb +287 -0
- data/lib/docscribe/version.rb +1 -1
- metadata +12 -3
|
@@ -20,7 +20,8 @@ module Docscribe
|
|
|
20
20
|
insert_full_doc_block: 'convention',
|
|
21
21
|
unsorted_tags: 'convention',
|
|
22
22
|
updated_param: 'warning',
|
|
23
|
-
updated_return: 'warning'
|
|
23
|
+
updated_return: 'warning',
|
|
24
|
+
invalid_type: 'warning'
|
|
24
25
|
}.freeze
|
|
25
26
|
|
|
26
27
|
COP_NAME_MAP = {
|
|
@@ -32,7 +33,8 @@ module Docscribe
|
|
|
32
33
|
insert_full_doc_block: 'Docscribe/MissingDocBlock',
|
|
33
34
|
unsorted_tags: 'Docscribe/UnsortedTags',
|
|
34
35
|
updated_param: 'Docscribe/UpdatedParam',
|
|
35
|
-
updated_return: 'Docscribe/UpdatedReturn'
|
|
36
|
+
updated_return: 'Docscribe/UpdatedReturn',
|
|
37
|
+
invalid_type: 'Docscribe/InvalidType'
|
|
36
38
|
}.freeze
|
|
37
39
|
|
|
38
40
|
# Output JSON check summary.
|
|
@@ -60,7 +62,7 @@ module Docscribe
|
|
|
60
62
|
# @private
|
|
61
63
|
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
62
64
|
# @param [Docscribe::CLI::Formatters::opts] _options runtime options hash
|
|
63
|
-
# @return [
|
|
65
|
+
# @return [Docscribe::CLI::Formatters::Json::json_document]
|
|
64
66
|
def build_document(state, _options)
|
|
65
67
|
document_hash(build_files(state), state)
|
|
66
68
|
end
|
|
@@ -68,9 +70,9 @@ module Docscribe
|
|
|
68
70
|
# Build document hash structure.
|
|
69
71
|
#
|
|
70
72
|
# @private
|
|
71
|
-
# @param [Array<
|
|
73
|
+
# @param [Array<Docscribe::CLI::Formatters::Json::json_file>] files files offenses array
|
|
72
74
|
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
73
|
-
# @return [
|
|
75
|
+
# @return [Docscribe::CLI::Formatters::Json::json_document]
|
|
74
76
|
def document_hash(files, state)
|
|
75
77
|
{
|
|
76
78
|
metadata: metadata_hash,
|
|
@@ -82,7 +84,7 @@ module Docscribe
|
|
|
82
84
|
# Build tool metadata hash.
|
|
83
85
|
#
|
|
84
86
|
# @private
|
|
85
|
-
# @return [
|
|
87
|
+
# @return [Docscribe::CLI::Formatters::Json::json_metadata]
|
|
86
88
|
def metadata_hash
|
|
87
89
|
{
|
|
88
90
|
docscribe_version: Docscribe::VERSION,
|
|
@@ -93,9 +95,9 @@ module Docscribe
|
|
|
93
95
|
# Build summary statistics hash.
|
|
94
96
|
#
|
|
95
97
|
# @private
|
|
96
|
-
# @param [Array<
|
|
98
|
+
# @param [Array<Docscribe::CLI::Formatters::Json::json_file>] files files offenses array
|
|
97
99
|
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
98
|
-
# @return [
|
|
100
|
+
# @return [Docscribe::CLI::Formatters::Json::json_summary]
|
|
99
101
|
def summary_hash(files, state)
|
|
100
102
|
{
|
|
101
103
|
offense_count: files.sum { |f| f[:offenses].size },
|
|
@@ -109,7 +111,7 @@ module Docscribe
|
|
|
109
111
|
#
|
|
110
112
|
# @private
|
|
111
113
|
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
112
|
-
# @return [Array<
|
|
114
|
+
# @return [Array<Docscribe::CLI::Formatters::Json::json_file>]
|
|
113
115
|
def build_files(state)
|
|
114
116
|
files = [] #: Array[Hash[untyped, untyped]]
|
|
115
117
|
|
|
@@ -124,15 +126,16 @@ module Docscribe
|
|
|
124
126
|
#
|
|
125
127
|
# @private
|
|
126
128
|
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
127
|
-
# @param [Array<
|
|
129
|
+
# @param [Array<Docscribe::CLI::Formatters::Json::json_file>] files files offenses array
|
|
128
130
|
# @return [void]
|
|
129
131
|
def append_check_files(state, files)
|
|
130
132
|
state[:fail_paths].each do |path|
|
|
131
|
-
files
|
|
133
|
+
merge_or_append(files, path, build_offenses(state[:fail_changes][path] || []))
|
|
132
134
|
end
|
|
133
135
|
|
|
134
136
|
state[:type_mismatch_paths].each do |path|
|
|
135
|
-
|
|
137
|
+
changes = state[:type_mismatch_changes][path] || []
|
|
138
|
+
merge_or_append(files, path, build_offenses(changes, severity: 'warning'))
|
|
136
139
|
end
|
|
137
140
|
end
|
|
138
141
|
|
|
@@ -140,7 +143,7 @@ module Docscribe
|
|
|
140
143
|
#
|
|
141
144
|
# @private
|
|
142
145
|
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
143
|
-
# @param [Array<
|
|
146
|
+
# @param [Array<Docscribe::CLI::Formatters::Json::json_file>] files files offenses array
|
|
144
147
|
# @return [void]
|
|
145
148
|
def append_corrected_files(state, files)
|
|
146
149
|
state[:corrected_paths].each do |path|
|
|
@@ -152,7 +155,7 @@ module Docscribe
|
|
|
152
155
|
#
|
|
153
156
|
# @private
|
|
154
157
|
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
155
|
-
# @param [Array<
|
|
158
|
+
# @param [Array<Docscribe::CLI::Formatters::Json::json_file>] files files offenses array
|
|
156
159
|
# @return [void]
|
|
157
160
|
def append_error_files(state, files)
|
|
158
161
|
state[:error_paths].each do |path|
|
|
@@ -163,12 +166,12 @@ module Docscribe
|
|
|
163
166
|
# Merge or append file offenses.
|
|
164
167
|
#
|
|
165
168
|
# @private
|
|
166
|
-
# @param [Array<
|
|
169
|
+
# @param [Array<Docscribe::CLI::Formatters::Json::json_file>] files files offenses array
|
|
167
170
|
# @param [String] path file path string
|
|
168
|
-
# @param [Array<
|
|
171
|
+
# @param [Array<Docscribe::CLI::Formatters::Json::json_offense>] offenses offense objects array
|
|
169
172
|
# @return [void]
|
|
170
173
|
def merge_or_append(files, path, offenses)
|
|
171
|
-
existing = files.find { |f| f[:path] == path }
|
|
174
|
+
existing = files.find { |f| normalize_path(f[:path]) == normalize_path(path) }
|
|
172
175
|
|
|
173
176
|
if existing
|
|
174
177
|
existing[:offenses].concat(offenses)
|
|
@@ -177,15 +180,18 @@ module Docscribe
|
|
|
177
180
|
end
|
|
178
181
|
end
|
|
179
182
|
|
|
180
|
-
#
|
|
183
|
+
# Normalize a path for dedup comparison, resolving symlinks
|
|
184
|
+
# (e.g. /tmp vs /private/tmp on macOS).
|
|
181
185
|
#
|
|
182
186
|
# @private
|
|
183
187
|
# @param [String] path file path string
|
|
184
|
-
# @
|
|
185
|
-
# @
|
|
186
|
-
# @return [
|
|
187
|
-
def
|
|
188
|
-
|
|
188
|
+
# @raise [SystemCallError]
|
|
189
|
+
# @raise [ArgumentError]
|
|
190
|
+
# @return [String]
|
|
191
|
+
def normalize_path(path)
|
|
192
|
+
File.realpath(path)
|
|
193
|
+
rescue SystemCallError, ArgumentError
|
|
194
|
+
File.expand_path(path)
|
|
189
195
|
end
|
|
190
196
|
|
|
191
197
|
# Build error offense entry.
|
|
@@ -193,7 +199,7 @@ module Docscribe
|
|
|
193
199
|
# @private
|
|
194
200
|
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
195
201
|
# @param [String] path file path string
|
|
196
|
-
# @return [
|
|
202
|
+
# @return [Docscribe::CLI::Formatters::Json::json_offense]
|
|
197
203
|
def error_offense(state, path)
|
|
198
204
|
error_offense_hash(state[:error_messages][path] || 'Unknown error')
|
|
199
205
|
end
|
|
@@ -202,7 +208,7 @@ module Docscribe
|
|
|
202
208
|
#
|
|
203
209
|
# @private
|
|
204
210
|
# @param [String] message error message string
|
|
205
|
-
# @return [
|
|
211
|
+
# @return [Docscribe::CLI::Formatters::Json::json_offense]
|
|
206
212
|
def error_offense_hash(message)
|
|
207
213
|
{ severity: 'fatal', cop_name: 'Docscribe/ProcessingError', message: message,
|
|
208
214
|
corrected: false, correctable: false, location: default_location }
|
|
@@ -211,7 +217,7 @@ module Docscribe
|
|
|
211
217
|
# Default location hash value.
|
|
212
218
|
#
|
|
213
219
|
# @private
|
|
214
|
-
# @return [
|
|
220
|
+
# @return [Docscribe::CLI::Formatters::Json::json_location]
|
|
215
221
|
def default_location
|
|
216
222
|
{ start_line: 1, start_column: 1, last_line: 1, last_column: 1 }
|
|
217
223
|
end
|
|
@@ -221,7 +227,7 @@ module Docscribe
|
|
|
221
227
|
# @private
|
|
222
228
|
# @param [Array<Docscribe::CLI::Formatters::change>] changes changes info array
|
|
223
229
|
# @param [String?] severity offense severity level
|
|
224
|
-
# @return [Array<
|
|
230
|
+
# @return [Array<Docscribe::CLI::Formatters::Json::json_offense>]
|
|
225
231
|
def build_offenses(changes, severity: nil)
|
|
226
232
|
changes.map { |change| build_offense(change, severity) }
|
|
227
233
|
end
|
|
@@ -231,8 +237,18 @@ module Docscribe
|
|
|
231
237
|
# @private
|
|
232
238
|
# @param [Docscribe::CLI::Formatters::change] change change info hash
|
|
233
239
|
# @param [String?] severity offense severity level
|
|
234
|
-
# @return [
|
|
240
|
+
# @return [Docscribe::CLI::Formatters::Json::json_offense]
|
|
235
241
|
def build_offense(change, severity)
|
|
242
|
+
offense = base_offense(change, severity)
|
|
243
|
+
attach_source(offense, change)
|
|
244
|
+
attach_type(offense, change)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# @private
|
|
248
|
+
# @param [Docscribe::CLI::Formatters::change] change
|
|
249
|
+
# @param [String?] severity
|
|
250
|
+
# @return [Docscribe::CLI::Formatters::Json::json_offense]
|
|
251
|
+
def base_offense(change, severity)
|
|
236
252
|
{
|
|
237
253
|
severity: severity || SEVERITY_MAP[change[:type]] || 'convention',
|
|
238
254
|
cop_name: COP_NAME_MAP[change[:type]] || cop_name_fallback(change),
|
|
@@ -243,11 +259,40 @@ module Docscribe
|
|
|
243
259
|
}
|
|
244
260
|
end
|
|
245
261
|
|
|
262
|
+
# @private
|
|
263
|
+
# @param [Docscribe::CLI::Formatters::Json::json_offense] offense
|
|
264
|
+
# @param [Docscribe::CLI::Formatters::change] change
|
|
265
|
+
# @return [Docscribe::CLI::Formatters::Json::json_offense]
|
|
266
|
+
def attach_source(offense, change)
|
|
267
|
+
source = offense_source(change)
|
|
268
|
+
offense[:source] = source if source
|
|
269
|
+
offense
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# Attach machine-readable change type when present.
|
|
273
|
+
#
|
|
274
|
+
# @private
|
|
275
|
+
# @param [Docscribe::CLI::Formatters::Json::json_offense] offense offense hash being built
|
|
276
|
+
# @param [Docscribe::CLI::Formatters::change] change change info hash
|
|
277
|
+
# @return [Docscribe::CLI::Formatters::Json::json_offense]
|
|
278
|
+
def attach_type(offense, change)
|
|
279
|
+
type = change[:type] || change['type']
|
|
280
|
+
offense[:type] = type.to_s if type
|
|
281
|
+
offense
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
# @private
|
|
285
|
+
# @param [Docscribe::CLI::Formatters::change] change
|
|
286
|
+
# @return [String, nil]
|
|
287
|
+
def offense_source(change)
|
|
288
|
+
change[:source] || change['source']
|
|
289
|
+
end
|
|
290
|
+
|
|
246
291
|
# Build location hash from change.
|
|
247
292
|
#
|
|
248
293
|
# @private
|
|
249
294
|
# @param [Docscribe::CLI::Formatters::change] change change info hash
|
|
250
|
-
# @return [
|
|
295
|
+
# @return [Docscribe::CLI::Formatters::Json::json_location]
|
|
251
296
|
def location_for(change)
|
|
252
297
|
line = change[:line] || 1
|
|
253
298
|
{ start_line: line, start_column: 1, last_line: line, last_column: 1 }
|
|
@@ -24,7 +24,8 @@ module Docscribe
|
|
|
24
24
|
insert_full_doc_block: 'note',
|
|
25
25
|
unsorted_tags: 'note',
|
|
26
26
|
updated_param: 'warning',
|
|
27
|
-
updated_return: 'warning'
|
|
27
|
+
updated_return: 'warning',
|
|
28
|
+
invalid_type: 'warning'
|
|
28
29
|
}.freeze
|
|
29
30
|
|
|
30
31
|
COP_NAME_MAP = {
|
|
@@ -36,7 +37,8 @@ module Docscribe
|
|
|
36
37
|
insert_full_doc_block: 'Docscribe/MissingDocBlock',
|
|
37
38
|
unsorted_tags: 'Docscribe/UnsortedTags',
|
|
38
39
|
updated_param: 'Docscribe/UpdatedParam',
|
|
39
|
-
updated_return: 'Docscribe/UpdatedReturn'
|
|
40
|
+
updated_return: 'Docscribe/UpdatedReturn',
|
|
41
|
+
invalid_type: 'Docscribe/InvalidType'
|
|
40
42
|
}.freeze
|
|
41
43
|
|
|
42
44
|
SARIF_SCHEMA = 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/' \
|
|
@@ -159,12 +161,27 @@ module Docscribe
|
|
|
159
161
|
# @param [String?] level
|
|
160
162
|
# @return [Hash<Symbol, Object>]
|
|
161
163
|
def build_result(change, path, level: nil)
|
|
162
|
-
{
|
|
164
|
+
result = {
|
|
163
165
|
ruleId: cop_name_for(change),
|
|
164
166
|
level: level || SEVERITY_MAP[change[:type]] || 'note',
|
|
165
167
|
message: { text: message_for(change) },
|
|
166
168
|
locations: [location(path, change[:line] || 1)]
|
|
167
169
|
}
|
|
170
|
+
properties = result_properties(change)
|
|
171
|
+
result[:properties] = properties unless properties.empty?
|
|
172
|
+
result
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# @private
|
|
176
|
+
# @param [Docscribe::CLI::Formatters::change] change
|
|
177
|
+
# @return [Hash<Symbol, String>]
|
|
178
|
+
def result_properties(change)
|
|
179
|
+
source = change[:source] || change['source']
|
|
180
|
+
type = change[:type] || change['type']
|
|
181
|
+
properties = {}
|
|
182
|
+
properties[:source] = source if source
|
|
183
|
+
properties[:type] = type.to_s if type
|
|
184
|
+
properties
|
|
168
185
|
end
|
|
169
186
|
|
|
170
187
|
# @private
|
|
@@ -28,7 +28,8 @@ module Docscribe
|
|
|
28
28
|
no_boilerplate: false,
|
|
29
29
|
progress: false,
|
|
30
30
|
parallel: false,
|
|
31
|
-
server: false
|
|
31
|
+
server: false,
|
|
32
|
+
validate_types: nil #: true or false when --[no-]validate-types is passed, nil otherwise
|
|
32
33
|
}.freeze
|
|
33
34
|
|
|
34
35
|
module_function
|
|
@@ -39,7 +40,7 @@ module Docscribe
|
|
|
39
40
|
docscribe generate <type> <name> [options]
|
|
40
41
|
docscribe sigs [options] [files...]
|
|
41
42
|
docscribe rbs [options] [files...]
|
|
42
|
-
docscribe update_types [directory]
|
|
43
|
+
docscribe update_types [directory|file]
|
|
43
44
|
docscribe check_for_comments [paths...]
|
|
44
45
|
|
|
45
46
|
Default behavior:
|
|
@@ -63,6 +64,7 @@ module Docscribe
|
|
|
63
64
|
--sorbet Use Sorbet signatures from inline sigs / RBI files when available
|
|
64
65
|
--rbi-dir DIR Add a Sorbet RBI directory (repeatable). Implies --sorbet.
|
|
65
66
|
--rbs-collection Auto-discover RBS collection from rbs_collection.lock.yaml. Implies --rbs.
|
|
67
|
+
--validate-types Validate YARD types against inferred/RBS types and report mismatches
|
|
66
68
|
|
|
67
69
|
Filtering:
|
|
68
70
|
--include PATTERN Include PATTERN (method id or file path; glob or /regex/)
|
|
@@ -202,6 +204,7 @@ module Docscribe
|
|
|
202
204
|
define_sorbet_option(opts, options)
|
|
203
205
|
define_rbi_dir_option(opts, options)
|
|
204
206
|
define_rbs_collection_option(opts, options)
|
|
207
|
+
define_validate_types_option(opts, options)
|
|
205
208
|
end
|
|
206
209
|
|
|
207
210
|
# Define rbs option
|
|
@@ -267,6 +270,18 @@ module Docscribe
|
|
|
267
270
|
end
|
|
268
271
|
end
|
|
269
272
|
|
|
273
|
+
# Define validate types option
|
|
274
|
+
#
|
|
275
|
+
# @note module_function: defines #define_validate_types_option (visibility: private)
|
|
276
|
+
# @param [OptionParser] opts the option parser to configure
|
|
277
|
+
# @param [Hash<Symbol, Object>] options mutable parsed options hash
|
|
278
|
+
# @return [void]
|
|
279
|
+
def define_validate_types_option(opts, options)
|
|
280
|
+
opts.on('--[no-]validate-types', 'Validate YARD types against inferred/RBS types and report mismatches') do |value|
|
|
281
|
+
options[:validate_types] = value
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
270
285
|
# Define filter options
|
|
271
286
|
#
|
|
272
287
|
# @note module_function: defines #define_filter_options (visibility: private)
|
|
@@ -29,7 +29,7 @@ module Docscribe
|
|
|
29
29
|
# @!attribute [rw] options
|
|
30
30
|
# @return [Array<Docscribe::CLI::RbsGen::ParamTag>]
|
|
31
31
|
# @param [Array<Docscribe::CLI::RbsGen::ParamTag>] value
|
|
32
|
-
YardTags = Struct.new(:params, :return_type, :options, keyword_init: true)
|
|
32
|
+
YardTags = Struct.new(:params, :return_type, :options, keyword_init: true) #: Class[YardTags]
|
|
33
33
|
# @!attribute [rw] name
|
|
34
34
|
# @return [String]
|
|
35
35
|
# @param [String] value
|
|
@@ -37,7 +37,7 @@ module Docscribe
|
|
|
37
37
|
# @!attribute [rw] type
|
|
38
38
|
# @return [String]
|
|
39
39
|
# @param [String] value
|
|
40
|
-
ParamTag = Struct.new(:name, :type, keyword_init: true)
|
|
40
|
+
ParamTag = Struct.new(:name, :type, keyword_init: true) #: Class[ParamTag]
|
|
41
41
|
# @!attribute [rw] name
|
|
42
42
|
# @return [Symbol]
|
|
43
43
|
# @param [Symbol] value
|
|
@@ -61,7 +61,7 @@ module Docscribe
|
|
|
61
61
|
# @!attribute [rw] yard_tags
|
|
62
62
|
# @return [Docscribe::CLI::RbsGen::YardTags?]
|
|
63
63
|
# @param [Docscribe::CLI::RbsGen::YardTags?] value
|
|
64
|
-
MethodDef = Struct.new(:name, :scope, :container, :file, :line, :yard_tags, keyword_init: true)
|
|
64
|
+
MethodDef = Struct.new(:name, :scope, :container, :file, :line, :yard_tags, keyword_init: true) #: Class[MethodDef]
|
|
65
65
|
# @!attribute [rw] containers
|
|
66
66
|
# @return [Array<String>]
|
|
67
67
|
# @param [Array<String>] value
|
|
@@ -86,7 +86,7 @@ module Docscribe
|
|
|
86
86
|
# @return [Boolean]
|
|
87
87
|
# @param [Boolean] value
|
|
88
88
|
WalkContext = Struct.new(:containers, :method_defs, :path, :comment_map, :src_lines, :inside_sclass,
|
|
89
|
-
keyword_init: true)
|
|
89
|
+
keyword_init: true) #: Class[WalkContext]
|
|
90
90
|
|
|
91
91
|
class << self
|
|
92
92
|
# @param [Array<String>] argv
|
data/lib/docscribe/cli/run.rb
CHANGED
|
@@ -42,6 +42,7 @@ module Docscribe
|
|
|
42
42
|
include exclude include_file exclude_file
|
|
43
43
|
rbs rbs_collection sig_dirs
|
|
44
44
|
sorbet rbi_dirs
|
|
45
|
+
validate_types
|
|
45
46
|
].freeze
|
|
46
47
|
|
|
47
48
|
# Run Docscribe for files or STDIN using the selected mode and strategy.
|
|
@@ -145,7 +146,7 @@ module Docscribe
|
|
|
145
146
|
#
|
|
146
147
|
# @param [Docscribe::CLI::Formatters::opts] options parsed CLI options
|
|
147
148
|
# @param [Docscribe::Config] conf effective config
|
|
148
|
-
# @return [
|
|
149
|
+
# @return [Docscribe::CLI::Run::rewrite_result] rewrite result with :output key
|
|
149
150
|
def stdin_rewrite_result(options, conf)
|
|
150
151
|
Docscribe::InlineRewriter.rewrite_with_report(
|
|
151
152
|
$stdin.read,
|
|
@@ -243,7 +244,7 @@ module Docscribe
|
|
|
243
244
|
# @param [Hash<String, Object>] result server result with :changed and :changes keys
|
|
244
245
|
# @param [Array<Docscribe::CLI::Formatters::change>] file_changes change records
|
|
245
246
|
# @param [String] path file path
|
|
246
|
-
# @param [
|
|
247
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx context hash with :display_path, :options, :state keys
|
|
247
248
|
# @return [void]
|
|
248
249
|
def dispatch_server_result(result, file_changes, path, **ctx)
|
|
249
250
|
if ctx[:options][:mode] == :check
|
|
@@ -326,14 +327,17 @@ module Docscribe
|
|
|
326
327
|
#
|
|
327
328
|
# @param [Hash<String, Object>] change change record from server
|
|
328
329
|
# @return [Docscribe::CLI::Formatters::change]
|
|
329
|
-
def symbolize_change(change)
|
|
330
|
-
{
|
|
330
|
+
def symbolize_change(change) # steep:ignore
|
|
331
|
+
hash = {
|
|
331
332
|
type: change['type'].to_sym,
|
|
332
333
|
file: change['file'],
|
|
333
334
|
line: change['line'],
|
|
334
335
|
method: change['method'],
|
|
335
|
-
message: change['message']
|
|
336
|
+
message: change['message'],
|
|
337
|
+
source: change['source']
|
|
336
338
|
}
|
|
339
|
+
hash[:param] = change['param'] if change['param']
|
|
340
|
+
hash.compact
|
|
337
341
|
end
|
|
338
342
|
|
|
339
343
|
# Expand CLI path arguments into a sorted list of Ruby files.
|
|
@@ -416,8 +420,8 @@ module Docscribe
|
|
|
416
420
|
run_exit_code(options, state)
|
|
417
421
|
end
|
|
418
422
|
|
|
419
|
-
# @param [
|
|
420
|
-
# @param [
|
|
423
|
+
# @param [Docscribe::CLI::Formatters::opts] options
|
|
424
|
+
# @param [Docscribe::Config] conf
|
|
421
425
|
# @param [Array<String>] paths
|
|
422
426
|
# @param [Docscribe::CLI::Formatters::state] state
|
|
423
427
|
# @return [void]
|
|
@@ -430,7 +434,7 @@ module Docscribe
|
|
|
430
434
|
thread_count.times.map { parallel_worker(pool) }.each(&:join)
|
|
431
435
|
end
|
|
432
436
|
|
|
433
|
-
# @param [
|
|
437
|
+
# @param [Docscribe::CLI::Run::pool] pool
|
|
434
438
|
# @return [Thread]
|
|
435
439
|
def parallel_worker(pool)
|
|
436
440
|
Thread.new do
|
|
@@ -451,7 +455,7 @@ module Docscribe
|
|
|
451
455
|
end
|
|
452
456
|
|
|
453
457
|
# @param [String] path
|
|
454
|
-
# @param [
|
|
458
|
+
# @param [Docscribe::CLI::Run::pool] pool
|
|
455
459
|
# @raise [StandardError]
|
|
456
460
|
# @return [void]
|
|
457
461
|
# @return [Object] if StandardError
|
|
@@ -605,7 +609,7 @@ module Docscribe
|
|
|
605
609
|
return unless result
|
|
606
610
|
|
|
607
611
|
dispatch_file_result(path, src: src, out: result[:output], file_changes: result[:changes] || [],
|
|
608
|
-
display_path: display_path, options: options, state: state)
|
|
612
|
+
display_path: display_path, options: options, state: state, conf: conf)
|
|
609
613
|
end
|
|
610
614
|
|
|
611
615
|
# Print progress indicator to stderr when --progress is active.
|
|
@@ -629,7 +633,7 @@ module Docscribe
|
|
|
629
633
|
# @param [String] src original source code
|
|
630
634
|
# @param [String] out rewritten source code
|
|
631
635
|
# @param [Array<Docscribe::CLI::Formatters::change>] file_changes structured change records
|
|
632
|
-
# @param [
|
|
636
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx context hash with :options, :state, :display_path, :conf
|
|
633
637
|
# @return [void]
|
|
634
638
|
def dispatch_file_result(path, src:, out:, file_changes:, **ctx)
|
|
635
639
|
if ctx[:options][:mode] == :check
|
|
@@ -687,9 +691,9 @@ module Docscribe
|
|
|
687
691
|
# @private
|
|
688
692
|
# @param [String] path file path
|
|
689
693
|
# @param [String] src source code
|
|
690
|
-
# @param [
|
|
694
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx context hash with :conf, :display_path, :options, :state keys
|
|
691
695
|
# @raise [StandardError]
|
|
692
|
-
# @return [
|
|
696
|
+
# @return [Docscribe::CLI::Run::rewrite_result, nil]
|
|
693
697
|
# @return [nil] if StandardError
|
|
694
698
|
def rewrite_result_for_path(path, src:, ctx:)
|
|
695
699
|
conf = ctx[:conf]
|
|
@@ -710,7 +714,7 @@ module Docscribe
|
|
|
710
714
|
# @private
|
|
711
715
|
# @param [String] path file path that caused the error
|
|
712
716
|
# @param [StandardError] error the exception raised during rewriting
|
|
713
|
-
# @param [
|
|
717
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx context hash with :state, :options, :display_path
|
|
714
718
|
# @return [void]
|
|
715
719
|
def record_rewrite_error(path, error, ctx)
|
|
716
720
|
state = ctx[:state]
|
|
@@ -733,18 +737,97 @@ module Docscribe
|
|
|
733
737
|
# @param [String] src original source code
|
|
734
738
|
# @param [String] out rewritten source code
|
|
735
739
|
# @param [Array<Docscribe::CLI::Formatters::change>] file_changes structured change records
|
|
736
|
-
# @param [
|
|
740
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx context hash with :display_path, :options, :state keys
|
|
737
741
|
# @return [void]
|
|
738
742
|
def handle_check_result(path, src:, out:, file_changes:, **ctx)
|
|
739
743
|
type_mismatches = type_mismatch_changes(file_changes)
|
|
740
|
-
has_real_changes =
|
|
744
|
+
has_real_changes = real_changes?(file_changes)
|
|
745
|
+
return handle_validated_type_mismatch(path, file_changes, type_mismatches, ctx) if validated_mismatch?(ctx, type_mismatches, out, src, has_real_changes)
|
|
746
|
+
return handle_no_changes(path, type_mismatches, ctx) if no_real_changes?(out, src, has_real_changes)
|
|
741
747
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
748
|
+
handle_failed_check(path, file_changes, ctx)
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
# @private
|
|
752
|
+
# @param [Array<Docscribe::CLI::Formatters::change>] file_changes
|
|
753
|
+
# @return [Boolean]
|
|
754
|
+
def real_changes?(file_changes)
|
|
755
|
+
file_changes.any? { |c| !%i[updated_param updated_return invalid_type].include?(c[:type]) }
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
# @private
|
|
759
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx
|
|
760
|
+
# @param [Array<Docscribe::CLI::Formatters::change>] type_mismatches
|
|
761
|
+
# @param [String] out
|
|
762
|
+
# @param [String] src
|
|
763
|
+
# @param [Boolean] has_real_changes
|
|
764
|
+
# @return [Boolean]
|
|
765
|
+
def validated_mismatch?(ctx, type_mismatches, out, src, has_real_changes)
|
|
766
|
+
validate_types_enabled?(ctx) && type_mismatches.any? && out == src && !has_real_changes
|
|
767
|
+
end
|
|
768
|
+
|
|
769
|
+
# @private
|
|
770
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx
|
|
771
|
+
# @return [Boolean]
|
|
772
|
+
def validate_types_enabled?(ctx)
|
|
773
|
+
return true if ctx[:options][:validate_types] == true
|
|
774
|
+
return false if ctx[:options][:validate_types] == false
|
|
747
775
|
|
|
776
|
+
ctx[:conf].respond_to?(:validate_types?) && ctx[:conf].validate_types?
|
|
777
|
+
end
|
|
778
|
+
|
|
779
|
+
# @private
|
|
780
|
+
# @param [String] out
|
|
781
|
+
# @param [String] src
|
|
782
|
+
# @param [Boolean] has_real_changes
|
|
783
|
+
# @return [Boolean]
|
|
784
|
+
def no_real_changes?(out, src, has_real_changes)
|
|
785
|
+
out == src && !has_real_changes
|
|
786
|
+
end
|
|
787
|
+
|
|
788
|
+
# @private
|
|
789
|
+
# @param [String] path
|
|
790
|
+
# @param [Array<Docscribe::CLI::Formatters::change>] file_changes
|
|
791
|
+
# @param [Array<Docscribe::CLI::Formatters::change>] type_mismatches
|
|
792
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx
|
|
793
|
+
# @return [void]
|
|
794
|
+
def handle_validated_type_mismatch(path, file_changes, type_mismatches, ctx)
|
|
795
|
+
handle_failed_check(path, file_changes, ctx)
|
|
796
|
+
# Drop the records the tracker already holds: the same mismatch must
|
|
797
|
+
# not appear (and count) twice in JSON output.
|
|
798
|
+
stored = ctx[:state][:fail_changes][path] || []
|
|
799
|
+
ctx[:state][:fail_changes][path] = stored - type_mismatches
|
|
800
|
+
track_validated_mismatch(type_mismatches, ctx, path)
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
# @private
|
|
804
|
+
# @param [Array<Docscribe::CLI::Formatters::change>] type_mismatches
|
|
805
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx
|
|
806
|
+
# @param [String] path raw file path, used as the map key so fail and
|
|
807
|
+
# mismatch entries merge in JSON output
|
|
808
|
+
# @return [void]
|
|
809
|
+
def track_validated_mismatch(type_mismatches, ctx, path)
|
|
810
|
+
state = ctx[:state]
|
|
811
|
+
state[:type_mismatch_paths] << path unless state[:type_mismatch_paths].include?(path)
|
|
812
|
+
state[:type_mismatch_changes][path] = type_mismatches
|
|
813
|
+
end
|
|
814
|
+
|
|
815
|
+
# @private
|
|
816
|
+
# @param [String] path
|
|
817
|
+
# @param [Array<Docscribe::CLI::Formatters::change>] type_mismatches
|
|
818
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx
|
|
819
|
+
# @return [void]
|
|
820
|
+
def handle_no_changes(path, type_mismatches, ctx)
|
|
821
|
+
handle_check_no_changes(path, type_mismatches: type_mismatches, display_path: ctx[:display_path],
|
|
822
|
+
options: ctx[:options], state: ctx[:state])
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
# @private
|
|
826
|
+
# @param [String] path
|
|
827
|
+
# @param [Array<Docscribe::CLI::Formatters::change>] file_changes
|
|
828
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx
|
|
829
|
+
# @return [void]
|
|
830
|
+
def handle_failed_check(path, file_changes, ctx)
|
|
748
831
|
handle_check_failed(path, file_changes: file_changes, display_path: ctx[:display_path],
|
|
749
832
|
options: ctx[:options], state: ctx[:state])
|
|
750
833
|
end
|
|
@@ -755,7 +838,7 @@ module Docscribe
|
|
|
755
838
|
# @param [Array<Docscribe::CLI::Formatters::change>] file_changes structured change records
|
|
756
839
|
# @return [Array<Docscribe::CLI::Formatters::change>]
|
|
757
840
|
def type_mismatch_changes(file_changes)
|
|
758
|
-
file_changes.select { |c| %i[updated_param updated_return].include?(c[:type]) }
|
|
841
|
+
file_changes.select { |c| %i[updated_param updated_return invalid_type].include?(c[:type]) }
|
|
759
842
|
end
|
|
760
843
|
|
|
761
844
|
# Handle check result when there are no real changes.
|
|
@@ -809,7 +892,7 @@ module Docscribe
|
|
|
809
892
|
# @param [String] src original source code
|
|
810
893
|
# @param [String] out rewritten source code
|
|
811
894
|
# @param [Array<Docscribe::CLI::Formatters::change>] file_changes structured change records
|
|
812
|
-
# @param [
|
|
895
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx context hash with :display_path, :options, :state keys
|
|
813
896
|
# @raise [StandardError]
|
|
814
897
|
# @return [void]
|
|
815
898
|
# @return [Object] if StandardError
|
|
@@ -827,7 +910,7 @@ module Docscribe
|
|
|
827
910
|
# @param [String] path file path
|
|
828
911
|
# @param [String] out rewritten source code
|
|
829
912
|
# @param [Array<Docscribe::CLI::Formatters::change>] file_changes structured change records
|
|
830
|
-
# @param [
|
|
913
|
+
# @param [Docscribe::CLI::Run::run_ctx] ctx context hash with :display_path, :options, :state keys
|
|
831
914
|
# @return [void]
|
|
832
915
|
def apply_correction(path, out, file_changes, ctx)
|
|
833
916
|
File.write(path, out)
|