puppet-strings 2.4.0 → 2.5.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 +4 -4
- data/CHANGELOG.md +30 -2
- data/lib/puppet-strings.rb +2 -2
- data/lib/puppet-strings/markdown.rb +1 -1
- data/lib/puppet-strings/markdown/base.rb +6 -0
- data/lib/puppet-strings/markdown/data_type.rb +16 -0
- data/lib/puppet-strings/markdown/resource_type.rb +19 -2
- data/lib/puppet-strings/markdown/templates/classes_and_defines.erb +4 -4
- data/lib/puppet-strings/markdown/templates/data_type.erb +11 -4
- data/lib/puppet-strings/markdown/templates/data_type_function.erb +67 -0
- data/lib/puppet-strings/markdown/templates/function.erb +2 -1
- data/lib/puppet-strings/markdown/templates/puppet_task.erb +1 -1
- data/lib/puppet-strings/markdown/templates/resource_type.erb +12 -12
- data/lib/puppet-strings/markdown/templates/table_of_contents.erb +6 -6
- data/lib/puppet-strings/version.rb +1 -1
- data/lib/puppet-strings/yard/code_objects/data_type.rb +26 -6
- data/lib/puppet-strings/yard/code_objects/type.rb +46 -5
- data/lib/puppet-strings/yard/handlers/ruby/data_type_handler.rb +190 -43
- data/lib/puppet-strings/yard/handlers/ruby/type_base.rb +6 -0
- data/lib/puppet-strings/yard/handlers/ruby/type_extras_handler.rb +1 -1
- data/lib/puppet-strings/yard/handlers/ruby/type_handler.rb +6 -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/setup.rb +9 -1
- data/lib/puppet-strings/yard/templates/default/puppet_type/html/setup.rb +3 -1
- metadata +4 -46
- data/CODEOWNERS +0 -1
- data/Gemfile +0 -53
- data/HISTORY.md +0 -218
- data/JSON.md +0 -832
- data/Rakefile +0 -160
- data/codecov.yml +0 -3
- data/misc/ANNOUNCEMENT_TEMPLATE.md +0 -40
- data/spec/acceptance/emit_json_options_spec.rb +0 -69
- data/spec/acceptance/generate_markdown_spec.rb +0 -47
- data/spec/acceptance/running_strings_generate_spec.rb +0 -88
- 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 -31
- data/spec/fixtures/acceptance/modules/test/manifests/triple_nested_classes.pp +0 -27
- data/spec/fixtures/acceptance/modules/test/metadata.json +0 -10
- data/spec/fixtures/acceptance/modules/test/types/elephant.pp +0 -2
- data/spec/fixtures/unit/markdown/output.md +0 -561
- data/spec/fixtures/unit/markdown/output_with_data_types.md +0 -606
- data/spec/fixtures/unit/markdown/output_with_plan.md +0 -595
- data/spec/spec_helper.rb +0 -49
- data/spec/spec_helper_acceptance.rb +0 -58
- data/spec/spec_helper_acceptance_local.rb +0 -10
- data/spec/unit/puppet-strings/describe_spec.rb +0 -141
- data/spec/unit/puppet-strings/json_spec.rb +0 -302
- data/spec/unit/puppet-strings/markdown/base_spec.rb +0 -146
- data/spec/unit/puppet-strings/markdown_spec.rb +0 -374
- 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/data_type_alias_handler_spec.rb +0 -65
- 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/data_type_handler_spec.rb +0 -309
- data/spec/unit/puppet-strings/yard/handlers/ruby/function_handler_spec.rb +0 -746
- data/spec/unit/puppet-strings/yard/handlers/ruby/provider_handler_spec.rb +0 -158
- 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 -311
- 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 -251
- data/spec/unit/puppet-strings/yard/util_spec.rb +0 -48
@@ -24,7 +24,6 @@ class PuppetStrings::Yard::CodeObjects::DataType < PuppetStrings::Yard::CodeObje
|
|
24
24
|
# @return [void]
|
25
25
|
def initialize(name)
|
26
26
|
super(PuppetStrings::Yard::CodeObjects::DataTypes.instance, name)
|
27
|
-
@parameters = []
|
28
27
|
@defaults = {}
|
29
28
|
end
|
30
29
|
|
@@ -41,10 +40,6 @@ class PuppetStrings::Yard::CodeObjects::DataType < PuppetStrings::Yard::CodeObje
|
|
41
40
|
nil
|
42
41
|
end
|
43
42
|
|
44
|
-
def parameter_exist?(name)
|
45
|
-
!docstring.tags(:param).find { |item| item.name == name }.nil?
|
46
|
-
end
|
47
|
-
|
48
43
|
def add_parameter(name, type, default)
|
49
44
|
tag = docstring.tags(:param).find { |item| item.name == name }
|
50
45
|
if tag.nil?
|
@@ -65,6 +60,24 @@ class PuppetStrings::Yard::CodeObjects::DataType < PuppetStrings::Yard::CodeObje
|
|
65
60
|
docstring.tags(:param).map { |tag| [tag.name, defaults[tag.name]] }
|
66
61
|
end
|
67
62
|
|
63
|
+
def add_function(name, return_type, parameter_types)
|
64
|
+
meth_obj = YARD::CodeObjects::MethodObject.new(self, name, :class)
|
65
|
+
|
66
|
+
# Add return tag
|
67
|
+
meth_obj.add_tag(YARD::Tags::Tag.new(:return, '', return_type))
|
68
|
+
|
69
|
+
# Add parameters
|
70
|
+
parameter_types.each_with_index do |param_type, index|
|
71
|
+
meth_obj.add_tag(YARD::Tags::Tag.new(:param, '', [param_type], "param#{index + 1}"))
|
72
|
+
end
|
73
|
+
|
74
|
+
self.meths << meth_obj
|
75
|
+
end
|
76
|
+
|
77
|
+
def functions
|
78
|
+
meths
|
79
|
+
end
|
80
|
+
|
68
81
|
# Converts the code object to a hash representation.
|
69
82
|
# @return [Hash] Returns a hash representation of the code object.
|
70
83
|
def to_hash
|
@@ -72,9 +85,16 @@ class PuppetStrings::Yard::CodeObjects::DataType < PuppetStrings::Yard::CodeObje
|
|
72
85
|
hash[:name] = name
|
73
86
|
hash[:file] = file
|
74
87
|
hash[:line] = line
|
75
|
-
hash[:docstring] = PuppetStrings::Yard::Util.docstring_to_hash(docstring)
|
88
|
+
hash[:docstring] = PuppetStrings::Yard::Util.docstring_to_hash(docstring, %i[param option enum return example])
|
76
89
|
hash[:defaults] = defaults unless defaults.empty?
|
77
90
|
hash[:source] = source unless source && source.empty?
|
91
|
+
hash[:functions] = functions.map do |func|
|
92
|
+
{
|
93
|
+
name: func.name,
|
94
|
+
signature: func.signature,
|
95
|
+
docstring: PuppetStrings::Yard::Util.docstring_to_hash(func.docstring, %i[param option enum return example])
|
96
|
+
}
|
97
|
+
end
|
78
98
|
hash
|
79
99
|
end
|
80
100
|
end
|
@@ -73,6 +73,9 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects:
|
|
73
73
|
class Property < Parameter
|
74
74
|
end
|
75
75
|
|
76
|
+
class Check < Parameter
|
77
|
+
end
|
78
|
+
|
76
79
|
# Represents a resource type feature.
|
77
80
|
class Feature
|
78
81
|
attr_reader :name, :docstring
|
@@ -95,7 +98,7 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects:
|
|
95
98
|
end
|
96
99
|
end
|
97
100
|
|
98
|
-
attr_reader :properties, :
|
101
|
+
attr_reader :properties, :features, :checks
|
99
102
|
|
100
103
|
# Initializes a new resource type.
|
101
104
|
# @param [String] name The resource type name.
|
@@ -134,17 +137,55 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects:
|
|
134
137
|
@features << feature
|
135
138
|
end
|
136
139
|
|
140
|
+
# Adds a check to the resource type.
|
141
|
+
# @param [PuppetStrings::Yard::CodeObjects::Type::Check] check The check to add.
|
142
|
+
# @return [void]
|
143
|
+
def add_check(check)
|
144
|
+
@checks ||= []
|
145
|
+
@checks << check
|
146
|
+
end
|
147
|
+
|
148
|
+
def parameters
|
149
|
+
# just return params if there are no providers
|
150
|
+
return @parameters if providers.empty?
|
151
|
+
|
152
|
+
# return existing params if we have already added provider
|
153
|
+
return @parameters if @parameters.any? { |p| p.name == 'provider' }
|
154
|
+
|
155
|
+
provider_param = Parameter.new(
|
156
|
+
'provider',
|
157
|
+
"The specific backend to use for this `#{self.name.to_s}` resource. You will seldom need " + \
|
158
|
+
"to specify this --- Puppet will usually discover the appropriate provider for your platform."
|
159
|
+
)
|
160
|
+
|
161
|
+
@parameters << provider_param
|
162
|
+
end
|
163
|
+
|
164
|
+
# Not sure if this is where this belongs or if providers should only be resolved at
|
165
|
+
# render-time. For now, this should re-resolve on every call.
|
166
|
+
# may be able to memoize this
|
167
|
+
def providers
|
168
|
+
providers = YARD::Registry.all("puppet_providers_#{name}".intern)
|
169
|
+
return providers if providers.empty?
|
170
|
+
providers.first.children
|
171
|
+
end
|
172
|
+
|
137
173
|
# Converts the code object to a hash representation.
|
138
174
|
# @return [Hash] Returns a hash representation of the code object.
|
139
175
|
def to_hash
|
140
176
|
hash = {}
|
177
|
+
|
141
178
|
hash[:name] = name
|
142
179
|
hash[:file] = file
|
143
180
|
hash[:line] = line
|
144
|
-
|
145
|
-
hash[:
|
146
|
-
hash[:
|
147
|
-
hash[:
|
181
|
+
|
182
|
+
hash[:docstring] = PuppetStrings::Yard::Util.docstring_to_hash(docstring)
|
183
|
+
hash[:properties] = properties.sort_by { |p| p.name }.map(&:to_hash) if properties && !properties.empty?
|
184
|
+
hash[:parameters] = parameters.sort_by { |p| p.name }.map(&:to_hash) if parameters && !parameters.empty?
|
185
|
+
hash[:checks] = checks.sort_by { |c| c.name }.map(&:to_hash) if checks && !checks.empty?
|
186
|
+
hash[:features] = features.sort_by { |f| f.name }.map(&:to_hash) if features && !features.empty?
|
187
|
+
hash[:providers] = providers.sort_by { |p| p.name }.map(&:to_hash) if providers && !providers.empty?
|
188
|
+
|
148
189
|
hash
|
149
190
|
end
|
150
191
|
end
|
@@ -13,13 +13,16 @@ class PuppetStrings::Yard::Handlers::Ruby::DataTypeHandler < PuppetStrings::Yard
|
|
13
13
|
ruby_module_name = statement[0].source
|
14
14
|
return unless ruby_module_name == 'Puppet::DataTypes' || ruby_module_name == 'DataTypes' # rubocop:disable Style/MultipleComparison This reads better
|
15
15
|
object = get_datatype_yard_object(get_name(statement, 'Puppet::DataTypes.create_type'))
|
16
|
-
|
17
|
-
|
16
|
+
# Extract the interface definition
|
17
|
+
type_interface = extract_data_type_interface
|
18
|
+
actual_params = extract_params(type_interface)
|
19
|
+
actual_funcs = extract_functions(object, type_interface)
|
18
20
|
|
19
21
|
# Mark the data type as public if it doesn't already have an api tag
|
20
22
|
object.add_tag YARD::Tags::Tag.new(:api, 'public') unless object.has_tag? :api
|
21
23
|
|
22
|
-
|
24
|
+
validate_param_tags!(object, actual_params)
|
25
|
+
validate_methods!(object, actual_funcs)
|
23
26
|
|
24
27
|
# Set the default values for all parameters
|
25
28
|
actual_params.each { |name, data| object.set_parameter_default(name, data[:default]) }
|
@@ -49,44 +52,60 @@ class PuppetStrings::Yard::Handlers::Ruby::DataTypeHandler < PuppetStrings::Yard
|
|
49
52
|
object
|
50
53
|
end
|
51
54
|
|
52
|
-
|
53
|
-
|
54
|
-
# Traverse the block looking for interface
|
55
|
+
# @return [Hash{Object => Object}] The Puppet DataType interface definition as a ruby Hash
|
56
|
+
def extract_data_type_interface
|
55
57
|
block = statement.block
|
56
|
-
return unless block
|
57
|
-
|
58
|
-
|
59
|
-
|
58
|
+
return {} unless block
|
59
|
+
|
60
|
+
# Declare the parsed interface outside of the closure
|
61
|
+
parsed_interface = nil
|
60
62
|
|
61
|
-
|
63
|
+
# Recursively traverse the block looking for the first valid 'interface' call
|
64
|
+
interface_node = find_ruby_ast_node(block, true) do |node|
|
65
|
+
next false unless node.is_a?(YARD::Parser::Ruby::MethodCallNode) &&
|
66
|
+
node.method_name &&
|
67
|
+
node.method_name.source == 'interface'
|
62
68
|
parameters = node.parameters(false)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
69
|
+
next false unless parameters.count >= 1
|
70
|
+
interface_string = node_as_string(parameters[0])
|
71
|
+
next false unless interface_string
|
72
|
+
|
73
|
+
begin
|
67
74
|
# Ref - https://github.com/puppetlabs/puppet/blob/ba4d1a1aba0095d3c70b98fea5c67434a4876a61/lib/puppet/datatypes.rb#L159
|
68
|
-
parsed_interface =
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
75
|
+
parsed_interface = Puppet::Pops::Parser::EvaluatingParser.new.parse_string("{ #{interface_string} }").body
|
76
|
+
rescue Puppet::Error => e
|
77
|
+
log.warn "Invalid datatype definition at #{statement.file}:#{statement.line}: #{e.basic_message}"
|
78
|
+
next false
|
79
|
+
end
|
80
|
+
!parsed_interface.nil?
|
81
|
+
end
|
82
|
+
|
83
|
+
# Now that we parsed the Puppet code (as a string) into a LiteralHash PCore type (Puppet AST),
|
84
|
+
# We need to convert the LiteralHash into a conventional ruby hash of strings. The
|
85
|
+
# LazyLiteralEvaluator does this by traversing the AST tree can converting objects to strings
|
86
|
+
# where possible and ignoring object types which cannot (thus the 'Lazy' name)
|
87
|
+
literal_eval = LazyLiteralEvaluator.new
|
88
|
+
literal_eval.literal(parsed_interface)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Find the first Ruby AST node within an AST Tree, optionally recursively. Returns nil of none could be found
|
92
|
+
#
|
93
|
+
# @param [YARD::Parser::Ruby::AstNode] ast_node The root AST node object to inspect
|
94
|
+
# @param [Boolean] recurse Whether to search the tree recursively. Defaults to false
|
95
|
+
# @yieldparam [YARD::Parser::Ruby::AstNode] ast_node The AST Node that should be checked
|
96
|
+
# @yieldreturn [Boolean] Whether the node was what was searched for
|
97
|
+
# @return [YARD::Parser::Ruby::AstNode, nil]
|
98
|
+
def find_ruby_ast_node(ast_node, recurse = false, &block)
|
99
|
+
raise ArgumentError, 'find_ruby_ast_node requires a block' unless block_given?
|
100
|
+
is_found = yield ast_node
|
101
|
+
return ast_node if is_found
|
102
|
+
if ast_node.respond_to?(:children)
|
103
|
+
ast_node.children.each do |child_node|
|
104
|
+
child_found = find_ruby_ast_node(child_node, recurse, &block)
|
105
|
+
return child_found unless child_found.nil?
|
87
106
|
end
|
88
107
|
end
|
89
|
-
|
108
|
+
nil
|
90
109
|
end
|
91
110
|
|
92
111
|
# Lazily evaluates a Pops object, ignoring any objects that cannot
|
@@ -179,7 +198,7 @@ class PuppetStrings::Yard::Handlers::Ruby::DataTypeHandler < PuppetStrings::Yard
|
|
179
198
|
end
|
180
199
|
|
181
200
|
def literal_LiteralList(o) # rubocop:disable Naming/UncommunicativeMethodParamName
|
182
|
-
o.values.map {|v| literal(v) }
|
201
|
+
o.values.map { |v| literal(v) }
|
183
202
|
end
|
184
203
|
|
185
204
|
def literal_LiteralHash(o) # rubocop:disable Naming/UncommunicativeMethodParamName
|
@@ -190,27 +209,58 @@ class PuppetStrings::Yard::Handlers::Ruby::DataTypeHandler < PuppetStrings::Yard
|
|
190
209
|
end
|
191
210
|
end
|
192
211
|
|
193
|
-
|
194
|
-
|
212
|
+
# Extracts the datatype attributes from a Puppet Data Type interface hash.
|
213
|
+
# Returns a Hash with a :types key (Array of data types for the parameter) and :default key (The default value of the parameter)
|
214
|
+
# @return Hash[Symbol => Hash] The Datatype Attributes as a hash
|
215
|
+
def extract_params(hash)
|
216
|
+
params_hash = {}
|
195
217
|
# Exit early if there are no entries in the hash
|
196
|
-
return if hash['attributes'].nil? || hash['attributes'].
|
218
|
+
return params_hash if hash.nil? || hash['attributes'].nil? || hash['attributes'].empty?
|
197
219
|
|
198
220
|
hash['attributes'].each do |key, value|
|
199
221
|
data_type = nil
|
200
222
|
default = nil
|
201
|
-
|
202
|
-
when String
|
223
|
+
if value.is_a?(String)
|
203
224
|
data_type = value
|
204
|
-
|
225
|
+
elsif value.is_a?(Hash)
|
205
226
|
data_type = value['type'] unless value['type'].nil?
|
206
227
|
default = value['value'] unless value['value'].nil?
|
207
228
|
end
|
208
229
|
data_type = [data_type] unless data_type.nil? || data_type.is_a?(Array)
|
209
230
|
params_hash[key] = { :types => data_type, :default => default }
|
210
231
|
end
|
232
|
+
|
233
|
+
params_hash
|
211
234
|
end
|
212
235
|
|
213
|
-
|
236
|
+
# Extracts the datatype functions from a Puppet Data Type interface hash.
|
237
|
+
# Returns a Hash with a :param_types key (Array of types for each parameter) and :return_type key (The return type of the function)
|
238
|
+
# @return Hash[Symbol => Hash] The Datatype Attributes as a hash
|
239
|
+
def extract_functions(object, hash)
|
240
|
+
funcs_hash = {}
|
241
|
+
# Exit early if there are no entries in the hash
|
242
|
+
return funcs_hash if hash.nil? || hash['functions'].nil? || hash['functions'].empty?
|
243
|
+
|
244
|
+
hash['functions'].each do |key, func_type|
|
245
|
+
func_hash = { :param_types => [], :return_type => nil }
|
246
|
+
begin
|
247
|
+
callable_type = Puppet::Pops::Types::TypeParser.singleton.parse(func_type)
|
248
|
+
if callable_type.is_a?(Puppet::Pops::Types::PCallableType)
|
249
|
+
func_hash[:param_types] = callable_type.param_types.map { |pt| pt.to_s }
|
250
|
+
func_hash[:return_type] = callable_type.return_type.to_s
|
251
|
+
else
|
252
|
+
log.warn "The function definition for '#{key}' near #{object.file}:#{object.line} is not a Callable type"
|
253
|
+
end
|
254
|
+
rescue Puppet::ParseError => e
|
255
|
+
log.warn "Unable to parse the function definition for '#{key}' near #{object.file}:#{object.line}. #{e}"
|
256
|
+
end
|
257
|
+
funcs_hash[key] = func_hash
|
258
|
+
end
|
259
|
+
funcs_hash
|
260
|
+
end
|
261
|
+
|
262
|
+
# Validates and automatically fixes yard @param tags for the data type
|
263
|
+
def validate_param_tags!(object, actual_params_hash)
|
214
264
|
actual_param_names = actual_params_hash.keys
|
215
265
|
tagged_param_names = object.tags(:param).map(&:name)
|
216
266
|
# Log any errors
|
@@ -243,4 +293,101 @@ class PuppetStrings::Yard::Handlers::Ruby::DataTypeHandler < PuppetStrings::Yard
|
|
243
293
|
tag.types = actual_params_hash[tag.name][:types]
|
244
294
|
end
|
245
295
|
end
|
296
|
+
|
297
|
+
# Validates and automatically fixes yard @method! tags for the data type
|
298
|
+
def validate_methods!(object, actual_functions_hash)
|
299
|
+
actual_func_names = actual_functions_hash.keys
|
300
|
+
tagged_func_names = object.meths.map { |meth| meth.name.to_s }
|
301
|
+
|
302
|
+
# Log any errors
|
303
|
+
# Find functions which are not documented
|
304
|
+
(actual_func_names - tagged_func_names).each do |item|
|
305
|
+
log.warn "Missing @!method tag for function '#{item}' near #{object.file}:#{object.line}."
|
306
|
+
end
|
307
|
+
# Find functions which are not defined
|
308
|
+
(tagged_func_names - actual_func_names).each do |item|
|
309
|
+
log.warn "The @!method tag for '#{item}' has no matching function definition near #{object.file}:#{object.line}."
|
310
|
+
end
|
311
|
+
# Functions with the wrong return type
|
312
|
+
object.meths.each do |meth|
|
313
|
+
next unless actual_func_names.include?(meth.name.to_s)
|
314
|
+
return_tag = meth.docstring.tag(:return)
|
315
|
+
next if return_tag.nil?
|
316
|
+
actual_return_types = [actual_functions_hash[meth.name.to_s][:return_type]]
|
317
|
+
next if return_tag.types == actual_return_types
|
318
|
+
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}"
|
319
|
+
return_tag.types = actual_return_types
|
320
|
+
end
|
321
|
+
|
322
|
+
# Automatically fix missing methods
|
323
|
+
(actual_func_names - tagged_func_names).each do |name|
|
324
|
+
object.add_function(name, actual_functions_hash[name][:return_type], actual_functions_hash[name][:param_types])
|
325
|
+
end
|
326
|
+
# Remove extra methods. Can't use `meths` as that's a derived property
|
327
|
+
object.children.reject! { |child| child.is_a?(YARD::CodeObjects::MethodObject) && !actual_func_names.include?(child.name.to_s) }
|
328
|
+
|
329
|
+
# Add the return type for the methods if missing
|
330
|
+
object.meths.each do |meth|
|
331
|
+
next unless meth.docstring.tag(:return).nil?
|
332
|
+
meth.docstring.add_tag(YARD::Tags::Tag.new(:return, '', actual_functions_hash[meth.name.to_s][:return_type]))
|
333
|
+
end
|
334
|
+
|
335
|
+
# Sync the method properties and add the return type for the methods if missing
|
336
|
+
object.meths.each do |meth|
|
337
|
+
validate_function_method!(object, meth, actual_functions_hash[meth.name.to_s])
|
338
|
+
next unless meth.docstring.tag(:return).nil?
|
339
|
+
meth.docstring.add_tag(YARD::Tags::Tag.new(:return, '', actual_functions_hash[meth.name.to_s][:return_type]))
|
340
|
+
end
|
341
|
+
|
342
|
+
# The default meth.signature assumes ruby invocation (e.g. def meth(...)) but this doesn't make sense for a
|
343
|
+
# Puppet Data Type function invocation. So instead we derive a signature from the method definition.
|
344
|
+
object.meths.each do |meth|
|
345
|
+
params = ''
|
346
|
+
unless meth.docstring.tags(:param).empty?
|
347
|
+
params += '(' + meth.docstring.tags(:param).map { |t| t.name }.join(', ') + ')'
|
348
|
+
end
|
349
|
+
meth.signature = "#{object.name}.#{meth.name}" + params
|
350
|
+
end
|
351
|
+
|
352
|
+
nil
|
353
|
+
end
|
354
|
+
|
355
|
+
# Validates and automatically fixes a single yard @method!
|
356
|
+
# Used by the validate_methods! method.
|
357
|
+
def validate_function_method!(object, meth, actual_function)
|
358
|
+
# Remove extra params
|
359
|
+
if meth.docstring.tags(:param).count > actual_function[:param_types].count
|
360
|
+
index = 0
|
361
|
+
meth.docstring.delete_tag_if do |tag|
|
362
|
+
if tag.tag_name == 'param'
|
363
|
+
index += 1
|
364
|
+
if index > actual_function[:param_types].count
|
365
|
+
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"
|
366
|
+
true
|
367
|
+
else
|
368
|
+
false
|
369
|
+
end
|
370
|
+
else
|
371
|
+
false
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
# Add missing params
|
377
|
+
if meth.docstring.tags(:param).count < actual_function[:param_types].count
|
378
|
+
start = meth.docstring.tags(:param).count + 1
|
379
|
+
(start..actual_function[:param_types].count).each do |index| # Using 1-based index here instead of usual zero
|
380
|
+
meth.add_tag(YARD::Tags::Tag.new(:param, '', actual_function[:param_types][index - 1], "param#{index}"))
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
# Ensure the parameter types are correct
|
385
|
+
meth.docstring.tags(:param).each_with_index do |tag, index|
|
386
|
+
actual_types = [actual_function[:param_types][index]]
|
387
|
+
if tag.types != actual_types
|
388
|
+
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}"
|
389
|
+
tag.types = actual_types
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
246
393
|
end
|
@@ -52,6 +52,12 @@ class PuppetStrings::Yard::Handlers::Ruby::TypeBase < PuppetStrings::Yard::Handl
|
|
52
52
|
property
|
53
53
|
end
|
54
54
|
|
55
|
+
def create_check(name, node)
|
56
|
+
check = PuppetStrings::Yard::CodeObjects::Type::Check.new(name, find_docstring(node, "Puppet resource check '#{name}'"))
|
57
|
+
set_values(node, check)
|
58
|
+
check
|
59
|
+
end
|
60
|
+
|
55
61
|
def set_values(node, object)
|
56
62
|
return unless node.block && node.block.count >= 2
|
57
63
|
|
@@ -32,7 +32,7 @@ class PuppetStrings::Yard::Handlers::Ruby::TypeExtrasHandler < PuppetStrings::Ya
|
|
32
32
|
|
33
33
|
return unless (statement.count > 1) && (statement[0].children.count > 2)
|
34
34
|
module_name = statement[0].children[0].source
|
35
|
-
method1_name = statement[0].children
|
35
|
+
method1_name = statement[0].children.drop(1).find{ |c| c.type == :ident }.source
|
36
36
|
return unless (module_name == 'Puppet::Type' || module_name == 'Type') && method1_name == 'type'
|
37
37
|
|
38
38
|
typename = get_name(statement[0], 'Puppet::Type.type')
|
@@ -59,6 +59,12 @@ class PuppetStrings::Yard::Handlers::Ruby::TypeHandler < PuppetStrings::Yard::Ha
|
|
59
59
|
name = node_as_string(parameters[0])
|
60
60
|
next unless name
|
61
61
|
object.add_parameter(create_parameter(name, node))
|
62
|
+
elsif method_name == 'newcheck'
|
63
|
+
# Add a check to the object
|
64
|
+
next unless parameters.count >= 1
|
65
|
+
name = node_as_string(parameters[0])
|
66
|
+
next unless name
|
67
|
+
object.add_check(create_check(name, node))
|
62
68
|
elsif method_name == 'feature'
|
63
69
|
# Add a feature to the object
|
64
70
|
next unless parameters.count >= 2
|