puppet-strings 2.2.0 → 2.6.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 +5 -5
- data/CHANGELOG.md +87 -1
- data/CONTRIBUTING.md +32 -2
- data/README.md +81 -17
- data/lib/puppet-strings.rb +5 -3
- data/lib/puppet-strings/describe.rb +2 -0
- data/lib/puppet-strings/json.rb +4 -0
- data/lib/puppet-strings/markdown.rb +13 -9
- data/lib/puppet-strings/markdown/base.rb +30 -3
- data/lib/puppet-strings/markdown/data_type.rb +36 -0
- data/lib/puppet-strings/markdown/data_types.rb +43 -0
- data/lib/puppet-strings/markdown/defined_type.rb +2 -0
- data/lib/puppet-strings/markdown/defined_types.rb +3 -1
- data/lib/puppet-strings/markdown/function.rb +9 -7
- data/lib/puppet-strings/markdown/functions.rb +3 -1
- data/lib/puppet-strings/markdown/puppet_class.rb +2 -0
- data/lib/puppet-strings/markdown/puppet_classes.rb +3 -1
- data/lib/puppet-strings/markdown/puppet_plan.rb +2 -0
- data/lib/puppet-strings/markdown/puppet_plans.rb +3 -1
- data/lib/puppet-strings/markdown/puppet_task.rb +2 -0
- data/lib/puppet-strings/markdown/puppet_tasks.rb +3 -1
- data/lib/puppet-strings/markdown/resource_type.rb +21 -2
- data/lib/puppet-strings/markdown/resource_types.rb +3 -1
- data/lib/puppet-strings/markdown/table_of_contents.rb +4 -1
- data/lib/puppet-strings/markdown/templates/classes_and_defines.erb +18 -6
- data/lib/puppet-strings/markdown/templates/data_type.erb +101 -0
- data/lib/puppet-strings/markdown/templates/data_type_function.erb +67 -0
- data/lib/puppet-strings/markdown/templates/function.erb +10 -1
- data/lib/puppet-strings/markdown/templates/puppet_task.erb +1 -1
- data/lib/puppet-strings/markdown/templates/resource_type.erb +35 -13
- data/lib/puppet-strings/markdown/templates/table_of_contents.erb +6 -6
- data/lib/puppet-strings/monkey_patches/display_object_command.rb +2 -0
- data/lib/puppet-strings/tasks.rb +2 -0
- data/lib/puppet-strings/tasks/generate.rb +5 -2
- data/lib/puppet-strings/tasks/gh_pages.rb +3 -0
- data/lib/puppet-strings/version.rb +3 -1
- data/lib/puppet-strings/yard.rb +19 -0
- data/lib/puppet-strings/yard/code_objects.rb +4 -0
- data/lib/puppet-strings/yard/code_objects/base.rb +2 -0
- data/lib/puppet-strings/yard/code_objects/class.rb +5 -3
- data/lib/puppet-strings/yard/code_objects/data_type.rb +102 -0
- data/lib/puppet-strings/yard/code_objects/data_type_alias.rb +60 -0
- data/lib/puppet-strings/yard/code_objects/defined_type.rb +5 -3
- data/lib/puppet-strings/yard/code_objects/function.rb +9 -6
- data/lib/puppet-strings/yard/code_objects/group.rb +3 -0
- data/lib/puppet-strings/yard/code_objects/plan.rb +5 -3
- data/lib/puppet-strings/yard/code_objects/provider.rb +6 -0
- data/lib/puppet-strings/yard/code_objects/task.rb +3 -1
- data/lib/puppet-strings/yard/code_objects/type.rb +49 -5
- data/lib/puppet-strings/yard/handlers.rb +4 -0
- data/lib/puppet-strings/yard/handlers/helpers.rb +2 -0
- data/lib/puppet-strings/yard/handlers/json/base.rb +2 -0
- data/lib/puppet-strings/yard/handlers/json/task_handler.rb +2 -0
- data/lib/puppet-strings/yard/handlers/puppet/base.rb +3 -0
- data/lib/puppet-strings/yard/handlers/puppet/class_handler.rb +2 -0
- data/lib/puppet-strings/yard/handlers/puppet/data_type_alias_handler.rb +26 -0
- data/lib/puppet-strings/yard/handlers/puppet/defined_type_handler.rb +2 -0
- data/lib/puppet-strings/yard/handlers/puppet/function_handler.rb +3 -1
- data/lib/puppet-strings/yard/handlers/puppet/plan_handler.rb +2 -0
- data/lib/puppet-strings/yard/handlers/ruby/base.rb +7 -2
- data/lib/puppet-strings/yard/handlers/ruby/data_type_handler.rb +409 -0
- data/lib/puppet-strings/yard/handlers/ruby/function_handler.rb +9 -9
- data/lib/puppet-strings/yard/handlers/ruby/provider_handler.rb +13 -0
- data/lib/puppet-strings/yard/handlers/ruby/rsapi_handler.rb +6 -3
- data/lib/puppet-strings/yard/handlers/ruby/type_base.rb +25 -12
- data/lib/puppet-strings/yard/handlers/ruby/type_extras_handler.rb +6 -3
- data/lib/puppet-strings/yard/handlers/ruby/type_handler.rb +18 -1
- data/lib/puppet-strings/yard/parsers.rb +2 -0
- data/lib/puppet-strings/yard/parsers/json/parser.rb +3 -1
- data/lib/puppet-strings/yard/parsers/json/task_statement.rb +2 -0
- data/lib/puppet-strings/yard/parsers/puppet/parser.rb +11 -2
- data/lib/puppet-strings/yard/parsers/puppet/statement.rb +29 -0
- data/lib/puppet-strings/yard/tags.rb +4 -0
- data/lib/puppet-strings/yard/tags/enum_tag.rb +14 -0
- data/lib/puppet-strings/yard/tags/factory.rb +18 -0
- data/lib/puppet-strings/yard/tags/overload_tag.rb +5 -2
- data/lib/puppet-strings/yard/tags/parameter_directive.rb +5 -4
- data/lib/puppet-strings/yard/tags/property_directive.rb +5 -4
- data/lib/puppet-strings/yard/tags/summary_tag.rb +2 -0
- data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_data_type.erb +10 -0
- data/lib/puppet-strings/yard/templates/default/fulldoc/html/setup.rb +9 -0
- data/lib/puppet-strings/yard/templates/default/layout/html/objects.erb +2 -0
- data/lib/puppet-strings/yard/templates/default/layout/html/setup.rb +18 -1
- data/lib/puppet-strings/yard/templates/default/puppet_data_type/html/box_info.erb +10 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type/html/header.erb +1 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type/html/method_details_list.erb +6 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type/html/note.erb +6 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type/html/overview.erb +6 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type/html/setup.rb +13 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type/html/source.erb +12 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type/html/summary.erb +4 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type/html/todo.erb +6 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type_alias/html/alias_of.erb +10 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type_alias/html/box_info.erb +10 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type_alias/html/header.erb +1 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type_alias/html/note.erb +6 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type_alias/html/overview.erb +6 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type_alias/html/setup.rb +17 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type_alias/html/source.erb +12 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type_alias/html/summary.erb +4 -0
- data/lib/puppet-strings/yard/templates/default/puppet_data_type_alias/html/todo.erb +6 -0
- data/lib/puppet-strings/yard/templates/default/puppet_function/html/setup.rb +1 -1
- data/lib/puppet-strings/yard/templates/default/puppet_type/html/setup.rb +3 -1
- data/lib/puppet-strings/yard/templates/default/tags/html/enum.erb +17 -0
- data/lib/puppet-strings/yard/templates/default/tags/setup.rb +7 -0
- data/lib/puppet-strings/yard/util.rb +7 -4
- data/lib/puppet/application/strings.rb +2 -0
- data/lib/puppet/face/strings.rb +7 -4
- data/lib/puppet/feature/rgen.rb +2 -0
- data/lib/puppet/feature/yard.rb +2 -0
- metadata +35 -45
- data/Gemfile +0 -38
- data/HISTORY.md +0 -218
- data/JSON.md +0 -802
- data/Rakefile +0 -98
- data/codecov.yml +0 -3
- data/misc/ANNOUNCEMENT_TEMPLATE.md +0 -40
- data/spec/acceptance/emit_json_options.rb +0 -71
- data/spec/acceptance/generate_markdown_spec.rb +0 -49
- data/spec/acceptance/lib/util.rb +0 -163
- data/spec/acceptance/running_strings_generate.rb +0 -54
- data/spec/fixtures/acceptance/modules/test/functions/add.pp +0 -9
- data/spec/fixtures/acceptance/modules/test/lib/puppet/functions/4x_function.rb +0 -5
- data/spec/fixtures/acceptance/modules/test/lib/puppet/parser/functions/function3x.rb +0 -2
- data/spec/fixtures/acceptance/modules/test/lib/puppet/provider/server/linux.rb +0 -9
- data/spec/fixtures/acceptance/modules/test/lib/puppet/type/database.rb +0 -15
- data/spec/fixtures/acceptance/modules/test/manifests/init.pp +0 -27
- data/spec/fixtures/acceptance/modules/test/manifests/triple_nested_classes.pp +0 -27
- data/spec/fixtures/acceptance/modules/test/metadata.json +0 -6
- data/spec/fixtures/unit/markdown/output.md +0 -508
- data/spec/fixtures/unit/markdown/output_with_plan.md +0 -542
- data/spec/spec_helper.rb +0 -46
- data/spec/spec_helper_acceptance.rb +0 -28
- data/spec/unit/puppet-strings/describe_spec.rb +0 -141
- data/spec/unit/puppet-strings/json_spec.rb +0 -283
- data/spec/unit/puppet-strings/markdown/base_spec.rb +0 -146
- data/spec/unit/puppet-strings/markdown_spec.rb +0 -296
- data/spec/unit/puppet-strings/yard/code_objects/task_spec.rb +0 -92
- data/spec/unit/puppet-strings/yard/handlers/json/task_handler_spec.rb +0 -116
- data/spec/unit/puppet-strings/yard/handlers/puppet/class_handler_spec.rb +0 -217
- data/spec/unit/puppet-strings/yard/handlers/puppet/defined_type_handler_spec.rb +0 -231
- data/spec/unit/puppet-strings/yard/handlers/puppet/function_handler_spec.rb +0 -315
- data/spec/unit/puppet-strings/yard/handlers/ruby/function_handler_spec.rb +0 -729
- data/spec/unit/puppet-strings/yard/handlers/ruby/provider_handler_spec.rb +0 -139
- data/spec/unit/puppet-strings/yard/handlers/ruby/rsapi_handler_spec.rb +0 -235
- data/spec/unit/puppet-strings/yard/handlers/ruby/type_handler_spec.rb +0 -295
- data/spec/unit/puppet-strings/yard/parsers/json/parser_spec.rb +0 -72
- data/spec/unit/puppet-strings/yard/parsers/json/task_statement_spec.rb +0 -56
- data/spec/unit/puppet-strings/yard/parsers/puppet/parser_spec.rb +0 -209
- data/spec/unit/puppet-strings/yard/util_spec.rb +0 -48
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'puppet-strings/yard/code_objects/group'
|
|
4
|
+
require 'puppet-strings/yard/util'
|
|
5
|
+
|
|
6
|
+
# Implements the group for Puppet DataTypeAliases.
|
|
7
|
+
class PuppetStrings::Yard::CodeObjects::DataTypeAliases < PuppetStrings::Yard::CodeObjects::Group
|
|
8
|
+
# Gets the singleton instance of the group.
|
|
9
|
+
# @return Returns the singleton instance of the group.
|
|
10
|
+
def self.instance
|
|
11
|
+
super(:puppet_data_type_aliases)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Gets the display name of the group.
|
|
15
|
+
# @param [Boolean] prefix whether to show a prefix. Ignored for Puppet group namespaces.
|
|
16
|
+
# @return [String] Returns the display name of the group.
|
|
17
|
+
def name(prefix = false)
|
|
18
|
+
'Puppet Data Type Aliases'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Implements the Puppet DataTypeAlias code object.
|
|
23
|
+
class PuppetStrings::Yard::CodeObjects::DataTypeAlias < PuppetStrings::Yard::CodeObjects::Base
|
|
24
|
+
attr_reader :statement
|
|
25
|
+
attr_accessor :alias_of
|
|
26
|
+
|
|
27
|
+
# Initializes a Puppet data type alias code object.
|
|
28
|
+
# @param [PuppetStrings::Parsers::DataTypeAliasStatement] statement The data type alias statement that was parsed.
|
|
29
|
+
# @return [void]
|
|
30
|
+
def initialize(statement)
|
|
31
|
+
@statement = statement
|
|
32
|
+
@alias_of = statement.alias_of
|
|
33
|
+
super(PuppetStrings::Yard::CodeObjects::DataTypeAliases.instance, statement.name)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Gets the type of the code object.
|
|
37
|
+
# @return Returns the type of the code object.
|
|
38
|
+
def type
|
|
39
|
+
:puppet_data_type_alias
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Gets the source of the code object.
|
|
43
|
+
# @return Returns the source of the code object.
|
|
44
|
+
def source
|
|
45
|
+
# Not implemented, but would be nice!
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Converts the code object to a hash representation.
|
|
50
|
+
# @return [Hash] Returns a hash representation of the code object.
|
|
51
|
+
def to_hash
|
|
52
|
+
hash = {}
|
|
53
|
+
hash[:name] = name
|
|
54
|
+
hash[:file] = file
|
|
55
|
+
hash[:line] = line
|
|
56
|
+
hash[:docstring] = PuppetStrings::Yard::Util.docstring_to_hash(docstring)
|
|
57
|
+
hash[:alias_of] = alias_of
|
|
58
|
+
hash
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'puppet-strings/yard/code_objects/group'
|
|
2
4
|
|
|
3
5
|
# Implements the group for Puppet defined types.
|
|
@@ -50,9 +52,9 @@ class PuppetStrings::Yard::CodeObjects::DefinedType < PuppetStrings::Yard::CodeO
|
|
|
50
52
|
hash[:file] = file
|
|
51
53
|
hash[:line] = line
|
|
52
54
|
hash[:docstring] = PuppetStrings::Yard::Util.docstring_to_hash(docstring)
|
|
53
|
-
defaults = Hash[*parameters.
|
|
54
|
-
hash[:defaults] = defaults unless defaults.empty?
|
|
55
|
-
hash[:source] = source unless source
|
|
55
|
+
defaults = Hash[*parameters.reject{ |p| p[1].nil? }.flatten]
|
|
56
|
+
hash[:defaults] = defaults unless defaults.nil? || defaults.empty?
|
|
57
|
+
hash[:source] = source unless source.nil? || source.empty?
|
|
56
58
|
hash
|
|
57
59
|
end
|
|
58
60
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'puppet-strings/yard/code_objects/group'
|
|
2
4
|
|
|
3
5
|
# Implements the group for Puppet functions.
|
|
@@ -61,11 +63,12 @@ class PuppetStrings::Yard::CodeObjects::Function < PuppetStrings::Yard::CodeObje
|
|
|
61
63
|
# @return [String] Returns the Puppet signature of the function.
|
|
62
64
|
def signature
|
|
63
65
|
return '' if self.has_tag? :overload
|
|
66
|
+
|
|
64
67
|
tags = self.tags(:param)
|
|
65
68
|
args = @parameters.map do |parameter|
|
|
66
69
|
name, default = parameter
|
|
67
70
|
tag = tags.find { |t| t.name == name } if tags
|
|
68
|
-
type = tag
|
|
71
|
+
type = tag&.types ? "#{tag.type} " : 'Any '
|
|
69
72
|
prefix = "#{name[0]}" if name.start_with?('*', '&')
|
|
70
73
|
name = name[1..-1] if prefix
|
|
71
74
|
default = " = #{default}" if default
|
|
@@ -88,16 +91,16 @@ class PuppetStrings::Yard::CodeObjects::Function < PuppetStrings::Yard::CodeObje
|
|
|
88
91
|
if self.has_tag? :overload
|
|
89
92
|
# loop over overloads and append onto the signatures array
|
|
90
93
|
self.tags(:overload).each do |o|
|
|
91
|
-
hash[:signatures] << { :signature => o.signature, :docstring => PuppetStrings::Yard::Util.docstring_to_hash(o.docstring, [
|
|
94
|
+
hash[:signatures] << { :signature => o.signature, :docstring => PuppetStrings::Yard::Util.docstring_to_hash(o.docstring, %i[param option enum return example]) }
|
|
92
95
|
end
|
|
93
96
|
else
|
|
94
|
-
hash[:signatures] << { :signature => self.signature, :docstring => PuppetStrings::Yard::Util.docstring_to_hash(docstring, [
|
|
97
|
+
hash[:signatures] << { :signature => self.signature, :docstring => PuppetStrings::Yard::Util.docstring_to_hash(docstring, %i[param option enum return example]) }
|
|
95
98
|
end
|
|
96
99
|
|
|
97
100
|
hash[:docstring] = PuppetStrings::Yard::Util.docstring_to_hash(docstring)
|
|
98
|
-
defaults = Hash[*parameters.
|
|
99
|
-
hash[:defaults] = defaults unless defaults.empty?
|
|
100
|
-
hash[:source] = source unless source
|
|
101
|
+
defaults = Hash[*parameters.reject{ |p| p[1].nil? }.flatten]
|
|
102
|
+
hash[:defaults] = defaults unless defaults.nil? || defaults.empty?
|
|
103
|
+
hash[:source] = source unless source.nil? || source.empty?
|
|
101
104
|
hash
|
|
102
105
|
end
|
|
103
106
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'puppet-strings/yard/code_objects/base'
|
|
2
4
|
|
|
3
5
|
# Implements the base class for "groups".
|
|
@@ -10,6 +12,7 @@ class PuppetStrings::Yard::CodeObjects::Group < PuppetStrings::Yard::CodeObjects
|
|
|
10
12
|
def self.instance(key)
|
|
11
13
|
instance = P(:root, key)
|
|
12
14
|
return instance unless instance.is_a?(YARD::CodeObjects::Proxy)
|
|
15
|
+
|
|
13
16
|
instance = self.new(:root, key)
|
|
14
17
|
instance.visibility = :hidden
|
|
15
18
|
P(:root).children << instance
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'puppet-strings/yard/code_objects/group'
|
|
2
4
|
|
|
3
5
|
class PuppetStrings::Yard::CodeObjects::Plans < PuppetStrings::Yard::CodeObjects::Group
|
|
@@ -48,9 +50,9 @@ class PuppetStrings::Yard::CodeObjects::Plan < PuppetStrings::Yard::CodeObjects:
|
|
|
48
50
|
hash[:file] = file
|
|
49
51
|
hash[:line] = line
|
|
50
52
|
hash[:docstring] = PuppetStrings::Yard::Util.docstring_to_hash(docstring)
|
|
51
|
-
defaults = Hash[*parameters.
|
|
52
|
-
hash[:defaults] = defaults unless defaults.empty?
|
|
53
|
-
hash[:source] = source unless source
|
|
53
|
+
defaults = Hash[*parameters.reject{ |p| p[1].nil? }.flatten]
|
|
54
|
+
hash[:defaults] = defaults unless defaults.nil? || defaults.empty?
|
|
55
|
+
hash[:source] = source unless source.nil? || source.empty?
|
|
54
56
|
hash
|
|
55
57
|
end
|
|
56
58
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'puppet-strings/yard/code_objects/group'
|
|
2
4
|
|
|
3
5
|
# Implements the group for Puppet providers.
|
|
@@ -42,6 +44,7 @@ class PuppetStrings::Yard::CodeObjects::Provider < PuppetStrings::Yard::CodeObje
|
|
|
42
44
|
# @return [void]
|
|
43
45
|
def add_confine(key, value)
|
|
44
46
|
return unless key && value
|
|
47
|
+
|
|
45
48
|
@confines ||= {}
|
|
46
49
|
@confines[key] = value
|
|
47
50
|
end
|
|
@@ -51,6 +54,7 @@ class PuppetStrings::Yard::CodeObjects::Provider < PuppetStrings::Yard::CodeObje
|
|
|
51
54
|
# @return [void]
|
|
52
55
|
def add_feature(feature)
|
|
53
56
|
return unless feature
|
|
57
|
+
|
|
54
58
|
@features ||= []
|
|
55
59
|
@features << feature
|
|
56
60
|
end
|
|
@@ -60,6 +64,7 @@ class PuppetStrings::Yard::CodeObjects::Provider < PuppetStrings::Yard::CodeObje
|
|
|
60
64
|
# @return [void]
|
|
61
65
|
def add_default(constraints)
|
|
62
66
|
return unless constraints
|
|
67
|
+
|
|
63
68
|
@defaults ||= []
|
|
64
69
|
@defaults << constraints
|
|
65
70
|
end
|
|
@@ -70,6 +75,7 @@ class PuppetStrings::Yard::CodeObjects::Provider < PuppetStrings::Yard::CodeObje
|
|
|
70
75
|
# @return [void]
|
|
71
76
|
def add_command(key, value)
|
|
72
77
|
return unless key && value
|
|
78
|
+
|
|
73
79
|
@commands ||= {}
|
|
74
80
|
@commands[key] = value
|
|
75
81
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'puppet-strings/yard/code_objects/group'
|
|
2
4
|
|
|
3
5
|
# Implements the group for Puppet tasks.
|
|
@@ -43,7 +45,7 @@ class PuppetStrings::Yard::CodeObjects::Task < PuppetStrings::Yard::CodeObjects:
|
|
|
43
45
|
|
|
44
46
|
def parameters
|
|
45
47
|
parameters = []
|
|
46
|
-
statement.
|
|
48
|
+
statement.parameters.each do |name,props|
|
|
47
49
|
parameters.push({ name: name.to_s,
|
|
48
50
|
tag_name: 'param',
|
|
49
51
|
text: props['description'] || "",
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'puppet-strings/yard/code_objects/group'
|
|
2
4
|
require 'puppet-strings/yard/util'
|
|
3
5
|
|
|
@@ -73,6 +75,9 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects:
|
|
|
73
75
|
class Property < Parameter
|
|
74
76
|
end
|
|
75
77
|
|
|
78
|
+
class Check < Parameter
|
|
79
|
+
end
|
|
80
|
+
|
|
76
81
|
# Represents a resource type feature.
|
|
77
82
|
class Feature
|
|
78
83
|
attr_reader :name, :docstring
|
|
@@ -95,7 +100,7 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects:
|
|
|
95
100
|
end
|
|
96
101
|
end
|
|
97
102
|
|
|
98
|
-
attr_reader :properties, :
|
|
103
|
+
attr_reader :properties, :features, :checks
|
|
99
104
|
|
|
100
105
|
# Initializes a new resource type.
|
|
101
106
|
# @param [String] name The resource type name.
|
|
@@ -134,17 +139,56 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects:
|
|
|
134
139
|
@features << feature
|
|
135
140
|
end
|
|
136
141
|
|
|
142
|
+
# Adds a check to the resource type.
|
|
143
|
+
# @param [PuppetStrings::Yard::CodeObjects::Type::Check] check The check to add.
|
|
144
|
+
# @return [void]
|
|
145
|
+
def add_check(check)
|
|
146
|
+
@checks ||= []
|
|
147
|
+
@checks << check
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def parameters
|
|
151
|
+
# just return params if there are no providers
|
|
152
|
+
return @parameters if providers.empty?
|
|
153
|
+
|
|
154
|
+
# return existing params if we have already added provider
|
|
155
|
+
return @parameters if @parameters.any? { |p| p.name == 'provider' }
|
|
156
|
+
|
|
157
|
+
provider_param = Parameter.new(
|
|
158
|
+
'provider',
|
|
159
|
+
"The specific backend to use for this `#{self.name.to_s}` resource. You will seldom need " + \
|
|
160
|
+
"to specify this --- Puppet will usually discover the appropriate provider for your platform."
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
@parameters << provider_param
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Not sure if this is where this belongs or if providers should only be resolved at
|
|
167
|
+
# render-time. For now, this should re-resolve on every call.
|
|
168
|
+
# may be able to memoize this
|
|
169
|
+
def providers
|
|
170
|
+
providers = YARD::Registry.all("puppet_providers_#{name}".intern)
|
|
171
|
+
return providers if providers.empty?
|
|
172
|
+
|
|
173
|
+
providers.first.children
|
|
174
|
+
end
|
|
175
|
+
|
|
137
176
|
# Converts the code object to a hash representation.
|
|
138
177
|
# @return [Hash] Returns a hash representation of the code object.
|
|
139
178
|
def to_hash
|
|
140
179
|
hash = {}
|
|
180
|
+
|
|
141
181
|
hash[:name] = name
|
|
142
182
|
hash[:file] = file
|
|
143
183
|
hash[:line] = line
|
|
144
|
-
|
|
145
|
-
hash[:
|
|
146
|
-
hash[:
|
|
147
|
-
hash[:
|
|
184
|
+
|
|
185
|
+
hash[:docstring] = PuppetStrings::Yard::Util.docstring_to_hash(docstring)
|
|
186
|
+
hash[:properties] = properties.sort_by { |p| p.name }.map(&:to_hash) if properties && !properties.empty?
|
|
187
|
+
hash[:parameters] = parameters.sort_by { |p| p.name }.map(&:to_hash) if parameters && !parameters.empty?
|
|
188
|
+
hash[:checks] = checks.sort_by { |c| c.name }.map(&:to_hash) if checks && !checks.empty?
|
|
189
|
+
hash[:features] = features.sort_by { |f| f.name }.map(&:to_hash) if features && !features.empty?
|
|
190
|
+
hash[:providers] = providers.sort_by { |p| p.name }.map(&:to_hash) if providers && !providers.empty?
|
|
191
|
+
|
|
148
192
|
hash
|
|
149
193
|
end
|
|
150
194
|
end
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# The module for custom YARD handlers.
|
|
2
4
|
module PuppetStrings::Yard::Handlers
|
|
3
5
|
# The module for custom Ruby YARD handlers.
|
|
4
6
|
module Ruby
|
|
7
|
+
require 'puppet-strings/yard/handlers/ruby/data_type_handler'
|
|
5
8
|
require 'puppet-strings/yard/handlers/ruby/type_handler'
|
|
6
9
|
require 'puppet-strings/yard/handlers/ruby/type_extras_handler'
|
|
7
10
|
require 'puppet-strings/yard/handlers/ruby/rsapi_handler'
|
|
@@ -17,6 +20,7 @@ module PuppetStrings::Yard::Handlers
|
|
|
17
20
|
# The module for custom Puppet YARD handlers.
|
|
18
21
|
module Puppet
|
|
19
22
|
require 'puppet-strings/yard/handlers/puppet/class_handler'
|
|
23
|
+
require 'puppet-strings/yard/handlers/puppet/data_type_alias_handler'
|
|
20
24
|
require 'puppet-strings/yard/handlers/puppet/defined_type_handler'
|
|
21
25
|
require 'puppet-strings/yard/handlers/puppet/function_handler'
|
|
22
26
|
require 'puppet-strings/yard/handlers/puppet/plan_handler'
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Implements the base handler for Puppet language handlers.
|
|
2
4
|
class PuppetStrings::Yard::Handlers::Puppet::Base < YARD::Handlers::Base
|
|
3
5
|
# Determine sif the handler handles the given statement.
|
|
@@ -17,6 +19,7 @@ class PuppetStrings::Yard::Handlers::Puppet::Base < YARD::Handlers::Base
|
|
|
17
19
|
tags = object.tags(:param)
|
|
18
20
|
tags.each do |tag|
|
|
19
21
|
next if statement.parameters.find { |p| tag.name == p.name }
|
|
22
|
+
|
|
20
23
|
log.warn "The @param tag for parameter '#{tag.name}' has no matching parameter at #{statement.file}:#{statement.line}." unless tag.name == 'name' || tag.name == 'title'
|
|
21
24
|
end
|
|
22
25
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'puppet-strings/yard/handlers/helpers'
|
|
4
|
+
require 'puppet-strings/yard/handlers/puppet/base'
|
|
5
|
+
require 'puppet-strings/yard/parsers'
|
|
6
|
+
require 'puppet-strings/yard/code_objects'
|
|
7
|
+
|
|
8
|
+
# Implements the handler for Puppet Data Type Alias.
|
|
9
|
+
class PuppetStrings::Yard::Handlers::Puppet::DataTypeAliasHandler < PuppetStrings::Yard::Handlers::Puppet::Base
|
|
10
|
+
handles PuppetStrings::Yard::Parsers::Puppet::DataTypeAliasStatement
|
|
11
|
+
|
|
12
|
+
process do
|
|
13
|
+
# Register the object
|
|
14
|
+
object = PuppetStrings::Yard::CodeObjects::DataTypeAlias.new(statement)
|
|
15
|
+
register object
|
|
16
|
+
|
|
17
|
+
# Log a warning if missing documentation
|
|
18
|
+
log.warn "Missing documentation for Puppet type alias '#{object.name}' at #{statement.file}:#{statement.line}." if object.docstring.empty? && object.tags.empty?
|
|
19
|
+
|
|
20
|
+
# Mark the class as public if it doesn't already have an api tag
|
|
21
|
+
object.add_tag YARD::Tags::Tag.new(:api, 'public') unless object.has_tag? :api
|
|
22
|
+
|
|
23
|
+
# Warn if a summary longer than 140 characters was provided
|
|
24
|
+
PuppetStrings::Yard::Handlers::Helpers.validate_summary_tag(object) if object.has_tag? :summary
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'puppet-strings/yard/handlers/helpers'
|
|
2
4
|
require 'puppet-strings/yard/handlers/puppet/base'
|
|
3
5
|
require 'puppet-strings/yard/parsers'
|
|
@@ -37,7 +39,7 @@ class PuppetStrings::Yard::Handlers::Puppet::FunctionHandler < PuppetStrings::Ya
|
|
|
37
39
|
def add_return_tag(object, type=nil)
|
|
38
40
|
tag = object.tag(:return)
|
|
39
41
|
if tag
|
|
40
|
-
if (type && tag.types.first) && (type != tag.types.first)
|
|
42
|
+
if (type && tag.types && tag.types.first) && (type != tag.types.first)
|
|
41
43
|
log.warn "Documented return type does not match return type in function definition near #{statement.file}:#{statement.line}."
|
|
42
44
|
end
|
|
43
45
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'ripper'
|
|
2
4
|
|
|
3
5
|
# Implements the base handler for Ruby language handlers.
|
|
@@ -12,13 +14,15 @@ class PuppetStrings::Yard::Handlers::Ruby::Base < YARD::Handlers::Ruby::Base
|
|
|
12
14
|
# @return [String] Returns a string representation of the node or nil if a string representation was not possible.
|
|
13
15
|
def node_as_string(node)
|
|
14
16
|
return nil unless node
|
|
17
|
+
|
|
15
18
|
case node.type
|
|
16
19
|
when :symbol, :symbol_literal
|
|
17
20
|
node.source[1..-1]
|
|
18
21
|
when :label
|
|
19
22
|
node.source[0..-2]
|
|
20
23
|
when :dyna_symbol
|
|
21
|
-
node.
|
|
24
|
+
content = node.jump(:tstring_content)
|
|
25
|
+
content.nil? ? node.source : content.source
|
|
22
26
|
when :string_literal
|
|
23
27
|
content = node.jump(:tstring_content)
|
|
24
28
|
return content.source if content != node
|
|
@@ -41,9 +45,10 @@ class PuppetStrings::Yard::Handlers::Ruby::Base < YARD::Handlers::Ruby::Base
|
|
|
41
45
|
def get_name(statementobject, statementtype)
|
|
42
46
|
parameters = statementobject.parameters(false)
|
|
43
47
|
raise YARD::Parser::UndocumentableError, "Expected at least one parameter to #{statementtype} at #{statementobject.file}:#{statementobject.line}." if parameters.empty?
|
|
48
|
+
|
|
44
49
|
name = node_as_string(parameters.first)
|
|
45
50
|
raise YARD::Parser::UndocumentableError, "Expected a symbol or string literal for first parameter but found '#{parameters.first.type}' at #{statement.file}:#{statement.line}." unless name
|
|
51
|
+
|
|
46
52
|
name
|
|
47
53
|
end
|
|
48
|
-
|
|
49
54
|
end
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'puppet-strings/yard/handlers/helpers'
|
|
4
|
+
require 'puppet-strings/yard/handlers/ruby/base'
|
|
5
|
+
require 'puppet-strings/yard/code_objects'
|
|
6
|
+
require 'puppet-strings/yard/util'
|
|
7
|
+
|
|
8
|
+
# Implements the handler for Puppet Data Types written in Ruby.
|
|
9
|
+
class PuppetStrings::Yard::Handlers::Ruby::DataTypeHandler < PuppetStrings::Yard::Handlers::Ruby::Base
|
|
10
|
+
namespace_only
|
|
11
|
+
handles method_call(:create_type)
|
|
12
|
+
|
|
13
|
+
process do
|
|
14
|
+
return unless statement.count > 1
|
|
15
|
+
|
|
16
|
+
ruby_module_name = statement[0].source
|
|
17
|
+
return unless ruby_module_name == 'Puppet::DataTypes' || ruby_module_name == 'DataTypes' # rubocop:disable Style/MultipleComparison This reads better
|
|
18
|
+
|
|
19
|
+
object = get_datatype_yard_object(get_name(statement, 'Puppet::DataTypes.create_type'))
|
|
20
|
+
# Extract the interface definition
|
|
21
|
+
type_interface = extract_data_type_interface
|
|
22
|
+
actual_params = extract_params(type_interface)
|
|
23
|
+
actual_funcs = extract_functions(object, type_interface)
|
|
24
|
+
|
|
25
|
+
# Mark the data type as public if it doesn't already have an api tag
|
|
26
|
+
object.add_tag YARD::Tags::Tag.new(:api, 'public') unless object.has_tag? :api
|
|
27
|
+
|
|
28
|
+
validate_param_tags!(object, actual_params)
|
|
29
|
+
validate_methods!(object, actual_funcs)
|
|
30
|
+
|
|
31
|
+
# Set the default values for all parameters
|
|
32
|
+
actual_params.each { |name, data| object.set_parameter_default(name, data[:default]) }
|
|
33
|
+
|
|
34
|
+
# Default any typeless param tag to 'Any'
|
|
35
|
+
object.tags(:param).each do |tag|
|
|
36
|
+
tag.types = ['Any'] unless tag.types && !tag.types.empty?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Warn if a summary longer than 140 characters was provided
|
|
40
|
+
PuppetStrings::Yard::Handlers::Helpers.validate_summary_tag(object) if object.has_tag? :summary
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def get_datatype_yard_object(name)
|
|
46
|
+
# Have to guess the path - if we create the object to get the true path from the code,
|
|
47
|
+
# it also shows up in the .at call - self registering?
|
|
48
|
+
guess_path = "puppet_data_types::#{name}"
|
|
49
|
+
object = YARD::Registry.at(guess_path)
|
|
50
|
+
|
|
51
|
+
return object unless object.nil?
|
|
52
|
+
|
|
53
|
+
# Didn't find, create instead
|
|
54
|
+
object = PuppetStrings::Yard::CodeObjects::DataType.new(name)
|
|
55
|
+
register object
|
|
56
|
+
object
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @return [Hash{Object => Object}] The Puppet DataType interface definition as a ruby Hash
|
|
60
|
+
def extract_data_type_interface
|
|
61
|
+
block = statement.block
|
|
62
|
+
return {} unless block
|
|
63
|
+
|
|
64
|
+
# Declare the parsed interface outside of the closure
|
|
65
|
+
parsed_interface = nil
|
|
66
|
+
|
|
67
|
+
# Recursively traverse the block looking for the first valid 'interface' call
|
|
68
|
+
interface_node = find_ruby_ast_node(block, true) do |node|
|
|
69
|
+
next false unless node.is_a?(YARD::Parser::Ruby::MethodCallNode) &&
|
|
70
|
+
node.method_name &&
|
|
71
|
+
node.method_name.source == 'interface'
|
|
72
|
+
|
|
73
|
+
parameters = node.parameters(false)
|
|
74
|
+
next false unless parameters.count >= 1
|
|
75
|
+
|
|
76
|
+
interface_string = node_as_string(parameters[0])
|
|
77
|
+
next false unless interface_string
|
|
78
|
+
|
|
79
|
+
begin
|
|
80
|
+
# Ref - https://github.com/puppetlabs/puppet/blob/ba4d1a1aba0095d3c70b98fea5c67434a4876a61/lib/puppet/datatypes.rb#L159
|
|
81
|
+
parsed_interface = Puppet::Pops::Parser::EvaluatingParser.new.parse_string("{ #{interface_string} }").body
|
|
82
|
+
rescue Puppet::Error => e
|
|
83
|
+
log.warn "Invalid datatype definition at #{statement.file}:#{statement.line}: #{e.basic_message}"
|
|
84
|
+
next false
|
|
85
|
+
end
|
|
86
|
+
!parsed_interface.nil?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Now that we parsed the Puppet code (as a string) into a LiteralHash PCore type (Puppet AST),
|
|
90
|
+
# We need to convert the LiteralHash into a conventional ruby hash of strings. The
|
|
91
|
+
# LazyLiteralEvaluator does this by traversing the AST tree can converting objects to strings
|
|
92
|
+
# where possible and ignoring object types which cannot (thus the 'Lazy' name)
|
|
93
|
+
literal_eval = LazyLiteralEvaluator.new
|
|
94
|
+
literal_eval.literal(parsed_interface)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Find the first Ruby AST node within an AST Tree, optionally recursively. Returns nil of none could be found
|
|
98
|
+
#
|
|
99
|
+
# @param [YARD::Parser::Ruby::AstNode] ast_node The root AST node object to inspect
|
|
100
|
+
# @param [Boolean] recurse Whether to search the tree recursively. Defaults to false
|
|
101
|
+
# @yieldparam [YARD::Parser::Ruby::AstNode] ast_node The AST Node that should be checked
|
|
102
|
+
# @yieldreturn [Boolean] Whether the node was what was searched for
|
|
103
|
+
# @return [YARD::Parser::Ruby::AstNode, nil]
|
|
104
|
+
def find_ruby_ast_node(ast_node, recurse = false, &block)
|
|
105
|
+
raise ArgumentError, 'find_ruby_ast_node requires a block' unless block_given?
|
|
106
|
+
|
|
107
|
+
is_found = yield ast_node
|
|
108
|
+
return ast_node if is_found
|
|
109
|
+
|
|
110
|
+
if ast_node.respond_to?(:children)
|
|
111
|
+
ast_node.children.each do |child_node|
|
|
112
|
+
child_found = find_ruby_ast_node(child_node, recurse, &block)
|
|
113
|
+
return child_found unless child_found.nil?
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
nil
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Lazily evaluates a Pops object, ignoring any objects that cannot
|
|
120
|
+
# be converted to a literal value. Based on the Puppet Literal Evaluator
|
|
121
|
+
# Ref - https://github.com/puppetlabs/puppet/blob/ba4d1a1aba0095d3c70b98fea5c67434a4876a61/lib/puppet/pops/evaluator/literal_evaluator.rb
|
|
122
|
+
#
|
|
123
|
+
# Literal values for:
|
|
124
|
+
# String (not containing interpolation)
|
|
125
|
+
# Numbers
|
|
126
|
+
# Booleans
|
|
127
|
+
# Undef (produces nil)
|
|
128
|
+
# Array
|
|
129
|
+
# Hash
|
|
130
|
+
# QualifiedName
|
|
131
|
+
# Default (produced :default)
|
|
132
|
+
# Regular Expression (produces ruby regular expression)
|
|
133
|
+
# QualifiedReference e.g. File, FooBar
|
|
134
|
+
# AccessExpression
|
|
135
|
+
#
|
|
136
|
+
# Anything else is ignored
|
|
137
|
+
class LazyLiteralEvaluator
|
|
138
|
+
def initialize
|
|
139
|
+
@literal_visitor = ::Puppet::Pops::Visitor.new(self, "literal", 0, 0)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def literal(ast)
|
|
143
|
+
@literal_visitor.visit_this_0(self, ast)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# ----- The following methods are different/additions from the original Literal_evaluator
|
|
147
|
+
def literal_Object(o)
|
|
148
|
+
# Ignore any other object types
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def literal_AccessExpression(o)
|
|
152
|
+
# Extract the raw text of the Access Expression
|
|
153
|
+
::Puppet::Pops::Adapters::SourcePosAdapter.adapt(o).extract_text
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def literal_QualifiedReference(o)
|
|
157
|
+
# Extract the raw text of the Qualified Reference
|
|
158
|
+
::Puppet::Pops::Adapters::SourcePosAdapter.adapt(o).extract_text
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# ----- The following methods are the same as the original Literal_evaluator
|
|
162
|
+
def literal_Factory(o)
|
|
163
|
+
literal(o.model)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def literal_Program(o)
|
|
167
|
+
literal(o.body)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def literal_LiteralString(o)
|
|
171
|
+
o.value
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def literal_QualifiedName(o)
|
|
175
|
+
o.value
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def literal_LiteralNumber(o)
|
|
179
|
+
o.value
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def literal_UnaryMinusExpression(o)
|
|
183
|
+
-1 * literal(o.expr)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def literal_LiteralBoolean(o)
|
|
187
|
+
o.value
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def literal_LiteralUndef(o)
|
|
191
|
+
nil
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def literal_LiteralDefault(o)
|
|
195
|
+
:default
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def literal_LiteralRegularExpression(o)
|
|
199
|
+
o.value
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def literal_ConcatenatedString(o)
|
|
203
|
+
# use double quoted string value if there is no interpolation
|
|
204
|
+
throw :not_literal unless o.segments.size == 1 && o.segments[0].is_a?(Model::LiteralString)
|
|
205
|
+
o.segments[0].value
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def literal_LiteralList(o)
|
|
209
|
+
o.values.map { |v| literal(v) }
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def literal_LiteralHash(o)
|
|
213
|
+
o.entries.reduce({}) do |result, entry|
|
|
214
|
+
result[literal(entry.key)] = literal(entry.value)
|
|
215
|
+
result
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Extracts the datatype attributes from a Puppet Data Type interface hash.
|
|
221
|
+
# Returns a Hash with a :types key (Array of data types for the parameter) and :default key (The default value of the parameter)
|
|
222
|
+
# @return Hash[Symbol => Hash] The Datatype Attributes as a hash
|
|
223
|
+
def extract_params(hash)
|
|
224
|
+
params_hash = {}
|
|
225
|
+
# Exit early if there are no entries in the hash
|
|
226
|
+
return params_hash if hash.nil? || hash['attributes'].nil? || hash['attributes'].empty?
|
|
227
|
+
|
|
228
|
+
hash['attributes'].each do |key, value|
|
|
229
|
+
data_type = nil
|
|
230
|
+
default = nil
|
|
231
|
+
if value.is_a?(String)
|
|
232
|
+
data_type = value
|
|
233
|
+
elsif value.is_a?(Hash)
|
|
234
|
+
data_type = value['type'] unless value['type'].nil?
|
|
235
|
+
default = value['value'] unless value['value'].nil?
|
|
236
|
+
end
|
|
237
|
+
data_type = [data_type] unless data_type.nil? || data_type.is_a?(Array)
|
|
238
|
+
params_hash[key] = { :types => data_type, :default => default }
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
params_hash
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# Extracts the datatype functions from a Puppet Data Type interface hash.
|
|
245
|
+
# Returns a Hash with a :param_types key (Array of types for each parameter) and :return_type key (The return type of the function)
|
|
246
|
+
# @return Hash[Symbol => Hash] The Datatype Attributes as a hash
|
|
247
|
+
def extract_functions(object, hash)
|
|
248
|
+
funcs_hash = {}
|
|
249
|
+
# Exit early if there are no entries in the hash
|
|
250
|
+
return funcs_hash if hash.nil? || hash['functions'].nil? || hash['functions'].empty?
|
|
251
|
+
|
|
252
|
+
hash['functions'].each do |key, func_type|
|
|
253
|
+
func_hash = { :param_types => [], :return_type => nil }
|
|
254
|
+
begin
|
|
255
|
+
callable_type = Puppet::Pops::Types::TypeParser.singleton.parse(func_type)
|
|
256
|
+
if callable_type.is_a?(Puppet::Pops::Types::PCallableType)
|
|
257
|
+
func_hash[:param_types] = callable_type.param_types.map { |pt| pt.to_s }
|
|
258
|
+
func_hash[:return_type] = callable_type.return_type.to_s
|
|
259
|
+
else
|
|
260
|
+
log.warn "The function definition for '#{key}' near #{object.file}:#{object.line} is not a Callable type"
|
|
261
|
+
end
|
|
262
|
+
rescue Puppet::ParseError => e
|
|
263
|
+
log.warn "Unable to parse the function definition for '#{key}' near #{object.file}:#{object.line}. #{e}"
|
|
264
|
+
end
|
|
265
|
+
funcs_hash[key] = func_hash
|
|
266
|
+
end
|
|
267
|
+
funcs_hash
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# Validates and automatically fixes yard @param tags for the data type
|
|
271
|
+
def validate_param_tags!(object, actual_params_hash)
|
|
272
|
+
actual_param_names = actual_params_hash.keys
|
|
273
|
+
tagged_param_names = object.tags(:param).map(&:name)
|
|
274
|
+
# Log any errors
|
|
275
|
+
# Find attributes which are not documented
|
|
276
|
+
(actual_param_names - tagged_param_names).each do |item|
|
|
277
|
+
log.warn "Missing @param tag for attribute '#{item}' near #{object.file}:#{object.line}."
|
|
278
|
+
end
|
|
279
|
+
# Find param tags with no matching attribute
|
|
280
|
+
(tagged_param_names - actual_param_names).each do |item|
|
|
281
|
+
log.warn "The @param tag for '#{item}' has no matching attribute near #{object.file}:#{object.line}."
|
|
282
|
+
end
|
|
283
|
+
# Find param tags with a type that is different from the actual definition
|
|
284
|
+
object.tags(:param).reject { |tag| tag.types.nil? }.each do |tag|
|
|
285
|
+
next if actual_params_hash[tag.name].nil?
|
|
286
|
+
|
|
287
|
+
actual_data_type = actual_params_hash[tag.name][:types]
|
|
288
|
+
next if actual_data_type.nil?
|
|
289
|
+
|
|
290
|
+
log.warn "The @param tag for '#{tag.name}' has a different type definition than the actual attribute near #{object.file}:#{object.line}." if tag.types != actual_data_type
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Automatically fix missing @param tags
|
|
294
|
+
(actual_param_names - tagged_param_names).each do |name|
|
|
295
|
+
object.add_parameter(name, actual_params_hash[name][:types], actual_params_hash[name][:default])
|
|
296
|
+
end
|
|
297
|
+
# Remove extra param tags
|
|
298
|
+
object.docstring.delete_tag_if { |item| item.tag_name == 'param' && !actual_param_names.include?(item.name) }
|
|
299
|
+
|
|
300
|
+
# Set the type in the param tag
|
|
301
|
+
object.tags(:param).each do |tag|
|
|
302
|
+
next if actual_params_hash[tag.name].nil?
|
|
303
|
+
|
|
304
|
+
tag.types = actual_params_hash[tag.name][:types]
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# Validates and automatically fixes yard @method! tags for the data type
|
|
309
|
+
def validate_methods!(object, actual_functions_hash)
|
|
310
|
+
actual_func_names = actual_functions_hash.keys
|
|
311
|
+
tagged_func_names = object.meths.map { |meth| meth.name.to_s }
|
|
312
|
+
|
|
313
|
+
# Log any errors
|
|
314
|
+
# Find functions which are not documented
|
|
315
|
+
(actual_func_names - tagged_func_names).each do |item|
|
|
316
|
+
log.warn "Missing @!method tag for function '#{item}' near #{object.file}:#{object.line}."
|
|
317
|
+
end
|
|
318
|
+
# Find functions which are not defined
|
|
319
|
+
(tagged_func_names - actual_func_names).each do |item|
|
|
320
|
+
log.warn "The @!method tag for '#{item}' has no matching function definition near #{object.file}:#{object.line}."
|
|
321
|
+
end
|
|
322
|
+
# Functions with the wrong return type
|
|
323
|
+
object.meths.each do |meth|
|
|
324
|
+
next unless actual_func_names.include?(meth.name.to_s)
|
|
325
|
+
|
|
326
|
+
return_tag = meth.docstring.tag(:return)
|
|
327
|
+
next if return_tag.nil?
|
|
328
|
+
|
|
329
|
+
actual_return_types = [actual_functions_hash[meth.name.to_s][:return_type]]
|
|
330
|
+
next if return_tag.types == actual_return_types
|
|
331
|
+
|
|
332
|
+
log.warn "The @return tag for '#{meth.name}' has a different type definition than the actual function near #{object.file}:#{object.line}. Expected #{actual_return_types}"
|
|
333
|
+
return_tag.types = actual_return_types
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
# Automatically fix missing methods
|
|
337
|
+
(actual_func_names - tagged_func_names).each do |name|
|
|
338
|
+
object.add_function(name, actual_functions_hash[name][:return_type], actual_functions_hash[name][:param_types])
|
|
339
|
+
end
|
|
340
|
+
# Remove extra methods. Can't use `meths` as that's a derived property
|
|
341
|
+
object.children.reject! { |child| child.is_a?(YARD::CodeObjects::MethodObject) && !actual_func_names.include?(child.name.to_s) }
|
|
342
|
+
|
|
343
|
+
# Add the return type for the methods if missing
|
|
344
|
+
object.meths.each do |meth|
|
|
345
|
+
next unless meth.docstring.tag(:return).nil?
|
|
346
|
+
|
|
347
|
+
meth.docstring.add_tag(YARD::Tags::Tag.new(:return, '', actual_functions_hash[meth.name.to_s][:return_type]))
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
# Sync the method properties and add the return type for the methods if missing
|
|
351
|
+
object.meths.each do |meth|
|
|
352
|
+
validate_function_method!(object, meth, actual_functions_hash[meth.name.to_s])
|
|
353
|
+
next unless meth.docstring.tag(:return).nil?
|
|
354
|
+
|
|
355
|
+
meth.docstring.add_tag(YARD::Tags::Tag.new(:return, '', actual_functions_hash[meth.name.to_s][:return_type]))
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
# The default meth.signature assumes ruby invocation (e.g. def meth(...)) but this doesn't make sense for a
|
|
359
|
+
# Puppet Data Type function invocation. So instead we derive a signature from the method definition.
|
|
360
|
+
object.meths.each do |meth|
|
|
361
|
+
params = ''
|
|
362
|
+
unless meth.docstring.tags(:param).empty?
|
|
363
|
+
params += '(' + meth.docstring.tags(:param).map { |t| t.name }.join(', ') + ')'
|
|
364
|
+
end
|
|
365
|
+
meth.signature = "#{object.name}.#{meth.name}" + params
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
nil
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# Validates and automatically fixes a single yard @method!
|
|
372
|
+
# Used by the validate_methods! method.
|
|
373
|
+
def validate_function_method!(object, meth, actual_function)
|
|
374
|
+
# Remove extra params
|
|
375
|
+
if meth.docstring.tags(:param).count > actual_function[:param_types].count
|
|
376
|
+
index = 0
|
|
377
|
+
meth.docstring.delete_tag_if do |tag|
|
|
378
|
+
if tag.tag_name == 'param'
|
|
379
|
+
index += 1
|
|
380
|
+
if index > actual_function[:param_types].count
|
|
381
|
+
log.warn "The @param tag for '#{tag.name}' should not exist for function '#{meth.name}' that is defined near #{object.file}:#{object.line}. Expected only #{actual_function[:param_types].count} parameter/s"
|
|
382
|
+
true
|
|
383
|
+
else
|
|
384
|
+
false
|
|
385
|
+
end
|
|
386
|
+
else
|
|
387
|
+
false
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
# Add missing params
|
|
393
|
+
if meth.docstring.tags(:param).count < actual_function[:param_types].count
|
|
394
|
+
start = meth.docstring.tags(:param).count + 1
|
|
395
|
+
(start..actual_function[:param_types].count).each do |index| # Using 1-based index here instead of usual zero
|
|
396
|
+
meth.add_tag(YARD::Tags::Tag.new(:param, '', actual_function[:param_types][index - 1], "param#{index}"))
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
# Ensure the parameter types are correct
|
|
401
|
+
meth.docstring.tags(:param).each_with_index do |tag, index|
|
|
402
|
+
actual_types = [actual_function[:param_types][index]]
|
|
403
|
+
if tag.types != actual_types
|
|
404
|
+
log.warn "The @param tag for '#{tag.name}' for function '#{meth.name}' has a different type definition than the actual function near #{object.file}:#{object.line}. Expected #{actual_types}"
|
|
405
|
+
tag.types = actual_types
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
end
|