diff --git a/lib/puppet-strings.rb b/lib/puppet-strings.rb index f2cbdfc..410d92b 100644 --- a/lib/puppet-strings.rb +++ b/lib/puppet-strings.rb @@ -47,7 +47,8 @@ module PuppetStrings # If outputting JSON, render the output if render_as_json - # TODO: implement + require 'puppet-strings/json' + PuppetStrings::Json.render(json_file) end end diff --git a/lib/puppet-strings/json.rb b/lib/puppet-strings/json.rb new file mode 100644 index 0000000..32b8d52 --- /dev/null +++ b/lib/puppet-strings/json.rb @@ -0,0 +1,50 @@ +require 'json' + +# The module for JSON related functionality. +module PuppetStrings::Json + + # Renders the current YARD registry as JSON to the given file (or STDOUT if nil). + # @param [String] file The path to the output file to render the registry to. If nil, output will be to STDOUT. + # @return [void] + def self.render(file = nil) + document = { + puppet_classes: YARD::Registry.all(:puppet_class).sort_by! { |c| c.name }.map! { |c| c.to_hash }, + defined_types: YARD::Registry.all(:puppet_defined_type).sort_by! { |dt| dt.name }.map! { |dt| dt.to_hash }, + resource_types: YARD::Registry.all(:puppet_type).sort_by! { |t| t.name }.map! { |t| t.to_hash }, + providers: YARD::Registry.all(:puppet_provider).sort_by! { |p| p.name }.map! { |p| p.to_hash }, + puppet_functions: YARD::Registry.all(:puppet_function).sort_by! { |f| f.name }.map! { |f| f.to_hash }, + # TODO: Need Ruby documentation? + } + + if file + File.open(file, 'w') do |f| + f.write(JSON.pretty_generate(document)) + f.write("\n") + end + else + puts JSON.pretty_generate(document) + end + end + + # Converts a YARD::Docstring (or String) to a docstring hash for JSON output. + # @param [YARD::Docstring, String] docstring The docstring to convert to a hash. + # @return [Hash] Returns a hash representation of the given docstring. + def self.docstring_to_hash(docstring) + hash = {} + hash[:text] = docstring + if docstring.is_a? YARD::Docstring + # Skip over the API tags that are public + tags = docstring.tags.select { |t| t.tag_name != 'api' || t.text != 'public' }.map do |t| + next t.to_hash if t.respond_to?(:to_hash) + + tag = { tag_name: t.tag_name } + tag[:text] = t.text if t.text + tag[:types] = t.types if t.types + tag[:name] = t.name if t.name + tag + end + hash[:tags] = tags unless tags.empty? + end + hash + end +end diff --git a/lib/puppet-strings/yard/code_objects/class.rb b/lib/puppet-strings/yard/code_objects/class.rb index 71461c5..121ebd2 100644 --- a/lib/puppet-strings/yard/code_objects/class.rb +++ b/lib/puppet-strings/yard/code_objects/class.rb @@ -41,4 +41,19 @@ class PuppetStrings::Yard::CodeObjects::Class < PuppetStrings::Yard::CodeObjects def source @statement.source end + + # Converts the code object to a hash representation. + # @return [Hash] Returns a hash representation of the code object. + def to_hash + hash = {} + hash[:name] = name + hash[:file] = file + hash[:line] = line + hash[:inherits] = statement.parent_class if statement.parent_class + hash[:docstring] = PuppetStrings::Json.docstring_to_hash(docstring) + defaults = Hash[*parameters.select{ |p| !p[1].nil? }.flatten] + hash[:defaults] = defaults unless defaults.empty? + hash[:source] = source unless source && source.empty? + hash + end end diff --git a/lib/puppet-strings/yard/code_objects/defined_type.rb b/lib/puppet-strings/yard/code_objects/defined_type.rb index 12d4afb..e9088c1 100644 --- a/lib/puppet-strings/yard/code_objects/defined_type.rb +++ b/lib/puppet-strings/yard/code_objects/defined_type.rb @@ -41,4 +41,18 @@ class PuppetStrings::Yard::CodeObjects::DefinedType < PuppetStrings::Yard::CodeO def source @statement.source end + + # Converts the code object to a hash representation. + # @return [Hash] Returns a hash representation of the code object. + def to_hash + hash = {} + hash[:name] = name + hash[:file] = file + hash[:line] = line + hash[:docstring] = PuppetStrings::Json.docstring_to_hash(docstring) + defaults = Hash[*parameters.select{ |p| !p[1].nil? }.flatten] + hash[:defaults] = defaults unless defaults.empty? + hash[:source] = source unless source && source.empty? + hash + end end diff --git a/lib/puppet-strings/yard/code_objects/function.rb b/lib/puppet-strings/yard/code_objects/function.rb index 695b4aa..f295d29 100644 --- a/lib/puppet-strings/yard/code_objects/function.rb +++ b/lib/puppet-strings/yard/code_objects/function.rb @@ -57,9 +57,10 @@ class PuppetStrings::Yard::CodeObjects::Function < PuppetStrings::Yard::CodeObje end end - # Gets the Puppet signature of the function. + # Gets the Puppet signature of the function (single overload only). # @return [String] Returns the Puppet signature of the function. def signature + return '' if self.has_tag? :overload tags = self.tags(:param) args = @parameters.map do |parameter| name, default = parameter @@ -72,4 +73,21 @@ class PuppetStrings::Yard::CodeObjects::Function < PuppetStrings::Yard::CodeObje end.join(', ') @name.to_s + '(' + args + ')' end + + # Converts the code object to a hash representation. + # @return [Hash] Returns a hash representation of the code object. + def to_hash + hash = {} + hash[:name] = name + hash[:file] = file + hash[:line] = line + hash[:type] = @function_type.to_s + signature = self.signature + hash[:signature] = signature unless signature.empty? + hash[:docstring] = PuppetStrings::Json.docstring_to_hash(docstring) + defaults = Hash[*parameters.select{ |p| !p[1].nil? }.flatten] + hash[:defaults] = defaults unless defaults.empty? + hash[:source] = source unless source && source.empty? + hash + end end diff --git a/lib/puppet-strings/yard/code_objects/provider.rb b/lib/puppet-strings/yard/code_objects/provider.rb index 8a30075..06a4f1b 100644 --- a/lib/puppet-strings/yard/code_objects/provider.rb +++ b/lib/puppet-strings/yard/code_objects/provider.rb @@ -74,4 +74,20 @@ class PuppetStrings::Yard::CodeObjects::Provider < PuppetStrings::Yard::CodeObje @commands ||= {} @commands[key] = value end + + # Converts the code object to a hash representation. + # @return [Hash] Returns a hash representation of the code object. + def to_hash + hash = {} + hash[:name] = name + hash[:type_name] = type_name + hash[:file] = file + hash[:line] = line + hash[:docstring] = PuppetStrings::Json.docstring_to_hash(docstring) + hash[:confines] = confines if confines && !confines.empty? + hash[:features] = features if features && !features.empty? + hash[:defaults] = defaults if defaults && !defaults.empty? + hash[:commands] = commands if commands && !commands.empty? + hash + end end diff --git a/lib/puppet-strings/yard/code_objects/type.rb b/lib/puppet-strings/yard/code_objects/type.rb index bf80e14..8e3185e 100644 --- a/lib/puppet-strings/yard/code_objects/type.rb +++ b/lib/puppet-strings/yard/code_objects/type.rb @@ -50,6 +50,19 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects: @values << new unless @values.include? new @aliases[new] = old end + + # Converts the parameter to a hash representation. + # @return [Hash] Returns a hash representation of the parameter. + def to_hash + hash = {} + hash[:name] = name + hash[:description] = docstring unless docstring.empty? + hash[:values] = values unless values.empty? + hash[:aliases] = aliases unless aliases.empty? + hash[:isnamevar] = true if isnamevar + hash[:default] = default if default + hash + end end # Represents a resource type property (same attributes as a parameter). @@ -67,6 +80,15 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects: @name = name @docstring = docstring end + + # Converts the feature to a hash representation. + # @return [Hash] Returns a hash representation of the feature. + def to_hash + hash = {} + hash[:name] = name + hash[:description] = docstring unless docstring.empty? + hash + end end attr_reader :properties, :parameters, :features @@ -107,4 +129,18 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects: @features ||= [] @features << feature end + + # Converts the code object to a hash representation. + # @return [Hash] Returns a hash representation of the code object. + def to_hash + hash = {} + hash[:name] = name + hash[:file] = file + hash[:line] = line + hash[:docstring] = PuppetStrings::Json.docstring_to_hash(docstring) + hash[:properties] = properties.map { |p| p.to_hash } if properties && !properties.empty? + hash[:parameters] = parameters.map { |p| p.to_hash } if parameters && !parameters.empty? + hash[:features] = features.map { |f| f.to_hash } if features && !features.empty? + hash + end end diff --git a/lib/puppet-strings/yard/tags/overload_tag.rb b/lib/puppet-strings/yard/tags/overload_tag.rb index 50a505e..84ce878 100644 --- a/lib/puppet-strings/yard/tags/overload_tag.rb +++ b/lib/puppet-strings/yard/tags/overload_tag.rb @@ -91,4 +91,19 @@ class PuppetStrings::Yard::Tags::OverloadTag < YARD::Tags::Tag def type object.type end + + # Converts the overload tag to a hash representation. + # @return [Hash] Returns a hash representation of the overload. + def to_hash + hash = {} + hash[:tag_name] = tag_name + hash[:text] = text if text + hash[:signature] = signature + hash[:docstring] = PuppetStrings::Json.docstring_to_hash(docstring) if !docstring.empty? + defaults = Hash[*parameters.select{ |p| !p[1].nil? }.flatten] + hash[:defaults] = defaults unless defaults.empty? + hash[:types] = types if types + hash[:name] = name if name + hash + end end