yard-lint 1.2.3 → 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 +150 -1
- data/README.md +98 -4
- data/Rakefile +20 -0
- data/bin/yard-lint +71 -38
- data/lib/yard/lint/config.rb +5 -0
- 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 +50 -38
- data/lib/yard/lint/templates/default_config.yml +105 -0
- data/lib/yard/lint/templates/strict_config.yml +105 -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/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/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/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/validator.rb +53 -84
- data/lib/yard/lint/validators/tags/tag_type_position.rb +0 -1
- data/lib/yard/lint/validators/tags/type_syntax/parser.rb +7 -2
- 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 +38 -2
- data/lib/yard/lint/command_cache.rb +0 -93
|
@@ -7,63 +7,31 @@ module Yard
|
|
|
7
7
|
module MeaninglessTag
|
|
8
8
|
# Validates that @param/@option tags only appear on methods
|
|
9
9
|
class Validator < Base
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
#
|
|
14
|
-
# @param
|
|
15
|
-
# @
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
10
|
+
# Enable in-process execution with all visibility
|
|
11
|
+
in_process visibility: :all
|
|
12
|
+
|
|
13
|
+
# Execute query for a single object during in-process execution.
|
|
14
|
+
# Checks for @param/@option tags on non-method objects.
|
|
15
|
+
# @param object [YARD::CodeObjects::Base] the code object to query
|
|
16
|
+
# @param collector [Executor::ResultCollector] collector for output
|
|
17
|
+
# @return [void]
|
|
18
|
+
def in_process_query(object, collector)
|
|
19
|
+
object_type = object.type.to_s
|
|
20
|
+
invalid_types = invalid_object_types
|
|
21
|
+
tags_to_check = checked_tags
|
|
22
|
+
|
|
23
|
+
return unless invalid_types.include?(object_type)
|
|
24
|
+
|
|
25
|
+
object.docstring.tags.each do |tag|
|
|
26
|
+
next unless tags_to_check.include?(tag.tag_name)
|
|
27
|
+
|
|
28
|
+
collector.puts "#{object.file}:#{object.line}: #{object.title}"
|
|
29
|
+
collector.puts "#{object_type}|#{tag.tag_name}"
|
|
30
|
+
break
|
|
28
31
|
end
|
|
29
32
|
end
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
# Format output as two lines per violation:
|
|
33
|
-
# Line 1: file.rb:LINE: ClassName
|
|
34
|
-
# Line 2: object_type|tag_name
|
|
35
|
-
# @return [String] YARD query string
|
|
36
|
-
def query
|
|
37
|
-
<<~QUERY.strip
|
|
38
|
-
'
|
|
39
|
-
object_type = object.type.to_s
|
|
40
|
-
|
|
41
|
-
if #{invalid_object_types_array}.include?(object_type)
|
|
42
|
-
docstring.tags.each do |tag|
|
|
43
|
-
if #{checked_tags_array}.include?(tag.tag_name)
|
|
44
|
-
puts object.file + ":" + object.line.to_s + ": " + object.title
|
|
45
|
-
puts object_type + "|" + tag.tag_name
|
|
46
|
-
break
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
false
|
|
52
|
-
'
|
|
53
|
-
QUERY
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Array of tag names to check, formatted for YARD query
|
|
57
|
-
# @return [String] Ruby array literal string
|
|
58
|
-
def checked_tags_array
|
|
59
|
-
"[#{checked_tags.map { |t| "\"#{t}\"" }.join(',')}]"
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Array of invalid object types, formatted for YARD query
|
|
63
|
-
# @return [String] Ruby array literal string
|
|
64
|
-
def invalid_object_types_array
|
|
65
|
-
"[#{invalid_object_types.map { |t| "\"#{t}\"" }.join(',')}]"
|
|
66
|
-
end
|
|
34
|
+
private
|
|
67
35
|
|
|
68
36
|
# @return [Array<String>] tags that should only appear on methods
|
|
69
37
|
def checked_tags
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Tags
|
|
7
|
+
module NonAsciiType
|
|
8
|
+
# Configuration for NonAsciiType validator
|
|
9
|
+
class Config < ::Yard::Lint::Validators::Config
|
|
10
|
+
self.id = :non_ascii_type
|
|
11
|
+
self.defaults = {
|
|
12
|
+
'Enabled' => true,
|
|
13
|
+
'Severity' => 'warning',
|
|
14
|
+
'ValidatedTags' => %w[param option return yieldreturn yieldparam]
|
|
15
|
+
}.freeze
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Tags
|
|
7
|
+
module NonAsciiType
|
|
8
|
+
# Builds human-readable messages for non-ASCII type violations
|
|
9
|
+
class MessagesBuilder
|
|
10
|
+
class << self
|
|
11
|
+
# Formats a non-ASCII type violation message
|
|
12
|
+
# @param offense [Hash] offense details with tag_name, type_string, character, codepoint
|
|
13
|
+
# @return [String] formatted message
|
|
14
|
+
def call(offense)
|
|
15
|
+
tag = offense[:tag_name]
|
|
16
|
+
type = offense[:type_string]
|
|
17
|
+
char = offense[:character]
|
|
18
|
+
codepoint = offense[:codepoint]
|
|
19
|
+
|
|
20
|
+
"Type specification in @#{tag} tag contains non-ASCII character " \
|
|
21
|
+
"'#{char}' (#{codepoint}) in '#{type}'. Ruby type names must use ASCII characters only."
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Tags
|
|
7
|
+
module NonAsciiType
|
|
8
|
+
# Parser for NonAsciiType validator output
|
|
9
|
+
# Parses output that reports non-ASCII characters in type specifications
|
|
10
|
+
class Parser < ::Yard::Lint::Parsers::Base
|
|
11
|
+
# Parses validator output and extracts non-ASCII type violations
|
|
12
|
+
# Expected format (two lines per violation):
|
|
13
|
+
# file.rb:LINE: ClassName#method_name
|
|
14
|
+
# tag_name|type_string|character|codepoint
|
|
15
|
+
# @param yard_output [String] raw validator query results
|
|
16
|
+
# @option _kwargs [Object] :unused this parameter accepts no options (reserved for future use)
|
|
17
|
+
# @return [Array<Hash>] array with violation details
|
|
18
|
+
def call(yard_output, **_kwargs)
|
|
19
|
+
return [] if yard_output.nil?
|
|
20
|
+
|
|
21
|
+
# Handle potential encoding issues
|
|
22
|
+
sanitized = yard_output.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')
|
|
23
|
+
return [] if sanitized.strip.empty?
|
|
24
|
+
|
|
25
|
+
lines = sanitized.split("\n").map(&:strip).reject(&:empty?)
|
|
26
|
+
violations = []
|
|
27
|
+
|
|
28
|
+
lines.each_slice(2) do |location_line, details_line|
|
|
29
|
+
next unless location_line && details_line
|
|
30
|
+
|
|
31
|
+
# Parse location: "file.rb:10: ClassName#method_name"
|
|
32
|
+
location_match = location_line.match(/^(.+):(\d+): (.+)$/)
|
|
33
|
+
next unless location_match
|
|
34
|
+
|
|
35
|
+
# Parse details: "tag_name|type_string|character|codepoint"
|
|
36
|
+
details = details_line.split('|', 4)
|
|
37
|
+
next unless details.size == 4
|
|
38
|
+
|
|
39
|
+
tag_name, type_string, character, codepoint = details
|
|
40
|
+
|
|
41
|
+
violations << {
|
|
42
|
+
location: location_match[1],
|
|
43
|
+
line: location_match[2].to_i,
|
|
44
|
+
method_name: location_match[3],
|
|
45
|
+
tag_name: tag_name,
|
|
46
|
+
type_string: type_string,
|
|
47
|
+
character: character,
|
|
48
|
+
codepoint: codepoint
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
violations
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Tags
|
|
7
|
+
module NonAsciiType
|
|
8
|
+
# Result wrapper for NonAsciiType validator
|
|
9
|
+
class Result < Results::Base
|
|
10
|
+
self.default_severity = 'warning'
|
|
11
|
+
self.offense_type = 'method'
|
|
12
|
+
self.offense_name = 'NonAsciiType'
|
|
13
|
+
|
|
14
|
+
# Builds a human-readable message for the offense
|
|
15
|
+
# @param offense [Hash] offense details
|
|
16
|
+
# @return [String] formatted message
|
|
17
|
+
def build_message(offense)
|
|
18
|
+
MessagesBuilder.call(offense)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Tags
|
|
7
|
+
module NonAsciiType
|
|
8
|
+
# Validates that type specifications contain only ASCII characters
|
|
9
|
+
# Ruby type names must be valid Ruby identifiers (ASCII only)
|
|
10
|
+
class Validator < Base
|
|
11
|
+
# Enable in-process execution
|
|
12
|
+
in_process visibility: :public
|
|
13
|
+
|
|
14
|
+
# Pattern to match non-ASCII characters
|
|
15
|
+
NON_ASCII_PATTERN = /[^\x00-\x7F]/
|
|
16
|
+
|
|
17
|
+
# Execute query for a single object during in-process execution.
|
|
18
|
+
# Checks type specifications for non-ASCII characters.
|
|
19
|
+
# @param object [YARD::CodeObjects::Base] the code object to query
|
|
20
|
+
# @param collector [Executor::ResultCollector] collector for output
|
|
21
|
+
# @return [void]
|
|
22
|
+
def in_process_query(object, collector)
|
|
23
|
+
validated_tags = config.validator_config('Tags/NonAsciiType', 'ValidatedTags') ||
|
|
24
|
+
%w[param option return yieldreturn yieldparam]
|
|
25
|
+
|
|
26
|
+
object.docstring.tags
|
|
27
|
+
.select { |tag| validated_tags.include?(tag.tag_name) }
|
|
28
|
+
.each do |tag|
|
|
29
|
+
next unless tag.types
|
|
30
|
+
|
|
31
|
+
tag.types.each do |type_str|
|
|
32
|
+
non_ascii_chars = type_str.scan(NON_ASCII_PATTERN).uniq
|
|
33
|
+
next if non_ascii_chars.empty?
|
|
34
|
+
|
|
35
|
+
# Format: file:line: object_title
|
|
36
|
+
# Then: tag_name|type_string|char|codepoint
|
|
37
|
+
non_ascii_chars.each do |char|
|
|
38
|
+
codepoint = format('U+%04X', char.ord)
|
|
39
|
+
collector.puts "#{object.file}:#{object.line}: #{object.title}"
|
|
40
|
+
collector.puts "#{tag.tag_name}|#{type_str}|#{char}|#{codepoint}"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Tags
|
|
7
|
+
# NonAsciiType validator
|
|
8
|
+
#
|
|
9
|
+
# Detects non-ASCII characters in YARD type specifications. Ruby type names
|
|
10
|
+
# must be valid Ruby identifiers which only support ASCII characters. Non-ASCII
|
|
11
|
+
# characters in type specifications are usually the result of copy-paste errors
|
|
12
|
+
# from word processors that use smart typography (e.g., `…` instead of `...`).
|
|
13
|
+
#
|
|
14
|
+
# This validator is enabled by default.
|
|
15
|
+
#
|
|
16
|
+
# @example Bad - Non-ASCII characters in type specification
|
|
17
|
+
# # @param flags [Symbol, …] variadic flags
|
|
18
|
+
# # @return [String→Integer] transformation result
|
|
19
|
+
# def process(flags)
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# @example Good - Valid ASCII type syntax
|
|
23
|
+
# # @param flags [Symbol] variadic flags
|
|
24
|
+
# # @return [Hash{String => Integer}] transformation result
|
|
25
|
+
# def process(flags)
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# ## Configuration
|
|
29
|
+
#
|
|
30
|
+
# To disable this validator:
|
|
31
|
+
#
|
|
32
|
+
# Tags/NonAsciiType:
|
|
33
|
+
# Enabled: false
|
|
34
|
+
module NonAsciiType
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -24,14 +24,14 @@ module Yard
|
|
|
24
24
|
# @return [Array<Hash>] array of offense hashes
|
|
25
25
|
def build_offenses
|
|
26
26
|
@parsed_data.map do |offense_data|
|
|
27
|
-
|
|
27
|
+
offense_data.merge(
|
|
28
28
|
severity: configured_severity,
|
|
29
29
|
type: self.class.offense_type,
|
|
30
30
|
name: offense_data[:name] || self.class.offense_name,
|
|
31
31
|
message: build_message(offense_data),
|
|
32
32
|
location: offense_data[:location] || offense_data[:file],
|
|
33
33
|
location_line: offense_data[:line] || offense_data[:location_line] || 0
|
|
34
|
-
|
|
34
|
+
)
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -7,53 +7,38 @@ module Yard
|
|
|
7
7
|
module OptionTags
|
|
8
8
|
# Validator to check methods with options hash have @option tags
|
|
9
9
|
class Validator < Base
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# Runs yard list query to find methods with options parameter but missing @option tags
|
|
13
|
-
# @param dir [String] dir where the yard db is (or where it should be generated)
|
|
14
|
-
# @param file_list_path [String] path to temp file containing file paths (one per line)
|
|
15
|
-
# @return [Hash] shell command execution hash results
|
|
16
|
-
def yard_cmd(dir, file_list_path)
|
|
17
|
-
cmd = <<~CMD
|
|
18
|
-
cat #{Shellwords.escape(file_list_path)} | xargs yard list \
|
|
19
|
-
--private \
|
|
20
|
-
--protected \
|
|
21
|
-
-b #{Shellwords.escape(dir)}
|
|
22
|
-
CMD
|
|
23
|
-
cmd = cmd.tr("\n", ' ')
|
|
24
|
-
cmd = cmd.gsub('yard list', "yard list --query #{query}")
|
|
10
|
+
# Enable in-process execution with all visibility
|
|
11
|
+
in_process visibility: :all
|
|
25
12
|
|
|
26
|
-
|
|
27
|
-
|
|
13
|
+
# Execute query for a single object during in-process execution.
|
|
14
|
+
# Checks if methods with options parameter have @option tags.
|
|
15
|
+
# @param object [YARD::CodeObjects::Base] the code object to query
|
|
16
|
+
# @param collector [Executor::ResultCollector] collector for output
|
|
17
|
+
# @return [void]
|
|
18
|
+
def in_process_query(object, collector)
|
|
19
|
+
return unless object.is_a?(YARD::CodeObjects::MethodObject)
|
|
28
20
|
|
|
29
|
-
# @return [String] yard query to find methods with options parameter
|
|
30
|
-
# but no @option tags
|
|
31
|
-
def query
|
|
32
21
|
parameter_names = config_parameter_names
|
|
33
|
-
<<~QUERY
|
|
34
|
-
'
|
|
35
|
-
if object.is_a?(YARD::CodeObjects::MethodObject)
|
|
36
|
-
# Check if method has a parameter named "options" or "opts"
|
|
37
|
-
has_options_param = object.parameters.any? do |param|
|
|
38
|
-
param_name = param[0].to_s.gsub(/[*:]/, '')
|
|
39
|
-
#{parameter_names.inspect}.include?(param_name)
|
|
40
|
-
end
|
|
41
22
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
23
|
+
# Check if method has a parameter named "options" or "opts" etc.
|
|
24
|
+
has_options_param = object.parameters.any? do |param|
|
|
25
|
+
param_name = param[0].to_s.gsub(/[*:]/, '')
|
|
26
|
+
parameter_names.include?(param_name)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
return unless has_options_param
|
|
45
30
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
'
|
|
54
|
-
QUERY
|
|
31
|
+
# Check if method has any @option tags
|
|
32
|
+
option_tags = object.tags(:option)
|
|
33
|
+
|
|
34
|
+
return unless option_tags.empty?
|
|
35
|
+
|
|
36
|
+
collector.puts "#{object.file}:#{object.line}: #{object.title}"
|
|
37
|
+
collector.puts 'missing_option_tags'
|
|
55
38
|
end
|
|
56
39
|
|
|
40
|
+
private
|
|
41
|
+
|
|
57
42
|
# @return [Array<String>] parameter names that should have @option tags
|
|
58
43
|
def config_parameter_names
|
|
59
44
|
config.validator_config('Tags/OptionTags', 'ParameterNames') || Config.defaults['ParameterNames']
|
|
@@ -8,78 +8,51 @@ module Yard
|
|
|
8
8
|
# Runs a query that will pick all the objects that have docs with tags in an invalid
|
|
9
9
|
# order. By invalid we mean, that they are not as defined in the settings.
|
|
10
10
|
class Validator < Base
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
# @
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
result[:stdout] = { result: result[:stdout], tags_order: tags_order }
|
|
28
|
-
result
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# @return [String] multiline yard query that we use to find methods with
|
|
32
|
-
# tags that are not in the valid order
|
|
33
|
-
# @note We need to print things for all of the elements as some of them
|
|
34
|
-
# are listed in yard twice (for example module functions), and for the
|
|
35
|
-
# second time, yard injects things by itself making it impossible to
|
|
36
|
-
# figure out whether the order is ok or now. That's why we print all and those
|
|
37
|
-
# that are ok, we mark with 'valid' and if it is reported later as invalid again,
|
|
38
|
-
# we know, that it is valid
|
|
39
|
-
def query
|
|
40
|
-
<<-QUERY
|
|
41
|
-
'
|
|
42
|
-
tags_order = #{query_array(tags_order)}
|
|
11
|
+
# Enable in-process execution with all visibility
|
|
12
|
+
in_process visibility: :all
|
|
13
|
+
|
|
14
|
+
# Execute query for a single object during in-process execution.
|
|
15
|
+
# Checks if tags appear in the configured order.
|
|
16
|
+
# @param object [YARD::CodeObjects::Base] the code object to query
|
|
17
|
+
# @param collector [Executor::ResultCollector] collector for output
|
|
18
|
+
# @return [void]
|
|
19
|
+
def in_process_query(object, collector)
|
|
20
|
+
return if object.is_alias?
|
|
21
|
+
|
|
22
|
+
# Extract @tag names from docstring
|
|
23
|
+
tag_pattern = /^@(\S+)/
|
|
24
|
+
doc_tags = object.docstring.all.scan(tag_pattern).flatten
|
|
25
|
+
|
|
26
|
+
# Remove consecutive duplicates
|
|
43
27
|
accu = []
|
|
44
|
-
str = "@"
|
|
45
|
-
slash = 92.chr
|
|
46
|
-
regexp = "^"+str+"("+slash+"S+)"
|
|
47
|
-
doc_tags = object.docstring.all.scan(Regexp.new(regexp)).flatten
|
|
48
|
-
|
|
49
28
|
doc_tags.each do |param|
|
|
50
29
|
accu << param unless accu.last == param
|
|
51
30
|
end
|
|
52
31
|
|
|
53
|
-
|
|
54
|
-
|
|
32
|
+
# Filter to only configured tags
|
|
33
|
+
order = tags_order.dup
|
|
34
|
+
order.delete_if { |el| !accu.include?(el) }
|
|
35
|
+
accu.delete_if { |el| !order.include?(el) }
|
|
55
36
|
|
|
56
|
-
|
|
37
|
+
# Compare order using base-36 encoding
|
|
38
|
+
tags_orders = order.join.to_i(36)
|
|
57
39
|
accus = accu.join.to_i(36)
|
|
58
40
|
|
|
59
|
-
puts object.file
|
|
41
|
+
collector.puts "#{object.file}:#{object.line}: #{object.title}"
|
|
60
42
|
|
|
61
|
-
if accus != tags_orders
|
|
62
|
-
puts
|
|
43
|
+
if accus != tags_orders
|
|
44
|
+
collector.puts order.join(',')
|
|
63
45
|
else
|
|
64
|
-
puts
|
|
46
|
+
collector.puts 'valid'
|
|
65
47
|
end
|
|
66
|
-
|
|
67
|
-
false
|
|
68
|
-
' \\
|
|
69
|
-
QUERY
|
|
70
48
|
end
|
|
71
49
|
|
|
50
|
+
private
|
|
51
|
+
|
|
72
52
|
# @return [Array<String>] tags order
|
|
73
53
|
def tags_order
|
|
74
54
|
config.validator_config('Tags/Order', 'EnforcedOrder')
|
|
75
55
|
end
|
|
76
|
-
|
|
77
|
-
# @param elements [Array<String>] array of elements that we want to convert into
|
|
78
|
-
# a string ruby yard query array form
|
|
79
|
-
# @return [String] array of elements for yard query converted into a string
|
|
80
|
-
def query_array(elements)
|
|
81
|
-
"[#{elements.map { |type| "\"#{type}\"" }.join(',')}]"
|
|
82
|
-
end
|
|
83
56
|
end
|
|
84
57
|
end
|
|
85
58
|
end
|
|
@@ -15,6 +15,19 @@ module Yard
|
|
|
15
15
|
'Articles' => %w[The the A a An an],
|
|
16
16
|
'MaxRedundantWords' => 6,
|
|
17
17
|
'GenericTerms' => %w[object instance value data item element],
|
|
18
|
+
'LowValueConnectors' => %w[being to that which for],
|
|
19
|
+
'LowValueVerbs' => %w[
|
|
20
|
+
perform performed performing
|
|
21
|
+
process processed processing
|
|
22
|
+
use used using
|
|
23
|
+
handle handled handling
|
|
24
|
+
act acted acting
|
|
25
|
+
pass passed passing
|
|
26
|
+
invoke invoked invoking
|
|
27
|
+
call called calling
|
|
28
|
+
execute executed executing
|
|
29
|
+
run running
|
|
30
|
+
],
|
|
18
31
|
'EnabledPatterns' => {
|
|
19
32
|
'ArticleParam' => true,
|
|
20
33
|
'PossessiveParam' => true,
|
|
@@ -22,7 +35,8 @@ module Yard
|
|
|
22
35
|
'ParamToVerb' => true,
|
|
23
36
|
'IdPattern' => true,
|
|
24
37
|
'DirectionalDate' => true,
|
|
25
|
-
'TypeGeneric' => true
|
|
38
|
+
'TypeGeneric' => true,
|
|
39
|
+
'ArticleParamPhrase' => true
|
|
26
40
|
}
|
|
27
41
|
}.freeze
|
|
28
42
|
end
|
|
@@ -48,6 +48,11 @@ module Yard
|
|
|
48
48
|
'The @' + tag_name + ' description \'' + description + '\' just combines type and generic terms. ' \
|
|
49
49
|
'Consider removing it or providing specific details about this ' + param_name + '.'
|
|
50
50
|
|
|
51
|
+
when 'article_param_phrase'
|
|
52
|
+
'The @' + tag_name + ' description \'' + description + '\' is a filler phrase that adds no value ' \
|
|
53
|
+
'beyond the parameter name. ' \
|
|
54
|
+
'Consider removing it or explaining the specific purpose of ' + param_name + '.'
|
|
55
|
+
|
|
51
56
|
else
|
|
52
57
|
'The @' + tag_name + ' description \'' + description + '\' appears redundant. ' \
|
|
53
58
|
'Consider providing a meaningful description or omitting it entirely.'
|