yard-lint 1.2.2 → 1.3.0.rc1
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/CHANGELOG.md +174 -1
- data/README.md +118 -3
- data/Rakefile +20 -0
- data/bin/yard-lint +80 -37
- data/lib/yard/lint/config.rb +5 -0
- data/lib/yard/lint/config_generator.rb +8 -179
- data/lib/yard/lint/config_updater.rb +222 -0
- data/lib/yard/lint/errors.rb +6 -0
- data/lib/yard/lint/executor/in_process_registry.rb +130 -0
- data/lib/yard/lint/executor/query_executor.rb +109 -0
- data/lib/yard/lint/executor/result_collector.rb +55 -0
- data/lib/yard/lint/executor/warning_dispatcher.rb +79 -0
- data/lib/yard/lint/results/base.rb +2 -1
- data/lib/yard/lint/runner.rb +88 -35
- data/lib/yard/lint/stats_calculator.rb +1 -1
- data/lib/yard/lint/templates/default_config.yml +279 -0
- data/lib/yard/lint/templates/strict_config.yml +283 -0
- data/lib/yard/lint/validators/base.rb +52 -118
- data/lib/yard/lint/validators/documentation/blank_line_before_definition/config.rb +25 -0
- data/lib/yard/lint/validators/documentation/blank_line_before_definition/messages_builder.rb +39 -0
- data/lib/yard/lint/validators/documentation/blank_line_before_definition/parser.rb +59 -0
- data/lib/yard/lint/validators/documentation/blank_line_before_definition/result.rb +61 -0
- data/lib/yard/lint/validators/documentation/blank_line_before_definition/validator.rb +94 -0
- data/lib/yard/lint/validators/documentation/blank_line_before_definition.rb +63 -0
- data/lib/yard/lint/validators/documentation/empty_comment_line/config.rb +24 -0
- data/lib/yard/lint/validators/documentation/empty_comment_line/messages_builder.rb +34 -0
- data/lib/yard/lint/validators/documentation/empty_comment_line/parser.rb +60 -0
- data/lib/yard/lint/validators/documentation/empty_comment_line/result.rb +25 -0
- data/lib/yard/lint/validators/documentation/empty_comment_line/validator.rb +109 -0
- data/lib/yard/lint/validators/documentation/empty_comment_line.rb +58 -0
- data/lib/yard/lint/validators/documentation/markdown_syntax/validator.rb +36 -21
- data/lib/yard/lint/validators/documentation/markdown_syntax.rb +0 -1
- data/lib/yard/lint/validators/documentation/undocumented_boolean_methods/validator.rb +19 -29
- data/lib/yard/lint/validators/documentation/undocumented_boolean_methods.rb +0 -1
- data/lib/yard/lint/validators/documentation/undocumented_method_arguments/validator.rb +18 -34
- data/lib/yard/lint/validators/documentation/undocumented_method_arguments.rb +0 -1
- data/lib/yard/lint/validators/documentation/undocumented_objects/parser.rb +2 -2
- data/lib/yard/lint/validators/documentation/undocumented_objects/validator.rb +17 -25
- data/lib/yard/lint/validators/documentation/undocumented_objects.rb +4 -5
- data/lib/yard/lint/validators/documentation/undocumented_options/validator.rb +30 -21
- data/lib/yard/lint/validators/documentation/undocumented_options.rb +0 -1
- data/lib/yard/lint/validators/semantic/abstract_methods/result.rb +2 -2
- data/lib/yard/lint/validators/semantic/abstract_methods/validator.rb +31 -43
- data/lib/yard/lint/validators/semantic/abstract_methods.rb +0 -1
- data/lib/yard/lint/validators/tags/api_tags/validator.rb +24 -39
- data/lib/yard/lint/validators/tags/api_tags.rb +0 -1
- data/lib/yard/lint/validators/tags/collection_type/parser.rb +1 -1
- data/lib/yard/lint/validators/tags/collection_type/validator.rb +37 -66
- data/lib/yard/lint/validators/tags/collection_type.rb +0 -1
- data/lib/yard/lint/validators/tags/example_syntax/validator.rb +51 -64
- data/lib/yard/lint/validators/tags/example_syntax.rb +0 -1
- data/lib/yard/lint/validators/tags/informal_notation/config.rb +40 -0
- data/lib/yard/lint/validators/tags/informal_notation/messages_builder.rb +35 -0
- data/lib/yard/lint/validators/tags/informal_notation/parser.rb +55 -0
- data/lib/yard/lint/validators/tags/informal_notation/result.rb +26 -0
- data/lib/yard/lint/validators/tags/informal_notation/validator.rb +133 -0
- data/lib/yard/lint/validators/tags/informal_notation.rb +45 -0
- data/lib/yard/lint/validators/tags/invalid_types/validator.rb +57 -70
- data/lib/yard/lint/validators/tags/invalid_types.rb +0 -1
- data/lib/yard/lint/validators/tags/meaningless_tag/parser.rb +1 -1
- data/lib/yard/lint/validators/tags/meaningless_tag/validator.rb +22 -54
- data/lib/yard/lint/validators/tags/meaningless_tag.rb +0 -1
- data/lib/yard/lint/validators/tags/non_ascii_type/config.rb +21 -0
- data/lib/yard/lint/validators/tags/non_ascii_type/messages_builder.rb +29 -0
- data/lib/yard/lint/validators/tags/non_ascii_type/parser.rb +59 -0
- data/lib/yard/lint/validators/tags/non_ascii_type/result.rb +25 -0
- data/lib/yard/lint/validators/tags/non_ascii_type/validator.rb +50 -0
- data/lib/yard/lint/validators/tags/non_ascii_type.rb +39 -0
- data/lib/yard/lint/validators/tags/option_tags/result.rb +2 -2
- data/lib/yard/lint/validators/tags/option_tags/validator.rb +25 -40
- data/lib/yard/lint/validators/tags/option_tags.rb +0 -1
- data/lib/yard/lint/validators/tags/order/validator.rb +28 -55
- data/lib/yard/lint/validators/tags/order.rb +0 -1
- data/lib/yard/lint/validators/tags/redundant_param_description/config.rb +15 -1
- data/lib/yard/lint/validators/tags/redundant_param_description/messages_builder.rb +5 -0
- data/lib/yard/lint/validators/tags/redundant_param_description/validator.rb +134 -100
- data/lib/yard/lint/validators/tags/redundant_param_description.rb +0 -1
- data/lib/yard/lint/validators/tags/tag_group_separator/config.rb +29 -0
- data/lib/yard/lint/validators/tags/tag_group_separator/messages_builder.rb +49 -0
- data/lib/yard/lint/validators/tags/tag_group_separator/parser.rb +67 -0
- data/lib/yard/lint/validators/tags/tag_group_separator/result.rb +28 -0
- data/lib/yard/lint/validators/tags/tag_group_separator/validator.rb +117 -0
- data/lib/yard/lint/validators/tags/tag_group_separator.rb +49 -0
- data/lib/yard/lint/validators/tags/tag_type_position/parser.rb +1 -1
- data/lib/yard/lint/validators/tags/tag_type_position/validator.rb +53 -84
- data/lib/yard/lint/validators/tags/tag_type_position.rb +4 -5
- data/lib/yard/lint/validators/tags/type_syntax/parser.rb +8 -3
- data/lib/yard/lint/validators/tags/type_syntax/validator.rb +29 -59
- data/lib/yard/lint/validators/tags/type_syntax.rb +0 -1
- data/lib/yard/lint/validators/warnings/duplicated_parameter_name/validator.rb +1 -18
- data/lib/yard/lint/validators/warnings/invalid_directive_format/validator.rb +1 -18
- data/lib/yard/lint/validators/warnings/invalid_tag_format/validator.rb +1 -18
- data/lib/yard/lint/validators/warnings/unknown_directive/validator.rb +1 -18
- data/lib/yard/lint/validators/warnings/unknown_parameter_name/messages_builder.rb +243 -0
- data/lib/yard/lint/validators/warnings/unknown_parameter_name/result.rb +4 -3
- data/lib/yard/lint/validators/warnings/unknown_parameter_name/validator.rb +1 -18
- data/lib/yard/lint/validators/warnings/unknown_tag/messages_builder.rb +144 -0
- data/lib/yard/lint/validators/warnings/unknown_tag/result.rb +4 -3
- data/lib/yard/lint/validators/warnings/unknown_tag/validator.rb +1 -18
- data/lib/yard/lint/validators/warnings/unknown_tag.rb +10 -0
- data/lib/yard/lint/version.rb +1 -1
- data/lib/yard/lint.rb +81 -13
- data/renovate.json +1 -8
- metadata +40 -6
- data/bin/console +0 -11
- data/bin/setup +0 -8
- data/lib/yard/lint/command_cache.rb +0 -93
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# YARD-Lint Configuration (Strict Mode)
|
|
2
|
+
# See https://github.com/mensfeld/yard-lint for documentation
|
|
3
|
+
#
|
|
4
|
+
# This is a strict configuration suitable for new projects with high documentation standards.
|
|
5
|
+
# All validators are set to 'error' severity (no warnings or conventions).
|
|
6
|
+
# Minimum coverage is set to 100%.
|
|
7
|
+
|
|
8
|
+
# Global settings for all validators
|
|
9
|
+
AllValidators:
|
|
10
|
+
# YARD command-line options (applied to all validators by default)
|
|
11
|
+
YardOptions:
|
|
12
|
+
- --private
|
|
13
|
+
- --protected
|
|
14
|
+
|
|
15
|
+
# Global file exclusion patterns
|
|
16
|
+
Exclude:
|
|
17
|
+
- '\.git'
|
|
18
|
+
- 'vendor/**/*'
|
|
19
|
+
- 'node_modules/**/*'
|
|
20
|
+
- 'spec/**/*'
|
|
21
|
+
- 'test/**/*'
|
|
22
|
+
|
|
23
|
+
# Exit code behavior (error, warning, convention, never)
|
|
24
|
+
FailOnSeverity: error
|
|
25
|
+
|
|
26
|
+
# Minimum documentation coverage percentage (0-100)
|
|
27
|
+
# Fails if coverage is below this threshold
|
|
28
|
+
MinCoverage: 100.0
|
|
29
|
+
|
|
30
|
+
# Diff mode settings
|
|
31
|
+
DiffMode:
|
|
32
|
+
# Default base ref for --diff (auto-detects main/master if not specified)
|
|
33
|
+
DefaultBaseRef: ~
|
|
34
|
+
|
|
35
|
+
# Documentation validators
|
|
36
|
+
Documentation/UndocumentedObjects:
|
|
37
|
+
Description: 'Checks for classes, modules, and methods without documentation.'
|
|
38
|
+
Enabled: true
|
|
39
|
+
Severity: error
|
|
40
|
+
ExcludedMethods:
|
|
41
|
+
- 'initialize/0' # Exclude parameter-less initialize
|
|
42
|
+
- '/^_/' # Exclude private methods (by convention)
|
|
43
|
+
|
|
44
|
+
Documentation/UndocumentedMethodArguments:
|
|
45
|
+
Description: 'Checks for method parameters without @param tags.'
|
|
46
|
+
Enabled: true
|
|
47
|
+
Severity: error
|
|
48
|
+
|
|
49
|
+
Documentation/UndocumentedBooleanMethods:
|
|
50
|
+
Description: 'Checks that question mark methods document their boolean return.'
|
|
51
|
+
Enabled: true
|
|
52
|
+
Severity: error
|
|
53
|
+
|
|
54
|
+
Documentation/UndocumentedOptions:
|
|
55
|
+
Description: 'Detects methods with options hash parameters but no @option tags.'
|
|
56
|
+
Enabled: true
|
|
57
|
+
Severity: error
|
|
58
|
+
|
|
59
|
+
Documentation/MarkdownSyntax:
|
|
60
|
+
Description: 'Detects common markdown syntax errors in documentation.'
|
|
61
|
+
Enabled: true
|
|
62
|
+
Severity: error
|
|
63
|
+
|
|
64
|
+
Documentation/EmptyCommentLine:
|
|
65
|
+
Description: 'Detects empty comment lines at the start or end of documentation blocks.'
|
|
66
|
+
Enabled: true
|
|
67
|
+
Severity: error
|
|
68
|
+
EnabledPatterns:
|
|
69
|
+
Leading: true
|
|
70
|
+
Trailing: true
|
|
71
|
+
|
|
72
|
+
Documentation/BlankLineBeforeDefinition:
|
|
73
|
+
Description: 'Detects blank lines between YARD documentation and method definition.'
|
|
74
|
+
Enabled: true
|
|
75
|
+
Severity: error
|
|
76
|
+
OrphanedSeverity: error
|
|
77
|
+
EnabledPatterns:
|
|
78
|
+
SingleBlankLine: true
|
|
79
|
+
OrphanedDocs: true
|
|
80
|
+
|
|
81
|
+
# Tags validators
|
|
82
|
+
Tags/Order:
|
|
83
|
+
Description: 'Enforces consistent ordering of YARD tags.'
|
|
84
|
+
Enabled: true
|
|
85
|
+
Severity: error
|
|
86
|
+
EnforcedOrder:
|
|
87
|
+
- param
|
|
88
|
+
- option
|
|
89
|
+
- yield
|
|
90
|
+
- yieldparam
|
|
91
|
+
- yieldreturn
|
|
92
|
+
- return
|
|
93
|
+
- raise
|
|
94
|
+
- see
|
|
95
|
+
- example
|
|
96
|
+
- note
|
|
97
|
+
- todo
|
|
98
|
+
|
|
99
|
+
Tags/InvalidTypes:
|
|
100
|
+
Description: 'Validates type definitions in @param, @return, @option tags.'
|
|
101
|
+
Enabled: true
|
|
102
|
+
Severity: error
|
|
103
|
+
ValidatedTags:
|
|
104
|
+
- param
|
|
105
|
+
- option
|
|
106
|
+
- return
|
|
107
|
+
|
|
108
|
+
Tags/TypeSyntax:
|
|
109
|
+
Description: 'Validates YARD type syntax using YARD parser.'
|
|
110
|
+
Enabled: true
|
|
111
|
+
Severity: error
|
|
112
|
+
ValidatedTags:
|
|
113
|
+
- param
|
|
114
|
+
- option
|
|
115
|
+
- return
|
|
116
|
+
- yieldreturn
|
|
117
|
+
|
|
118
|
+
Tags/MeaninglessTag:
|
|
119
|
+
Description: 'Detects @param/@option tags on classes, modules, or constants.'
|
|
120
|
+
Enabled: true
|
|
121
|
+
Severity: error
|
|
122
|
+
CheckedTags:
|
|
123
|
+
- param
|
|
124
|
+
- option
|
|
125
|
+
InvalidObjectTypes:
|
|
126
|
+
- class
|
|
127
|
+
- module
|
|
128
|
+
- constant
|
|
129
|
+
|
|
130
|
+
Tags/CollectionType:
|
|
131
|
+
Description: 'Validates Hash collection syntax consistency.'
|
|
132
|
+
Enabled: true
|
|
133
|
+
Severity: error
|
|
134
|
+
EnforcedStyle: long # 'long' for Hash{K => V} (YARD standard), 'short' for {K => V}
|
|
135
|
+
ValidatedTags:
|
|
136
|
+
- param
|
|
137
|
+
- option
|
|
138
|
+
- return
|
|
139
|
+
- yieldreturn
|
|
140
|
+
|
|
141
|
+
Tags/TagTypePosition:
|
|
142
|
+
Description: 'Validates type annotation position in tags.'
|
|
143
|
+
Enabled: true
|
|
144
|
+
Severity: error
|
|
145
|
+
CheckedTags:
|
|
146
|
+
- param
|
|
147
|
+
- option
|
|
148
|
+
# EnforcedStyle: 'type_after_name' (YARD standard: @param name [Type])
|
|
149
|
+
# or 'type_first' (@param [Type] name)
|
|
150
|
+
EnforcedStyle: type_after_name
|
|
151
|
+
|
|
152
|
+
Tags/ApiTags:
|
|
153
|
+
Description: 'Enforces @api tags on public objects.'
|
|
154
|
+
Enabled: false # Opt-in validator
|
|
155
|
+
Severity: error
|
|
156
|
+
AllowedApis:
|
|
157
|
+
- public
|
|
158
|
+
- private
|
|
159
|
+
- internal
|
|
160
|
+
|
|
161
|
+
Tags/OptionTags:
|
|
162
|
+
Description: 'Requires @option tags for methods with options parameters.'
|
|
163
|
+
Enabled: true
|
|
164
|
+
Severity: error
|
|
165
|
+
|
|
166
|
+
Tags/ExampleSyntax:
|
|
167
|
+
Description: 'Validates Ruby syntax in @example tags.'
|
|
168
|
+
Enabled: true
|
|
169
|
+
Severity: error
|
|
170
|
+
|
|
171
|
+
Tags/RedundantParamDescription:
|
|
172
|
+
Description: 'Detects meaningless parameter descriptions that add no value.'
|
|
173
|
+
Enabled: true
|
|
174
|
+
Severity: error
|
|
175
|
+
CheckedTags:
|
|
176
|
+
- param
|
|
177
|
+
- option
|
|
178
|
+
Articles:
|
|
179
|
+
- The
|
|
180
|
+
- the
|
|
181
|
+
- A
|
|
182
|
+
- a
|
|
183
|
+
- An
|
|
184
|
+
- an
|
|
185
|
+
MaxRedundantWords: 6
|
|
186
|
+
GenericTerms:
|
|
187
|
+
- object
|
|
188
|
+
- instance
|
|
189
|
+
- value
|
|
190
|
+
- data
|
|
191
|
+
- item
|
|
192
|
+
- element
|
|
193
|
+
EnabledPatterns:
|
|
194
|
+
ArticleParam: true
|
|
195
|
+
PossessiveParam: true
|
|
196
|
+
TypeRestatement: true
|
|
197
|
+
ParamToVerb: true
|
|
198
|
+
IdPattern: true
|
|
199
|
+
DirectionalDate: true
|
|
200
|
+
TypeGeneric: true
|
|
201
|
+
|
|
202
|
+
Tags/InformalNotation:
|
|
203
|
+
Description: 'Detects informal tag notation patterns like "Note:" instead of @note.'
|
|
204
|
+
Enabled: true
|
|
205
|
+
Severity: error
|
|
206
|
+
CaseSensitive: false
|
|
207
|
+
RequireStartOfLine: true
|
|
208
|
+
Patterns:
|
|
209
|
+
Note: '@note'
|
|
210
|
+
Todo: '@todo'
|
|
211
|
+
TODO: '@todo'
|
|
212
|
+
FIXME: '@todo'
|
|
213
|
+
See: '@see'
|
|
214
|
+
See also: '@see'
|
|
215
|
+
Warning: '@deprecated'
|
|
216
|
+
Deprecated: '@deprecated'
|
|
217
|
+
Author: '@author'
|
|
218
|
+
Version: '@version'
|
|
219
|
+
Since: '@since'
|
|
220
|
+
Returns: '@return'
|
|
221
|
+
Raises: '@raise'
|
|
222
|
+
Example: '@example'
|
|
223
|
+
|
|
224
|
+
Tags/NonAsciiType:
|
|
225
|
+
Description: 'Detects non-ASCII characters in type annotations.'
|
|
226
|
+
Enabled: true
|
|
227
|
+
Severity: error
|
|
228
|
+
ValidatedTags:
|
|
229
|
+
- param
|
|
230
|
+
- option
|
|
231
|
+
- return
|
|
232
|
+
- yieldreturn
|
|
233
|
+
- yieldparam
|
|
234
|
+
|
|
235
|
+
Tags/TagGroupSeparator:
|
|
236
|
+
Description: 'Enforces blank line separators between different YARD tag groups.'
|
|
237
|
+
Enabled: false # Opt-in validator
|
|
238
|
+
Severity: error
|
|
239
|
+
TagGroups:
|
|
240
|
+
param: [param, option]
|
|
241
|
+
return: [return]
|
|
242
|
+
error: [raise, throws]
|
|
243
|
+
example: [example]
|
|
244
|
+
meta: [see, note, todo, deprecated, since, version, api]
|
|
245
|
+
yield: [yield, yieldparam, yieldreturn]
|
|
246
|
+
RequireAfterDescription: false
|
|
247
|
+
|
|
248
|
+
# Warnings validators - catches YARD parser errors
|
|
249
|
+
Warnings/UnknownTag:
|
|
250
|
+
Description: 'Detects unknown YARD tags.'
|
|
251
|
+
Enabled: true
|
|
252
|
+
Severity: error
|
|
253
|
+
|
|
254
|
+
Warnings/UnknownDirective:
|
|
255
|
+
Description: 'Detects unknown YARD directives.'
|
|
256
|
+
Enabled: true
|
|
257
|
+
Severity: error
|
|
258
|
+
|
|
259
|
+
Warnings/InvalidTagFormat:
|
|
260
|
+
Description: 'Detects malformed tag syntax.'
|
|
261
|
+
Enabled: true
|
|
262
|
+
Severity: error
|
|
263
|
+
|
|
264
|
+
Warnings/InvalidDirectiveFormat:
|
|
265
|
+
Description: 'Detects malformed directive syntax.'
|
|
266
|
+
Enabled: true
|
|
267
|
+
Severity: error
|
|
268
|
+
|
|
269
|
+
Warnings/DuplicatedParameterName:
|
|
270
|
+
Description: 'Detects duplicate @param tags.'
|
|
271
|
+
Enabled: true
|
|
272
|
+
Severity: error
|
|
273
|
+
|
|
274
|
+
Warnings/UnknownParameterName:
|
|
275
|
+
Description: 'Detects @param tags for non-existent parameters.'
|
|
276
|
+
Enabled: true
|
|
277
|
+
Severity: error
|
|
278
|
+
|
|
279
|
+
# Semantic validators
|
|
280
|
+
Semantic/AbstractMethods:
|
|
281
|
+
Description: 'Ensures @abstract methods do not have real implementations.'
|
|
282
|
+
Enabled: true
|
|
283
|
+
Severity: error
|
|
@@ -6,47 +6,52 @@ module Yard
|
|
|
6
6
|
module Validators
|
|
7
7
|
# Base YARD validator class
|
|
8
8
|
class Base
|
|
9
|
-
# Class-level
|
|
10
|
-
#
|
|
11
|
-
@
|
|
12
|
-
|
|
13
|
-
# Default YARD command options that we need to use
|
|
14
|
-
DEFAULT_OPTIONS = [
|
|
15
|
-
'--charset utf-8',
|
|
16
|
-
'--markup markdown',
|
|
17
|
-
'--no-progress'
|
|
18
|
-
].freeze
|
|
19
|
-
|
|
20
|
-
# Base temp directory for YARD databases
|
|
21
|
-
# Each unique set of arguments gets its own subdirectory to prevent contamination
|
|
22
|
-
YARDOC_BASE_TEMP_DIR = Dir.mktmpdir.freeze
|
|
23
|
-
|
|
24
|
-
private_constant :YARDOC_BASE_TEMP_DIR
|
|
9
|
+
# Class-level settings for in-process execution
|
|
10
|
+
# These must be set on each subclass, not on Base
|
|
11
|
+
@in_process_enabled = nil
|
|
12
|
+
@in_process_visibility = nil
|
|
25
13
|
|
|
26
14
|
attr_reader :config, :selection
|
|
27
15
|
|
|
28
16
|
class << self
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
# Declare that this validator supports in-process execution
|
|
18
|
+
# @param visibility [Symbol] visibility filter for objects (:public or :all)
|
|
19
|
+
# :public - only include public methods (default, no --private/--protected)
|
|
20
|
+
# :all - include all methods (equivalent to --private --protected)
|
|
21
|
+
# @return [void]
|
|
22
|
+
# @example
|
|
23
|
+
# class Validator < Base
|
|
24
|
+
# in_process visibility: :all
|
|
25
|
+
# end
|
|
26
|
+
def in_process(visibility: :public)
|
|
27
|
+
@in_process_enabled = true
|
|
28
|
+
@in_process_visibility = visibility
|
|
36
29
|
end
|
|
37
30
|
|
|
38
|
-
#
|
|
39
|
-
# @return [
|
|
40
|
-
def
|
|
41
|
-
|
|
31
|
+
# Check if this validator supports in-process execution
|
|
32
|
+
# @return [Boolean]
|
|
33
|
+
def in_process?
|
|
34
|
+
@in_process_enabled == true
|
|
42
35
|
end
|
|
43
36
|
|
|
44
|
-
#
|
|
45
|
-
# @return [
|
|
46
|
-
def
|
|
47
|
-
|
|
37
|
+
# Get the visibility setting for in-process execution
|
|
38
|
+
# @return [Symbol, nil] :public, :all, or nil if not set
|
|
39
|
+
def in_process_visibility
|
|
40
|
+
@in_process_visibility
|
|
41
|
+
end
|
|
48
42
|
|
|
49
|
-
|
|
43
|
+
# Get the validator name from the class namespace
|
|
44
|
+
# @return [String, nil] validator name like 'Tags/Order' or nil
|
|
45
|
+
# @example
|
|
46
|
+
# Yard::Lint::Validators::Tags::Order::Validator.validator_name
|
|
47
|
+
# # => 'Tags/Order'
|
|
48
|
+
def validator_name
|
|
49
|
+
name&.split('::')&.then do |parts|
|
|
50
|
+
idx = parts.index('Validators')
|
|
51
|
+
return nil unless idx && parts[idx + 1] && parts[idx + 2]
|
|
52
|
+
|
|
53
|
+
"#{parts[idx + 1]}/#{parts[idx + 2]}"
|
|
54
|
+
end
|
|
50
55
|
end
|
|
51
56
|
end
|
|
52
57
|
|
|
@@ -57,105 +62,34 @@ module Yard
|
|
|
57
62
|
@selection = selection
|
|
58
63
|
end
|
|
59
64
|
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
yardoc_dir = yardoc_temp_dir_for_arguments(escaped_file_names.join(' '))
|
|
73
|
-
|
|
74
|
-
# For large file lists, use a temporary file to avoid ARG_MAX limits
|
|
75
|
-
# Write file paths to temp file, one per line
|
|
76
|
-
Tempfile.create(['yard_files', '.txt']) do |f|
|
|
77
|
-
escaped_file_names.each { |file| f.puts(file) }
|
|
78
|
-
f.flush
|
|
79
|
-
|
|
80
|
-
yard_cmd(yardoc_dir, f.path)
|
|
81
|
-
end
|
|
65
|
+
# Execute query for a single object during in-process execution.
|
|
66
|
+
# Override this method in validators that support in-process execution.
|
|
67
|
+
# @param object [YARD::CodeObjects::Base] the code object to query
|
|
68
|
+
# @param collector [Executor::ResultCollector] collector for output
|
|
69
|
+
# @return [void]
|
|
70
|
+
# @example
|
|
71
|
+
# def in_process_query(object, collector)
|
|
72
|
+
# return unless object.docstring.all.empty?
|
|
73
|
+
# collector.puts "#{object.file}:#{object.line}: #{object.title}"
|
|
74
|
+
# end
|
|
75
|
+
def in_process_query(object, collector)
|
|
76
|
+
raise NotImplementedError, "#{self.class} must implement in_process_query for in-process execution"
|
|
82
77
|
end
|
|
83
78
|
|
|
84
79
|
private
|
|
85
80
|
|
|
86
|
-
# Returns a unique YARD database directory for the given arguments
|
|
87
|
-
# Uses SHA256 hash of the normalized arguments to ensure different file sets
|
|
88
|
-
# get separate databases, preventing contamination
|
|
89
|
-
# @param escaped_file_names [String] escaped file names to process
|
|
90
|
-
# @return [String] path to the YARD database directory
|
|
91
|
-
def yardoc_temp_dir_for_arguments(escaped_file_names)
|
|
92
|
-
# Combine all arguments that affect YARD output
|
|
93
|
-
all_args = "#{shell_arguments} #{escaped_file_names}"
|
|
94
|
-
|
|
95
|
-
# Create a hash of the arguments for a unique directory name
|
|
96
|
-
args_hash = Digest::SHA256.hexdigest(all_args)
|
|
97
|
-
|
|
98
|
-
# Create subdirectory under base temp dir
|
|
99
|
-
dir = File.join(YARDOC_BASE_TEMP_DIR, args_hash)
|
|
100
|
-
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
|
101
|
-
|
|
102
|
-
dir
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# @return [String] all arguments with which YARD command should be executed
|
|
106
|
-
def shell_arguments
|
|
107
|
-
validator_name = self.class.name&.split('::')&.then do |parts|
|
|
108
|
-
idx = parts.index('Validators')
|
|
109
|
-
next config.options unless idx && parts[idx + 1] && parts[idx + 2]
|
|
110
|
-
|
|
111
|
-
"#{parts[idx + 1]}/#{parts[idx + 2]}"
|
|
112
|
-
end || config.options
|
|
113
|
-
|
|
114
|
-
yard_options = config.validator_yard_options(validator_name)
|
|
115
|
-
args = escape(yard_options).join(' ')
|
|
116
|
-
"#{args} #{DEFAULT_OPTIONS.join(' ')}"
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# @param array [Array] escape all elements in an array
|
|
120
|
-
# @return [Array] array with escaped elements
|
|
121
|
-
def escape(array)
|
|
122
|
-
array.map { |cmd| Shellwords.escape(cmd) }
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# Builds a raw hash that can be used for further processing
|
|
126
|
-
# @param stdout [String, Hash, Array] anything that we want to return as stdout
|
|
127
|
-
# @param stderr [String, Hash, Array] any errors that occurred
|
|
128
|
-
# @param exit_code [Integer, false] result exit code or false if we want to decide it based
|
|
129
|
-
# on the stderr content
|
|
130
|
-
# @return [Hash] hash with stdout, stderr and exit_code keys
|
|
131
|
-
def raw(stdout = '', stderr = '', exit_code = false)
|
|
132
|
-
{
|
|
133
|
-
stdout: stdout,
|
|
134
|
-
stderr: stderr,
|
|
135
|
-
exit_code: exit_code || (stderr.empty? ? 0 : 1)
|
|
136
|
-
}
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
# Executes a shell command and returns the result
|
|
140
|
-
# Routes through command cache to avoid duplicate executions
|
|
141
|
-
# @param cmd [String] shell command to execute
|
|
142
|
-
# @return [Hash] hash with stdout, stderr and exit_code keys
|
|
143
|
-
def shell(cmd)
|
|
144
|
-
self.class.command_cache.execute(cmd)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
81
|
# Retrieves configuration value with fallback to default
|
|
148
82
|
# Automatically determines the validator name from the class namespace
|
|
149
83
|
#
|
|
150
84
|
# @param key [String] the configuration key to retrieve
|
|
151
85
|
# @return [Object] the configured value or default value from the validator's Config.defaults
|
|
152
|
-
# @note The validator name is automatically extracted from the class namespace.
|
|
153
|
-
# For example, Yard::Lint::Validators::Tags::RedundantParamDescription::Validator
|
|
154
|
-
# becomes 'Tags/RedundantParamDescription'
|
|
155
86
|
# @example Usage in a validator (e.g., Tags::RedundantParamDescription)
|
|
156
87
|
# def config_articles
|
|
157
88
|
# config_or_default('Articles')
|
|
158
89
|
# end
|
|
90
|
+
# @note The validator name is automatically extracted from the class namespace.
|
|
91
|
+
# For example, Yard::Lint::Validators::Tags::RedundantParamDescription::Validator
|
|
92
|
+
# becomes 'Tags/RedundantParamDescription'
|
|
159
93
|
def config_or_default(key)
|
|
160
94
|
validator_name = self.class.name&.split('::')&.then do |parts|
|
|
161
95
|
idx = parts.index('Validators')
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module BlankLineBeforeDefinition
|
|
8
|
+
# Configuration for BlankLineBeforeDefinition validator
|
|
9
|
+
class Config < ::Yard::Lint::Validators::Config
|
|
10
|
+
self.id = :blank_line_before_definition
|
|
11
|
+
self.defaults = {
|
|
12
|
+
'Enabled' => true,
|
|
13
|
+
'Severity' => 'convention',
|
|
14
|
+
'OrphanedSeverity' => 'convention',
|
|
15
|
+
'EnabledPatterns' => {
|
|
16
|
+
'SingleBlankLine' => true,
|
|
17
|
+
'OrphanedDocs' => true
|
|
18
|
+
}
|
|
19
|
+
}.freeze
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module BlankLineBeforeDefinition
|
|
8
|
+
# Builds human-readable messages for blank line before definition violations
|
|
9
|
+
class MessagesBuilder
|
|
10
|
+
# Maps violation types to human-readable descriptions
|
|
11
|
+
ERROR_DESCRIPTIONS = {
|
|
12
|
+
'single' => 'Blank line between documentation and definition',
|
|
13
|
+
'orphaned' => 'Documentation is orphaned (YARD ignores it due to blank lines)'
|
|
14
|
+
}.freeze
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
# Formats a violation message
|
|
18
|
+
# @param offense [Hash] the offense details
|
|
19
|
+
# @return [String] formatted message
|
|
20
|
+
def call(offense)
|
|
21
|
+
type = offense[:violation_type]
|
|
22
|
+
object_name = offense[:object_name]
|
|
23
|
+
blank_count = offense[:blank_count]
|
|
24
|
+
|
|
25
|
+
description = ERROR_DESCRIPTIONS[type] || 'Blank line before definition'
|
|
26
|
+
|
|
27
|
+
if type == 'orphaned'
|
|
28
|
+
"#{description} for '#{object_name}' (#{blank_count} blank lines)"
|
|
29
|
+
else
|
|
30
|
+
"#{description} for '#{object_name}'"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module BlankLineBeforeDefinition
|
|
8
|
+
# Parses YARD output for blank line before definition violations
|
|
9
|
+
class Parser < Parsers::Base
|
|
10
|
+
# Parse YARD output into structured violations
|
|
11
|
+
# @param output [String] raw YARD output
|
|
12
|
+
# @return [Array<Hash>] array of violation hashes
|
|
13
|
+
def call(output)
|
|
14
|
+
return [] if output.nil? || output.empty?
|
|
15
|
+
|
|
16
|
+
violations = []
|
|
17
|
+
lines = output.lines.map(&:chomp)
|
|
18
|
+
|
|
19
|
+
i = 0
|
|
20
|
+
while i < lines.size
|
|
21
|
+
line = lines[i]
|
|
22
|
+
|
|
23
|
+
# Match location line: "file:line: object_name"
|
|
24
|
+
if (location_match = line.match(/^(.+):(\d+): (.+)$/))
|
|
25
|
+
file_path = location_match[1]
|
|
26
|
+
object_line = location_match[2].to_i
|
|
27
|
+
object_name = location_match[3]
|
|
28
|
+
|
|
29
|
+
# Next line contains violation details
|
|
30
|
+
i += 1
|
|
31
|
+
next unless i < lines.size
|
|
32
|
+
|
|
33
|
+
# Parse violation: "single:1" or "orphaned:3"
|
|
34
|
+
detail_parts = lines[i].split(':', 2)
|
|
35
|
+
next unless detail_parts.size == 2
|
|
36
|
+
|
|
37
|
+
violation_type = detail_parts[0]
|
|
38
|
+
blank_count = detail_parts[1].to_i
|
|
39
|
+
|
|
40
|
+
violations << {
|
|
41
|
+
location: file_path,
|
|
42
|
+
line: object_line,
|
|
43
|
+
object_name: object_name,
|
|
44
|
+
violation_type: violation_type,
|
|
45
|
+
blank_count: blank_count
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
i += 1
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
violations
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module BlankLineBeforeDefinition
|
|
8
|
+
# Result builder for blank line before definition violations
|
|
9
|
+
class Result < Results::Base
|
|
10
|
+
self.default_severity = 'convention'
|
|
11
|
+
self.offense_type = 'line'
|
|
12
|
+
self.offense_name = 'BlankLineBeforeDefinition'
|
|
13
|
+
|
|
14
|
+
# Build human-readable message for blank line violation
|
|
15
|
+
# @param offense [Hash] offense data with violation details
|
|
16
|
+
# @return [String] formatted message
|
|
17
|
+
def build_message(offense)
|
|
18
|
+
MessagesBuilder.call(offense)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
# Override to handle per-violation severity based on violation type
|
|
24
|
+
# @return [Array<Hash>] array of offense hashes
|
|
25
|
+
def build_offenses
|
|
26
|
+
@parsed_data.map do |offense_data|
|
|
27
|
+
severity = severity_for_violation(offense_data[:violation_type])
|
|
28
|
+
|
|
29
|
+
offense_data.merge(
|
|
30
|
+
severity: severity,
|
|
31
|
+
type: self.class.offense_type,
|
|
32
|
+
name: computed_offense_name,
|
|
33
|
+
message: build_message(offense_data),
|
|
34
|
+
location: offense_data[:location] || offense_data[:file],
|
|
35
|
+
location_line: offense_data[:line] || offense_data[:location_line] || 0
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Get severity for a specific violation type
|
|
41
|
+
# @param violation_type [String] 'single' or 'orphaned'
|
|
42
|
+
# @return [String] severity level
|
|
43
|
+
def severity_for_violation(violation_type)
|
|
44
|
+
default = self.class.default_severity
|
|
45
|
+
return default unless config
|
|
46
|
+
|
|
47
|
+
case violation_type
|
|
48
|
+
when 'orphaned'
|
|
49
|
+
config.validator_config(validator_name, 'OrphanedSeverity') ||
|
|
50
|
+
config.validator_severity(validator_name) ||
|
|
51
|
+
default
|
|
52
|
+
else
|
|
53
|
+
config.validator_severity(validator_name) || default
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|