yard-chefdoc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +15 -0
  3. data/LICENSE +20 -0
  4. data/README.md +103 -0
  5. data/Rakefile +30 -0
  6. data/lib/yard/cli/stats.rb +142 -0
  7. data/lib/yard-chefdoc/code_objects/attribute.rb +43 -0
  8. data/lib/yard-chefdoc/code_objects/chef.rb +116 -0
  9. data/lib/yard-chefdoc/code_objects/cookbook.rb +55 -0
  10. data/lib/yard-chefdoc/code_objects/recipe.rb +29 -0
  11. data/lib/yard-chefdoc/code_objects/resource.rb +70 -0
  12. data/lib/yard-chefdoc/handlers/attribute.rb +32 -0
  13. data/lib/yard-chefdoc/handlers/base.rb +36 -0
  14. data/lib/yard-chefdoc/handlers/cookbook.rb +40 -0
  15. data/lib/yard-chefdoc/handlers/recipe.rb +15 -0
  16. data/lib/yard-chefdoc/handlers/resource_action.rb +31 -0
  17. data/lib/yard-chefdoc/handlers/resource_default_action.rb +16 -0
  18. data/lib/yard-chefdoc/handlers/resource_property.rb +54 -0
  19. data/lib/yard-chefdoc/handlers/resource_resource_name.rb +16 -0
  20. data/lib/yard-chefdoc/template_helpers/chef.rb +24 -0
  21. data/lib/yard-chefdoc/version.rb +9 -0
  22. data/lib/yard-chefdoc.rb +50 -0
  23. data/spec/attributes_spec.rb +19 -0
  24. data/spec/home_spec.rb +42 -0
  25. data/spec/recipes_spec.rb +15 -0
  26. data/spec/resources_spec.rb +11 -0
  27. data/spec/spec_helper.rb +32 -0
  28. data/templates/default/attribute/html/attribute.erb +30 -0
  29. data/templates/default/attribute/html/setup.rb +5 -0
  30. data/templates/default/cookbook/html/attributes.erb +14 -0
  31. data/templates/default/cookbook/html/cookbook_title.erb +2 -0
  32. data/templates/default/cookbook/html/docstring.erb +1 -0
  33. data/templates/default/cookbook/html/element_details.erb +3 -0
  34. data/templates/default/cookbook/html/generated_docs.erb +2 -0
  35. data/templates/default/cookbook/html/libraries.erb +13 -0
  36. data/templates/default/cookbook/html/metadata.erb +86 -0
  37. data/templates/default/cookbook/html/recipes.erb +14 -0
  38. data/templates/default/cookbook/html/resources.erb +14 -0
  39. data/templates/default/cookbook/html/setup.rb +9 -0
  40. data/templates/default/fulldoc/html/css/chefdoc.css +52 -0
  41. data/templates/default/fulldoc/html/full_list_attributes.erb +14 -0
  42. data/templates/default/fulldoc/html/full_list_libraries.erb +6 -0
  43. data/templates/default/fulldoc/html/full_list_recipes.erb +13 -0
  44. data/templates/default/fulldoc/html/full_list_resources.erb +13 -0
  45. data/templates/default/fulldoc/html/setup.rb +117 -0
  46. data/templates/default/layout/html/layout.erb +24 -0
  47. data/templates/default/layout/html/setup.rb +81 -0
  48. data/templates/default/layout/html/title.erb +1 -0
  49. data/templates/default/recipe/html/recipe.erb +8 -0
  50. data/templates/default/recipe/html/setup.rb +8 -0
  51. data/templates/default/recipe/html/source.erb +10 -0
  52. data/templates/default/resource/html/actions.erb +19 -0
  53. data/templates/default/resource/html/properties.erb +18 -0
  54. data/templates/default/resource/html/resource.erb +3 -0
  55. data/templates/default/resource/html/setup.rb +15 -0
  56. metadata +111 -0
@@ -0,0 +1,36 @@
1
+ require 'yard'
2
+
3
+ module YARD::Handlers
4
+ module Chef
5
+ # Base handler for chef elements.
6
+ class Base < YARD::Handlers::Ruby::Base
7
+ include YARD::CodeObjects::Chef
8
+
9
+ # Gets the name of the handled object.
10
+ #
11
+ def name
12
+ statement.parameters.first.jump(:string_content, :ident).source
13
+ end
14
+
15
+ # Gets the filename which is often used as the object name in chef
16
+ #
17
+ # @return [String] the file name without the rb extension
18
+ #
19
+ def filename
20
+ File.basename(statement.file, '.rb')
21
+ end
22
+
23
+ # Registers the cookbook in {YARD::Registry} and returns the same.
24
+ #
25
+ # @return [ChefObject] the ChefObject
26
+ #
27
+ def cookbook
28
+ cbs = YARD::Registry.all(:cookbook)
29
+ raise 'Something went wrong! Found more that one cookbook.' if cbs.length > 1
30
+ raise 'Something went wrong! Could not find any cookbook' if cbs.empty?
31
+
32
+ cbs.first
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,40 @@
1
+ require 'yard'
2
+
3
+ module YARD::Handlers
4
+ module Chef
5
+ # Handles specific cookbook information like README, description and version.
6
+ #
7
+ class CookbookHandler < Base
8
+ in_file(/^metadata\.json$/)
9
+ handles(/.*/) # Handle the file itself, so everything in it
10
+
11
+ def process
12
+ metadata = JSON.parse(File.read(File.expand_path(statement.file)))
13
+ base_dir = File.dirname(statement.file)
14
+
15
+ cookbook_obj = cookbook
16
+
17
+ %w[name version dependencies source_url
18
+ issues_url maintainer maintainer_email
19
+ license platforms gems].each do |m|
20
+ cookbook_obj.send("#{m}=", metadata[m]) if metadata.key?(m)
21
+ end
22
+
23
+ cookbook_obj.docstring = docstring(base_dir)
24
+ cookbook_obj.docstring_type = :markdown
25
+ end
26
+
27
+ # Generates docstring from the README file.
28
+ #
29
+ # @return [YARD::Docstring] the docstring
30
+ #
31
+ def docstring(base_dir)
32
+ string = ''
33
+ readme_path = base_dir + '/README.md'
34
+ string = IO.read(readme_path) if File.exist?(readme_path)
35
+
36
+ YARD::DocstringParser.new.parse(string).to_docstring
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,15 @@
1
+ require 'yard'
2
+
3
+ module YARD::Handlers
4
+ module Chef
5
+ # Handles "recipes" in a cookbook.
6
+ class RecipeHandler < Base
7
+ in_file(%r{^recipes\/.*\.rb$})
8
+ handles(/.*/) # Handle the file itself, so everything in it
9
+
10
+ def process
11
+ ChefObject.register(filename, :recipe, statement.file)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,31 @@
1
+ require 'yard'
2
+
3
+ module YARD::Handlers
4
+ module Chef
5
+ # Handles actions in custom resources and LWRPs
6
+ class ResourceActionHandler < Base
7
+ in_file(%r{^resources\/.*\.rb$})
8
+ handles method_call(:action)
9
+
10
+ def process
11
+ resource_obj = ChefObject.register(filename, :resource, statement.file)
12
+
13
+ docstring_is_header = (statement.docstring == resource_obj.header)
14
+ resource_obj.add_action action_hash(docstring_is_header)
15
+ end
16
+
17
+ # Creates the hash to initialize the single resource property object
18
+ #
19
+ # @return [Hash] the hash to initialize the property in the resource code object
20
+ #
21
+ def action_hash(nodoc)
22
+ {
23
+ identifier: statement[1][0].source.to_s[1..-1],
24
+ source: statement.source,
25
+ docstring: nodoc ? '' : statement.docstring,
26
+ line: statement.line
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,16 @@
1
+ require 'yard'
2
+
3
+ module YARD::Handlers
4
+ module Chef
5
+ # Handles the default_action in custom resources and LWRPs
6
+ class ResourceDefaultActionHandler < Base
7
+ in_file(%r{^resources\/.*\.rb$})
8
+ handles method_call(:default_action)
9
+
10
+ def process
11
+ resource_obj = ChefObject.register(filename, :resource, statement.file)
12
+ resource_obj.default_action = statement.parameters[0][0][0].source # Gets the first parameter as string
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,54 @@
1
+ require 'yard'
2
+
3
+ module YARD::Handlers
4
+ module Chef
5
+ # Handles properties in custom resources and LWRPs
6
+ class ResourcePropertyHandler < Base
7
+ in_file(%r{^resources\/.*\.rb$})
8
+ handles method_call(:property)
9
+
10
+ def process
11
+ resource_obj = ChefObject.register(filename, :resource, statement.file)
12
+
13
+ docstring_is_header = (statement.docstring == resource_obj.header)
14
+ resource_obj.add_property res_prop_hash(docstring_is_header)
15
+ end
16
+
17
+ # Creates the hash to initialize the single resource property object
18
+ #
19
+ # @return [Hash] the hash to initialize the property in the resource code object
20
+ #
21
+ def res_prop_hash(nodoc)
22
+ props = {}
23
+ statement[1].entries.each do |e|
24
+ next if e == false
25
+ if %i[var_ref array].include?(e.type)
26
+ props[:type] = e.source
27
+ elsif e.type == :symbol_literal
28
+ props[:identifier] = e.source.delete(':')
29
+ elsif e.type == :list
30
+ props[:options] = parse_option_list(e)
31
+ end
32
+ end
33
+ props[:docstring] = nodoc ? '' : statement.docstring
34
+
35
+ props
36
+ end
37
+
38
+ # Goes through the option list AST node and returns a simple hash
39
+ #
40
+ # @return [Hash] The options passed as a hash
41
+ #
42
+ def parse_option_list(list)
43
+ return nil if list.nil? || list.empty?
44
+ opts = {}
45
+ list.each do |opt|
46
+ next unless opt.type == :assoc
47
+ opts[opt[0].source.delete(':')] = opt[1].source
48
+ end
49
+
50
+ opts
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,16 @@
1
+ require 'yard'
2
+
3
+ module YARD::Handlers
4
+ module Chef
5
+ # Handles the resource name in custom resources and LWRPs
6
+ class ResourceResourceNameHandler < Base
7
+ in_file(%r{^resources\/.*\.rb$})
8
+ handles method_call(:resource_name)
9
+
10
+ def process
11
+ resource_obj = ChefObject.register(filename, :resource, statement.file)
12
+ resource_obj.resource_name = statement.parameters[0][0][0].source # Gets the first parameter as string
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YARD::Templates::Helpers
4
+ # The chef helper module
5
+ module ChefHelper
6
+ # Returns children of an object of a particular type sorted the chef
7
+ # way. This means that the object with the name 'default' will be first
8
+ # and any remaining objects will be sorted alphabetically.
9
+ #
10
+ # @param type [Symbol] type of CookbookObject to be selected
11
+ #
12
+ # @return [Array<CookbookObject>] list of CookbookObjects
13
+ #
14
+ def chefsorted_objects(type = nil)
15
+ children = ::YARD::Registry.all.select { |o| o.type == type }.sort { |x, y| x.name.to_s <=> y.name.to_s }
16
+ default_index = children.find_index { |r| r.name.to_s == 'default' }
17
+
18
+ return children if default_index.nil?
19
+
20
+ default_child = children.delete_at(default_index)
21
+ [default_child].concat(children)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YARD
4
+ module CodeObjects
5
+ module Chef
6
+ VERSION = '0.1.0'.freeze
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,50 @@
1
+ require 'yard'
2
+ require 'json'
3
+
4
+ require_relative 'yard/cli/stats'
5
+
6
+ require 'yard-chefdoc/code_objects/chef'
7
+ require 'yard-chefdoc/code_objects/cookbook'
8
+ require 'yard-chefdoc/code_objects/recipe'
9
+ require 'yard-chefdoc/code_objects/attribute'
10
+ require 'yard-chefdoc/code_objects/resource'
11
+
12
+ require 'yard-chefdoc/handlers/base'
13
+ require 'yard-chefdoc/handlers/cookbook'
14
+ require 'yard-chefdoc/handlers/recipe'
15
+ require 'yard-chefdoc/handlers/attribute'
16
+ require 'yard-chefdoc/handlers/resource_property'
17
+ require 'yard-chefdoc/handlers/resource_action'
18
+ require 'yard-chefdoc/handlers/resource_resource_name'
19
+ require 'yard-chefdoc/handlers/resource_default_action'
20
+
21
+ require 'yard-chefdoc/template_helpers/chef'
22
+
23
+ require 'yard-chefdoc/version'
24
+
25
+ module YARD::CodeObjects
26
+ module Chef
27
+ # Initialize the whole magic
28
+ namespace = ChefObject.new(nil, :root)
29
+ CookbookObject.new(namespace, :root)
30
+ end
31
+
32
+ # YARD::Tags::Library.define_tag('Recipe description', :recipe)
33
+
34
+ # Register template directory for the chef plugin
35
+ template_dir = File.expand_path('../templates', File.dirname(__FILE__))
36
+ YARD::Templates::Engine.register_template_path(template_dir.to_s)
37
+ end
38
+
39
+ module YARD
40
+ module CLI
41
+ class Yardoc
42
+ # This overrides the method from Yard adding Chefs own objects to be rendered
43
+ # as individual pages. This adds recipes, attributes...
44
+ # @return [Array<CodeObjects::Base>] a list of code objects to process
45
+ def all_objects
46
+ Registry.all(:root, :module, :class, :recipe, :attribute, :resource)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'home page' do
4
+ before(:each) do
5
+ visit('/docs/attribute/default')
6
+ end
7
+
8
+ it 'shows the description' do
9
+ expect(page).to have_content('Some default attributes')
10
+ end
11
+
12
+ it 'has the test-attribute1' do
13
+ expect(page).to have_content("['test-cookbook1']['test-attribute1']")
14
+ end
15
+
16
+ it 'has the test-attribute1 description' do
17
+ expect(page).to have_content('This is the documentation of an attribute')
18
+ end
19
+ end
data/spec/home_spec.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'home page' do
4
+ before(:each) do
5
+ visit('/')
6
+ end
7
+
8
+ it 'presents the README' do
9
+ expect(page).to have_content('Lorem ipsum dolor sit amet')
10
+ end
11
+
12
+ it 'shows metadata version' do
13
+ expect(page).to have_tag('td', text: '0.1.0')
14
+ end
15
+
16
+ it 'does not show empty license' do
17
+ expect(page).to_not have_tag('td', text: 'License')
18
+ end
19
+
20
+ it 'shows the recipe summary' do
21
+ expect(page).to have_content('Recipes summary')
22
+ expect(page).to have_content('Installs the system package for some_service')
23
+ end
24
+
25
+ it 'shows the attribute summary' do
26
+ expect(page).to have_content('Attributes summary')
27
+ end
28
+
29
+ it 'gives an overview of the libraries' do
30
+ expect(page).to have_content('Finder')
31
+ expect(page).to have_content('Finder::Node')
32
+ expect(page).to have_content('MyTestLib')
33
+ end
34
+
35
+ it 'shows cookbook documentation table' do
36
+ expect(page).to have_content('Cookbook documentation statistics')
37
+ end
38
+
39
+ it 'shows overall percentage' do
40
+ expect(page).to have_content('Total percentage 86.96%')
41
+ end
42
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'home page' do
4
+ before(:each) do
5
+ visit('/docs/recipe/default')
6
+ end
7
+
8
+ it 'shows the description' do
9
+ expect(page).to have_content('This is the description for the default recipe')
10
+ end
11
+
12
+ it 'shows the recipe file name and location' do
13
+ expect(find(:xpath, "//span[@class='info file']").text).to eq('# File \'recipes/default.rb\'')
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'home page' do
4
+ before(:each) do
5
+ visit('/docs/resource/etc_dir')
6
+ end
7
+
8
+ it 'shows the default_action as create' do
9
+ expect(page).to have_content('Default action: create')
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ require 'rspec'
2
+ require 'rspec-html-matchers'
3
+ require 'action_view'
4
+
5
+ # Add this to load Capybara integration:
6
+ require 'capybara'
7
+ require 'capybara/rspec'
8
+ # require 'capybara/rails'
9
+ require 'capybara/dsl'
10
+
11
+ require 'yard'
12
+ require_relative '../lib/yard-chefdoc'
13
+
14
+ RSpec.configure do |config|
15
+ config.include Capybara::DSL
16
+ config.include RSpecHtmlMatchers
17
+ end
18
+
19
+ # disable :run
20
+ # From: https://github.com/lsegal/yard/blob/master/lib/yard/cli/server.rb#L50
21
+ doc_root = File.expand_path('../../test/fixtures/test-cookbook1', __FILE__)
22
+ server_options = {
23
+ Port: 8808
24
+ }
25
+ db = File.expand_path('.yardoc', doc_root)
26
+ libver = YARD::Server::LibraryVersion.new('test-cookbook1', nil, db)
27
+ libver.source_path = doc_root
28
+ libraries = {
29
+ 'test-cookbook1' => [libver]
30
+ }
31
+ options = SymbolHash.new(false).update(single_library: true, caching: false)
32
+ Capybara.app = YARD::Server::RackAdapter.new(libraries, options, server_options)
@@ -0,0 +1,30 @@
1
+ <h2>Attribute <%= object.name %></h2>
2
+ <%= htmlify(object.docstring, :markdown) %>
3
+ <table style="width:100%">
4
+ <thead>
5
+ <th>Attribute</th>
6
+ <th>Precedence</th>
7
+ <th>Description</th>
8
+ <th>Default value</th>
9
+ </thead>
10
+ <tbody>
11
+ <% n = 2 %>
12
+ <% object.attributes.each do |attribute| %>
13
+ <tr class="r<%= n %>">
14
+ <td>
15
+ <strong><%= attribute.path %></strong>
16
+ </td>
17
+ <td><%= attribute.precedence %></td>
18
+ <td><%= htmlify attribute.docstring %></td>
19
+ <td>
20
+ <% if attribute.default.size > 60 %>
21
+ <span>[<a href="#" onclick="return false;" class="toggleSource">View source</a>]</span><br /><span class="source_code"><%= htmlify attribute.default %></span>
22
+ <% else %>
23
+ <%= htmlify attribute.default %>
24
+ <%end%>
25
+ </td>
26
+ </tr>
27
+ <% n = n == 1 ? 2 : 1 %>
28
+ <% end %>
29
+ </tbody>
30
+ </table>
@@ -0,0 +1,5 @@
1
+ include Helpers::ChefHelper
2
+
3
+ def init
4
+ sections.push :attribute
5
+ end
@@ -0,0 +1,14 @@
1
+ <% attributes = chefsorted_objects(:attribute) %>
2
+ <% if attributes.size > 0 %>
3
+ <h2>Attributes summary</h2>
4
+ <ul class="summary">
5
+ <% attributes.each do |attribute| %>
6
+ <li>
7
+ <span class="summary_signature">
8
+ <strong><a href="<%= url_for(attribute,nil) %>"><%= attribute.name %></a></strong>
9
+ </span>
10
+ <span class="summary_desc"><%= htmlify(attribute.docstring, :markdown) %></span>
11
+ </li>
12
+ <% end %>
13
+ </ul>
14
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <h1>Cookbook <%= object.name.to_s %></h1>
2
+ <%= yieldall %>
@@ -0,0 +1 @@
1
+ <%= htmlify(object.docstring, object.docstring_type) %>
@@ -0,0 +1,3 @@
1
+ <div class="method_details_list">
2
+ <%= yieldall %>
3
+ </div>
@@ -0,0 +1,2 @@
1
+ <h1>Cookbook elements overview</h1>
2
+ <%= yieldall %>
@@ -0,0 +1,13 @@
1
+ <% libraries = object.libraries %>
2
+ <% if libraries.size > 0 %>
3
+ <h2>Libraries</h2>
4
+ <ul class="summary compact">
5
+ <% libraries.each do |lib| %>
6
+ <li>
7
+ <span class="summary_signature">
8
+ <a href="<%= url_for(lib, nil) %>"><%= lib %></a>
9
+ </span>
10
+ </li>
11
+ <% end %>
12
+ </ul>
13
+ <% end %>
@@ -0,0 +1,86 @@
1
+ <table class="metadata-box">
2
+ <tr>
3
+ <th class="merged" colspan="2">Cookbook metadata</th>
4
+ </tr>
5
+ <% { 'name' => 'Name',
6
+ 'version' => 'Version',
7
+ 'maintainer' => 'Maintainer',
8
+ 'maintainer_email' => 'Contact',
9
+ 'license' => 'License',
10
+ 'source_url' => 'Source',
11
+ 'issues_url' => 'Issues'}.each do |m, n| %>
12
+ <% meta_info = object.send(m.to_sym) %>
13
+ <% next if meta_info.nil? || meta_info.empty? %>
14
+ <tr>
15
+ <td><%= n %></td>
16
+ <% if m.end_with?('_url') %>
17
+ <td><a href="<%= meta_info %>" target="_blank"><%= meta_info %></a></td>
18
+ <% else %>
19
+ <td><%= meta_info %></td>
20
+ <% end %>
21
+ </tr>
22
+ <% end %>
23
+
24
+ <% unless object.dependencies.nil? || object.dependencies.empty? %>
25
+ <tr class="section">
26
+ <td class="merged" colspan="2">Dependencies</td>
27
+ </tr>
28
+ <% object.dependencies.each do |cookbook, version| %>
29
+ <tr>
30
+ <td><%= cookbook %></td>
31
+ <td><%= version %> </td>
32
+ </tr>
33
+ <% end %>
34
+ <% end %>
35
+ <% unless object.platforms.nil? || object.platforms.empty? %>
36
+ <tr class="section">
37
+ <td class="merged" colspan="2">Supported platforms</td>
38
+ </tr>
39
+ <% object.platforms.each do |platform, version| %>
40
+ <tr>
41
+ <td><%= platform %></td>
42
+ <td><%= version %> </td>
43
+ </tr>
44
+ <% end %>
45
+ <% end %>
46
+ <% unless object.gems.nil? || object.gems.empty? %>
47
+ <tr class="section">
48
+ <td class="merged" colspan="2">Rubygem dependencies</td>
49
+ </tr>
50
+ <% object.gems.each do |g| %>
51
+ <tr>
52
+ <td colspan="2"><%= g %></td>
53
+ </tr>
54
+ <% end %>
55
+ <% end %>
56
+ </table>
57
+
58
+ <table class="metadata-box">
59
+ <tr>
60
+ <th class="merged" colspan="2">Cookbook documentation statistics</th>
61
+ </tr>
62
+ <tr>
63
+ <td>Total percentage</td>
64
+ <td><%= @cookbook_statistics['total_percentage'].round(2) %>%</td>
65
+ </tr>
66
+ <tr>
67
+ <td class="merged" colspan="2">Chef</th>
68
+ </tr>
69
+ <% @cookbook_statistics.each do |stat, values| %>
70
+ <% next unless (values.is_a?(Hash) && stat.start_with?('chef_') && !values['items'].zero?) %>
71
+ <tr>
72
+ <td><%= values['name'].sub(/^Chef\s/, '') %></td>
73
+ <td><%= values['percentage'].to_f.round(1) %>% (<%= values['items'] - values['undocumented'] %> of <%= values['items'] %>)</td>
74
+ </tr>
75
+ <% end %>
76
+ <tr>
77
+ <td class="merged" colspan="2">Ruby</th>
78
+ </tr>
79
+ <% @cookbook_statistics.each do |stat, values| %>
80
+ <% next unless (values.is_a?(Hash) && !stat.start_with?('chef_') && !values['items'].zero?) %>
81
+ <tr>
82
+ <td><%= values['name'] %></td>
83
+ <td><%= values['percentage'].to_f.round(1) %>% (<%= values['items'] - values['undocumented'] %> of <%= values['items'] %>)</td>
84
+ </tr>
85
+ <% end %>
86
+ </table>
@@ -0,0 +1,14 @@
1
+ <% recipes = chefsorted_objects(:recipe) %>
2
+ <% if recipes.size > 0 %>
3
+ <h2>Recipes summary</h2>
4
+ <ul class="summary">
5
+ <% recipes.each do |recipe| %>
6
+ <li>
7
+ <span class="summary_signature">
8
+ <strong><a href="<%= url_for(recipe, nil) %>"><%= recipe.name %></a></strong>
9
+ </span>
10
+ <span class="summary_desc"><%= htmlify(recipe.docstring, :markdown) %></span>
11
+ </li>
12
+ <% end %>
13
+ </ul>
14
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <% resources = chefsorted_objects(:resource) %>
2
+ <% if resources.size > 0 %>
3
+ <h2>Resources summary</h2>
4
+ <ul class="summary">
5
+ <% resources.each do |resource| %>
6
+ <li>
7
+ <span class="summary_signature">
8
+ <strong><a href="<%= url_for(resource,nil) %>"><%= resource.name %></a></strong>
9
+ </span>
10
+ <span class="summary_desc"><%= htmlify(resource.docstring, :markdown) %></span>
11
+ </li>
12
+ <% end %>
13
+ </ul>
14
+ <% end %>
@@ -0,0 +1,9 @@
1
+ include Helpers::ChefHelper
2
+ include T('default/module')
3
+
4
+ def init
5
+ @cookbook_statistics = YARD::CLI::Stats.new(false).statistics_hash
6
+
7
+ recipe_parts = %I[recipes attributes resources libraries]
8
+ sections [:cookbook_title, :metadata, :docstring, :generated_docs, recipe_parts]
9
+ end