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
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