puppet-strings 0.4.0 → 0.99.0

Sign up to get free protection for your applications and to get access to all the features.
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