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.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +122 -0
  3. data/COMMITTERS.md +185 -0
  4. data/CONTRIBUTING.md +89 -0
  5. data/Gemfile +38 -0
  6. data/JSON.md +511 -0
  7. data/LICENSE +13 -0
  8. data/README.md +416 -0
  9. data/Rakefile +49 -0
  10. data/lib/puppet-strings.rb +63 -0
  11. data/lib/puppet-strings/json.rb +49 -0
  12. data/lib/puppet-strings/tasks.rb +10 -0
  13. data/lib/puppet-strings/tasks/generate.rb +23 -0
  14. data/lib/puppet-strings/tasks/gh_pages.rb +43 -0
  15. data/lib/puppet-strings/yard.rb +96 -0
  16. data/lib/puppet-strings/yard/code_objects.rb +8 -0
  17. data/lib/puppet-strings/yard/code_objects/base.rb +14 -0
  18. data/lib/puppet-strings/yard/code_objects/class.rb +59 -0
  19. data/lib/puppet-strings/yard/code_objects/defined_type.rb +58 -0
  20. data/lib/puppet-strings/yard/code_objects/function.rb +93 -0
  21. data/lib/puppet-strings/yard/code_objects/group.rb +30 -0
  22. data/lib/puppet-strings/yard/code_objects/provider.rb +93 -0
  23. data/lib/puppet-strings/yard/code_objects/type.rb +146 -0
  24. data/lib/puppet-strings/yard/handlers.rb +16 -0
  25. data/lib/puppet-strings/yard/handlers/puppet/base.rb +44 -0
  26. data/lib/puppet-strings/yard/handlers/puppet/class_handler.rb +23 -0
  27. data/lib/puppet-strings/yard/handlers/puppet/defined_type_handler.rb +23 -0
  28. data/lib/puppet-strings/yard/handlers/puppet/function_handler.rb +42 -0
  29. data/lib/puppet-strings/yard/handlers/ruby/base.rb +38 -0
  30. data/lib/puppet-strings/yard/handlers/ruby/function_handler.rb +357 -0
  31. data/lib/puppet-strings/yard/handlers/ruby/provider_handler.rb +113 -0
  32. data/lib/puppet-strings/yard/handlers/ruby/type_handler.rb +194 -0
  33. data/lib/puppet-strings/yard/parsers.rb +7 -0
  34. data/lib/puppet-strings/yard/parsers/puppet/parser.rb +70 -0
  35. data/lib/puppet-strings/yard/parsers/puppet/statement.rb +146 -0
  36. data/lib/puppet-strings/yard/tags.rb +6 -0
  37. data/lib/puppet-strings/yard/tags/overload_tag.rb +109 -0
  38. data/lib/puppet-strings/yard/tags/parameter_directive.rb +24 -0
  39. data/lib/puppet-strings/yard/tags/property_directive.rb +24 -0
  40. data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_class.erb +9 -0
  41. data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_defined_type.erb +9 -0
  42. data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_function.erb +10 -0
  43. data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_provider.erb +10 -0
  44. data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_type.erb +9 -0
  45. data/lib/puppet-strings/yard/templates/default/fulldoc/html/setup.rb +64 -0
  46. data/lib/puppet-strings/yard/templates/default/layout/html/objects.erb +35 -0
  47. data/lib/puppet-strings/yard/templates/default/layout/html/setup.rb +172 -0
  48. data/lib/puppet-strings/yard/templates/default/puppet_class/html/box_info.erb +26 -0
  49. data/lib/puppet-strings/yard/templates/default/puppet_class/html/header.erb +1 -0
  50. data/lib/puppet-strings/yard/templates/default/puppet_class/html/overview.erb +6 -0
  51. data/lib/puppet-strings/yard/templates/default/puppet_class/html/setup.rb +14 -0
  52. data/lib/puppet-strings/yard/templates/default/puppet_class/html/source.erb +12 -0
  53. data/lib/puppet-strings/yard/templates/default/puppet_defined_type/html/box_info.erb +10 -0
  54. data/lib/puppet-strings/yard/templates/default/puppet_defined_type/html/header.erb +1 -0
  55. data/lib/puppet-strings/yard/templates/default/puppet_defined_type/html/overview.erb +6 -0
  56. data/lib/puppet-strings/yard/templates/default/puppet_defined_type/html/setup.rb +5 -0
  57. data/lib/puppet-strings/yard/templates/default/puppet_defined_type/html/source.erb +12 -0
  58. data/lib/puppet-strings/yard/templates/default/puppet_function/html/box_info.erb +14 -0
  59. data/lib/puppet-strings/yard/templates/default/puppet_function/html/header.erb +1 -0
  60. data/lib/puppet-strings/yard/templates/default/puppet_function/html/overview.erb +18 -0
  61. data/lib/puppet-strings/yard/templates/default/puppet_function/html/setup.rb +5 -0
  62. data/lib/puppet-strings/yard/templates/default/puppet_function/html/source.erb +12 -0
  63. data/lib/puppet-strings/yard/templates/default/puppet_provider/html/box_info.erb +14 -0
  64. data/lib/puppet-strings/yard/templates/default/puppet_provider/html/collection.erb +10 -0
  65. data/lib/puppet-strings/yard/templates/default/puppet_provider/html/features.erb +12 -0
  66. data/lib/puppet-strings/yard/templates/default/puppet_provider/html/header.erb +1 -0
  67. data/lib/puppet-strings/yard/templates/default/puppet_provider/html/overview.erb +6 -0
  68. data/lib/puppet-strings/yard/templates/default/puppet_provider/html/setup.rb +29 -0
  69. data/lib/puppet-strings/yard/templates/default/puppet_type/html/box_info.erb +20 -0
  70. data/lib/puppet-strings/yard/templates/default/puppet_type/html/features.erb +13 -0
  71. data/lib/puppet-strings/yard/templates/default/puppet_type/html/header.erb +1 -0
  72. data/lib/puppet-strings/yard/templates/default/puppet_type/html/overview.erb +6 -0
  73. data/lib/puppet-strings/yard/templates/default/puppet_type/html/parameters.erb +35 -0
  74. data/lib/puppet-strings/yard/templates/default/puppet_type/html/setup.rb +32 -0
  75. data/lib/puppet-strings/yard/templates/default/tags/html/puppet_overload.erb +12 -0
  76. data/lib/puppet-strings/yard/templates/default/tags/setup.rb +15 -0
  77. data/lib/puppet/application/strings.rb +1 -0
  78. data/lib/puppet/face/strings.rb +80 -39
  79. data/spec/acceptance/emit_json_options.rb +41 -0
  80. data/spec/acceptance/lib/util.rb +15 -0
  81. data/spec/acceptance/running_strings_generate.rb +54 -0
  82. data/spec/fixtures/acceptance/modules/test/functions/add.pp +9 -0
  83. data/spec/fixtures/acceptance/modules/test/lib/puppet/functions/4x_function.rb +5 -0
  84. data/spec/fixtures/acceptance/modules/test/lib/puppet/parser/functions/function3x.rb +2 -0
  85. data/spec/fixtures/acceptance/modules/test/lib/puppet/provider/server/linux.rb +9 -0
  86. data/spec/fixtures/acceptance/modules/test/lib/puppet/type/database.rb +15 -0
  87. data/spec/fixtures/acceptance/modules/test/manifests/init.pp +27 -0
  88. data/spec/fixtures/acceptance/modules/test/manifests/triple_nested_classes.pp +27 -0
  89. data/spec/fixtures/acceptance/modules/test/metadata.json +6 -0
  90. data/spec/fixtures/unit/json/output.json +348 -0
  91. data/spec/fixtures/unit/json/output_without_puppet_function.json +301 -0
  92. data/spec/spec_helper.rb +21 -0
  93. data/spec/spec_helper_acceptance.rb +27 -0
  94. data/spec/unit/puppet-strings/json_spec.rb +136 -0
  95. data/spec/unit/puppet-strings/yard/handlers/puppet/class_handler_spec.rb +155 -0
  96. data/spec/unit/puppet-strings/yard/handlers/puppet/defined_type_handler_spec.rb +155 -0
  97. data/spec/unit/puppet-strings/yard/handlers/puppet/function_handler_spec.rb +169 -0
  98. data/spec/unit/puppet-strings/yard/handlers/ruby/function_handler_spec.rb +613 -0
  99. data/spec/unit/puppet-strings/yard/handlers/ruby/provider_handler_spec.rb +90 -0
  100. data/spec/unit/puppet-strings/yard/handlers/ruby/type_handler_spec.rb +214 -0
  101. data/spec/unit/puppet-strings/yard/parsers/puppet/parser_spec.rb +171 -0
  102. metadata +115 -92
  103. data/lib/puppet-strings/rake_tasks.rb +0 -18
  104. data/lib/puppet_x/puppetlabs/strings.rb +0 -64
  105. data/lib/puppet_x/puppetlabs/strings/actions.rb +0 -92
  106. data/lib/puppet_x/puppetlabs/strings/pops/yard_statement.rb +0 -79
  107. data/lib/puppet_x/puppetlabs/strings/pops/yard_transformer.rb +0 -47
  108. data/lib/puppet_x/puppetlabs/strings/util.rb +0 -65
  109. data/lib/puppet_x/puppetlabs/strings/yard/code_objects/defined_type_object.rb +0 -33
  110. data/lib/puppet_x/puppetlabs/strings/yard/code_objects/host_class_object.rb +0 -22
  111. data/lib/puppet_x/puppetlabs/strings/yard/code_objects/method_object.rb +0 -62
  112. data/lib/puppet_x/puppetlabs/strings/yard/code_objects/provider_object.rb +0 -24
  113. data/lib/puppet_x/puppetlabs/strings/yard/code_objects/puppet_namespace_object.rb +0 -48
  114. data/lib/puppet_x/puppetlabs/strings/yard/code_objects/type_object.rb +0 -42
  115. data/lib/puppet_x/puppetlabs/strings/yard/core_ext/yard.rb +0 -40
  116. data/lib/puppet_x/puppetlabs/strings/yard/handlers/base.rb +0 -13
  117. data/lib/puppet_x/puppetlabs/strings/yard/handlers/defined_type_handler.rb +0 -31
  118. data/lib/puppet_x/puppetlabs/strings/yard/handlers/heredoc_helper.rb +0 -80
  119. data/lib/puppet_x/puppetlabs/strings/yard/handlers/host_class_handler.rb +0 -42
  120. data/lib/puppet_x/puppetlabs/strings/yard/handlers/provider_handler.rb +0 -95
  121. data/lib/puppet_x/puppetlabs/strings/yard/handlers/puppet_3x_function_handler.rb +0 -54
  122. data/lib/puppet_x/puppetlabs/strings/yard/handlers/puppet_4x_function_handler.rb +0 -234
  123. data/lib/puppet_x/puppetlabs/strings/yard/handlers/type_handler.rb +0 -295
  124. data/lib/puppet_x/puppetlabs/strings/yard/json_registry_store.rb +0 -85
  125. data/lib/puppet_x/puppetlabs/strings/yard/monkey_patches.rb +0 -68
  126. data/lib/puppet_x/puppetlabs/strings/yard/parser.rb +0 -30
  127. data/lib/puppet_x/puppetlabs/strings/yard/tags/directives.rb +0 -9
  128. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/definedtype/html/docstring.erb +0 -34
  129. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/definedtype/html/header.erb +0 -5
  130. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/definedtype/html/parameter_details.erb +0 -6
  131. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/definedtype/html/setup.rb +0 -1
  132. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/definedtype/setup.rb +0 -49
  133. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/full_list_class.erb +0 -2
  134. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/full_list_puppet_manifest.erb +0 -1
  135. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/full_list_puppet_plugin.erb +0 -21
  136. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/full_list_puppet_provider.erb +0 -1
  137. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/full_list_puppet_type.erb +0 -1
  138. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/fulldoc/html/setup.rb +0 -82
  139. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/hostclass/html/box_info.erb +0 -22
  140. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/hostclass/html/setup.rb +0 -1
  141. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/hostclass/html/subclasses.erb +0 -4
  142. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/hostclass/setup.rb +0 -21
  143. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/html_helper.rb +0 -139
  144. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/layout/html/setup.rb +0 -18
  145. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/method_details/html/header.erb +0 -17
  146. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/method_details/setup.rb +0 -21
  147. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/method_details/text/header.erb +0 -2
  148. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/command_details.erb +0 -8
  149. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/confine_details.erb +0 -10
  150. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/default_details.erb +0 -10
  151. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/docstring.erb +0 -34
  152. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/feature_details.erb +0 -10
  153. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/header.erb +0 -5
  154. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/html/setup.rb +0 -1
  155. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/provider/setup.rb +0 -50
  156. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/html/box_info.erb +0 -11
  157. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/html/header.erb +0 -5
  158. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/html/method_details_list.erb +0 -53
  159. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/html/method_summary.erb +0 -20
  160. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/html/setup.rb +0 -1
  161. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/puppetnamespace/setup.rb +0 -91
  162. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/template_helper.rb +0 -192
  163. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/html/docstring.erb +0 -34
  164. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/html/header.erb +0 -5
  165. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/html/parameter_details.erb +0 -12
  166. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/html/provider_details.erb +0 -10
  167. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/html/setup.rb +0 -1
  168. data/lib/puppet_x/puppetlabs/strings/yard/templates/default/type/setup.rb +0 -55
@@ -0,0 +1,194 @@
1
+ require 'puppet-strings/yard/handlers/ruby/base'
2
+ require 'puppet-strings/yard/code_objects'
3
+ require 'puppet/util'
4
+
5
+ # Implements the handler for Puppet resource types written in Ruby.
6
+ class PuppetStrings::Yard::Handlers::Ruby::TypeHandler < PuppetStrings::Yard::Handlers::Ruby::Base
7
+ # The default docstring when ensurable is used without given a docstring.
8
+ DEFAULT_ENSURABLE_DOCSTRING = 'The basic property that the resource should be in.'.freeze
9
+
10
+ namespace_only
11
+ handles method_call(:newtype)
12
+
13
+ process do
14
+ # Only accept calls to Puppet::Type
15
+ return unless statement.count > 1
16
+ module_name = statement[0].source
17
+ return unless module_name == 'Puppet::Type' || module_name == 'Type'
18
+
19
+ object = PuppetStrings::Yard::CodeObjects::Type.new(get_name)
20
+ register object
21
+
22
+ docstring = find_docstring(statement, "Puppet resource type '#{object.name}'")
23
+ register_docstring(object, docstring, nil) if docstring
24
+
25
+ # Populate the parameters/properties/features to the type
26
+ populate_type_data(object)
27
+
28
+ # Set the default namevar
29
+ set_default_namevar(object)
30
+
31
+ # Mark the type as public if it doesn't already have an api tag
32
+ object.add_tag YARD::Tags::Tag.new(:api, 'public') unless object.has_tag? :api
33
+ end
34
+
35
+ private
36
+ def get_name
37
+ parameters = statement.parameters(false)
38
+ raise YARD::Parser::UndocumentableError, "Expected at least one parameter to Puppet::Type.newtype at #{statement.file}:#{statement.line}." if parameters.empty?
39
+ name = node_as_string(parameters.first)
40
+ 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
41
+ name
42
+ end
43
+
44
+ def find_docstring(node, kind)
45
+ # Walk the tree searching for assignments or calls to desc/doc=
46
+ node.traverse do |child|
47
+ if child.type == :assign
48
+ ivar = child.jump(:ivar)
49
+ next unless ivar != child && ivar.source == '@doc'
50
+ docstring = node_as_string(child[1])
51
+ log.error "Failed to parse docstring for #{kind} near #{child.file}:#{child.line}." and return nil unless docstring
52
+ return Puppet::Util::Docs.scrub(docstring)
53
+ elsif child.is_a?(YARD::Parser::Ruby::MethodCallNode)
54
+ # Look for a call to a dispatch method with a block
55
+ next unless child.method_name &&
56
+ (child.method_name.source == 'desc' || child.method_name.source == 'doc=') &&
57
+ child.parameters(false).count == 1
58
+
59
+ docstring = node_as_string(child.parameters[0])
60
+ log.error "Failed to parse docstring for #{kind} near #{child.file}:#{child.line}." and return nil unless docstring
61
+ return Puppet::Util::Docs.scrub(docstring)
62
+ end
63
+ end
64
+ log.warn "Missing a description for #{kind} at #{node.file}:#{node.line}."
65
+ nil
66
+ end
67
+
68
+ def populate_type_data(object)
69
+ # Traverse the block looking for properties/parameters/features
70
+ block = statement.block
71
+ return unless block && block.count >= 2
72
+ block[1].children.each do |node|
73
+ next unless node.is_a?(YARD::Parser::Ruby::MethodCallNode) &&
74
+ node.method_name
75
+
76
+ method_name = node.method_name.source
77
+ parameters = node.parameters(false)
78
+
79
+ if method_name == 'newproperty'
80
+ # Add a property to the object
81
+ next unless parameters.count >= 1
82
+ name = node_as_string(parameters[0])
83
+ next unless name
84
+ object.add_property(create_property(name, node))
85
+ elsif method_name == 'newparam'
86
+ # Add a parameter to the object
87
+ next unless parameters.count >= 1
88
+ name = node_as_string(parameters[0])
89
+ next unless name
90
+ object.add_parameter(create_parameter(name, node))
91
+ elsif method_name == 'feature'
92
+ # Add a feature to the object
93
+ next unless parameters.count >= 2
94
+ name = node_as_string(parameters[0])
95
+ next unless name
96
+
97
+ docstring = node_as_string(parameters[1])
98
+ next unless docstring
99
+
100
+ object.add_feature(PuppetStrings::Yard::CodeObjects::Type::Feature.new(name, docstring))
101
+ elsif method_name == 'ensurable'
102
+ if node.block
103
+ property = create_property('ensure', node)
104
+ property.docstring = DEFAULT_ENSURABLE_DOCSTRING if property.docstring.empty?
105
+ else
106
+ property = PuppetStrings::Yard::CodeObjects::Type::Property.new('ensure', DEFAULT_ENSURABLE_DOCSTRING)
107
+ property.add('present')
108
+ property.add('absent')
109
+ property.default = 'present'
110
+ end
111
+ object.add_property property
112
+ end
113
+ end
114
+ end
115
+
116
+ def create_parameter(name, node)
117
+ parameter = PuppetStrings::Yard::CodeObjects::Type::Parameter.new(name, find_docstring(node, "Puppet resource parameter '#{name}'"))
118
+ set_values(node, parameter)
119
+ parameter
120
+ end
121
+
122
+ def create_property(name, node)
123
+ property = PuppetStrings::Yard::CodeObjects::Type::Property.new(name, find_docstring(node, "Puppet resource property '#{name}'"))
124
+ set_values(node, property)
125
+ property
126
+ end
127
+
128
+ def set_values(node, object)
129
+ return unless node.block && node.block.count >= 2
130
+
131
+ node.block[1].children.each do |child|
132
+ next unless child.is_a?(YARD::Parser::Ruby::MethodCallNode) && child.method_name
133
+
134
+ method_name = child.method_name.source
135
+ parameters = child.parameters(false)
136
+
137
+ if method_name == 'newvalue'
138
+ next unless parameters.count >= 1
139
+ object.add(node_as_string(parameters[0]) || parameters[0].source)
140
+ elsif method_name == 'newvalues'
141
+ parameters.each do |p|
142
+ object.add(node_as_string(p) || p.source)
143
+ end
144
+ elsif method_name == 'aliasvalue'
145
+ next unless parameters.count >= 2
146
+ object.alias(node_as_string(parameters[0]) || parameters[0].source, node_as_string(parameters[1]) || parameters[1].source)
147
+ elsif method_name == 'defaultto'
148
+ next unless parameters.count >= 1
149
+ object.default = node_as_string(parameters[0]) || parameters[0].source
150
+ elsif method_name == 'isnamevar'
151
+ object.isnamevar = true
152
+ elsif method_name == 'defaultvalues' && object.name == 'ensure'
153
+ object.add('present')
154
+ object.add('absent')
155
+ object.default = 'present'
156
+ end
157
+ end
158
+ if object.is_a? PuppetStrings::Yard::CodeObjects::Type::Parameter
159
+ # Process the options for parameter base types
160
+ parameters = node.parameters(false)
161
+ if parameters.count >= 2
162
+ parameters[1].each do |kvp|
163
+ next unless kvp.count == 2
164
+ next unless node_as_string(kvp[0]) == 'parent'
165
+ if kvp[1].source == 'Puppet::Parameter::Boolean'
166
+ object.add('true') unless object.values.include? 'true'
167
+ object.add('false') unless object.values.include? 'false'
168
+ object.add('yes') unless object.values.include? 'yes'
169
+ object.add('no') unless object.values.include? 'no'
170
+ end
171
+ break
172
+ end
173
+ end
174
+ end
175
+ end
176
+
177
+ def set_default_namevar(object)
178
+ return unless object.properties || object.parameters
179
+ default = nil
180
+ if object.properties
181
+ object.properties.each do |property|
182
+ return nil if property.isnamevar
183
+ default = property if property.name == 'name'
184
+ end
185
+ end
186
+ if object.parameters
187
+ object.parameters.each do |parameter|
188
+ return nil if parameter.isnamevar
189
+ default ||= parameter if parameter.name == 'name'
190
+ end
191
+ end
192
+ default.isnamevar = true if default
193
+ end
194
+ end
@@ -0,0 +1,7 @@
1
+ # The module for custom YARD parsers.
2
+ module PuppetStrings::Yard::Parsers
3
+ # The module for custom YARD parsers for the Puppet language.
4
+ module Puppet
5
+ require 'puppet-strings/yard/parsers/puppet/parser'
6
+ end
7
+ end
@@ -0,0 +1,70 @@
1
+ require 'puppet'
2
+ require 'puppet/pops'
3
+ require 'puppet-strings/yard/parsers/puppet/statement'
4
+
5
+ # Implements the Puppet language parser.
6
+ class PuppetStrings::Yard::Parsers::Puppet::Parser < YARD::Parser::Base
7
+ attr_reader :file, :source
8
+
9
+ # Initializes the parser.
10
+ # @param [String] source The source being parsed.
11
+ # @param [String] filename The file name of the file being parsed.
12
+ # @return [void]
13
+ def initialize(source, filename)
14
+ @source = source
15
+ @file = filename
16
+ @visitor = ::Puppet::Pops::Visitor.new(self, 'transform')
17
+ end
18
+
19
+ # Parses the source.
20
+ # @return [void]
21
+ def parse
22
+ begin
23
+ @statements ||= (@visitor.visit(::Puppet::Pops::Parser::Parser.new.parse_string(source)) || []).compact
24
+ rescue ::Puppet::ParseError => ex
25
+ log.error "Failed to parse #{@file}: #{ex.message}"
26
+ @statements = []
27
+ end
28
+ @statements.freeze
29
+ self
30
+ end
31
+
32
+ # Gets an enumerator for the statements that were parsed.
33
+ # @return Returns an enumerator for the statements that were parsed.
34
+ def enumerator
35
+ @statements
36
+ end
37
+
38
+ private
39
+ def transform_Program(o)
40
+ # Cache the lines of the source text; we'll use this to locate comments
41
+ @lines = o.source_text.lines.to_a
42
+ o.definitions.map { |d| @visitor.visit(d) }
43
+ end
44
+
45
+ def transform_Factory(o)
46
+ @visitor.visit(o.current)
47
+ end
48
+
49
+ def transform_HostClassDefinition(o)
50
+ statement = PuppetStrings::Yard::Parsers::Puppet::ClassStatement.new(o, @file)
51
+ statement.extract_docstring(@lines)
52
+ statement
53
+ end
54
+
55
+ def transform_ResourceTypeDefinition(o)
56
+ statement = PuppetStrings::Yard::Parsers::Puppet::DefinedTypeStatement.new(o, @file)
57
+ statement.extract_docstring(@lines)
58
+ statement
59
+ end
60
+
61
+ def transform_FunctionDefinition(o)
62
+ statement = PuppetStrings::Yard::Parsers::Puppet::FunctionStatement.new(o, @file)
63
+ statement.extract_docstring(@lines)
64
+ statement
65
+ end
66
+
67
+ def transform_Object(o)
68
+ # Ignore anything else (will be compacted out of the resulting array)
69
+ end
70
+ end
@@ -0,0 +1,146 @@
1
+ require 'puppet'
2
+ require 'puppet/pops'
3
+
4
+ module PuppetStrings::Yard::Parsers::Puppet
5
+ # Represents the base Puppet language statement.
6
+ class Statement
7
+ # The pattern for parsing docstring comments.
8
+ COMMENT_REGEX = /^\s*#+\s?/
9
+
10
+ attr_reader :source
11
+ attr_reader :file
12
+ attr_reader :line
13
+ attr_reader :docstring
14
+ attr_reader :comments_range
15
+
16
+ # Initializes the Puppet language statement.
17
+ # @param object The Puppet parser model object for the statement.
18
+ # @param [String] file The file name of the file containing the statement.
19
+ def initialize(object, file)
20
+ @file = file
21
+
22
+ adapter = ::Puppet::Pops::Adapters::SourcePosAdapter.adapt(object)
23
+ @source = adapter.extract_text
24
+ @line = adapter.line
25
+ @comments_range = nil
26
+ end
27
+
28
+ # Extracts the docstring for the statement given the source lines.
29
+ # @param [Array<String>] lines The source lines for the file containing the statement.
30
+ # @return [void]
31
+ def extract_docstring(lines)
32
+ comment = []
33
+ (0..@line-2).reverse_each do |index|
34
+ break unless index <= lines.count
35
+ line = lines[index].strip
36
+ count = line.size
37
+ line.gsub!(COMMENT_REGEX, '')
38
+ # Break out if nothing was removed (wasn't a comment line)
39
+ break unless line.size < count
40
+ comment << line
41
+ end
42
+ @comments_range = (@line - comment.size - 1..@line - 1)
43
+ @docstring = YARD::Docstring.new(comment.reverse.join("\n"))
44
+ end
45
+
46
+ # Shows the first line context for the statement.
47
+ # @return [String] Returns the first line context for the statement.
48
+ def show
49
+ "\t#{@line}: #{first_line}"
50
+ end
51
+
52
+ # Gets the full comments of the statement.
53
+ # @return [String] Returns the full comments of the statement.
54
+ def comments
55
+ @docstring.all
56
+ end
57
+
58
+ # Determines if the comments have hash flag.
59
+ # @return [Boolean] Returns true if the comments have a hash flag or false if not.
60
+ def comments_hash_flag
61
+ false
62
+ end
63
+
64
+ private
65
+ def first_line
66
+ @source.split(/\r?\n/).first.strip
67
+ end
68
+ end
69
+
70
+ # Implements a parameterized statement (a statement that takes parameters).
71
+ class ParameterizedStatement < Statement
72
+ # Implements a parameter for a parameterized statement.
73
+ class Parameter
74
+ attr_reader :name
75
+ attr_reader :type
76
+ attr_reader :value
77
+
78
+ # Initializes the parameter.
79
+ # @param [Puppet::Pops::Model::Parameter] parameter The parameter model object.
80
+ def initialize(parameter)
81
+ @name = parameter.name
82
+ # Take the exact text for the type expression
83
+ if parameter.type_expr
84
+ adapter = ::Puppet::Pops::Adapters::SourcePosAdapter.adapt(parameter.type_expr)
85
+ @type = adapter.extract_text
86
+ end
87
+ # Take the exact text for the default value expression
88
+ if parameter.value
89
+ adapter = ::Puppet::Pops::Adapters::SourcePosAdapter.adapt(parameter.value)
90
+ @value = adapter.extract_text
91
+ end
92
+ end
93
+ end
94
+
95
+ attr_reader :parameters
96
+
97
+ # Initializes the parameterized statement.
98
+ # @param object The Puppet parser model object that has parameters.
99
+ # @param [String] file The file containing the statement.
100
+ def initialize(object, file)
101
+ super(object, file)
102
+ @parameters = object.parameters.map { |parameter| Parameter.new(parameter) }
103
+ end
104
+ end
105
+
106
+ # Implements the Puppet class statement.
107
+ class ClassStatement < ParameterizedStatement
108
+ attr_reader :name
109
+ attr_reader :parent_class
110
+
111
+ # Initializes the Puppet class statement.
112
+ # @param [Puppet::Pops::Model::HostClassDefinition] object The model object for the class statement.
113
+ # @param [String] file The file containing the statement.
114
+ def initialize(object, file)
115
+ super(object, file)
116
+ @name = object.name
117
+ @parent_class = object.parent_class
118
+ end
119
+ end
120
+
121
+ # Implements the Puppet defined type statement.
122
+ class DefinedTypeStatement < ParameterizedStatement
123
+ attr_reader :name
124
+
125
+ # Initializes the Puppet defined type statement.
126
+ # @param [Puppet::Pops::Model::ResourceTypeDefinition] object The model object for the defined type statement.
127
+ # @param [String] file The file containing the statement.
128
+ def initialize(object, file)
129
+ super(object, file)
130
+ @name = object.name
131
+ end
132
+ end
133
+
134
+ # Implements the Puppet function statement.
135
+ class FunctionStatement < ParameterizedStatement
136
+ attr_reader :name
137
+
138
+ # Initializes the Puppet function statement.
139
+ # @param [Puppet::Pops::Model::FunctionDefinition] object The model object for the function statement.
140
+ # @param [String] file The file containing the statement.
141
+ def initialize(object, file)
142
+ super(object, file)
143
+ @name = object.name
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,6 @@
1
+ # The module for custom YARD tags.
2
+ module PuppetStrings::Yard::Tags
3
+ require 'puppet-strings/yard/tags/parameter_directive'
4
+ require 'puppet-strings/yard/tags/property_directive'
5
+ require 'puppet-strings/yard/tags/overload_tag'
6
+ end
@@ -0,0 +1,109 @@
1
+ # Implements an overload tag for Puppet functions
2
+ #
3
+ # This differs from Yard's overload tag in that the signatures are formatted according to Puppet language rules.
4
+ class PuppetStrings::Yard::Tags::OverloadTag < YARD::Tags::Tag
5
+ attr_reader :parameters, :docstring
6
+
7
+ # Initializes the overload tag.
8
+ # @param [String, Symbol] name The name of the function being overloaded.
9
+ # @param [String] docstring The docstring for the overload.
10
+ # @return [void]
11
+ def initialize(name, docstring)
12
+ super(:overload, nil)
13
+ @name = name.to_s
14
+ @parameters = []
15
+ @docstring = YARD::Docstring.new(docstring)
16
+ end
17
+
18
+ # Gets the signature of the overload.
19
+ # @return [String] Returns the signature of the overload.
20
+ def signature
21
+ tags = self.tags(:param)
22
+ args = @parameters.map do |parameter|
23
+ name, default = parameter
24
+ tag = tags.find { |tag| tag.name == name } if tags
25
+ type = tag && tag.types ? "#{tag.type} " : 'Any '
26
+ prefix = "#{name[0]}" if name.start_with?('*', '&')
27
+ name = name[1..-1] if prefix
28
+ default = " = #{default}" if default
29
+ "#{type}#{prefix}$#{name}#{default}"
30
+ end.join(', ')
31
+ @name + '(' + args + ')'
32
+ end
33
+
34
+ # Adds a tag to the overload's docstring.
35
+ # @param [YARD::Tag] tag The tag to add to the overload's docstring.
36
+ # @return [void]
37
+ def add_tag(tag)
38
+ @docstring.add_tag(tag)
39
+ end
40
+
41
+ # Gets the first tag of the given name.
42
+ # @param [String, Symbol] name The name of the tag.
43
+ # @return [YARD::Tag] Returns the first tag if found or nil if not found.
44
+ def tag(name)
45
+ @docstring.tag(name)
46
+ end
47
+
48
+ # Gets all tags or tags of a given name.
49
+ # @param [String, Symbol] name The name of the tag to get or nil for all tags.
50
+ # @return [Array<Yard::Tag>] Returns an array of tags.
51
+ def tags(name = nil)
52
+ @docstring.tags(name)
53
+ end
54
+
55
+ # Determines if a tag with the given name is present.
56
+ # @param [String, Symbol] name The tag name.
57
+ # @return [Boolean] Returns true if there is at least one tag with the given name or false if not.
58
+ def has_tag?(name)
59
+ @docstring.has_tag?(name)
60
+ end
61
+
62
+ # Sets the object associated with this tag.
63
+ # @param [Object] value The object to associate with this tag.
64
+ # @return [void]
65
+ def object=(value)
66
+ super(value)
67
+ @docstring.object = value
68
+ @docstring.tags.each {|tag| tag.object = value }
69
+ end
70
+
71
+ # Responsible for forwarding method calls to the associated object.
72
+ # @param [Symbol] method_name The method being invoked.
73
+ # @param [Array] args The args passed to the method.
74
+ # @param block The block passed to the method.
75
+ # @return Returns what the method call on the object would return.
76
+ def method_missing(method_name, *args, &block)
77
+ return object.send(method_name, *args, &block) if object.respond_to? method_name
78
+ super
79
+ end
80
+
81
+ # Determines if the associated object responds to the give missing method name.
82
+ # @param [Symbol, String] method_name The name of the method to check.
83
+ # @param [Boolean] include_all True to include all methods in the check or false for only public methods.
84
+ # @return [Boolean] Returns true if the object responds to the method or false if not.
85
+ def respond_to_missing?(method_name, include_all = false)
86
+ object.respond_to?(method_name, include_all) || super
87
+ end
88
+
89
+ # Gets the type of the object associated with this tag.
90
+ # @return [Symbol] Returns the type of the object associated with this tag.
91
+ def type
92
+ object.type
93
+ end
94
+
95
+ # Converts the overload tag to a hash representation.
96
+ # @return [Hash] Returns a hash representation of the overload.
97
+ def to_hash
98
+ hash = {}
99
+ hash[:tag_name] = tag_name
100
+ hash[:text] = text if text
101
+ hash[:signature] = signature
102
+ hash[:docstring] = PuppetStrings::Json.docstring_to_hash(docstring) if !docstring.empty?
103
+ defaults = Hash[*parameters.select{ |p| !p[1].nil? }.flatten]
104
+ hash[:defaults] = defaults unless defaults.empty?
105
+ hash[:types] = types if types
106
+ hash[:name] = name if name
107
+ hash
108
+ end
109
+ end