Merge pull request #156 from eputnam/pdoc184
(PDOC-184) generate markdown
This commit is contained in:
commit
7dff75642b
49
README.md
49
README.md
|
@ -162,17 +162,33 @@ Strings can produce documentation in JSON and then either generate a `.json` fil
|
|||
To generate JSON documentation to a file, run:
|
||||
|
||||
```
|
||||
$ puppet strings generate --emit-json documentation.json
|
||||
$ puppet strings generate --format json --out documentation.json
|
||||
```
|
||||
|
||||
To generate and then print JSON documentation to stdout, run:
|
||||
|
||||
```
|
||||
$ puppet strings generate --emit-json-stdout
|
||||
$ puppet strings generate --format json
|
||||
```
|
||||
|
||||
For details about Strings JSON output, see [Strings JSON schema](https://github.com/puppetlabs/puppet-strings/blob/master/JSON.md).
|
||||
|
||||
### Output documents in Markdown
|
||||
|
||||
Strings can also produce documentation in Markdown and then either generate an `.md` file or print Markdown to stdout. The generated markdown layout has been reviewed and approved by Puppet's tech pubs team and is the same that is used in Puppet Supported modules.
|
||||
|
||||
To generate REFERENCE.md:
|
||||
|
||||
```
|
||||
$ puppet strings generate --format markdown
|
||||
```
|
||||
|
||||
To write Markdown documentation to another file, use the --out option:
|
||||
|
||||
```
|
||||
$ puppet strings generate --format markdown --out docs/INFO.md
|
||||
```
|
||||
|
||||
### Output documents to GitHub Pages
|
||||
|
||||
To generate documents and then make them available on [GitHub Pages](https://pages.github.com/), use the Strings rake task `strings:gh_pages:update`. See [Rake tasks](#rake-tasks) for setup and usage details.
|
||||
|
@ -285,6 +301,35 @@ end
|
|||
|
||||
All provider method calls, including `confine`, `defaultfor`, and `commands`, are automatically parsed and documented by Strings. The `desc` method is used to generate the docstring, and can include tags such as `@example` if written as a heredoc.
|
||||
|
||||
Document types that use the new [Resource API](https://github.com/puppetlabs/puppet-resource_api):
|
||||
|
||||
```ruby
|
||||
Puppet::ResourceApi.register_type(
|
||||
name: 'database',
|
||||
docs: 'An example database server resource type.',
|
||||
attributes: {
|
||||
ensure: {
|
||||
type: 'Enum[present, absent, up, down]',
|
||||
desc: 'What state the database should be in.',
|
||||
default: 'up',
|
||||
},
|
||||
address: {
|
||||
type: 'String',
|
||||
desc: 'The database server name.',
|
||||
behaviour: :namevar,
|
||||
},
|
||||
encrypt: {
|
||||
type: 'Boolean',
|
||||
desc: 'Whether or not to encrypt the database.',
|
||||
default: false,
|
||||
behaviour: :parameter,
|
||||
},
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
Here, the `docs` key acts like the `desc` method of the traditional resource type. Everything else is the same, except that now everything is a value in the data structure, not passed to methods.
|
||||
|
||||
**Note**: Puppet Strings can not evaluate your Ruby code, so only certain static expressions are supported.
|
||||
|
||||
### Documenting functions
|
||||
|
|
|
@ -14,7 +14,9 @@ module PuppetStrings
|
|||
# @option options [Boolean] :debug Enable YARD debug output.
|
||||
# @option options [Boolean] :backtrace Enable YARD backtraces.
|
||||
# @option options [String] :markup The YARD markup format to use (defaults to 'markdown').
|
||||
# @option options [String] :json Enables JSON output to the given file. If the file is nil, STDOUT is used.
|
||||
# @option options [String] :path Write the selected format to a file path
|
||||
# @option options [Boolean] :markdown From the --format option, is the format Markdown?
|
||||
# @option options [Boolean] :json Is the format JSON?
|
||||
# @option options [Array<String>] :yard_args The arguments to pass to yard.
|
||||
# @return [void]
|
||||
def self.generate(search_patterns = DEFAULT_SEARCH_PATTERNS, options = {})
|
||||
|
@ -27,15 +29,18 @@ module PuppetStrings
|
|||
args << '--backtrace' if options[:backtrace]
|
||||
args << "-m#{options[:markup] || 'markdown'}"
|
||||
|
||||
render_as_json = options.key? :json
|
||||
json_file = nil
|
||||
if render_as_json
|
||||
json_file = options[:json]
|
||||
file = nil
|
||||
if options[:json] || options[:markdown]
|
||||
file = if options[:json]
|
||||
options[:path]
|
||||
elsif options[:markdown]
|
||||
options[:path] || "REFERENCE.md"
|
||||
end
|
||||
# Disable output and prevent stats/progress when writing to STDOUT
|
||||
args << '-n'
|
||||
args << '-q' unless json_file
|
||||
args << '--no-stats' unless json_file
|
||||
args << '--no-progress' unless json_file
|
||||
args << '-q' unless file
|
||||
args << '--no-stats' unless file
|
||||
args << '--no-progress' unless file
|
||||
end
|
||||
|
||||
yard_args = options[:yard_args]
|
||||
|
@ -46,10 +51,24 @@ module PuppetStrings
|
|||
YARD::CLI::Yardoc.run(*args)
|
||||
|
||||
# If outputting JSON, render the output
|
||||
if render_as_json
|
||||
require 'puppet-strings/json'
|
||||
PuppetStrings::Json.render(json_file)
|
||||
if options[:json]
|
||||
render_json(file)
|
||||
end
|
||||
|
||||
# If outputting Markdown, render the output
|
||||
if options[:markdown]
|
||||
render_markdown(file)
|
||||
end
|
||||
end
|
||||
|
||||
def self.render_json(path)
|
||||
require 'puppet-strings/json'
|
||||
PuppetStrings::Json.render(path)
|
||||
end
|
||||
|
||||
def self.render_markdown(path)
|
||||
require 'puppet-strings/markdown'
|
||||
PuppetStrings::Markdown.render(path)
|
||||
end
|
||||
|
||||
# Runs the YARD documentation server.
|
||||
|
|
|
@ -34,6 +34,13 @@ module PuppetStrings::Json
|
|||
next t.to_hash if t.respond_to?(:to_hash)
|
||||
|
||||
tag = { tag_name: t.tag_name }
|
||||
# grab nested information for @option tags
|
||||
if tag[:tag_name] == 'option'
|
||||
tag[:opt_name] = t.pair.name
|
||||
tag[:opt_text] = t.pair.text
|
||||
tag[:opt_types] = t.pair.types
|
||||
tag[:parent] = t.name
|
||||
end
|
||||
tag[:text] = t.text if t.text
|
||||
tag[:types] = t.types if t.types
|
||||
tag[:name] = t.name if t.name
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
require 'puppet-strings/json'
|
||||
|
||||
# module for parsing Yard Registries and generating markdown
|
||||
module PuppetStrings::Markdown
|
||||
require_relative 'markdown/puppet_classes'
|
||||
require_relative 'markdown/functions'
|
||||
require_relative 'markdown/defined_types'
|
||||
require_relative 'markdown/resource_types'
|
||||
require_relative 'markdown/table_of_contents'
|
||||
|
||||
# generates markdown documentation
|
||||
# @return [String] markdown doc
|
||||
def self.generate
|
||||
final = "# Reference\n\n"
|
||||
final << PuppetStrings::Markdown::TableOfContents.render
|
||||
final << PuppetStrings::Markdown::PuppetClasses.render
|
||||
final << PuppetStrings::Markdown::DefinedTypes.render
|
||||
final << PuppetStrings::Markdown::ResourceTypes.render
|
||||
final << PuppetStrings::Markdown::Functions.render
|
||||
|
||||
final
|
||||
end
|
||||
|
||||
# mimicks the behavior of the json render, although path will never be nil
|
||||
# @param [String] path path to destination file
|
||||
def self.render(path = nil)
|
||||
if path.nil?
|
||||
puts generate
|
||||
exit
|
||||
else
|
||||
File.open(path, 'w') { |file| file.write(generate) }
|
||||
YARD::Logger.instance.debug "Wrote markdown to #{path}"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,158 @@
|
|||
require 'puppet-strings'
|
||||
require 'puppet-strings/json'
|
||||
require 'puppet-strings/yard'
|
||||
|
||||
module PuppetStrings::Markdown
|
||||
# This class makes elements in a YARD::Registry hash easily accessible for templates.
|
||||
#
|
||||
# Here's an example hash:
|
||||
#{:name=>:klass,
|
||||
# :file=>"(stdin)",
|
||||
# :line=>16,
|
||||
# :inherits=>"foo::bar",
|
||||
# :docstring=>
|
||||
# {:text=>"An overview for a simple class.",
|
||||
# :tags=>
|
||||
# [{:tag_name=>"summary", :text=>"A simple class."},
|
||||
# {:tag_name=>"since", :text=>"1.0.0"},
|
||||
# {:tag_name=>"see", :name=>"www.puppet.com"},
|
||||
# {:tag_name=>"example",
|
||||
# :text=>
|
||||
# "class { 'klass':\n" +
|
||||
# " param1 => 1,\n" +
|
||||
# " param3 => 'foo',\n" +
|
||||
# "}",
|
||||
# :name=>"This is an example"},
|
||||
# {:tag_name=>"author", :text=>"eputnam"},
|
||||
# {:tag_name=>"option", :name=>"opts"},
|
||||
# {:tag_name=>"raise", :text=>"SomeError"},
|
||||
# {:tag_name=>"param",
|
||||
# :text=>"First param.",
|
||||
# :types=>["Integer"],
|
||||
# :name=>"param1"},
|
||||
# {:tag_name=>"param",
|
||||
# :text=>"Second param.",
|
||||
# :types=>["Any"],
|
||||
# :name=>"param2"},
|
||||
# {:tag_name=>"param",
|
||||
# :text=>"Third param.",
|
||||
# :types=>["String"],
|
||||
# :name=>"param3"}]},
|
||||
# :defaults=>{"param1"=>"1", "param2"=>"undef", "param3"=>"'hi'"},
|
||||
# :source=>
|
||||
# "class klass (\n" +
|
||||
# " Integer $param1 = 1,\n" +
|
||||
# " $param2 = undef,\n" +
|
||||
# " String $param3 = 'hi'\n" +
|
||||
# ") inherits foo::bar {\n" +
|
||||
# "}"}
|
||||
class Base
|
||||
def initialize(registry, component_type)
|
||||
@type = component_type
|
||||
@registry = registry
|
||||
@tags = registry[:docstring][:tags] || []
|
||||
end
|
||||
|
||||
# generate 1:1 tag methods
|
||||
# e.g. {:tag_name=>"author", :text=>"eputnam"}
|
||||
{ :return_val => 'return',
|
||||
:since => 'since',
|
||||
:summary => 'summary' }.each do |method_name, tag_name|
|
||||
# @return [String] unless the tag is nil or the string.length == 0
|
||||
define_method method_name do
|
||||
@tags.select { |tag| tag[:tag_name] == "#{tag_name}" }[0][:text] unless @tags.select { |tag| tag[:tag_name] == "#{tag_name}" }[0].nil? || @tags.select { |tag| tag[:tag_name] == "#{tag_name}" }[0][:text].length.zero?
|
||||
end
|
||||
end
|
||||
|
||||
# @return [String] top-level name
|
||||
def name
|
||||
@registry[:name].to_s unless @registry[:name].nil?
|
||||
end
|
||||
|
||||
# @return [String] 'Overview' text (untagged text)
|
||||
def text
|
||||
@registry[:docstring][:text] unless @registry[:docstring][:text].empty?
|
||||
end
|
||||
|
||||
# @return [String] data type of return value
|
||||
def return_type
|
||||
@tags.select { |tag| tag[:tag_name] == 'return' }[0][:types][0] unless @tags.select { |tag| tag[:tag_name] == 'return' }[0].nil?
|
||||
end
|
||||
|
||||
# @return [String] text from @since tag
|
||||
def since
|
||||
@tags.select { |tag| tag[:tag_name] == 'since' }[0][:text] unless @tags.select { |tag| tag[:tag_name] == 'since' }[0].nil?
|
||||
end
|
||||
|
||||
# @return [Array] @see tag hashes
|
||||
def see
|
||||
@tags.select { |tag| tag[:tag_name] == 'see' } unless @tags.select { |tag| tag[:tag_name] == 'see' }[0].nil?
|
||||
end
|
||||
|
||||
# @return [Array] parameter tag hashes
|
||||
def params
|
||||
@tags.select { |tag| tag[:tag_name] == 'param' } unless @tags.select { |tag| tag[:tag_name] == 'param' }[0].nil?
|
||||
end
|
||||
|
||||
# @return [Array] example tag hashes
|
||||
def examples
|
||||
@tags.select { |tag| tag[:tag_name] == 'example' } unless @tags.select { |tag| tag[:tag_name] == 'example' }[0].nil?
|
||||
end
|
||||
|
||||
# @return [Array] raise tag hashes
|
||||
def raises
|
||||
@tags.select { |tag| tag[:tag_name] == 'raise' } unless @tags.select { |tag| tag[:tag_name] == 'raise' }[0].nil?
|
||||
end
|
||||
|
||||
# @return [Array] option tag hashes
|
||||
def options
|
||||
@tags.select { |tag| tag[:tag_name] == 'option' } unless @tags.select { |tag| tag[:tag_name] == 'option' }[0].nil?
|
||||
end
|
||||
|
||||
# @param parameter_name
|
||||
# parameter name to match to option tags
|
||||
# @return [Array] option tag hashes that have a parent parameter_name
|
||||
def options_for_param(parameter_name)
|
||||
opts_for_p = options.select { |o| o[:parent] == parameter_name } unless options.nil?
|
||||
opts_for_p unless opts_for_p.nil? || opts_for_p.length.zero?
|
||||
end
|
||||
|
||||
# @return [Array] any defaults found for the component
|
||||
def defaults
|
||||
@registry[:defaults] unless @registry[:defaults].nil?
|
||||
end
|
||||
|
||||
# @return [Hash] information needed for the table of contents
|
||||
def toc_info
|
||||
{
|
||||
name: name.to_s,
|
||||
link: link,
|
||||
desc: summary || @registry[:docstring][:text].gsub("\n", ". ")
|
||||
}
|
||||
end
|
||||
|
||||
# @return [String] makes the component name suitable for a GitHub markdown link
|
||||
def link
|
||||
name.delete('::').strip.gsub(' ','-').downcase
|
||||
end
|
||||
|
||||
# Some return, default, or valid values need to be in backticks. Instead of fu in the handler or code_object, this just does the change on the front.
|
||||
# @param value
|
||||
# any string
|
||||
# @return [String] value or value in backticks if it is in a list
|
||||
def value_string(value)
|
||||
to_symbol = %w[undef true false]
|
||||
if to_symbol.include? value
|
||||
return "`#{value}`"
|
||||
else
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
# @return [String] full markdown rendering of a component
|
||||
def render(template)
|
||||
file = File.join(File.dirname(__FILE__),"templates/#{template}")
|
||||
ERB.new(File.read(file), nil, '-').result(binding)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,14 @@
|
|||
require 'puppet-strings/markdown/base'
|
||||
|
||||
module PuppetStrings::Markdown
|
||||
class DefinedType < Base
|
||||
def initialize(registry)
|
||||
@template = 'classes_and_defines.erb'
|
||||
super(registry, 'defined type')
|
||||
end
|
||||
|
||||
def render
|
||||
super(@template)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
require_relative 'defined_type'
|
||||
|
||||
module PuppetStrings::Markdown
|
||||
module DefinedTypes
|
||||
|
||||
# @return [Array] list of defined types
|
||||
def self.in_dtypes
|
||||
YARD::Registry.all(:puppet_defined_type).sort_by!(&:name).map!(&:to_hash)
|
||||
end
|
||||
|
||||
def self.render
|
||||
final = in_dtypes.length > 0 ? "## Defined types\n\n" : ""
|
||||
in_dtypes.each do |type|
|
||||
final << PuppetStrings::Markdown::DefinedType.new(type).render
|
||||
end
|
||||
final
|
||||
end
|
||||
|
||||
def self.toc_info
|
||||
final = []
|
||||
|
||||
in_dtypes.each do |type|
|
||||
final.push(PuppetStrings::Markdown::DefinedType.new(type).toc_info)
|
||||
end
|
||||
|
||||
final
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,52 @@
|
|||
require 'puppet-strings/markdown/base'
|
||||
|
||||
module PuppetStrings::Markdown
|
||||
class Function < Base
|
||||
attr_reader :signatures
|
||||
|
||||
def initialize(registry)
|
||||
@template = 'function.erb'
|
||||
super(registry, 'function')
|
||||
@signatures = []
|
||||
registry[:signatures].each do |sig|
|
||||
@signatures.push(Signature.new(sig))
|
||||
end
|
||||
end
|
||||
|
||||
def render
|
||||
super(@template)
|
||||
end
|
||||
|
||||
def type
|
||||
t = @registry[:type]
|
||||
if t =~ /ruby4x/
|
||||
"Ruby 4.x API"
|
||||
elsif t =~ /ruby3/
|
||||
"Ruby 3.x API"
|
||||
elsif t =~ /ruby/
|
||||
"Ruby"
|
||||
else
|
||||
"Puppet Language"
|
||||
end
|
||||
end
|
||||
|
||||
def error_type(r)
|
||||
"`#{r.split(' ')[0]}`"
|
||||
end
|
||||
|
||||
def error_text(r)
|
||||
"#{r.split(' ').drop(1).join(' ')}"
|
||||
end
|
||||
end
|
||||
|
||||
class Function::Signature < Base
|
||||
def initialize(registry)
|
||||
@registry = registry
|
||||
super(@registry, 'function signature')
|
||||
end
|
||||
|
||||
def signature
|
||||
@registry[:signature]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
require_relative 'function'
|
||||
|
||||
module PuppetStrings::Markdown
|
||||
module Functions
|
||||
|
||||
# @return [Array] list of functions
|
||||
def self.in_functions
|
||||
YARD::Registry.all(:puppet_function).sort_by!(&:name).map!(&:to_hash)
|
||||
end
|
||||
|
||||
def self.render
|
||||
final = in_functions.length > 0 ? "## Functions\n\n" : ""
|
||||
in_functions.each do |func|
|
||||
final << PuppetStrings::Markdown::Function.new(func).render
|
||||
end
|
||||
final
|
||||
end
|
||||
|
||||
def self.toc_info
|
||||
final = []
|
||||
|
||||
in_functions.each do |func|
|
||||
final.push(PuppetStrings::Markdown::Function.new(func).toc_info)
|
||||
end
|
||||
|
||||
final
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
require 'puppet-strings/markdown/base'
|
||||
|
||||
module PuppetStrings::Markdown
|
||||
class PuppetClass < Base
|
||||
def initialize(registry)
|
||||
@template = 'classes_and_defines.erb'
|
||||
super(registry, 'class')
|
||||
end
|
||||
|
||||
def render
|
||||
super(@template)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
require_relative 'puppet_class'
|
||||
|
||||
module PuppetStrings::Markdown
|
||||
module PuppetClasses
|
||||
|
||||
# @return [Array] list of classes
|
||||
def self.in_classes
|
||||
YARD::Registry.all(:puppet_class).sort_by!(&:name).map!(&:to_hash)
|
||||
end
|
||||
|
||||
def self.render
|
||||
final = in_classes.length > 0 ? "## Classes\n\n" : ""
|
||||
in_classes.each do |klass|
|
||||
final << PuppetStrings::Markdown::PuppetClass.new(klass).render
|
||||
end
|
||||
final
|
||||
end
|
||||
|
||||
def self.toc_info
|
||||
final = []
|
||||
|
||||
in_classes.each do |klass|
|
||||
final.push(PuppetStrings::Markdown::PuppetClass.new(klass).toc_info)
|
||||
end
|
||||
|
||||
final
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
require 'puppet-strings/markdown/base'
|
||||
|
||||
module PuppetStrings::Markdown
|
||||
class ResourceType < Base
|
||||
def initialize(registry)
|
||||
@template = 'resource_type.erb'
|
||||
super(registry, 'type')
|
||||
end
|
||||
|
||||
def render
|
||||
super(@template)
|
||||
end
|
||||
|
||||
def properties
|
||||
@registry[:properties]
|
||||
end
|
||||
|
||||
def parameters
|
||||
@registry[:parameters]
|
||||
end
|
||||
|
||||
def regex_in_data_type?(data_type)
|
||||
m = data_type.match(/\w+\[\/.*\/\]/)
|
||||
m unless m.nil? || m.length.zero?
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
require_relative 'resource_type'
|
||||
|
||||
module PuppetStrings::Markdown
|
||||
module ResourceTypes
|
||||
|
||||
# @return [Array] list of resource types
|
||||
def self.in_rtypes
|
||||
YARD::Registry.all(:puppet_type).sort_by!(&:name).map!(&:to_hash)
|
||||
end
|
||||
|
||||
def self.render
|
||||
final = in_rtypes.length > 0 ? "## Resource types\n\n" : ""
|
||||
in_rtypes.each do |type|
|
||||
final << PuppetStrings::Markdown::ResourceType.new(type).render
|
||||
end
|
||||
final
|
||||
end
|
||||
|
||||
def self.toc_info
|
||||
final = []
|
||||
|
||||
in_rtypes.each do |type|
|
||||
final.push(PuppetStrings::Markdown::ResourceType.new(type).toc_info)
|
||||
end
|
||||
|
||||
final
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
module PuppetStrings::Markdown
|
||||
module TableOfContents
|
||||
def self.render
|
||||
puppet_classes = PuppetStrings::Markdown::PuppetClasses.toc_info
|
||||
puppet_defined_types = PuppetStrings::Markdown::DefinedTypes.toc_info
|
||||
puppet_resource_types = PuppetStrings::Markdown::ResourceTypes.toc_info
|
||||
puppet_functions = PuppetStrings::Markdown::Functions.toc_info
|
||||
|
||||
template = File.join(File.dirname(__FILE__),"templates/table_of_contents.erb")
|
||||
ERB.new(File.read(template), nil, '-').result(binding)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,53 @@
|
|||
### <%= name %>
|
||||
|
||||
<% if since -%>
|
||||
* **Since** <%= since %>
|
||||
|
||||
<% end -%>
|
||||
<% if see -%>
|
||||
* **See also**
|
||||
<% see.each do |sa| -%>
|
||||
<%= sa[:name] %>
|
||||
<%= sa[:text] %>
|
||||
<% end -%>
|
||||
|
||||
<% end -%>
|
||||
<% if examples -%>
|
||||
#### Examples
|
||||
<% examples.each do |eg| -%>
|
||||
##### <%= eg[:name] %>
|
||||
```puppet
|
||||
<%= eg[:text] %>
|
||||
```
|
||||
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% if params %>
|
||||
#### Parameters
|
||||
|
||||
The following parameters are available in the `<%= name %>` <%= @type %>.
|
||||
|
||||
<% params.each do |param| -%>
|
||||
##### `<%= param[:name] %>`
|
||||
|
||||
<% if param[:types] -%>
|
||||
Data type: `<%= param[:types].join(', ') -%>`
|
||||
|
||||
<% end -%>
|
||||
<%= param[:text] %>
|
||||
|
||||
<% if options_for_param(param[:name]) -%>
|
||||
Options:
|
||||
|
||||
<% options_for_param(param[:name]).each do |o| -%>
|
||||
* **<%= o[:opt_name] %>** `<%= o[:opt_types][0] %>`: <%= o[:opt_text] %>
|
||||
<% end -%>
|
||||
|
||||
<% end -%>
|
||||
<% if defaults && defaults[param[:name]] -%>
|
||||
Default value: <%= value_string(defaults[param[:name]]) %>
|
||||
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
### <%= name %>
|
||||
Type: <%= type %>
|
||||
|
||||
<% signatures.each do |sig| -%>
|
||||
#### `<%= sig.signature %>`
|
||||
|
||||
<% if sig.text -%>
|
||||
<%= sig.text %>
|
||||
|
||||
<% end -%>
|
||||
<% if sig.return_type -%>
|
||||
Returns: `<%= sig.return_type %>`<% if sig.return_val %> <%= sig.return_val %><% end %>
|
||||
|
||||
<% end -%>
|
||||
<% if raises -%>
|
||||
Raises:
|
||||
<% raises.each do |r| -%>
|
||||
* <%= error_type(r[:text]) %> <%= error_text(r[:text]) %>
|
||||
<% end -%>
|
||||
|
||||
<% end -%>
|
||||
<% if sig.params -%>
|
||||
<% sig.params.each do |param| -%>
|
||||
##### `<%= param[:name] %>`
|
||||
|
||||
Data type: `<%= param[:types][0] %>`
|
||||
|
||||
<%= param[:text] %>
|
||||
|
||||
<% if sig.options_for_param(param[:name]) -%>
|
||||
Options:
|
||||
|
||||
<% sig.options_for_param(param[:name]).each do |o| -%>
|
||||
* **<%= o[:opt_name] %>** `<%= o[:opt_types][0] %>`: <%= o[:opt_text] %>
|
||||
<% end -%>
|
||||
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% end -%>
|
|
@ -0,0 +1,107 @@
|
|||
### <%= name %>
|
||||
|
||||
<% if since -%>
|
||||
* **Since** <%= since %>
|
||||
|
||||
<% end -%>
|
||||
<% if see -%>
|
||||
* **See also**
|
||||
<% see.each do |sa| -%>
|
||||
<%= sa[:name] %>
|
||||
<%= sa[:text] %>
|
||||
<% end -%>
|
||||
|
||||
<% end -%>
|
||||
<% if text -%>
|
||||
<%= text %>
|
||||
<% end %>
|
||||
<% if examples -%>
|
||||
#### Examples
|
||||
<% examples.each do |eg| -%>
|
||||
##### <%= eg[:name] %>
|
||||
```puppet
|
||||
<%= eg[:text] %>
|
||||
```
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% if properties %>
|
||||
#### Properties
|
||||
|
||||
The following properties are available in the `<%= name %>` <%= @type %>.
|
||||
|
||||
<% properties.each do |prop| -%>
|
||||
##### `<%= prop[:name] %>`
|
||||
|
||||
<% if prop[:values] -%>
|
||||
Valid values: <%= prop[:values].map { |value| value_string(value) }.join(', ') %>
|
||||
|
||||
<% end -%>
|
||||
<% if prop[:isnamevar] -%>
|
||||
namevar
|
||||
|
||||
<% end -%>
|
||||
<% if prop[:aliases] -%>
|
||||
Aliases: <%= prop[:aliases].to_s.delete('{').delete('}') %>
|
||||
|
||||
<% end -%>
|
||||
<% if prop[:data_type] -%>
|
||||
Data type: `<%= prop[:data_type] %>`<%= "\n_\*this data type contains a regex that may not be accurately reflected in generated documentation_" if regex_in_data_type?(prop[:data_type]) %>
|
||||
|
||||
<% end -%>
|
||||
<%= prop[:description] %>
|
||||
|
||||
<% if options_for_param(prop[:name]) -%>
|
||||
Options:
|
||||
|
||||
<% options_for_param(prop[:name]).each do |o| -%>
|
||||
* **<%= o[:opt_name] %>** `<%= o[:opt_types][0] %>`: <%= o[:opt_text] %>
|
||||
<% end -%>
|
||||
|
||||
<% end -%>
|
||||
<% if prop[:default] -%>
|
||||
Default value: <%= prop[:default] %>
|
||||
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% if parameters -%>
|
||||
#### Parameters
|
||||
|
||||
The following parameters are available in the `<%= name %>` <%= @type %>.
|
||||
|
||||
<% parameters.each do |param| -%>
|
||||
##### `<%= param[:name] %>`
|
||||
|
||||
<% if param[:values] -%>
|
||||
Valid values: <%= param[:values].map { |value| value_string(value) }.join(', ') %>
|
||||
|
||||
<% end -%>
|
||||
<% if param[:isnamevar] -%>
|
||||
namevar
|
||||
|
||||
<% end -%>
|
||||
<% if param[:aliases] -%>
|
||||
Aliases: <%= param[:aliases].to_s.delete('{').delete('}') %>
|
||||
|
||||
<% end -%>
|
||||
<% if param[:data_type] -%>
|
||||
Data type: `<%= param[:data_type] %>`<%= "\n_\*this data type contains a regex that may not be accurately reflected in generated documentation_" if regex_in_data_type?(param[:data_type]) %>
|
||||
|
||||
<% end -%>
|
||||
<%= param[:description] %>
|
||||
|
||||
<% if options_for_param(param[:name]) -%>
|
||||
Options:
|
||||
|
||||
<% options_for_param(param[:name]).each do |o| -%>
|
||||
* **<%= o[:opt_name] %>** `<%= o[:opt_types][0] %>`: <%= o[:opt_text] %>
|
||||
<% end -%>
|
||||
|
||||
<% end -%>
|
||||
<% if param[:default] -%>
|
||||
Default value: <%= value_string(param[:default]) %>
|
||||
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<% if puppet_classes.length > 0 -%>
|
||||
## Classes
|
||||
<% puppet_classes.each do |klassy| -%>
|
||||
* [`<%= klassy[:name] %>`](#<%= klassy[:link] %>): <%= klassy[:desc] %>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% if puppet_defined_types.length > 0 -%>
|
||||
## Defined types
|
||||
<% puppet_defined_types.each do |dtype| -%>
|
||||
* [`<%= dtype[:name] %>`](#<%= dtype[:link] %>): <%= dtype[:desc] %>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% if puppet_resource_types.length > 0 -%>
|
||||
## Resource types
|
||||
<% puppet_resource_types.each do |rtype| -%>
|
||||
* [`<%= rtype[:name] %>`](#<%= rtype[:link] %>): <%= rtype[:desc] %>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% if puppet_functions.length > 0 -%>
|
||||
## Functions
|
||||
<% puppet_functions.each do |func| -%>
|
||||
* [`<%= func[:name] %>`](#<%= func[:link] %>): <%= func[:desc] %>
|
||||
<% end -%>
|
||||
<% end -%>
|
|
@ -84,14 +84,14 @@ class PuppetStrings::Yard::CodeObjects::Function < PuppetStrings::Yard::CodeObje
|
|||
hash[:line] = line
|
||||
hash[:type] = @function_type.to_s
|
||||
hash[:signatures] = []
|
||||
|
||||
|
||||
if self.has_tag? :overload
|
||||
# loop over overloads and append onto the signatures array
|
||||
self.tags(:overload).each do |o|
|
||||
hash[:signatures] << { :signature => o.signature, :docstring => PuppetStrings::Json.docstring_to_hash(o.docstring, [:param, :return]) }
|
||||
hash[:signatures] << { :signature => o.signature, :docstring => PuppetStrings::Json.docstring_to_hash(o.docstring, [:param, :option, :return]) }
|
||||
end
|
||||
else
|
||||
hash[:signatures] << { :signature => self.signature, :docstring => PuppetStrings::Json.docstring_to_hash(docstring, [:param, :return]) }
|
||||
hash[:signatures] << { :signature => self.signature, :docstring => PuppetStrings::Json.docstring_to_hash(docstring, [:param, :option, :return]) }
|
||||
end
|
||||
|
||||
hash[:docstring] = PuppetStrings::Json.docstring_to_hash(docstring)
|
||||
|
|
|
@ -22,7 +22,7 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects:
|
|||
# Represents a resource type parameter.
|
||||
class Parameter
|
||||
attr_reader :name, :values, :aliases
|
||||
attr_accessor :docstring, :isnamevar, :default
|
||||
attr_accessor :docstring, :isnamevar, :default, :data_type
|
||||
|
||||
# Initializes a resource type parameter or property.
|
||||
# @param [String] name The name of the parameter or property.
|
||||
|
@ -31,6 +31,7 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects:
|
|||
@name = name
|
||||
@docstring = docstring || ''
|
||||
@values = []
|
||||
@data_type = []
|
||||
@aliases = {}
|
||||
@isnamevar = false
|
||||
@default = nil
|
||||
|
@ -59,6 +60,7 @@ class PuppetStrings::Yard::CodeObjects::Type < PuppetStrings::Yard::CodeObjects:
|
|||
hash[:name] = name
|
||||
hash[:description] = docstring unless docstring.empty?
|
||||
hash[:values] = values unless values.empty?
|
||||
hash[:data_type] = data_type unless data_type.empty?
|
||||
hash[:aliases] = aliases unless aliases.empty?
|
||||
hash[:isnamevar] = true if isnamevar
|
||||
hash[:default] = default if default
|
||||
|
|
|
@ -29,7 +29,7 @@ class PuppetStrings::Yard::Handlers::Ruby::Base < YARD::Handlers::Ruby::Base
|
|||
source = node.source
|
||||
if source =~ HEREDOC_START
|
||||
lines = source.split("\n")
|
||||
source = lines[1..(lines.last.include?($1) ? -2 : -1)].join("\n") if lines.size > 1
|
||||
source = lines[1..(lines.last.include?($1[0..-2]) ? -2 : -1)].join("\n") if lines.size > 1
|
||||
end
|
||||
|
||||
source
|
||||
|
|
|
@ -24,7 +24,7 @@ class PuppetStrings::Yard::Handlers::Ruby::RsapiHandler < PuppetStrings::Yard::H
|
|||
object = PuppetStrings::Yard::CodeObjects::Type.new(schema['name'])
|
||||
register object
|
||||
|
||||
docstring = schema['docs']
|
||||
docstring = schema['desc'] || ""
|
||||
if docstring
|
||||
register_docstring(object, PuppetStrings::Yard::Util.scrub_string(docstring.to_s), nil)
|
||||
else
|
||||
|
@ -49,7 +49,7 @@ class PuppetStrings::Yard::Handlers::Ruby::RsapiHandler < PuppetStrings::Yard::H
|
|||
|
||||
# check that the params of the register_type call are key/value pairs.
|
||||
def kv_arg_list?(params)
|
||||
params.type == :list && params.children.count > 0 && params.children.first.type == :list && params.children.first.children.count > 0 && statement.parameters.children.first.children.first.type == :assoc
|
||||
params.type == :list && params.children.count > 0 && params.children.first.type == :list && params.children.first.children.count > 0 && statement.parameters.children.first.children.first.type == :assoc
|
||||
end
|
||||
|
||||
def extract_schema
|
||||
|
@ -134,7 +134,7 @@ class PuppetStrings::Yard::Handlers::Ruby::RsapiHandler < PuppetStrings::Yard::H
|
|||
end
|
||||
|
||||
def set_values(definition, object)
|
||||
object.add(definition['type']) if definition.key? 'type'
|
||||
object.data_type = definition['type'] if definition.key? 'type'
|
||||
object.default = definition['default'] if definition.key? 'default'
|
||||
object.isnamevar = definition.key?('behaviour') && definition['behaviour'] == 'namevar'
|
||||
end
|
||||
|
|
|
@ -7,15 +7,21 @@ Puppet::Face.define(:strings, '0.0.1') do
|
|||
action(:generate) do
|
||||
default
|
||||
|
||||
option '--emit-json-stdout' do
|
||||
summary 'Print JSON representation of the documentation to stdout.'
|
||||
option '--format OUTPUT_FORMAT' do
|
||||
summary 'Designate output format, JSON or markdown.'
|
||||
end
|
||||
option '--emit-json FILE' do
|
||||
summary 'Write JSON representation of the documentation to the given file.'
|
||||
option '--out PATH' do
|
||||
summary 'Write selected format to PATH. If no path is designated, strings prints to STDOUT.'
|
||||
end
|
||||
option '--markup FORMAT' do
|
||||
summary "The markup format to use for docstring text (defaults to 'markdown')."
|
||||
end
|
||||
option '--emit-json-stdout' do
|
||||
summary 'DEPRECATED: Print JSON representation of the documentation to stdout.'
|
||||
end
|
||||
option '--emit-json PATH' do
|
||||
summary 'DEPRECATED: Write JSON representation of the documentation to the given file.'
|
||||
end
|
||||
|
||||
summary 'Generate documentation from files.'
|
||||
arguments '[[search_pattern] ...]'
|
||||
|
@ -94,11 +100,26 @@ Puppet::Face.define(:strings, '0.0.1') do
|
|||
generate_options[:yard_args] = yard_args unless yard_args.empty?
|
||||
|
||||
if options
|
||||
if options[:emit_json]
|
||||
$stderr.puts "WARNING: '--emit-json PATH' is deprecated. Use '--format json --out PATH' instead."
|
||||
end
|
||||
if options[:emit_json_stdout]
|
||||
$stderr.puts "WARNING: '--emit-json-stdout' is deprecated. Use '--format json' instead."
|
||||
end
|
||||
markup = options[:markup]
|
||||
generate_options[:markup] = markup if markup
|
||||
json_file = options[:emit_json]
|
||||
generate_options[:json] = json_file if json_file
|
||||
generate_options[:json] = nil if options[:emit_json_stdout]
|
||||
generate_options[:path] = options[:out] if options[:out]
|
||||
generate_options[:stdout] = options[:stdout]
|
||||
format = options[:format]
|
||||
if format
|
||||
if format.casecmp('markdown').zero?
|
||||
generate_options[:markdown] = true
|
||||
elsif format.casecmp('json').zero? || options[:emit_json] || options[:emit_json_stdout]
|
||||
generate_options[:json] = true
|
||||
else
|
||||
raise RuntimeError, "Invalid format #{options[:format]}. Please select 'json' or 'markdown'."
|
||||
end
|
||||
end
|
||||
end
|
||||
generate_options
|
||||
end
|
||||
|
|
|
@ -37,18 +37,18 @@ describe 'Emitting JSON' do
|
|||
]
|
||||
}
|
||||
|
||||
it 'should emit JSON to stdout when using the --emit-json-stdout option' do
|
||||
it 'should emit JSON to stdout when using --format json and --stdout' do
|
||||
test_module_path = get_test_module_path(master, /Module test/)
|
||||
on master, puppet('strings', 'generate', '--emit-json-stdout', "#{test_module_path}/lib/puppet/parser/functions/function3x.rb") do
|
||||
on master, puppet('strings', 'generate', '--format json', "#{test_module_path}/lib/puppet/parser/functions/function3x.rb") do
|
||||
output = stdout.chomp
|
||||
expect(JSON.parse(output)).to eq(expected)
|
||||
end
|
||||
end
|
||||
|
||||
it 'should write JSON to a file when using the --emit-json option' do
|
||||
it 'should write JSON to a file when using --format json and --out' do
|
||||
test_module_path = get_test_module_path(master, /Module test/)
|
||||
tmpfile = master.tmpfile('json_output.json')
|
||||
on master, puppet('strings', 'generate', "--emit-json #{tmpfile}", "#{test_module_path}/lib/puppet/parser/functions/function3x.rb")
|
||||
on master, puppet('strings', 'generate', '--format json', "--out #{tmpfile}", "#{test_module_path}/lib/puppet/parser/functions/function3x.rb")
|
||||
output = read_file_on(master, tmpfile)
|
||||
expect(JSON.parse(output)).to eq(expected)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
require 'spec_helper_acceptance'
|
||||
require 'util'
|
||||
|
||||
include PuppetStrings::Acceptance::Util
|
||||
|
||||
describe 'Generating Markdown' do
|
||||
expected = <<-EOF
|
||||
# Reference
|
||||
|
||||
## Classes
|
||||
* [`test`](#test): This class exists to serve as fixture data for testing the puppet strings face
|
||||
|
||||
## Classes
|
||||
|
||||
### test
|
||||
|
||||
#### Examples
|
||||
```puppet
|
||||
class { "test": }
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### `package_name`
|
||||
|
||||
The name of the package
|
||||
|
||||
##### `service_name`
|
||||
|
||||
The name of the service
|
||||
|
||||
EOF
|
||||
|
||||
it 'should render Markdown to stdout when using --format markdown and --stdout' do
|
||||
test_module_path = get_test_module_path(master, /Module test/)
|
||||
on master, puppet('strings', 'generate', '--format markdown', "#{test_module_path}/manifests/init.pp") do
|
||||
output = stdout.chomp
|
||||
expect(JSON.parse(output)).to eq(expected)
|
||||
end
|
||||
end
|
||||
|
||||
it 'should write Markdown to a file when using --format markdown and --out' do
|
||||
test_module_path = get_test_module_path(master, /Module test/)
|
||||
tmpfile = master.tmpfile('md_output.md')
|
||||
on master, puppet('strings', 'generate', '--format markdown', "--out #{tmpfile}", "#{test_module_path}/manifests/init.pp")
|
||||
output = read_file_on(master, tmpfile)
|
||||
expect(JSON.parse(output)).to eq(expected)
|
||||
end
|
||||
end
|
|
@ -81,6 +81,49 @@
|
|||
}
|
||||
],
|
||||
"resource_types": [
|
||||
{
|
||||
"name": "apt_key",
|
||||
"file": "(stdin)",
|
||||
"line": 92,
|
||||
"docstring": {
|
||||
"text": "This type provides Puppet with the capabilities to manage GPG keys needed\nby apt to perform package validation. Apt has it's own GPG keyring that can\nbe manipulated through the `apt-key` command.\n**Autorequires**:\nIf Puppet is given the location of a key file which looks like an absolute\npath this type will autorequire that file.",
|
||||
"tags": [
|
||||
{
|
||||
"tag_name": "summary",
|
||||
"text": "Example resource type using the new API."
|
||||
},
|
||||
{
|
||||
"tag_name": "raise",
|
||||
"text": "SomeError"
|
||||
},
|
||||
{
|
||||
"tag_name": "example",
|
||||
"text": "apt_key { '6F6B15509CF8E59E6E469F327F438280EF8D349F':\n source => 'http://apt.puppetlabs.com/pubkey.gpg'\n}",
|
||||
"name": "here's an example"
|
||||
}
|
||||
]
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"name": "ensure",
|
||||
"description": "Whether this apt key should be present or absent on the target system.",
|
||||
"data_type": "Enum[present, absent]"
|
||||
},
|
||||
{
|
||||
"name": "created",
|
||||
"description": "Date the key was created, in ISO format.",
|
||||
"data_type": "String"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"description": "The ID of the key you want to manage.",
|
||||
"data_type": "Variant[Pattern[/A(0x)?[0-9a-fA-F]{8}Z/], Pattern[/A(0x)?[0-9a-fA-F]{16}Z/], Pattern[/A(0x)?[0-9a-fA-F]{40}Z/]]",
|
||||
"isnamevar": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "database",
|
||||
"file": "(stdin)",
|
||||
|
|
|
@ -0,0 +1,368 @@
|
|||
# Reference
|
||||
|
||||
## Classes
|
||||
* [`klass`](#klass): A simple class.
|
||||
## Defined types
|
||||
* [`klass::dt`](#klassdt): A simple defined type.
|
||||
## Resource types
|
||||
* [`apt_key`](#apt_key): Example resource type using the new API.
|
||||
* [`database`](#database): An example database server type.
|
||||
## Functions
|
||||
* [`func`](#func): A simple Puppet function.
|
||||
* [`func3x`](#func3x): Documentation for an example 3.x function.
|
||||
* [`func4x`](#func4x): An example 4.x function.
|
||||
* [`func4x_1`](#func4x_1): An example 4.x function with only one signature.
|
||||
## Classes
|
||||
|
||||
### klass
|
||||
|
||||
* **Since** 1.0.0
|
||||
|
||||
* **See also**
|
||||
www.puppet.com
|
||||
|
||||
|
||||
#### Examples
|
||||
##### This is an example
|
||||
```puppet
|
||||
class { 'klass':
|
||||
param1 => 1,
|
||||
param3 => 'foo',
|
||||
}
|
||||
```
|
||||
|
||||
##### This is another example
|
||||
```puppet
|
||||
class { 'klass':
|
||||
param1 => 1,
|
||||
param3 => 'foo',
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### Parameters
|
||||
|
||||
The following parameters are available in the `klass` class.
|
||||
|
||||
##### `param1`
|
||||
|
||||
Data type: `Integer`
|
||||
|
||||
First param.
|
||||
|
||||
Default value: 1
|
||||
|
||||
##### `param2`
|
||||
|
||||
Data type: `Any`
|
||||
|
||||
Second param.
|
||||
|
||||
Options:
|
||||
|
||||
* **:opt1** `String`: something about opt1
|
||||
* **:opt2** `Hash`: a hash of stuff
|
||||
|
||||
Default value: `undef`
|
||||
|
||||
##### `param3`
|
||||
|
||||
Data type: `String`
|
||||
|
||||
Third param.
|
||||
|
||||
Default value: 'hi'
|
||||
|
||||
|
||||
## Defined types
|
||||
|
||||
### klass::dt
|
||||
|
||||
* **Since** 1.1.0
|
||||
|
||||
* **See also**
|
||||
www.puppet.com
|
||||
|
||||
|
||||
#### Examples
|
||||
##### Here's an example of this type:
|
||||
```puppet
|
||||
klass::dt { 'foo':
|
||||
param1 => 33,
|
||||
param4 => false,
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### Parameters
|
||||
|
||||
The following parameters are available in the `klass::dt` defined type.
|
||||
|
||||
##### `param1`
|
||||
|
||||
Data type: `Integer`
|
||||
|
||||
First param.
|
||||
|
||||
Default value: 44
|
||||
|
||||
##### `param2`
|
||||
|
||||
Data type: `Any`
|
||||
|
||||
Second param.
|
||||
|
||||
Options:
|
||||
|
||||
* **:opt1** `String`: something about opt1
|
||||
* **:opt2** `Hash`: a hash of stuff
|
||||
|
||||
##### `param3`
|
||||
|
||||
Data type: `String`
|
||||
|
||||
Third param.
|
||||
|
||||
Default value: 'hi'
|
||||
|
||||
##### `param4`
|
||||
|
||||
Data type: `Boolean`
|
||||
|
||||
Fourth param.
|
||||
|
||||
Default value: `true`
|
||||
|
||||
|
||||
## Resource types
|
||||
|
||||
### apt_key
|
||||
|
||||
This type provides Puppet with the capabilities to manage GPG keys needed
|
||||
by apt to perform package validation. Apt has it's own GPG keyring that can
|
||||
be manipulated through the `apt-key` command.
|
||||
**Autorequires**:
|
||||
If Puppet is given the location of a key file which looks like an absolute
|
||||
path this type will autorequire that file.
|
||||
|
||||
#### Examples
|
||||
##### here's an example
|
||||
```puppet
|
||||
apt_key { '6F6B15509CF8E59E6E469F327F438280EF8D349F':
|
||||
source => 'http://apt.puppetlabs.com/pubkey.gpg'
|
||||
}
|
||||
```
|
||||
|
||||
#### Properties
|
||||
|
||||
The following properties are available in the `apt_key` type.
|
||||
|
||||
##### `ensure`
|
||||
|
||||
Data type: `Enum[present, absent]`
|
||||
|
||||
Whether this apt key should be present or absent on the target system.
|
||||
|
||||
##### `created`
|
||||
|
||||
Data type: `String`
|
||||
|
||||
Date the key was created, in ISO format.
|
||||
|
||||
#### Parameters
|
||||
|
||||
The following parameters are available in the `apt_key` type.
|
||||
|
||||
##### `id`
|
||||
|
||||
namevar
|
||||
|
||||
Data type: `Variant[Pattern[/A(0x)?[0-9a-fA-F]{8}Z/], Pattern[/A(0x)?[0-9a-fA-F]{16}Z/], Pattern[/A(0x)?[0-9a-fA-F]{40}Z/]]`
|
||||
_*this data type contains a regex that may not be accurately reflected in generated documentation_
|
||||
|
||||
The ID of the key you want to manage.
|
||||
|
||||
|
||||
### database
|
||||
|
||||
An example database server type.
|
||||
|
||||
#### Examples
|
||||
##### here's an example
|
||||
```puppet
|
||||
database { 'foo':
|
||||
address => 'qux.baz.bar',
|
||||
}
|
||||
```
|
||||
|
||||
#### Properties
|
||||
|
||||
The following properties are available in the `database` type.
|
||||
|
||||
##### `ensure`
|
||||
|
||||
Valid values: present, absent, up, down
|
||||
|
||||
Aliases: "up"=>"present", "down"=>"absent"
|
||||
|
||||
What state the database should be in.
|
||||
|
||||
Default value: up
|
||||
|
||||
##### `file`
|
||||
|
||||
The database file to use.
|
||||
|
||||
##### `log_level`
|
||||
|
||||
Valid values: debug, warn, error
|
||||
|
||||
The log level to use.
|
||||
|
||||
Default value: warn
|
||||
|
||||
#### Parameters
|
||||
|
||||
The following parameters are available in the `database` type.
|
||||
|
||||
##### `address`
|
||||
|
||||
namevar
|
||||
|
||||
The database server name.
|
||||
|
||||
##### `encryption_key`
|
||||
|
||||
The encryption key to use.
|
||||
|
||||
##### `encrypt`
|
||||
|
||||
Valid values: `true`, `false`, yes, no
|
||||
|
||||
Whether or not to encrypt the database.
|
||||
|
||||
Default value: `false`
|
||||
|
||||
|
||||
## Functions
|
||||
|
||||
### func
|
||||
Type: Puppet Language
|
||||
|
||||
#### `func(Integer $param1, Any $param2, String $param3 = hi)`
|
||||
|
||||
A simple Puppet function.
|
||||
|
||||
Returns: `Undef` Returns nothing.
|
||||
|
||||
Raises:
|
||||
* `SomeError` this is some error
|
||||
|
||||
##### `param1`
|
||||
|
||||
Data type: `Integer`
|
||||
|
||||
First param.
|
||||
|
||||
##### `param2`
|
||||
|
||||
Data type: `Any`
|
||||
|
||||
Second param.
|
||||
|
||||
##### `param3`
|
||||
|
||||
Data type: `String`
|
||||
|
||||
Third param.
|
||||
|
||||
Options:
|
||||
|
||||
* **:param3opt** `Array`: Something about this option
|
||||
|
||||
### func3x
|
||||
Type: Ruby 3.x API
|
||||
|
||||
#### `func3x(String $param1, Integer $param2)`
|
||||
|
||||
Documentation for an example 3.x function.
|
||||
|
||||
Returns: `Undef`
|
||||
|
||||
##### `param1`
|
||||
|
||||
Data type: `String`
|
||||
|
||||
The first parameter.
|
||||
|
||||
##### `param2`
|
||||
|
||||
Data type: `Integer`
|
||||
|
||||
The second parameter.
|
||||
|
||||
### func4x
|
||||
Type: Ruby 4.x API
|
||||
|
||||
#### `func4x(Integer $param1, Any $param2, Optional[Array[String]] $param3)`
|
||||
|
||||
An overview for the first overload.
|
||||
|
||||
Returns: `Undef` Returns nothing.
|
||||
|
||||
##### `param1`
|
||||
|
||||
Data type: `Integer`
|
||||
|
||||
The first parameter.
|
||||
|
||||
##### `param2`
|
||||
|
||||
Data type: `Any`
|
||||
|
||||
The second parameter.
|
||||
|
||||
Options:
|
||||
|
||||
* **:option** `String`: an option
|
||||
* **:option2** `String`: another option
|
||||
|
||||
##### `param3`
|
||||
|
||||
Data type: `Optional[Array[String]]`
|
||||
|
||||
The third parameter.
|
||||
|
||||
#### `func4x(Boolean $param, Callable &$block)`
|
||||
|
||||
An overview for the second overload.
|
||||
|
||||
Returns: `String` Returns a string.
|
||||
|
||||
##### `param`
|
||||
|
||||
Data type: `Boolean`
|
||||
|
||||
The first parameter.
|
||||
|
||||
##### `&block`
|
||||
|
||||
Data type: `Callable`
|
||||
|
||||
The block parameter.
|
||||
|
||||
### func4x_1
|
||||
Type: Ruby 4.x API
|
||||
|
||||
#### `func4x_1(Integer $param1)`
|
||||
|
||||
An example 4.x function with only one signature.
|
||||
|
||||
Returns: `Undef` Returns nothing.
|
||||
|
||||
##### `param1`
|
||||
|
||||
Data type: `Integer`
|
||||
|
||||
The first parameter.
|
||||
|
|
@ -19,6 +19,8 @@ require 'mocha'
|
|||
require 'rspec'
|
||||
require 'puppet/version'
|
||||
require 'puppet-strings'
|
||||
require 'puppet-strings/markdown'
|
||||
require 'puppet-strings/markdown/base'
|
||||
require 'puppet-strings/yard'
|
||||
|
||||
# Explicitly set up YARD once
|
||||
|
|
|
@ -123,6 +123,46 @@ Puppet::Type.newtype(:database) do
|
|||
defaultto 'warn'
|
||||
end
|
||||
end
|
||||
|
||||
Puppet::ResourceApi.register_type(
|
||||
name: 'apt_key',
|
||||
desc: <<-EOS,
|
||||
@summary Example resource type using the new API.
|
||||
@raise SomeError
|
||||
This type provides Puppet with the capabilities to manage GPG keys needed
|
||||
by apt to perform package validation. Apt has it's own GPG keyring that can
|
||||
be manipulated through the `apt-key` command.
|
||||
@example here's an example
|
||||
apt_key { '6F6B15509CF8E59E6E469F327F438280EF8D349F':
|
||||
source => 'http://apt.puppetlabs.com/pubkey.gpg'
|
||||
}
|
||||
|
||||
**Autorequires**:
|
||||
If Puppet is given the location of a key file which looks like an absolute
|
||||
path this type will autorequire that file.
|
||||
EOS
|
||||
attributes: {
|
||||
ensure: {
|
||||
type: 'Enum[present, absent]',
|
||||
desc: 'Whether this apt key should be present or absent on the target system.'
|
||||
},
|
||||
id: {
|
||||
type: 'Variant[Pattern[/\A(0x)?[0-9a-fA-F]{8}\Z/], Pattern[/\A(0x)?[0-9a-fA-F]{16}\Z/], Pattern[/\A(0x)?[0-9a-fA-F]{40}\Z/]]',
|
||||
behaviour: :namevar,
|
||||
desc: 'The ID of the key you want to manage.',
|
||||
},
|
||||
# ...
|
||||
created: {
|
||||
type: 'String',
|
||||
behaviour: :read_only,
|
||||
desc: 'Date the key was created, in ISO format.',
|
||||
},
|
||||
},
|
||||
autorequires: {
|
||||
file: '$source', # will evaluate to the value of the `source` attribute
|
||||
package: 'apt',
|
||||
},
|
||||
)
|
||||
SOURCE
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe PuppetStrings::Markdown::Base do
|
||||
context 'basic class' do
|
||||
before :each do
|
||||
YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet)
|
||||
# An overview
|
||||
# @summary A simple class.
|
||||
# @param param1 First param.
|
||||
# @param param2 Second param.
|
||||
# @param param3 Third param.
|
||||
class klass(Integer $param1, $param2, String $param3 = hi) inherits foo::bar {
|
||||
}
|
||||
SOURCE
|
||||
end
|
||||
|
||||
let(:reg) { YARD::Registry.all(:puppet_class).sort_by!(&:name).map!(&:to_hash)[0] }
|
||||
let(:component) { PuppetStrings::Markdown::Base.new(reg, 'class') }
|
||||
|
||||
describe '#name' do
|
||||
it 'returns the expected name' do
|
||||
expect(component.name).to eq 'klass'
|
||||
end
|
||||
end
|
||||
|
||||
[ 'examples',
|
||||
'see',
|
||||
'since',
|
||||
'return_val',
|
||||
'return_type',].each do |method|
|
||||
describe "##{method}" do
|
||||
it 'returns nil' do
|
||||
expect(component.method(method.to_sym).call).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#params' do
|
||||
it 'returns the expected params' do
|
||||
expect(component.params.size).to eq 3
|
||||
end
|
||||
end
|
||||
|
||||
describe '#summary' do
|
||||
it 'returns the expected summary' do
|
||||
expect(component.summary).to eq 'A simple class.'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#toc_info' do
|
||||
let(:toc) { component.toc_info }
|
||||
it 'returns a hash' do
|
||||
expect(toc).to be_instance_of Hash
|
||||
end
|
||||
it 'prefers the summary for :desc' do
|
||||
expect(toc[:desc]).to eq 'A simple class.'
|
||||
end
|
||||
end
|
||||
end
|
||||
context 'less basic class' do
|
||||
before :each do
|
||||
YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet)
|
||||
# An overview
|
||||
# It's a longer overview
|
||||
# Ya know?
|
||||
# @example A simple example.
|
||||
# class { 'klass::yeah':
|
||||
# param1 => 1,
|
||||
# }
|
||||
# @param param1 First param.
|
||||
# @param param2 Second param.
|
||||
# @param param3 Third param.
|
||||
class klass::yeah(
|
||||
Integer $param1,
|
||||
$param2,
|
||||
String $param3 = hi
|
||||
) inherits foo::bar {
|
||||
|
||||
}
|
||||
SOURCE
|
||||
end
|
||||
|
||||
let(:reg) { YARD::Registry.all(:puppet_class).sort_by!(&:name).map!(&:to_hash)[0] }
|
||||
let(:component) { PuppetStrings::Markdown::Base.new(reg, 'class') }
|
||||
|
||||
describe '#name' do
|
||||
it 'returns the expected name' do
|
||||
expect(component.name).to eq 'klass::yeah'
|
||||
end
|
||||
end
|
||||
|
||||
['summary',
|
||||
'see',
|
||||
'since',
|
||||
'return_val',
|
||||
'return_type'].each do |method|
|
||||
describe "##{method}" do
|
||||
it 'returns nil' do
|
||||
expect(component.method(method.to_sym).call).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#examples' do
|
||||
it 'should return one example' do
|
||||
expect(component.examples.size).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
describe '#params' do
|
||||
it 'returns the expected params' do
|
||||
expect(component.params.size).to eq 3
|
||||
end
|
||||
end
|
||||
|
||||
describe '#toc_info' do
|
||||
let(:toc) { component.toc_info }
|
||||
it 'returns a hash' do
|
||||
expect(toc).to be_instance_of Hash
|
||||
end
|
||||
it 'uses overview for :desc in absence of summary' do
|
||||
expect(toc[:desc]).to eq 'An overview. It\'s a longer overview. Ya know?'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link' do
|
||||
it 'returns a valid link' do
|
||||
expect(component.link).to eq 'klassyeah'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,244 @@
|
|||
require 'spec_helper'
|
||||
require 'puppet-strings/markdown'
|
||||
require 'puppet-strings/markdown/table_of_contents'
|
||||
require 'tempfile'
|
||||
|
||||
describe PuppetStrings::Markdown do
|
||||
before :each do
|
||||
# Populate the YARD registry with both Puppet and Ruby source
|
||||
YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet)
|
||||
# An overview for a simple class.
|
||||
# @summary A simple class.
|
||||
# @since 1.0.0
|
||||
# @see www.puppet.com
|
||||
# @example This is an example
|
||||
# class { 'klass':
|
||||
# param1 => 1,
|
||||
# param3 => 'foo',
|
||||
# }
|
||||
# @example This is another example
|
||||
# class { 'klass':
|
||||
# param1 => 1,
|
||||
# param3 => 'foo',
|
||||
# }
|
||||
# @raise SomeError
|
||||
# @param param1 First param.
|
||||
# @param param2 Second param.
|
||||
# @option param2 [String] :opt1 something about opt1
|
||||
# @option param2 [Hash] :opt2 a hash of stuff
|
||||
# @param param3 Third param.
|
||||
#
|
||||
class klass (
|
||||
Integer $param1 = 1,
|
||||
$param2 = undef,
|
||||
String $param3 = 'hi'
|
||||
) inherits foo::bar {
|
||||
}
|
||||
|
||||
# An overview for a simple defined type.
|
||||
# @summary A simple defined type.
|
||||
# @since 1.1.0
|
||||
# @see www.puppet.com
|
||||
# @example Here's an example of this type:
|
||||
# klass::dt { 'foo':
|
||||
# param1 => 33,
|
||||
# param4 => false,
|
||||
# }
|
||||
# @return shouldn't return squat
|
||||
# @raise SomeError
|
||||
# @param param1 First param.
|
||||
# @param param2 Second param.
|
||||
# @option param2 [String] :opt1 something about opt1
|
||||
# @option param2 [Hash] :opt2 a hash of stuff
|
||||
# @param param3 Third param.
|
||||
# @param param4 Fourth param.
|
||||
define klass::dt (
|
||||
Integer $param1 = 44,
|
||||
$param2,
|
||||
String $param3 = 'hi',
|
||||
Boolean $param4 = true
|
||||
) {
|
||||
}
|
||||
SOURCE
|
||||
|
||||
YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet)
|
||||
# A simple Puppet function.
|
||||
# @param param1 First param.
|
||||
# @param param2 Second param.
|
||||
# @param param3 Third param.
|
||||
# @option param3 [Array] :param3opt Something about this option
|
||||
# @raise SomeError this is some error
|
||||
# @return [Undef] Returns nothing.
|
||||
function func(Integer $param1, $param2, String $param3 = hi) {
|
||||
}
|
||||
SOURCE
|
||||
|
||||
YARD::Parser::SourceParser.parse_string(<<-SOURCE, :ruby)
|
||||
# An example 4.x function.
|
||||
Puppet::Functions.create_function(:func4x) do
|
||||
# An overview for the first overload.
|
||||
# @raise SomeError this is some error
|
||||
# @param param1 The first parameter.
|
||||
# @param param2 The second parameter.
|
||||
# @option param2 [String] :option an option
|
||||
# @option param2 [String] :option2 another option
|
||||
# @param param3 The third parameter.
|
||||
# @return Returns nothing.
|
||||
dispatch :foo do
|
||||
param 'Integer', :param1
|
||||
param 'Any', :param2
|
||||
optional_param 'Array[String]', :param3
|
||||
return_type 'Undef'
|
||||
end
|
||||
|
||||
# An overview for the second overload.
|
||||
# @param param The first parameter.
|
||||
# @param block The block parameter.
|
||||
# @return Returns a string.
|
||||
dispatch :other do
|
||||
param 'Boolean', :param
|
||||
block_param
|
||||
return_type 'String'
|
||||
end
|
||||
end
|
||||
|
||||
# An example 4.x function with only one signature.
|
||||
Puppet::Functions.create_function(:func4x_1) do
|
||||
# @param param1 The first parameter.
|
||||
# @return [Undef] Returns nothing.
|
||||
dispatch :foobarbaz do
|
||||
param 'Integer', :param1
|
||||
end
|
||||
end
|
||||
|
||||
# An example 3.x function
|
||||
Puppet::Parser::Functions.newfunction(:func3x, doc: <<-DOC
|
||||
Documentation for an example 3.x function.
|
||||
@param param1 [String] The first parameter.
|
||||
@param param2 [Integer] The second parameter.
|
||||
@return [Undef]
|
||||
@example Calling the function.
|
||||
func3x('hi', 10)
|
||||
DOC
|
||||
) do |*args|
|
||||
#...
|
||||
end
|
||||
|
||||
Puppet::Type.type(:database).provide :linux do
|
||||
desc 'An example provider on Linux.'
|
||||
confine kernel: 'Linux'
|
||||
confine osfamily: 'RedHat'
|
||||
defaultfor :kernel => 'Linux'
|
||||
defaultfor :osfamily => 'RedHat', :operatingsystemmajrelease => '7'
|
||||
has_feature :implements_some_feature
|
||||
has_feature :some_other_feature
|
||||
commands foo: '/usr/bin/foo'
|
||||
end
|
||||
|
||||
Puppet::Type.newtype(:database) do
|
||||
desc <<-DESC
|
||||
An example database server type.
|
||||
@option opts :foo bar
|
||||
@raise SomeError
|
||||
@example here's an example
|
||||
database { 'foo':
|
||||
address => 'qux.baz.bar',
|
||||
}
|
||||
DESC
|
||||
feature :encryption, 'The provider supports encryption.', methods: [:encrypt]
|
||||
ensurable do
|
||||
desc 'What state the database should be in.'
|
||||
defaultvalues
|
||||
aliasvalue(:up, :present)
|
||||
aliasvalue(:down, :absent)
|
||||
defaultto :up
|
||||
end
|
||||
|
||||
newparam(:address) do
|
||||
isnamevar
|
||||
desc 'The database server name.'
|
||||
end
|
||||
|
||||
newparam(:encryption_key, required_features: :encryption) do
|
||||
desc 'The encryption key to use.'
|
||||
end
|
||||
|
||||
newparam(:encrypt, :parent => Puppet::Parameter::Boolean) do
|
||||
desc 'Whether or not to encrypt the database.'
|
||||
defaultto false
|
||||
end
|
||||
|
||||
newproperty(:file) do
|
||||
desc 'The database file to use.'
|
||||
end
|
||||
|
||||
newproperty(:log_level) do
|
||||
desc 'The log level to use.'
|
||||
newvalue(:debug)
|
||||
newvalue(:warn)
|
||||
newvalue(:error)
|
||||
defaultto 'warn'
|
||||
end
|
||||
end
|
||||
|
||||
Puppet::ResourceApi.register_type(
|
||||
name: 'apt_key',
|
||||
desc: <<-EOS,
|
||||
@summary Example resource type using the new API.
|
||||
@raise SomeError
|
||||
This type provides Puppet with the capabilities to manage GPG keys needed
|
||||
by apt to perform package validation. Apt has it's own GPG keyring that can
|
||||
be manipulated through the `apt-key` command.
|
||||
@example here's an example
|
||||
apt_key { '6F6B15509CF8E59E6E469F327F438280EF8D349F':
|
||||
source => 'http://apt.puppetlabs.com/pubkey.gpg'
|
||||
}
|
||||
|
||||
**Autorequires**:
|
||||
If Puppet is given the location of a key file which looks like an absolute
|
||||
path this type will autorequire that file.
|
||||
EOS
|
||||
attributes: {
|
||||
ensure: {
|
||||
type: 'Enum[present, absent]',
|
||||
desc: 'Whether this apt key should be present or absent on the target system.'
|
||||
},
|
||||
id: {
|
||||
type: 'Variant[Pattern[/\A(0x)?[0-9a-fA-F]{8}\Z/], Pattern[/\A(0x)?[0-9a-fA-F]{16}\Z/], Pattern[/\A(0x)?[0-9a-fA-F]{40}\Z/]]',
|
||||
behaviour: :namevar,
|
||||
desc: 'The ID of the key you want to manage.',
|
||||
},
|
||||
# ...
|
||||
created: {
|
||||
type: 'String',
|
||||
behaviour: :read_only,
|
||||
desc: 'Date the key was created, in ISO format.',
|
||||
},
|
||||
},
|
||||
autorequires: {
|
||||
file: '$source', # will evaluate to the value of the `source` attribute
|
||||
package: 'apt',
|
||||
},
|
||||
)
|
||||
SOURCE
|
||||
end
|
||||
|
||||
let(:filename) { 'output.md' }
|
||||
let(:baseline_path) { File.join(File.dirname(__FILE__), "../../fixtures/unit/markdown/#{filename}") }
|
||||
let(:baseline) { File.read(baseline_path) }
|
||||
|
||||
describe 'rendering markdown to a file' do
|
||||
it 'should output the expected markdown content' do
|
||||
Tempfile.open('md') do |file|
|
||||
PuppetStrings::Markdown.render(file.path)
|
||||
expect(File.read(file.path)).to eq(baseline)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'rendering markdown to stdout' do
|
||||
it 'should output the expected markdown content' do
|
||||
expect{ PuppetStrings::Markdown.render }.to output(baseline).to_stdout
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue