puppet-strings 0.4.0 → 0.99.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 +122 -0
- data/COMMITTERS.md +185 -0
- data/CONTRIBUTING.md +89 -0
- data/Gemfile +38 -0
- data/JSON.md +511 -0
- data/LICENSE +13 -0
- data/README.md +416 -0
- data/Rakefile +49 -0
- data/lib/puppet-strings.rb +63 -0
- data/lib/puppet-strings/json.rb +49 -0
- data/lib/puppet-strings/tasks.rb +10 -0
- data/lib/puppet-strings/tasks/generate.rb +23 -0
- data/lib/puppet-strings/tasks/gh_pages.rb +43 -0
- data/lib/puppet-strings/yard.rb +96 -0
- data/lib/puppet-strings/yard/code_objects.rb +8 -0
- data/lib/puppet-strings/yard/code_objects/base.rb +14 -0
- data/lib/puppet-strings/yard/code_objects/class.rb +59 -0
- data/lib/puppet-strings/yard/code_objects/defined_type.rb +58 -0
- data/lib/puppet-strings/yard/code_objects/function.rb +93 -0
- data/lib/puppet-strings/yard/code_objects/group.rb +30 -0
- data/lib/puppet-strings/yard/code_objects/provider.rb +93 -0
- data/lib/puppet-strings/yard/code_objects/type.rb +146 -0
- data/lib/puppet-strings/yard/handlers.rb +16 -0
- data/lib/puppet-strings/yard/handlers/puppet/base.rb +44 -0
- data/lib/puppet-strings/yard/handlers/puppet/class_handler.rb +23 -0
- data/lib/puppet-strings/yard/handlers/puppet/defined_type_handler.rb +23 -0
- data/lib/puppet-strings/yard/handlers/puppet/function_handler.rb +42 -0
- data/lib/puppet-strings/yard/handlers/ruby/base.rb +38 -0
- data/lib/puppet-strings/yard/handlers/ruby/function_handler.rb +357 -0
- data/lib/puppet-strings/yard/handlers/ruby/provider_handler.rb +113 -0
- data/lib/puppet-strings/yard/handlers/ruby/type_handler.rb +194 -0
- data/lib/puppet-strings/yard/parsers.rb +7 -0
- data/lib/puppet-strings/yard/parsers/puppet/parser.rb +70 -0
- data/lib/puppet-strings/yard/parsers/puppet/statement.rb +146 -0
- data/lib/puppet-strings/yard/tags.rb +6 -0
- data/lib/puppet-strings/yard/tags/overload_tag.rb +109 -0
- data/lib/puppet-strings/yard/tags/parameter_directive.rb +24 -0
- data/lib/puppet-strings/yard/tags/property_directive.rb +24 -0
- data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_class.erb +9 -0
- data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_defined_type.erb +9 -0
- data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_function.erb +10 -0
- data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_provider.erb +10 -0
- data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_type.erb +9 -0
- data/lib/puppet-strings/yard/templates/default/fulldoc/html/setup.rb +64 -0
- data/lib/puppet-strings/yard/templates/default/layout/html/objects.erb +35 -0
- data/lib/puppet-strings/yard/templates/default/layout/html/setup.rb +172 -0
- data/lib/puppet-strings/yard/templates/default/puppet_class/html/box_info.erb +26 -0
- data/lib/puppet-strings/yard/templates/default/puppet_class/html/header.erb +1 -0
- data/lib/puppet-strings/yard/templates/default/puppet_class/html/overview.erb +6 -0
- data/lib/puppet-strings/yard/templates/default/puppet_class/html/setup.rb +14 -0
- data/lib/puppet-strings/yard/templates/default/puppet_class/html/source.erb +12 -0
- data/lib/puppet-strings/yard/templates/default/puppet_defined_type/html/box_info.erb +10 -0
- data/lib/puppet-strings/yard/templates/default/puppet_defined_type/html/header.erb +1 -0
- data/lib/puppet-strings/yard/templates/default/puppet_defined_type/html/overview.erb +6 -0
- data/lib/puppet-strings/yard/templates/default/puppet_defined_type/html/setup.rb +5 -0
- data/lib/puppet-strings/yard/templates/default/puppet_defined_type/html/source.erb +12 -0
- data/lib/puppet-strings/yard/templates/default/puppet_function/html/box_info.erb +14 -0
- data/lib/puppet-strings/yard/templates/default/puppet_function/html/header.erb +1 -0
- data/lib/puppet-strings/yard/templates/default/puppet_function/html/overview.erb +18 -0
- data/lib/puppet-strings/yard/templates/default/puppet_function/html/setup.rb +5 -0
- data/lib/puppet-strings/yard/templates/default/puppet_function/html/source.erb +12 -0
- data/lib/puppet-strings/yard/templates/default/puppet_provider/html/box_info.erb +14 -0
- data/lib/puppet-strings/yard/templates/default/puppet_provider/html/collection.erb +10 -0
- data/lib/puppet-strings/yard/templates/default/puppet_provider/html/features.erb +12 -0
- data/lib/puppet-strings/yard/templates/default/puppet_provider/html/header.erb +1 -0
- data/lib/puppet-strings/yard/templates/default/puppet_provider/html/overview.erb +6 -0
- data/lib/puppet-strings/yard/templates/default/puppet_provider/html/setup.rb +29 -0
- data/lib/puppet-strings/yard/templates/default/puppet_type/html/box_info.erb +20 -0
- data/lib/puppet-strings/yard/templates/default/puppet_type/html/features.erb +13 -0
- data/lib/puppet-strings/yard/templates/default/puppet_type/html/header.erb +1 -0
- data/lib/puppet-strings/yard/templates/default/puppet_type/html/overview.erb +6 -0
- data/lib/puppet-strings/yard/templates/default/puppet_type/html/parameters.erb +35 -0
- data/lib/puppet-strings/yard/templates/default/puppet_type/html/setup.rb +32 -0
- data/lib/puppet-strings/yard/templates/default/tags/html/puppet_overload.erb +12 -0
- data/lib/puppet-strings/yard/templates/default/tags/setup.rb +15 -0
- data/lib/puppet/application/strings.rb +1 -0
- data/lib/puppet/face/strings.rb +80 -39
- data/spec/acceptance/emit_json_options.rb +41 -0
- data/spec/acceptance/lib/util.rb +15 -0
- data/spec/acceptance/running_strings_generate.rb +54 -0
- data/spec/fixtures/acceptance/modules/test/functions/add.pp +9 -0
- data/spec/fixtures/acceptance/modules/test/lib/puppet/functions/4x_function.rb +5 -0
- data/spec/fixtures/acceptance/modules/test/lib/puppet/parser/functions/function3x.rb +2 -0
- data/spec/fixtures/acceptance/modules/test/lib/puppet/provider/server/linux.rb +9 -0
- data/spec/fixtures/acceptance/modules/test/lib/puppet/type/database.rb +15 -0
- data/spec/fixtures/acceptance/modules/test/manifests/init.pp +27 -0
- data/spec/fixtures/acceptance/modules/test/manifests/triple_nested_classes.pp +27 -0
- data/spec/fixtures/acceptance/modules/test/metadata.json +6 -0
- data/spec/fixtures/unit/json/output.json +348 -0
- data/spec/fixtures/unit/json/output_without_puppet_function.json +301 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/spec_helper_acceptance.rb +27 -0
- data/spec/unit/puppet-strings/json_spec.rb +136 -0
- data/spec/unit/puppet-strings/yard/handlers/puppet/class_handler_spec.rb +155 -0
- data/spec/unit/puppet-strings/yard/handlers/puppet/defined_type_handler_spec.rb +155 -0
- data/spec/unit/puppet-strings/yard/handlers/puppet/function_handler_spec.rb +169 -0
- data/spec/unit/puppet-strings/yard/handlers/ruby/function_handler_spec.rb +613 -0
- data/spec/unit/puppet-strings/yard/handlers/ruby/provider_handler_spec.rb +90 -0
- data/spec/unit/puppet-strings/yard/handlers/ruby/type_handler_spec.rb +214 -0
- data/spec/unit/puppet-strings/yard/parsers/puppet/parser_spec.rb +171 -0
- metadata +115 -92
- data/lib/puppet-strings/rake_tasks.rb +0 -18
- data/lib/puppet_x/puppetlabs/strings.rb +0 -64
- data/lib/puppet_x/puppetlabs/strings/actions.rb +0 -92
- data/lib/puppet_x/puppetlabs/strings/pops/yard_statement.rb +0 -79
- data/lib/puppet_x/puppetlabs/strings/pops/yard_transformer.rb +0 -47
- data/lib/puppet_x/puppetlabs/strings/util.rb +0 -65
- data/lib/puppet_x/puppetlabs/strings/yard/code_objects/defined_type_object.rb +0 -33
- data/lib/puppet_x/puppetlabs/strings/yard/code_objects/host_class_object.rb +0 -22
- data/lib/puppet_x/puppetlabs/strings/yard/code_objects/method_object.rb +0 -62
- data/lib/puppet_x/puppetlabs/strings/yard/code_objects/provider_object.rb +0 -24
- data/lib/puppet_x/puppetlabs/strings/yard/code_objects/puppet_namespace_object.rb +0 -48
- data/lib/puppet_x/puppetlabs/strings/yard/code_objects/type_object.rb +0 -42
- data/lib/puppet_x/puppetlabs/strings/yard/core_ext/yard.rb +0 -40
- data/lib/puppet_x/puppetlabs/strings/yard/handlers/base.rb +0 -13
- data/lib/puppet_x/puppetlabs/strings/yard/handlers/defined_type_handler.rb +0 -31
- data/lib/puppet_x/puppetlabs/strings/yard/handlers/heredoc_helper.rb +0 -80
- data/lib/puppet_x/puppetlabs/strings/yard/handlers/host_class_handler.rb +0 -42
- data/lib/puppet_x/puppetlabs/strings/yard/handlers/provider_handler.rb +0 -95
- data/lib/puppet_x/puppetlabs/strings/yard/handlers/puppet_3x_function_handler.rb +0 -54
- data/lib/puppet_x/puppetlabs/strings/yard/handlers/puppet_4x_function_handler.rb +0 -234
- data/lib/puppet_x/puppetlabs/strings/yard/handlers/type_handler.rb +0 -295
- data/lib/puppet_x/puppetlabs/strings/yard/json_registry_store.rb +0 -85
- data/lib/puppet_x/puppetlabs/strings/yard/monkey_patches.rb +0 -68
- data/lib/puppet_x/puppetlabs/strings/yard/parser.rb +0 -30
- data/lib/puppet_x/puppetlabs/strings/yard/tags/directives.rb +0 -9
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/definedtype/html/docstring.erb +0 -34
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/definedtype/html/header.erb +0 -5
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/definedtype/html/parameter_details.erb +0 -6
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/definedtype/html/setup.rb +0 -1
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/definedtype/setup.rb +0 -49
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/full_list_class.erb +0 -2
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/full_list_puppet_manifest.erb +0 -1
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/full_list_puppet_plugin.erb +0 -21
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/full_list_puppet_provider.erb +0 -1
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/full_list_puppet_type.erb +0 -1
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/setup.rb +0 -82
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/hostclass/html/box_info.erb +0 -22
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/hostclass/html/setup.rb +0 -1
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/hostclass/html/subclasses.erb +0 -4
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/hostclass/setup.rb +0 -21
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/html_helper.rb +0 -139
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/layout/html/setup.rb +0 -18
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/method_details/html/header.erb +0 -17
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/method_details/setup.rb +0 -21
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/method_details/text/header.erb +0 -2
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/command_details.erb +0 -8
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/confine_details.erb +0 -10
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/default_details.erb +0 -10
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/docstring.erb +0 -34
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/feature_details.erb +0 -10
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/header.erb +0 -5
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/setup.rb +0 -1
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/setup.rb +0 -50
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/html/box_info.erb +0 -11
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/html/header.erb +0 -5
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/html/method_details_list.erb +0 -53
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/html/method_summary.erb +0 -20
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/html/setup.rb +0 -1
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/setup.rb +0 -91
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/template_helper.rb +0 -192
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/html/docstring.erb +0 -34
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/html/header.erb +0 -5
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/html/parameter_details.erb +0 -12
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/html/provider_details.erb +0 -10
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/html/setup.rb +0 -1
- data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/setup.rb +0 -55
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
require 'puppet-strings/yard/handlers/ruby/base'
|
|
2
|
+
require 'puppet-strings/yard/code_objects'
|
|
3
|
+
require 'puppet/util/docs'
|
|
4
|
+
|
|
5
|
+
# Implements the handler for Puppet functions written in Ruby.
|
|
6
|
+
class PuppetStrings::Yard::Handlers::Ruby::FunctionHandler < PuppetStrings::Yard::Handlers::Ruby::Base
|
|
7
|
+
# Represents the list of Puppet 4.x function API methods to support.
|
|
8
|
+
DISPATCH_METHOD_NAMES = %w(
|
|
9
|
+
param
|
|
10
|
+
required_param
|
|
11
|
+
optional_param
|
|
12
|
+
repeated_param
|
|
13
|
+
optional_repeated_param
|
|
14
|
+
required_repeated_param
|
|
15
|
+
block_param
|
|
16
|
+
required_block_param
|
|
17
|
+
optional_block_param
|
|
18
|
+
).freeze
|
|
19
|
+
|
|
20
|
+
namespace_only
|
|
21
|
+
handles method_call(:create_function)
|
|
22
|
+
handles method_call(:newfunction)
|
|
23
|
+
|
|
24
|
+
process do
|
|
25
|
+
# Only accept calls to Puppet::Functions (4.x) or Puppet::Parser::Functions (3.x)
|
|
26
|
+
return unless statement.count > 1
|
|
27
|
+
module_name = statement[0].source
|
|
28
|
+
return unless module_name == 'Puppet::Functions' || module_name == 'Puppet::Parser::Functions'
|
|
29
|
+
|
|
30
|
+
# Create and register the function object
|
|
31
|
+
is_3x = module_name == 'Puppet::Parser::Functions'
|
|
32
|
+
object = PuppetStrings::Yard::CodeObjects::Function.new(
|
|
33
|
+
get_name,
|
|
34
|
+
is_3x ? PuppetStrings::Yard::CodeObjects::Function::RUBY_3X : PuppetStrings::Yard::CodeObjects::Function::RUBY_4X
|
|
35
|
+
)
|
|
36
|
+
object.source = statement
|
|
37
|
+
register object
|
|
38
|
+
|
|
39
|
+
# For 3x, parse the doc parameter for the docstring
|
|
40
|
+
# This must be done after the `register` call above because `register` always uses the statement's docstring
|
|
41
|
+
if is_3x
|
|
42
|
+
docstring = get_3x_docstring(object.name)
|
|
43
|
+
register_docstring(object, docstring, nil) if docstring
|
|
44
|
+
|
|
45
|
+
# Default any typeless param tag to 'Any'
|
|
46
|
+
object.tags(:param).each do |tag|
|
|
47
|
+
tag.types = ['Any'] unless tag.types && !tag.types.empty?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Populate the parameters and the return tag
|
|
51
|
+
object.parameters = object.tags(:param).map{ |p| [p.name, nil] }
|
|
52
|
+
add_return_tag(object, statement.file, statement.line)
|
|
53
|
+
else
|
|
54
|
+
# For 4x, auto generate tags based on dispatch docstrings
|
|
55
|
+
add_tags(object)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Mark the function as public if it doesn't already have an api tag
|
|
59
|
+
object.add_tag YARD::Tags::Tag.new(:api, 'public') unless object.has_tag? :api
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
def get_name
|
|
64
|
+
parameters = statement.parameters(false)
|
|
65
|
+
raise YARD::Parser::UndocumentableError, "Expected at least one parameter to Puppet::Functions.create_function at #{statement.file}:#{statement.line}." if parameters.empty?
|
|
66
|
+
name = node_as_string(parameters.first)
|
|
67
|
+
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
|
|
68
|
+
name
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def add_tags(object)
|
|
72
|
+
log.warn "Missing documentation for Puppet function '#{object.name}' at #{statement.file}:#{statement.line}." if object.docstring.empty?
|
|
73
|
+
log.warn "The docstring for Puppet 4.x function '#{object.name}' contains @param tags near #{object.file}:#{object.line}: parameter documentation should be made on the dispatch call." unless object.tags(:param).empty?
|
|
74
|
+
log.warn "The docstring for Puppet 4.x function '#{object.name}' contains @return tags near #{object.file}:#{object.line}: return value documentation should be made on the dispatch call." unless object.tags(:return).empty?
|
|
75
|
+
log.warn "The docstring for Puppet 4.x function '#{object.name}' contains @overload tags near #{object.file}:#{object.line}: overload tags are automatically generated from the dispatch calls." unless object.tags(:overload).empty?
|
|
76
|
+
|
|
77
|
+
# Delete any existing param/return/overload tags
|
|
78
|
+
object.docstring.delete_tags(:param)
|
|
79
|
+
object.docstring.delete_tags(:return)
|
|
80
|
+
object.docstring.delete_tags(:overload)
|
|
81
|
+
|
|
82
|
+
block = statement.block
|
|
83
|
+
return unless block && block.count >= 2
|
|
84
|
+
|
|
85
|
+
# Get the unqualified name of the Puppet function
|
|
86
|
+
unqualified_name = object.name.to_s.split('::').last
|
|
87
|
+
|
|
88
|
+
# Walk the block statements looking for dispatch calls and methods with the same name as the Puppet function
|
|
89
|
+
default = nil
|
|
90
|
+
block[1].children.each do |node|
|
|
91
|
+
if node.is_a?(YARD::Parser::Ruby::MethodCallNode)
|
|
92
|
+
add_overload_tag(object, node)
|
|
93
|
+
elsif node.is_a?(YARD::Parser::Ruby::MethodDefinitionNode)
|
|
94
|
+
default = node if node.method_name && node.method_name.source == unqualified_name
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Create an overload for the default method if there is one
|
|
99
|
+
overloads = object.tags(:overload)
|
|
100
|
+
if overloads.empty? && default
|
|
101
|
+
add_method_overload(object, default)
|
|
102
|
+
overloads = object.tags(:overload)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# If there's only one overload, move the tags to the object itself
|
|
106
|
+
if overloads.count == 1
|
|
107
|
+
overload = overloads.first
|
|
108
|
+
object.parameters = overload.parameters
|
|
109
|
+
object.add_tag(*overload.tags)
|
|
110
|
+
object.docstring.delete_tags(:overload)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def add_overload_tag(object, node)
|
|
115
|
+
# Look for a call to a dispatch method with a block
|
|
116
|
+
return unless node.is_a?(YARD::Parser::Ruby::MethodCallNode) &&
|
|
117
|
+
node.method_name &&
|
|
118
|
+
node.method_name.source == 'dispatch' &&
|
|
119
|
+
node.parameters(false).count == 1 &&
|
|
120
|
+
node.block &&
|
|
121
|
+
node.block.count >= 2
|
|
122
|
+
|
|
123
|
+
overload_tag = PuppetStrings::Yard::Tags::OverloadTag.new(object.name, node.docstring || '')
|
|
124
|
+
param_tags = overload_tag.tags(:param)
|
|
125
|
+
|
|
126
|
+
block = nil
|
|
127
|
+
node.block[1].children.each do |child|
|
|
128
|
+
next unless child.is_a?(YARD::Parser::Ruby::MethodCallNode) && child.method_name
|
|
129
|
+
|
|
130
|
+
method_name = child.method_name.source
|
|
131
|
+
next unless DISPATCH_METHOD_NAMES.include?(method_name)
|
|
132
|
+
|
|
133
|
+
# Check for block
|
|
134
|
+
if method_name.include?('block')
|
|
135
|
+
if block
|
|
136
|
+
log.warn "A duplicate block parameter was found for Puppet function '#{object.name}' at #{child.file}:#{child.line}."
|
|
137
|
+
next
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Store the block; needs to be appended last
|
|
141
|
+
block = child
|
|
142
|
+
next
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Ensure two parameters to parameter definition
|
|
146
|
+
parameters = child.parameters(false)
|
|
147
|
+
unless parameters.count == 2
|
|
148
|
+
log.warn "Expected 2 arguments to '#{method_name}' call at #{child.file}:#{child.line}: parameter information may not be correct."
|
|
149
|
+
next
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
add_param_tag(
|
|
153
|
+
overload_tag,
|
|
154
|
+
param_tags,
|
|
155
|
+
node_as_string(parameters[1]),
|
|
156
|
+
child.file,
|
|
157
|
+
child.line,
|
|
158
|
+
node_as_string(parameters[0]),
|
|
159
|
+
nil, # TODO: determine default from corresponding Ruby method signature?
|
|
160
|
+
method_name.include?('optional'),
|
|
161
|
+
method_name.include?('repeated')
|
|
162
|
+
)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Handle the block parameter after others so it appears last in the list
|
|
166
|
+
if block
|
|
167
|
+
parameters = block.parameters(false)
|
|
168
|
+
if parameters.empty?
|
|
169
|
+
name = 'block'
|
|
170
|
+
type = 'Callable'
|
|
171
|
+
elsif parameters.count == 1
|
|
172
|
+
name = node_as_string(parameters[0])
|
|
173
|
+
type = 'Callable'
|
|
174
|
+
elsif parameters.count == 2
|
|
175
|
+
type = node_as_string(parameters[0])
|
|
176
|
+
name = node_as_string(parameters[1])
|
|
177
|
+
else
|
|
178
|
+
log.warn "Unexpected number of arguments to block definition at #{block.file}:#{block.line}."
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
if name && type
|
|
182
|
+
add_param_tag(
|
|
183
|
+
overload_tag,
|
|
184
|
+
param_tags,
|
|
185
|
+
name,
|
|
186
|
+
block.file,
|
|
187
|
+
block.line,
|
|
188
|
+
type,
|
|
189
|
+
nil, # TODO: determine default from corresponding Ruby method signature?
|
|
190
|
+
block.method_name.source.include?('optional'),
|
|
191
|
+
false, # Not repeated
|
|
192
|
+
true # Is block
|
|
193
|
+
)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Add a return tag if missing
|
|
198
|
+
add_return_tag(overload_tag, node.file, node.line)
|
|
199
|
+
|
|
200
|
+
# Validate that tags have parameters
|
|
201
|
+
validate_overload(overload_tag, node.file, node.line)
|
|
202
|
+
|
|
203
|
+
object.add_tag overload_tag
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def add_method_overload(object, node)
|
|
207
|
+
overload_tag = PuppetStrings::Yard::Tags::OverloadTag.new(object.name, node.docstring || '')
|
|
208
|
+
param_tags = overload_tag.tags(:param)
|
|
209
|
+
|
|
210
|
+
parameters = node.parameters
|
|
211
|
+
|
|
212
|
+
# Populate the required parameters
|
|
213
|
+
params = parameters.unnamed_required_params
|
|
214
|
+
if params
|
|
215
|
+
params.each do |parameter|
|
|
216
|
+
add_param_tag(
|
|
217
|
+
overload_tag,
|
|
218
|
+
param_tags,
|
|
219
|
+
parameter.source,
|
|
220
|
+
parameter.file,
|
|
221
|
+
parameter.line
|
|
222
|
+
)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Populate the optional parameters
|
|
227
|
+
params = parameters.unnamed_optional_params
|
|
228
|
+
if params
|
|
229
|
+
params.each do |parameter|
|
|
230
|
+
add_param_tag(
|
|
231
|
+
overload_tag,
|
|
232
|
+
param_tags,
|
|
233
|
+
parameter[0].source,
|
|
234
|
+
parameter.file,
|
|
235
|
+
parameter.line,
|
|
236
|
+
nil,
|
|
237
|
+
parameter[1].source,
|
|
238
|
+
true
|
|
239
|
+
)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Populate the splat parameter
|
|
244
|
+
param = parameters.splat_param
|
|
245
|
+
if param
|
|
246
|
+
add_param_tag(
|
|
247
|
+
overload_tag,
|
|
248
|
+
param_tags,
|
|
249
|
+
param.source,
|
|
250
|
+
param.file,
|
|
251
|
+
param.line,
|
|
252
|
+
nil,
|
|
253
|
+
nil,
|
|
254
|
+
false,
|
|
255
|
+
true
|
|
256
|
+
)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Populate the block parameter
|
|
260
|
+
param = parameters.block_param
|
|
261
|
+
if param
|
|
262
|
+
add_param_tag(
|
|
263
|
+
overload_tag,
|
|
264
|
+
param_tags,
|
|
265
|
+
param.source,
|
|
266
|
+
param.file,
|
|
267
|
+
param.line,
|
|
268
|
+
nil,
|
|
269
|
+
nil,
|
|
270
|
+
false,
|
|
271
|
+
false,
|
|
272
|
+
true
|
|
273
|
+
)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# Add a return tag if missing
|
|
277
|
+
add_return_tag(overload_tag, node.file, node.line)
|
|
278
|
+
|
|
279
|
+
# Validate that tags have parameters
|
|
280
|
+
validate_overload(overload_tag, node.file, node.line)
|
|
281
|
+
|
|
282
|
+
object.add_tag overload_tag
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def add_param_tag(object, tags, name, file, line, type = nil, default = nil, optional = false, repeated = false, block = false)
|
|
286
|
+
tag = tags.find { |tag| tag.name == name } if tags
|
|
287
|
+
log.warn "Missing @param tag for parameter '#{name}' near #{file}:#{line}." unless tag || object.docstring.all.empty?
|
|
288
|
+
log.warn "The @param tag for parameter '#{name}' should not contain a type specification near #{file}:#{line}: ignoring in favor of dispatch type information." if type && tag && tag.types && !tag.types.empty?
|
|
289
|
+
|
|
290
|
+
if repeated
|
|
291
|
+
name = '*' + name
|
|
292
|
+
elsif block
|
|
293
|
+
name = '&' + name
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
unless type
|
|
297
|
+
type = tag && tag.types ? tag.type : 'Any'
|
|
298
|
+
end
|
|
299
|
+
type = optional ? "Optional[#{type}]" : type
|
|
300
|
+
|
|
301
|
+
object.parameters << [name, to_puppet_literal(default)]
|
|
302
|
+
|
|
303
|
+
if tag
|
|
304
|
+
tag.name = name
|
|
305
|
+
tag.types = [type]
|
|
306
|
+
else
|
|
307
|
+
object.add_tag YARD::Tags::Tag.new(:param, '', type, name)
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def add_return_tag(object, file, line)
|
|
312
|
+
tag = object.tag(:return)
|
|
313
|
+
if tag
|
|
314
|
+
tag.types = ['Any'] unless tag.types
|
|
315
|
+
return
|
|
316
|
+
end
|
|
317
|
+
log.warn "Missing @return tag near #{file}:#{line}."
|
|
318
|
+
object.add_tag YARD::Tags::Tag.new(:return, '', 'Any')
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def validate_overload(overload, file, line)
|
|
322
|
+
# Validate that tags have matching parameters
|
|
323
|
+
overload.tags(:param).each do |tag|
|
|
324
|
+
next if overload.parameters.find { |p| tag.name == p[0] }
|
|
325
|
+
log.warn "The @param tag for parameter '#{tag.name}' has no matching parameter at #{file}:#{line}."
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
def get_3x_docstring(name)
|
|
330
|
+
parameters = statement.parameters(false)
|
|
331
|
+
if parameters.count >= 2
|
|
332
|
+
parameters[1].each do |kvp|
|
|
333
|
+
next unless kvp.count == 2
|
|
334
|
+
next unless node_as_string(kvp[0]) == 'doc'
|
|
335
|
+
docstring = node_as_string(kvp[1])
|
|
336
|
+
|
|
337
|
+
log.error "Failed to parse docstring for 3.x Puppet function '#{name}' near #{statement.file}:#{statement.line}." and return nil unless docstring
|
|
338
|
+
return Puppet::Util::Docs.scrub(docstring)
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
# Log a warning for missing docstring
|
|
343
|
+
log.warn "Missing documentation for Puppet function '#{name}' at #{statement.file}:#{statement.line}."
|
|
344
|
+
nil
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
def to_puppet_literal(literal)
|
|
348
|
+
case literal
|
|
349
|
+
when 'nil'
|
|
350
|
+
'undef'
|
|
351
|
+
when ':default'
|
|
352
|
+
'default'
|
|
353
|
+
else
|
|
354
|
+
literal
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'puppet-strings/yard/handlers/ruby/base'
|
|
2
|
+
require 'puppet-strings/yard/code_objects'
|
|
3
|
+
require 'puppet/util/docs'
|
|
4
|
+
|
|
5
|
+
# Implements the handler for Puppet providers written in Ruby.
|
|
6
|
+
class PuppetStrings::Yard::Handlers::Ruby::ProviderHandler < PuppetStrings::Yard::Handlers::Ruby::Base
|
|
7
|
+
namespace_only
|
|
8
|
+
handles method_call(:provide)
|
|
9
|
+
|
|
10
|
+
process do
|
|
11
|
+
return unless statement.count >= 2
|
|
12
|
+
|
|
13
|
+
# Check that provide is being called on Puppet::Type.type(<name>)
|
|
14
|
+
type_call = statement[0]
|
|
15
|
+
return unless type_call.is_a?(YARD::Parser::Ruby::MethodCallNode) && type_call.count >= 3
|
|
16
|
+
return unless type_call[0].source == 'Puppet::Type'
|
|
17
|
+
return unless type_call[2].source == 'type'
|
|
18
|
+
|
|
19
|
+
# Extract the type name
|
|
20
|
+
type_call_parameters = type_call.parameters(false)
|
|
21
|
+
return unless type_call_parameters.count >= 1
|
|
22
|
+
type_name = node_as_string(type_call_parameters.first)
|
|
23
|
+
raise YARD::Parser::UndocumentableError, "Could not determine the resource type name for the provider defined at #{statement.file}:#{statement.line}." unless type_name
|
|
24
|
+
|
|
25
|
+
# Register the object
|
|
26
|
+
object = PuppetStrings::Yard::CodeObjects::Provider.new(type_name, get_name)
|
|
27
|
+
register object
|
|
28
|
+
|
|
29
|
+
# Extract the docstring
|
|
30
|
+
register_provider_docstring object
|
|
31
|
+
|
|
32
|
+
# Populate the provider data
|
|
33
|
+
populate_provider_data object
|
|
34
|
+
|
|
35
|
+
# Mark the provider as public if it doesn't already have an api tag
|
|
36
|
+
object.add_tag YARD::Tags::Tag.new(:api, 'public') unless object.has_tag? :api
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
def get_name
|
|
41
|
+
parameters = statement.parameters(false)
|
|
42
|
+
raise YARD::Parser::UndocumentableError, "Expected at least one parameter to 'provide' at #{statement.file}:#{statement.line}." if parameters.empty?
|
|
43
|
+
name = node_as_string(parameters.first)
|
|
44
|
+
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
|
|
45
|
+
name
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def register_provider_docstring(object)
|
|
49
|
+
# Walk the tree searching for assignments or calls to desc/doc=
|
|
50
|
+
statement.traverse do |child|
|
|
51
|
+
if child.type == :assign
|
|
52
|
+
ivar = child.jump(:ivar)
|
|
53
|
+
next unless ivar != child && ivar.source == '@doc'
|
|
54
|
+
docstring = node_as_string(child[1])
|
|
55
|
+
log.error "Failed to parse docstring for Puppet provider '#{object.name}' (resource type '#{object.type_name}') near #{child.file}:#{child.line}." and return nil unless docstring
|
|
56
|
+
register_docstring(object, Puppet::Util::Docs.scrub(docstring), nil)
|
|
57
|
+
return nil
|
|
58
|
+
elsif child.is_a?(YARD::Parser::Ruby::MethodCallNode)
|
|
59
|
+
# Look for a call to a dispatch method with a block
|
|
60
|
+
next unless
|
|
61
|
+
child.method_name &&
|
|
62
|
+
(child.method_name.source == 'desc' || child.method_name.source == 'doc=') &&
|
|
63
|
+
child.parameters(false).count == 1
|
|
64
|
+
|
|
65
|
+
docstring = node_as_string(child.parameters[0])
|
|
66
|
+
log.error "Failed to parse docstring for Puppet provider '#{object.name}' (resource type '#{object.type_name}') near #{child.file}:#{child.line}." and return nil unless docstring
|
|
67
|
+
register_docstring(object, Puppet::Util::Docs.scrub(docstring), nil)
|
|
68
|
+
return nil
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
log.warn "Missing a description for Puppet provider '#{object.name}' (resource type '#{object.type_name}') at #{statement.file}:#{statement.line}."
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def populate_provider_data(object)
|
|
75
|
+
# Traverse the block looking for confines/defaults/commands
|
|
76
|
+
block = statement.block
|
|
77
|
+
return unless block && block.count >= 2
|
|
78
|
+
block[1].children.each do |node|
|
|
79
|
+
next unless node.is_a?(YARD::Parser::Ruby::MethodCallNode) && node.method_name
|
|
80
|
+
|
|
81
|
+
method_name = node.method_name.source
|
|
82
|
+
parameters = node.parameters(false)
|
|
83
|
+
|
|
84
|
+
if method_name == 'confine'
|
|
85
|
+
# Add a confine to the object
|
|
86
|
+
next unless parameters.count >= 1
|
|
87
|
+
parameters[0].each do |kvp|
|
|
88
|
+
next unless kvp.count == 2
|
|
89
|
+
object.add_confine(node_as_string(kvp[0]) || kvp[0].source, node_as_string(kvp[1]) || kvp[1].source)
|
|
90
|
+
end
|
|
91
|
+
elsif method_name == 'has_feature' || method_name == 'has_features'
|
|
92
|
+
# Add the features to the object
|
|
93
|
+
parameters.each do |parameter|
|
|
94
|
+
object.add_feature(node_as_string(parameter) || parameter.source)
|
|
95
|
+
end
|
|
96
|
+
elsif method_name == 'defaultfor'
|
|
97
|
+
# Add a default to the object
|
|
98
|
+
next unless parameters.count >= 1
|
|
99
|
+
parameters[0].each do |kvp|
|
|
100
|
+
next unless kvp.count == 2
|
|
101
|
+
object.add_default(node_as_string(kvp[0]) || kvp[0].source, node_as_string(kvp[1]) || kvp[1].source)
|
|
102
|
+
end
|
|
103
|
+
elsif method_name == 'commands'
|
|
104
|
+
# Add the commands to the object
|
|
105
|
+
next unless parameters.count >= 1
|
|
106
|
+
parameters[0].each do |kvp|
|
|
107
|
+
next unless kvp.count == 2
|
|
108
|
+
object.add_command(node_as_string(kvp[0]) || kvp[0].source, node_as_string(kvp[1]) || kvp[1].source)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|