yard-lint 0.2.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 +7 -0
- data/.coditsu/ci.yml +3 -0
- data/CHANGELOG.md +28 -0
- data/LICENSE.txt +21 -0
- data/README.md +454 -0
- data/bin/console +11 -0
- data/bin/setup +8 -0
- data/bin/yard-lint +109 -0
- data/lib/yard/lint/command_cache.rb +77 -0
- data/lib/yard/lint/config.rb +255 -0
- data/lib/yard/lint/config_loader.rb +198 -0
- data/lib/yard/lint/errors.rb +17 -0
- data/lib/yard/lint/formatters/progress.rb +50 -0
- data/lib/yard/lint/parsers/base.rb +23 -0
- data/lib/yard/lint/parsers/one_line_base.rb +35 -0
- data/lib/yard/lint/parsers/two_line_base.rb +45 -0
- data/lib/yard/lint/result_builder.rb +130 -0
- data/lib/yard/lint/results/aggregate.rb +86 -0
- data/lib/yard/lint/results/base.rb +156 -0
- data/lib/yard/lint/runner.rb +125 -0
- data/lib/yard/lint/validators/base.rb +120 -0
- data/lib/yard/lint/validators/config.rb +30 -0
- data/lib/yard/lint/validators/documentation/undocumented_boolean_methods/config.rb +20 -0
- data/lib/yard/lint/validators/documentation/undocumented_boolean_methods/parser.rb +43 -0
- data/lib/yard/lint/validators/documentation/undocumented_boolean_methods/result.rb +26 -0
- data/lib/yard/lint/validators/documentation/undocumented_boolean_methods/validator.rb +48 -0
- data/lib/yard/lint/validators/documentation/undocumented_boolean_methods.rb +13 -0
- data/lib/yard/lint/validators/documentation/undocumented_method_arguments/config.rb +20 -0
- data/lib/yard/lint/validators/documentation/undocumented_method_arguments/messages_builder.rb +24 -0
- data/lib/yard/lint/validators/documentation/undocumented_method_arguments/parser.rb +45 -0
- data/lib/yard/lint/validators/documentation/undocumented_method_arguments/result.rb +25 -0
- data/lib/yard/lint/validators/documentation/undocumented_method_arguments/validator.rb +55 -0
- data/lib/yard/lint/validators/documentation/undocumented_method_arguments.rb +13 -0
- data/lib/yard/lint/validators/documentation/undocumented_objects/config.rb +21 -0
- data/lib/yard/lint/validators/documentation/undocumented_objects/messages_builder.rb +23 -0
- data/lib/yard/lint/validators/documentation/undocumented_objects/parser.rb +39 -0
- data/lib/yard/lint/validators/documentation/undocumented_objects/result.rb +25 -0
- data/lib/yard/lint/validators/documentation/undocumented_objects/validator.rb +39 -0
- data/lib/yard/lint/validators/documentation/undocumented_objects.rb +14 -0
- data/lib/yard/lint/validators/semantic/abstract_methods/config.rb +24 -0
- data/lib/yard/lint/validators/semantic/abstract_methods/messages_builder.rb +25 -0
- data/lib/yard/lint/validators/semantic/abstract_methods/parser.rb +45 -0
- data/lib/yard/lint/validators/semantic/abstract_methods/result.rb +42 -0
- data/lib/yard/lint/validators/semantic/abstract_methods/validator.rb +65 -0
- data/lib/yard/lint/validators/semantic/abstract_methods.rb +13 -0
- data/lib/yard/lint/validators/tags/api_tags/config.rb +21 -0
- data/lib/yard/lint/validators/tags/api_tags/messages_builder.rb +29 -0
- data/lib/yard/lint/validators/tags/api_tags/parser.rb +50 -0
- data/lib/yard/lint/validators/tags/api_tags/result.rb +42 -0
- data/lib/yard/lint/validators/tags/api_tags/validator.rb +69 -0
- data/lib/yard/lint/validators/tags/api_tags.rb +13 -0
- data/lib/yard/lint/validators/tags/invalid_types/config.rb +22 -0
- data/lib/yard/lint/validators/tags/invalid_types/messages_builder.rb +24 -0
- data/lib/yard/lint/validators/tags/invalid_types/parser.rb +16 -0
- data/lib/yard/lint/validators/tags/invalid_types/result.rb +25 -0
- data/lib/yard/lint/validators/tags/invalid_types/validator.rb +106 -0
- data/lib/yard/lint/validators/tags/invalid_types.rb +13 -0
- data/lib/yard/lint/validators/tags/option_tags/config.rb +21 -0
- data/lib/yard/lint/validators/tags/option_tags/messages_builder.rb +24 -0
- data/lib/yard/lint/validators/tags/option_tags/parser.rb +45 -0
- data/lib/yard/lint/validators/tags/option_tags/result.rb +42 -0
- data/lib/yard/lint/validators/tags/option_tags/validator.rb +61 -0
- data/lib/yard/lint/validators/tags/option_tags.rb +13 -0
- data/lib/yard/lint/validators/tags/order/config.rb +33 -0
- data/lib/yard/lint/validators/tags/order/messages_builder.rb +30 -0
- data/lib/yard/lint/validators/tags/order/parser.rb +66 -0
- data/lib/yard/lint/validators/tags/order/result.rb +26 -0
- data/lib/yard/lint/validators/tags/order/validator.rb +89 -0
- data/lib/yard/lint/validators/tags/order.rb +13 -0
- data/lib/yard/lint/validators/warnings/duplicated_parameter_name/config.rb +22 -0
- data/lib/yard/lint/validators/warnings/duplicated_parameter_name/parser.rb +22 -0
- data/lib/yard/lint/validators/warnings/duplicated_parameter_name/result.rb +25 -0
- data/lib/yard/lint/validators/warnings/duplicated_parameter_name/validator.rb +33 -0
- data/lib/yard/lint/validators/warnings/duplicated_parameter_name.rb +14 -0
- data/lib/yard/lint/validators/warnings/invalid_directive_format/config.rb +22 -0
- data/lib/yard/lint/validators/warnings/invalid_directive_format/parser.rb +22 -0
- data/lib/yard/lint/validators/warnings/invalid_directive_format/result.rb +25 -0
- data/lib/yard/lint/validators/warnings/invalid_directive_format/validator.rb +33 -0
- data/lib/yard/lint/validators/warnings/invalid_directive_format.rb +14 -0
- data/lib/yard/lint/validators/warnings/invalid_tag_format/config.rb +22 -0
- data/lib/yard/lint/validators/warnings/invalid_tag_format/parser.rb +22 -0
- data/lib/yard/lint/validators/warnings/invalid_tag_format/result.rb +25 -0
- data/lib/yard/lint/validators/warnings/invalid_tag_format/validator.rb +33 -0
- data/lib/yard/lint/validators/warnings/invalid_tag_format.rb +14 -0
- data/lib/yard/lint/validators/warnings/unknown_directive/config.rb +22 -0
- data/lib/yard/lint/validators/warnings/unknown_directive/parser.rb +22 -0
- data/lib/yard/lint/validators/warnings/unknown_directive/result.rb +25 -0
- data/lib/yard/lint/validators/warnings/unknown_directive/validator.rb +33 -0
- data/lib/yard/lint/validators/warnings/unknown_directive.rb +14 -0
- data/lib/yard/lint/validators/warnings/unknown_parameter_name/config.rb +22 -0
- data/lib/yard/lint/validators/warnings/unknown_parameter_name/parser.rb +22 -0
- data/lib/yard/lint/validators/warnings/unknown_parameter_name/result.rb +25 -0
- data/lib/yard/lint/validators/warnings/unknown_parameter_name/validator.rb +33 -0
- data/lib/yard/lint/validators/warnings/unknown_parameter_name.rb +14 -0
- data/lib/yard/lint/validators/warnings/unknown_tag/config.rb +22 -0
- data/lib/yard/lint/validators/warnings/unknown_tag/parser.rb +24 -0
- data/lib/yard/lint/validators/warnings/unknown_tag/result.rb +25 -0
- data/lib/yard/lint/validators/warnings/unknown_tag/validator.rb +33 -0
- data/lib/yard/lint/validators/warnings/unknown_tag.rb +14 -0
- data/lib/yard/lint/version.rb +8 -0
- data/lib/yard/lint.rb +76 -0
- data/lib/yard-lint.rb +11 -0
- data/renovate.json +22 -0
- metadata +178 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedBooleanMethods
|
|
8
|
+
# Configuration for UndocumentedBooleanMethods validator
|
|
9
|
+
class Config < ::Yard::Lint::Validators::Config
|
|
10
|
+
self.id = :undocumented_boolean_methods
|
|
11
|
+
self.defaults = {
|
|
12
|
+
'Enabled' => true,
|
|
13
|
+
'Severity' => 'warning'
|
|
14
|
+
}.freeze
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
# Documentation validators - check for missing or incomplete documentation
|
|
7
|
+
module Documentation
|
|
8
|
+
module UndocumentedBooleanMethods
|
|
9
|
+
# Class used to extract details about undocumented boolean methods
|
|
10
|
+
# @example
|
|
11
|
+
# Platform::Analysis::Authors#valid?
|
|
12
|
+
class Parser < Parsers::Base
|
|
13
|
+
# Regex to extract location and method name from yard list output
|
|
14
|
+
LOCATION_REGEX = /^(.+)#(.+)$|^(.+)\.(.+)$/
|
|
15
|
+
|
|
16
|
+
# @param yard_list [String] raw yard list results string
|
|
17
|
+
# @return [Array<Hash>] Array with undocumented boolean methods details
|
|
18
|
+
def call(yard_list)
|
|
19
|
+
yard_list
|
|
20
|
+
.split("\n")
|
|
21
|
+
.reject(&:empty?)
|
|
22
|
+
.filter_map do |line|
|
|
23
|
+
match_data = line.match(LOCATION_REGEX)
|
|
24
|
+
next unless match_data
|
|
25
|
+
|
|
26
|
+
# Handle both instance (#) and class (.) methods
|
|
27
|
+
location = match_data[1] || match_data[3]
|
|
28
|
+
method_name = match_data[2] || match_data[4]
|
|
29
|
+
|
|
30
|
+
{
|
|
31
|
+
location: location,
|
|
32
|
+
element: "#{location}##{method_name}",
|
|
33
|
+
method_name: method_name,
|
|
34
|
+
line: 0 # YARD list doesn't provide line numbers
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedBooleanMethods
|
|
8
|
+
# Result object for undocumented boolean methods validation
|
|
9
|
+
# Reuses UndocumentedObjects::MessagesBuilder
|
|
10
|
+
class Result < Results::Base
|
|
11
|
+
self.default_severity = 'warning'
|
|
12
|
+
self.offense_type = 'line'
|
|
13
|
+
self.offense_name = 'UndocumentedObject'
|
|
14
|
+
|
|
15
|
+
# Build human-readable message for undocumented boolean method offense
|
|
16
|
+
# @param offense [Hash] offense data
|
|
17
|
+
# @return [String] formatted message
|
|
18
|
+
def build_message(offense)
|
|
19
|
+
UndocumentedObjects::MessagesBuilder.call(offense)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedBooleanMethods
|
|
8
|
+
# Runs a query that will pick all the boolean methods (ending with ?) that
|
|
9
|
+
# do not have a return type or return description documented
|
|
10
|
+
class Validator < Base
|
|
11
|
+
# Query to find all the boolean methods without proper return documentation
|
|
12
|
+
QUERY = <<~QUERY.tr("\n", ' ')
|
|
13
|
+
'
|
|
14
|
+
type == :method &&
|
|
15
|
+
!is_alias? &&
|
|
16
|
+
is_explicit? &&
|
|
17
|
+
name.to_s.end_with?("?") &&
|
|
18
|
+
(tag("return").nil? || tag("return").text.to_s.strip.empty?)
|
|
19
|
+
'
|
|
20
|
+
QUERY
|
|
21
|
+
|
|
22
|
+
private_constant :QUERY
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
# Runs yard list query with proper settings on a given dir and files
|
|
27
|
+
# @param dir [String] dir where we should generate the temp docs
|
|
28
|
+
# @param escaped_file_names [String] files for which we want to get the stats
|
|
29
|
+
# @return [Hash] shell command execution hash results
|
|
30
|
+
def yard_cmd(dir, escaped_file_names)
|
|
31
|
+
cmd = <<~CMD
|
|
32
|
+
yard list \
|
|
33
|
+
#{shell_arguments} \
|
|
34
|
+
--query #{QUERY} \
|
|
35
|
+
-q \
|
|
36
|
+
-b #{Shellwords.escape(dir)} \
|
|
37
|
+
#{escaped_file_names}
|
|
38
|
+
CMD
|
|
39
|
+
cmd = cmd.tr("\n", ' ')
|
|
40
|
+
|
|
41
|
+
shell(cmd)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedMethodArguments
|
|
8
|
+
# Configuration for UndocumentedMethodArguments validator
|
|
9
|
+
class Config < ::Yard::Lint::Validators::Config
|
|
10
|
+
self.id = :undocumented_method_arguments
|
|
11
|
+
self.defaults = {
|
|
12
|
+
'Enabled' => true,
|
|
13
|
+
'Severity' => 'warning'
|
|
14
|
+
}.freeze
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedMethodArguments
|
|
8
|
+
# Builds messages for undocumented method arguments offenses
|
|
9
|
+
class MessagesBuilder
|
|
10
|
+
class << self
|
|
11
|
+
# Build message for undocumented method arguments
|
|
12
|
+
# @param offense [Hash] offense data with :method_name key
|
|
13
|
+
# @return [String] formatted message
|
|
14
|
+
def call(offense)
|
|
15
|
+
"The `#{offense[:method_name]}` method is missing documentation " \
|
|
16
|
+
'for some of the arguments.'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedMethodArguments
|
|
8
|
+
# Class used to extract details about methods with undocumented arguments
|
|
9
|
+
# @example
|
|
10
|
+
# /path/to/file.rb:10: Platform::Analysis::Authors#initialize
|
|
11
|
+
class Parser < Parsers::Base
|
|
12
|
+
# Regex to extract file, line, and method name from yard list output
|
|
13
|
+
# Format: /path/to/file.rb:10: ClassName#method_name
|
|
14
|
+
LOCATION_REGEX = /^(.+):(\d+):\s+(.+)[#.](.+)$/
|
|
15
|
+
|
|
16
|
+
# @param yard_list [String] raw yard list results string
|
|
17
|
+
# @return [Array<Hash>] Array with undocumented method arguments details
|
|
18
|
+
def call(yard_list)
|
|
19
|
+
yard_list
|
|
20
|
+
.split("\n")
|
|
21
|
+
.reject(&:empty?)
|
|
22
|
+
.filter_map do |line|
|
|
23
|
+
match_data = line.match(LOCATION_REGEX)
|
|
24
|
+
next unless match_data
|
|
25
|
+
|
|
26
|
+
# Extract: file path, line number, class name, method name
|
|
27
|
+
file_path = match_data[1]
|
|
28
|
+
line_number = match_data[2].to_i
|
|
29
|
+
class_name = match_data[3]
|
|
30
|
+
method_name = match_data[4]
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
location: file_path,
|
|
34
|
+
method_name: method_name,
|
|
35
|
+
line: line_number,
|
|
36
|
+
class_name: class_name
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedMethodArguments
|
|
8
|
+
# Result object for undocumented method arguments validation
|
|
9
|
+
class Result < Results::Base
|
|
10
|
+
self.default_severity = 'warning'
|
|
11
|
+
self.offense_type = 'method'
|
|
12
|
+
self.offense_name = 'UndocumentedMethodArgument'
|
|
13
|
+
|
|
14
|
+
# Build human-readable message for undocumented method argument offense
|
|
15
|
+
# @param offense [Hash] offense data
|
|
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,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedMethodArguments
|
|
8
|
+
# Runs yard list to check for missing args docs on methods that were documented
|
|
9
|
+
class Validator < Base
|
|
10
|
+
# Options that stats supports but not list
|
|
11
|
+
UNWANTED_OPTIONS = %w[
|
|
12
|
+
--list-undoc
|
|
13
|
+
].freeze
|
|
14
|
+
|
|
15
|
+
# Query to find all the documented methods that have some undocumented
|
|
16
|
+
# arguments
|
|
17
|
+
QUERY = <<~QUERY.tr("\n", ' ')
|
|
18
|
+
'
|
|
19
|
+
type == :method &&
|
|
20
|
+
!is_alias? &&
|
|
21
|
+
is_explicit? &&
|
|
22
|
+
(parameters.size > @@param.size)
|
|
23
|
+
'
|
|
24
|
+
QUERY
|
|
25
|
+
|
|
26
|
+
private_constant :UNWANTED_OPTIONS, :QUERY
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
# Runs yard list query with proper settings on a given dir and files
|
|
31
|
+
# @param dir [String] dir where we should generate the temp docs
|
|
32
|
+
# @param escaped_file_names [String] files for which we want to get the stats
|
|
33
|
+
# @return [Hash] shell command execution hash results
|
|
34
|
+
def yard_cmd(dir, escaped_file_names)
|
|
35
|
+
shell_args = shell_arguments
|
|
36
|
+
UNWANTED_OPTIONS.each { |opt| shell_args.gsub!(opt, '') }
|
|
37
|
+
|
|
38
|
+
cmd = <<~CMD
|
|
39
|
+
yard list \
|
|
40
|
+
#{shell_args} \
|
|
41
|
+
--query #{QUERY} \
|
|
42
|
+
-q \
|
|
43
|
+
-b #{Shellwords.escape(dir)} \
|
|
44
|
+
#{escaped_file_names}
|
|
45
|
+
CMD
|
|
46
|
+
cmd = cmd.tr("\n", ' ')
|
|
47
|
+
|
|
48
|
+
shell(cmd)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedObjects
|
|
8
|
+
# Configuration for UndocumentedObjects validator
|
|
9
|
+
class Config < ::Yard::Lint::Validators::Config
|
|
10
|
+
self.id = :undocumented_objects
|
|
11
|
+
self.defaults = {
|
|
12
|
+
'Enabled' => true,
|
|
13
|
+
'Severity' => 'warning'
|
|
14
|
+
}.freeze
|
|
15
|
+
self.combines_with = ['Documentation/UndocumentedBooleanMethods'].freeze
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedObjects
|
|
8
|
+
# Builds messages for undocumented objects offenses
|
|
9
|
+
class MessagesBuilder
|
|
10
|
+
class << self
|
|
11
|
+
# Build message for an undocumented object
|
|
12
|
+
# @param offense [Hash] offense data with :element key
|
|
13
|
+
# @return [String] formatted message
|
|
14
|
+
def call(offense)
|
|
15
|
+
"Documentation required for `#{offense[:element]}`"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
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 UndocumentedObjects
|
|
8
|
+
# Class used to extract details about undocumented objects from raw yard list output
|
|
9
|
+
# @example
|
|
10
|
+
# /path/to/file.rb:3: UndocumentedClass
|
|
11
|
+
# /path/to/file.rb:4: UndocumentedClass#method_one
|
|
12
|
+
class Parser < ::Yard::Lint::Parsers::Base
|
|
13
|
+
# Regex used to parse yard list output format: file.rb:LINE: ObjectName
|
|
14
|
+
LINE_REGEX = /^(.+):(\d+): (.+)$/
|
|
15
|
+
|
|
16
|
+
# @param yard_list_output [String] raw yard list results string
|
|
17
|
+
# @return [Array<Hash>] Array with undocumented objects details
|
|
18
|
+
def call(yard_list_output)
|
|
19
|
+
yard_list_output
|
|
20
|
+
.split("\n")
|
|
21
|
+
.map(&:strip)
|
|
22
|
+
.reject(&:empty?)
|
|
23
|
+
.filter_map do |line|
|
|
24
|
+
match = line.match(LINE_REGEX)
|
|
25
|
+
next unless match
|
|
26
|
+
|
|
27
|
+
{
|
|
28
|
+
location: match[1],
|
|
29
|
+
line: match[2].to_i,
|
|
30
|
+
element: match[3]
|
|
31
|
+
}
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedObjects
|
|
8
|
+
# Result object for undocumented objects validation
|
|
9
|
+
class Result < Results::Base
|
|
10
|
+
self.default_severity = 'warning'
|
|
11
|
+
self.offense_type = 'line'
|
|
12
|
+
self.offense_name = 'UndocumentedObject'
|
|
13
|
+
|
|
14
|
+
# Build human-readable message for undocumented object offense
|
|
15
|
+
# @param offense [Hash] offense data
|
|
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,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
module UndocumentedObjects
|
|
8
|
+
# Runs yard list to check for undocumented objects
|
|
9
|
+
class Validator < Base
|
|
10
|
+
# Query to find all objects without documentation
|
|
11
|
+
QUERY = "'docstring.blank?'"
|
|
12
|
+
|
|
13
|
+
private_constant :QUERY
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
# Runs yard list query with proper settings on a given dir and files
|
|
18
|
+
# @param dir [String] dir where we should generate the temp docs
|
|
19
|
+
# @param escaped_file_names [String] files for which we want to get the stats
|
|
20
|
+
# @return [Hash] shell command execution hash results
|
|
21
|
+
def yard_cmd(dir, escaped_file_names)
|
|
22
|
+
cmd = <<~CMD
|
|
23
|
+
yard list \
|
|
24
|
+
#{shell_arguments} \
|
|
25
|
+
--query #{QUERY} \
|
|
26
|
+
-q \
|
|
27
|
+
-b #{Shellwords.escape(dir)} \
|
|
28
|
+
#{escaped_file_names}
|
|
29
|
+
CMD
|
|
30
|
+
cmd = cmd.tr("\n", ' ')
|
|
31
|
+
|
|
32
|
+
shell(cmd)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Documentation
|
|
7
|
+
# UndocumentedObjects validator module
|
|
8
|
+
# This validator checks for missing documentation on objects
|
|
9
|
+
module UndocumentedObjects
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Semantic
|
|
7
|
+
module AbstractMethods
|
|
8
|
+
# Configuration for AbstractMethods validator
|
|
9
|
+
class Config < ::Yard::Lint::Validators::Config
|
|
10
|
+
self.id = :abstract_methods
|
|
11
|
+
self.defaults = {
|
|
12
|
+
'Enabled' => true,
|
|
13
|
+
'Severity' => 'warning',
|
|
14
|
+
'AllowedImplementations' => [
|
|
15
|
+
'raise NotImplementedError',
|
|
16
|
+
'raise NotImplementedError, ".+"'
|
|
17
|
+
]
|
|
18
|
+
}.freeze
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
# Semantic validators - check code semantics and implementation correctness
|
|
7
|
+
module Semantic
|
|
8
|
+
module AbstractMethods
|
|
9
|
+
# Builds messages for abstract method offenses
|
|
10
|
+
class MessagesBuilder
|
|
11
|
+
class << self
|
|
12
|
+
# Build message for abstract method offense
|
|
13
|
+
# @param offense [Hash] offense data with :method_name key
|
|
14
|
+
# @return [String] formatted message
|
|
15
|
+
def call(offense)
|
|
16
|
+
"Abstract method `#{offense[:method_name]}` has implementation " \
|
|
17
|
+
'(should only raise NotImplementedError or be empty)'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Semantic
|
|
7
|
+
module AbstractMethods
|
|
8
|
+
# Parser for @abstract method validation results
|
|
9
|
+
class Parser < Parsers::Base
|
|
10
|
+
# @param yard_output [String] raw yard output with abstract method issues
|
|
11
|
+
# @return [Array<Hash>] array with abstract method violation details
|
|
12
|
+
def call(yard_output)
|
|
13
|
+
return [] if yard_output.nil? || yard_output.empty?
|
|
14
|
+
|
|
15
|
+
lines = yard_output.split("\n").reject(&:empty?)
|
|
16
|
+
results = []
|
|
17
|
+
|
|
18
|
+
lines.each_slice(2) do |location_line, status_line|
|
|
19
|
+
next unless location_line && status_line
|
|
20
|
+
next unless status_line == 'has_implementation'
|
|
21
|
+
|
|
22
|
+
# Parse location line: "file.rb:10: ClassName#method_name"
|
|
23
|
+
match = location_line.match(/^(.+):(\d+): (.+)$/)
|
|
24
|
+
next unless match
|
|
25
|
+
|
|
26
|
+
file = match[1]
|
|
27
|
+
line = match[2].to_i
|
|
28
|
+
method_name = match[3]
|
|
29
|
+
|
|
30
|
+
results << {
|
|
31
|
+
name: 'AbstractMethod',
|
|
32
|
+
method_name: method_name,
|
|
33
|
+
location: file,
|
|
34
|
+
line: line
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
results
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yard
|
|
4
|
+
module Lint
|
|
5
|
+
module Validators
|
|
6
|
+
module Semantic
|
|
7
|
+
module AbstractMethods
|
|
8
|
+
# Result object for abstract methods validation
|
|
9
|
+
class Result < Results::Base
|
|
10
|
+
self.default_severity = 'warning'
|
|
11
|
+
self.offense_type = 'method'
|
|
12
|
+
self.offense_name = 'AbstractMethodViolation'
|
|
13
|
+
|
|
14
|
+
# Build human-readable message for abstract method offense
|
|
15
|
+
# @param offense [Hash] offense data with :name key
|
|
16
|
+
# @return [String] formatted message
|
|
17
|
+
def build_message(offense)
|
|
18
|
+
MessagesBuilder.call(offense)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
# Override to build offenses with dynamic names from parsed data
|
|
24
|
+
# @return [Array<Hash>] array of offense hashes
|
|
25
|
+
def build_offenses
|
|
26
|
+
@parsed_data.map do |offense_data|
|
|
27
|
+
{
|
|
28
|
+
severity: configured_severity,
|
|
29
|
+
type: self.class.offense_type,
|
|
30
|
+
name: offense_data[:name] || self.class.offense_name,
|
|
31
|
+
message: build_message(offense_data),
|
|
32
|
+
location: offense_data[:location] || offense_data[:file],
|
|
33
|
+
location_line: offense_data[:line] || offense_data[:location_line] || 0
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|