yard-chefdoc 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7c1b1b7c7d48d1fdfe371a9bc0e3208157ea869e
4
+ data.tar.gz: 48ae1a4b57dd8655ac6924dfab4583bb2bf413b6
5
+ SHA512:
6
+ metadata.gz: c9ae7cb39a84734379f979d5adda5a25567b319b5de254f986aba5b4b5e1eae6366c455a69129634dcff5e615c71b42176da96c8ec023f82039cc49b4e666126
7
+ data.tar.gz: f445225e242f27dbe83dd4d5b0ab9a106190d2a5938e3314fdef0fb6541935ef215bde5104a88d6d761eb058adda8ccb5422427b7197913c35eeedaa3d8a5132
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'yard'
6
+
7
+ group :test do
8
+ gem 'capybara'
9
+ gem 'rake'
10
+ gem 'rspec'
11
+ gem 'rspec-html-matchers'
12
+ gem 'rspec-rails'
13
+ gem 'rubocop'
14
+ gem 'rubygems-tasks'
15
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 RightScale, Inc.
2
+ Copyright (c) 2017 Jörg Herzinger
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # YARD-Chef
2
+
3
+ Disclaimer: This YARD plugin is still in the early development stages. Please use with care and expect things to break.
4
+
5
+ ## Description
6
+
7
+ yard-chefdoc is a [YARD](http://yardoc.org/) plugin for that adds support for documenting [Chef](http://www.chef.io/) cookbooks.
8
+
9
+ ## Installation
10
+
11
+ This project is still in early development, so it has not yet been released on rubygems.org.
12
+
13
+ ## How to document your Cookbooks
14
+
15
+ The cookbook to be documented has to be vendored, which can be done using Berkshelfs `vendor` command or by downloading the released cookbook from a Chef Supermarket or Chef Server.
16
+
17
+ For yard-chefdoc the most important part about the vendor process is that your metadata.rb gets evaluated to a static metadata.json.
18
+
19
+ ### Cookbook README
20
+
21
+ The cookbook README.md in markdown format will be the landing page. Additionally a list of all all other objects with their short description will be added.
22
+
23
+ ### Cookbook Metadata
24
+
25
+ Metadata information will be included in the documentation automatically. This requires a `metadata.json` to be present, not a `metadata.rb`. Check "cookbook vendoring" for more info.
26
+
27
+ ### Libraries and standard YARD functionality
28
+
29
+ Your libraries will be documented out of the box by YARD. See the [YARD Documentation](http://yardoc.org/) on how to document them.
30
+
31
+ ### File headers and descriptions
32
+
33
+ With Chefs special cookbook directory structure is makes sense to add descriptions for certain files rather than for Classes, Modules etc. like Ruby. For recipe and attribute files yard-chefdoc will try to find a header which is defined by a comment block starting at the first line and ending at the first blank line.
34
+
35
+ Within this header a description can be given. This is defined to start by a comment line containing the single word `Description` and ending at the end of the comment block/header. A working example is:
36
+
37
+ ```
38
+ #
39
+ # Cookbook Name:: my-cookbook
40
+ # Attribute:: default
41
+ #
42
+ # Copyright (c) 2016 The Authors, All Rights Reserved.
43
+ #
44
+ # Description
45
+ # Here are some default attributes
46
+
47
+ default['my-cookbook']['brokkoli'] = %(delicious healthy)
48
+ ```
49
+
50
+ In this example the description for the file `attributes/default.rb` would be `Here are some default attributes`. This description can of course also span multiple lines. Mind the blank line after the header, without this the header would serve as a description for the attribute `['my-cookbook']['brokkoli']`.
51
+
52
+ ### Attributes
53
+
54
+ Attributes are automatically parsed and added to the documentation. Each attribute can have its own description which is simply the comment block above the attribute. Example:
55
+
56
+ ```
57
+ # Set this attribute to define which plugins should be installed
58
+ default['my-application']['plugins'] = %w(github slack ldap)
59
+ ```
60
+
61
+ ### Resources
62
+
63
+ Modern Chef custom resources are automatically documented. Comments on properties and actions are added accordingly.
64
+
65
+ ## Generating Cookbook Docs
66
+
67
+ To generate documentation you can either use the command line or create a rake task.
68
+
69
+ Command line:
70
+ ```
71
+ cd /path/to/cookbook
72
+ yardoc --plugin chefdoc "**/*.{rb,json}"
73
+ ```
74
+
75
+ Rake task:
76
+ ```
77
+ require 'yard'
78
+
79
+ YARD::Config.load_plugin 'chefdoc'
80
+ YARD::Rake::YardocTask.new do |t|
81
+ t.files = ['<path_to_cookbooks_repo>/**/*.{rb,json}']
82
+ # t.options = ['--debug']
83
+ end
84
+ ```
85
+
86
+ Then just run `rake yard`.
87
+
88
+ ## Viewing Cookbook Docs
89
+
90
+ YARD output will be present in a directory named `doc` which will be located in the same folder from where the command was run. The will also be a cache directory with all the information necessary to render the documentation pages in a directory name `.yardoc`.
91
+
92
+ It is recommended to view these pages from a running YARD server. To start a local YARD server you should be in the same directory that contains your generated `.yardoc` directory. Once there run:
93
+
94
+ `yard server --plugin chefdoc --cache`
95
+
96
+ For more information about YARD server see [YARD documentation](http://rubydoc.info/docs/yard/file/docs/GettingStarted.md#yard_Executable)
97
+
98
+ # License and Thanks
99
+
100
+ This project was originally a fork of yard-chef by RightScale, Inc. Special thanks goes to them for providing the base for this.
101
+
102
+ Copyright (c) 2017 Jörg Herzinger. This code is distributed under the MIT license, see LICENSE for details.<br>
103
+ Copyright (c) 2012 RightScale, Inc.
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ require 'bundler/setup'
2
+ require 'rubygems/tasks'
3
+ require 'rspec/core/rake_task'
4
+ require 'rubocop/rake_task'
5
+
6
+ RuboCop::RakeTask.new
7
+
8
+ desc 'Create test docs'
9
+ task :doc_fixtures do
10
+ FileList.new('test/fixtures/*').each do |cb|
11
+ FileUtils.cd(cb) do
12
+ sh 'rm -rf .yardoc doc'
13
+ sh 'bundle exec yardoc --safe --plugin chefdoc --debug "**/*.{rb,json}"'
14
+ sh 'bundle exec yard server --plugin chefdoc --debug'
15
+ end
16
+ end
17
+ end
18
+
19
+ Gem::Tasks.new
20
+
21
+ RSpec::Core::RakeTask.new(:spec, %i[tag trigger] => ['gen_yardoc'])
22
+
23
+ desc 'Generate yard documentation of all test cookbook'
24
+ task :gen_yardoc do
25
+ FileList.new('test/fixtures/*').each do |cb|
26
+ FileUtils.cd(cb) do
27
+ sh 'bundle exec yardoc --debug --plugin chefdoc "**/*.{rb,json}"'
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,142 @@
1
+ require 'json'
2
+
3
+ module YARD
4
+ module CLI
5
+ class Stats < Yardoc
6
+ STATS_ORDER = %i[files modules classes constants attributes methods
7
+ chef_attribute_files chef_attributes chef_recipes chef_resources
8
+ chef_resource_properties chef_resource_actions]
9
+
10
+ def stats_for_chef_recipes
11
+ objs = all_objects.select { |m| m.type == :recipe }
12
+ undoc = objs.select { |m| !m.docstring.nil? && m.docstring.blank? }
13
+ @undoc_list |= undoc if @undoc_list
14
+ output 'Chef Recipes', objs.size, undoc.size
15
+ end
16
+
17
+ def stats_for_chef_attribute_files
18
+ objs = all_objects.select { |m| m.type == :attribute }
19
+ undoc = objs.select { |m| !m.docstring.nil? && m.docstring.empty? }
20
+ @undoc_list |= undoc if @undoc_list
21
+ output 'Chef Attribute files', objs.size, undoc.size
22
+ end
23
+
24
+ def stats_for_chef_attributes
25
+ objs = all_objects.select { |m| m.type == :attribute }
26
+ objs.map!(&:attributes).flatten!
27
+ undoc = objs.select { |m| !m.docstring.nil? && m.docstring.empty? }
28
+ @undoc_list |= undoc if @undoc_list
29
+ output 'Chef Attributes', objs.size, undoc.size
30
+ end
31
+
32
+ def stats_for_chef_resources
33
+ objs = all_objects.select { |m| m.type == :resource }
34
+ undoc = objs.select { |m| !m.docstring.nil? && m.docstring.blank? }
35
+ @undoc_list |= undoc if @undoc_list
36
+ output 'Chef Resources', objs.size, undoc.size
37
+ end
38
+
39
+ def stats_for_chef_resource_properties
40
+ objs = all_objects.select { |m| m.type == :resource }
41
+ objs.map!(&:properties).flatten!
42
+ undoc = objs.select { |m| !m.docstring.nil? && m.docstring.empty? }
43
+ @undoc_list |= undoc if @undoc_list
44
+ output 'Chef Resource properties', objs.size, undoc.size
45
+ end
46
+
47
+ def stats_for_chef_resource_actions
48
+ objs = all_objects.select { |m| m.type == :resource }
49
+ objs.map!(&:actions).flatten!
50
+ undoc = objs.select { |m| !m.docstring.nil? && m.docstring.empty? }
51
+ @undoc_list |= undoc if @undoc_list
52
+ output 'Chef Resource actions', objs.size, undoc.size
53
+ end
54
+
55
+ # We don't need the file stats, so remove it
56
+ remove_method :stats_for_files
57
+
58
+ # Overrides the output from Yard itself for better indentation
59
+ # Prints a statistic to standard out. This method is optimized for
60
+ # getting Integer values, though it allows any data to be printed.
61
+ #
62
+ # @param [String] name the statistic name
63
+ # @param [Integer, String] data the numeric (or any) data representing
64
+ # the statistic. If +data+ is an Integer, it should represent the
65
+ # total objects of a type.
66
+ # @param [Integer, nil] undoc number of undocumented objects for the type
67
+ # @return [void]
68
+ def output(name, data, undoc = nil)
69
+ @total += data if data.is_a?(Integer) && undoc
70
+ @undocumented += undoc if undoc.is_a?(Integer)
71
+ data = if undoc
72
+ "#{format('%5s', data)} (#{format('%5d', undoc)} undocumented)"
73
+ else
74
+ format('%5s', data)
75
+ end
76
+ log.puts("#{format('%-25s', name + ':')} #{format('%s', data)}")
77
+ end
78
+
79
+ # Returns statistics for machine readable output generation
80
+ #
81
+ # @param [String] name the statistic name
82
+ # @param [Integer, String] data the numeric (or any) data representing
83
+ # the statistic. If +data+ is an Integer, it should represent the
84
+ # total objects of a type.
85
+ # @param [Integer, nil] undoc number of undocumented objects for the type
86
+ # @return [Hash] Number of documented and undocumented items
87
+ def output_hash(name, data, undoc = nil)
88
+ @total += data if data.is_a?(Integer) && undoc
89
+ @undocumented += undoc if undoc.is_a?(Integer)
90
+ percent = data.to_i.zero? ? '100' : ((data.to_i - undoc.to_i) / data.to_f) * 100
91
+ { name.tr(' ', '_').downcase => { 'name' => name,
92
+ 'items' => data.to_i,
93
+ 'undocumented' => undoc.to_i,
94
+ 'percentage' => percent } }
95
+ end
96
+
97
+ # Prints statistics for different object types in JSON format
98
+ #
99
+ # To add statistics for a specific type, add a method +#stats_for_TYPE+
100
+ # to this class that calls {#output}.
101
+ def print_statistics_json
102
+ log.puts JSON.pretty_generate(statistics_hash)
103
+ end
104
+
105
+ def statistics_hash
106
+ # Use JSON output for the following stats_for_* calls
107
+ alias output output_hash
108
+ # This is necessary so we get full access to the stats from the templates. Probably a
109
+ # bad patch, but for now this is ok.
110
+ # TODO: Refactor
111
+ options.verifier = YARD::Verifier.new('[:public].include?(object.visibility)')
112
+
113
+ collection = {}
114
+ @total = 0
115
+ @undocumented = 0
116
+ meths = methods.map(&:to_s).grep(/^stats_for_/)
117
+
118
+ meths.each { |m| collection.merge!(send(m)) }
119
+
120
+ collection['total_percentage'] = total_percentage
121
+
122
+ collection
123
+ end
124
+
125
+ # Always use JSON output by default
126
+ # alias output output_hash
127
+ # alias print_statistics print_statistics_json
128
+
129
+ private
130
+
131
+ def total_percentage
132
+ if @undocumented.zero?
133
+ 100
134
+ elsif @total.zero?
135
+ 0
136
+ else
137
+ (@total - @undocumented).to_f / @total.to_f * 100
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,43 @@
1
+ require 'yard'
2
+
3
+ module YARD::CodeObjects
4
+ module Chef
5
+ class AttributeObject < ChefObject
6
+ register_element :attribute
7
+ attr_accessor :attributes
8
+
9
+ # Creates a new instance of the AttributeObject which represents a file in
10
+ # the attributes directory.
11
+ #
12
+ # @param namespace [NamespaceObject] namespace to which the attribute belongs
13
+ # @param name [String] name of the attribute file
14
+ #
15
+ # @return [AttributeObject] the newly created AttribteObject
16
+ #
17
+ def initialize(namespace, name)
18
+ super(namespace, name)
19
+ @attributes = []
20
+ end
21
+
22
+ # Add a single attribute as an Attribute object (see below)
23
+ #
24
+ # @param h [Hash] The attribute hash to add
25
+ #
26
+ def add(h)
27
+ @attributes.push(Attribute.new(h))
28
+ end
29
+ end
30
+
31
+ # Simple class to handle Attributes and their specifics
32
+ class Attribute
33
+ attr_accessor :default, # The default value
34
+ :path, # The attributes Hash path. Something like ['cookbook']['one']['two']
35
+ :docstring, # The attrbitues docstring
36
+ :precedence # The precedence the attribute is set with
37
+
38
+ def initialize(h)
39
+ h.each { |k, v| instance_variable_set("@#{k}", v) }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,116 @@
1
+ require 'yard'
2
+
3
+ module YARD::CodeObjects
4
+ module Chef
5
+ # The chef object will be the root of your namespace
6
+ class ChefObject < YARD::CodeObjects::NamespaceObject
7
+ attr_accessor :file # The file the object appears in
8
+ attr_accessor :header # The header found in the source file
9
+
10
+ # Creates a new ChefObject object.
11
+ #
12
+ # @param namespace [NamespaceObject] namespace to which the object belongs
13
+ # @param name [String] name of the ChefObject
14
+ #
15
+ # @return [ChefObject] the newly created ChefObject
16
+ #
17
+ def initialize(namespace, name)
18
+ super(namespace, name)
19
+ end
20
+
21
+ # Register a chef element class.
22
+ #
23
+ # @param element [Class] chef element class
24
+ #
25
+ def self.register_element(element)
26
+ @@chef_elements ||= {}
27
+ @@chef_elements[element] = self
28
+ end
29
+
30
+ # Factory for creating and registering chef element object in
31
+ # YARD::Registry.
32
+ #
33
+ # @param namespace [NamespaceObject] namespace to which the object must
34
+ # belong
35
+ # @param name [String] name of the chef element
36
+ # @param type [Symbol, String] type of the chef element
37
+ #
38
+ # @return [<type>Object] the element object
39
+ #
40
+ def self.register(name, type, file)
41
+ element = @@chef_elements[type]
42
+ raise "Invalid chef element type #{type}" unless element
43
+ element_obj = YARD::Registry.resolve(:root, "#{type}::#{name}")
44
+ if element_obj.nil?
45
+ element_obj = element.new(:root, "#{type}::#{name}")
46
+ log.info "Created [#{type.to_s.capitalize}] #{element_obj.name} => #{element_obj.namespace}"
47
+ element_obj.chef_init(file)
48
+ end
49
+ element_obj
50
+ end
51
+
52
+ # Returns children of an object of a particular type.
53
+ #
54
+ # @param type [Symbol] type of ChefObject to be selected
55
+ #
56
+ # @return [Array<ChefObject>] list of ChefObjects
57
+ #
58
+ def children_by_type(type)
59
+ children = YARD::Registry.all(type)
60
+ children.select { |child| child.parent == self }
61
+ end
62
+
63
+ # Does chef specific initalization tasks
64
+ #
65
+ # @param file [String] The file of the object thas is being initialized
66
+ #
67
+ # @return [ChefObject] The (chef) initialized object
68
+ #
69
+ def chef_init(file)
70
+ self.file = file
71
+ self.source = IO.read(File.expand_path(file))
72
+ self.header = find_header_in(source)
73
+ self.docstring = find_description_in(header)
74
+ end
75
+
76
+ # Gets the file header if available
77
+ # The header is defined by a every comment line starting at the beginning of the file
78
+ # Until the first blank line. If no blank line is found then the comment is considered
79
+ # the following resource's/blocks docstring.
80
+ #
81
+ # @return [String] The header of the file. Empty if no header is found
82
+ #
83
+ def find_header_in(src)
84
+ h = []
85
+ src.each_line do |line|
86
+ comment = line[/^\s*#\s?(.*)$/, 1]
87
+ break if comment.nil?
88
+
89
+ h.push comment
90
+ end
91
+
92
+ h.join("\n")
93
+ end
94
+
95
+ # Gets the description from the file header.
96
+ # Currently the docstring of recipes, attributes etc. is looked up in the file
97
+ # header and starts with a single line containing the keyword "Description".
98
+ #
99
+ # @return [String] The description
100
+ #
101
+ def find_description_in(header)
102
+ desc_found = false
103
+ docstring = []
104
+ header.each_line do |line|
105
+ if desc_found
106
+ docstring.push line
107
+ elsif line.chomp == 'Description'
108
+ desc_found = true
109
+ end
110
+ end
111
+
112
+ docstring.join("\n")
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,55 @@
1
+ require 'yard'
2
+
3
+ module YARD::CodeObjects
4
+ module Chef
5
+ # A CookbookObject represents a Chef cookbook.
6
+ # See http://wiki.opscode.com/display/chef/Cookbooks for more information
7
+ # about cookbooks.
8
+ #
9
+ class CookbookObject < ChefObject
10
+ register_element :cookbook
11
+
12
+ attr_accessor :docstring_type
13
+
14
+ # Cookbook metadata
15
+ attr_accessor :dependencies
16
+ attr_accessor :version
17
+ attr_accessor :source_url
18
+ attr_accessor :issues_url
19
+ attr_accessor :maintainer
20
+ attr_accessor :maintainer_email
21
+ attr_accessor :license
22
+ attr_accessor :platforms
23
+ attr_accessor :gems
24
+
25
+ # Creates a new CookbookObject instance.
26
+ # @param namespace [NamespaceObject] namespace to which the cookbook
27
+ # belongs
28
+ # @param name [String] name of the cookbook
29
+ #
30
+ # @return [CookbookObject] the newly created CookbookObject
31
+ #
32
+ def initialize(namespace, name)
33
+ super(namespace, name)
34
+ @docstring_type = :markdown
35
+ end
36
+
37
+ # Libraries defined in the cookbook.
38
+ # Catches all classes, modules and defintion directly defined without a namespace
39
+ #
40
+ # @return [Array] libraries in the cookbook
41
+ #
42
+ def libraries
43
+ modules = YARD::Registry.all(:module)
44
+ classes = YARD::Registry.all(:class)
45
+ root_definitions = YARD::Registry.all(:method).select { |m| m.path =~ /^root#/ }
46
+
47
+ classes + modules + root_definitions
48
+ end
49
+
50
+ def metadata
51
+ [@version, @maintainer, @dependencies]
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,29 @@
1
+ require 'yard'
2
+
3
+ module YARD::CodeObjects
4
+ module Chef
5
+ class RecipeObject < ChefObject
6
+ register_element :recipe
7
+
8
+ # Creates a new instance of RecipeObject.
9
+ #
10
+ # @param namespace [NamespaceObject] namespace to which the recipe belongs
11
+ # @param name [String] name of the recipe
12
+ #
13
+ # @return [RecipeObject] the newly created RecipeObject
14
+ #
15
+ def initialize(namespace, name)
16
+ super(namespace, name)
17
+ end
18
+
19
+ # Needed by the template to render recipe source code.
20
+ # Since we always display the full source we start with 1
21
+ #
22
+ # @return [Integer] 1
23
+ #
24
+ def line
25
+ 1
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,70 @@
1
+ require 'yard'
2
+
3
+ module YARD::CodeObjects
4
+ module Chef
5
+ class ResourceObject < ChefObject
6
+ register_element :resource
7
+ attr_accessor :properties,
8
+ :actions,
9
+ :default_action,
10
+ :resource_name,
11
+ :load_current_value
12
+
13
+ # Creates a new instance of the ResourceObject
14
+ #
15
+ # @param namespace [NamespaceObject] namespace to which the resource belongs
16
+ # @param name [String] name of the resource. This is the base name which chef
17
+ # automatically generates.
18
+ #
19
+ # @return [ResourceObject] the newly created ResourceObject
20
+ #
21
+ def initialize(namespace, name)
22
+ super(namespace, name)
23
+ @resource_name = name
24
+ @properties = []
25
+ @actions = []
26
+ end
27
+
28
+ # Add a single property as an Property object (see below)
29
+ #
30
+ # @param h [Hash] The property hash to add
31
+ #
32
+ def add_property(h)
33
+ @properties.push(Property.new(h))
34
+ end
35
+
36
+ # Add an action as an Action object (see below)
37
+ #
38
+ # @param h [Hash] The action hash to add
39
+ #
40
+ def add_action(h)
41
+ @actions.push(Action.new(h))
42
+ end
43
+ end
44
+
45
+ # Simple class to handle Properties and their specifics
46
+ # Full docs here http://www.rubydoc.info/gems/chef/Chef%2FMixin%2FProperties%2FClassMethods:property
47
+ class Property
48
+ attr_accessor :identifier, # The name of the property
49
+ :docstring, # The attrbitues docstring
50
+ :type, # The ruby type of the property
51
+ :options # The various property options
52
+
53
+ def initialize(h)
54
+ h.each { |k, v| instance_variable_set("@#{k}", v) }
55
+ end
56
+ end
57
+
58
+ # Simple class to handle actions
59
+ class Action
60
+ attr_accessor :identifier, # The name of the action
61
+ :source, # The source of the action block
62
+ :docstring, # The actions docstring
63
+ :line # The line number of the first line of the block needed for the output formatting
64
+
65
+ def initialize(h)
66
+ h.each { |k, v| instance_variable_set("@#{k}", v) }
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,32 @@
1
+ require 'yard'
2
+
3
+ module YARD::Handlers
4
+ module Chef
5
+ # Handles attributes in cookbook
6
+ class AttributeHandler < Base
7
+ MATCH = /^\s*(node\.)?(default|force_default|normal|override|force_override)(\[.+?\])\s*=\s*(.+)/m
8
+ in_file(%r{^attributes\/.*\.rb$})
9
+ handles MATCH
10
+
11
+ def process
12
+ attrib_obj = ChefObject.register(filename, :attribute, statement.file)
13
+
14
+ docstring_is_header = (statement.docstring == attrib_obj.header)
15
+ attrib_obj.add attr_hash(docstring_is_header) if statement.type == :assign
16
+ end
17
+
18
+ # Creates the hash to initialize the single attribute object
19
+ #
20
+ # @return [Hash] the hash to initialize the attribute in the attribute code object
21
+ #
22
+ def attr_hash(nodoc)
23
+ {
24
+ precedence: statement.jump(:ident).source,
25
+ default: statement.jump(:assign)[1].source,
26
+ docstring: nodoc ? '' : statement.docstring,
27
+ path: statement.source.match(MATCH)[3]
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end