yard-chef 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/lib/yard-chef.rb +12 -11
  3. data/lib/yard-chef/code_objects/attribute_object.rb +43 -0
  4. data/lib/yard-chef/code_objects/chef_object.rb +3 -3
  5. data/lib/yard-chef/code_objects/cookbook_object.rb +9 -1
  6. data/lib/yard-chef/code_objects/dependency_object.rb +52 -0
  7. data/lib/yard-chef/code_objects/provider_object.rb +7 -7
  8. data/lib/yard-chef/code_objects/recipe_object.rb +2 -1
  9. data/lib/yard-chef/code_objects/resource_object.rb +1 -1
  10. data/lib/yard-chef/handlers/actions.rb +2 -2
  11. data/lib/yard-chef/handlers/attribute.rb +38 -9
  12. data/lib/yard-chef/handlers/base.rb +14 -14
  13. data/lib/yard-chef/handlers/cookbook.rb +18 -8
  14. data/lib/yard-chef/handlers/dependency.rb +55 -0
  15. data/lib/yard-chef/handlers/recipe.rb +25 -13
  16. data/templates/default/action/html/action.erb +8 -0
  17. data/templates/default/action/html/setup.rb +1 -13
  18. data/templates/default/attribute/html/attribute.erb +7 -0
  19. data/templates/default/attribute/html/attribute_header.erb +1 -1
  20. data/templates/default/attribute/html/cookbook_attribute.erb +33 -0
  21. data/templates/default/attribute/html/{table.erb → resource_attribute.erb} +24 -2
  22. data/templates/default/attribute/html/setup.rb +2 -1
  23. data/templates/default/chef/html/cookbook_table.erb +323 -2
  24. data/templates/default/chef/html/setup.rb +1 -1
  25. data/templates/default/chef_tags/html/example.erb +11 -0
  26. data/templates/default/chef_tags/html/index.erb +3 -0
  27. data/templates/default/chef_tags/html/note.erb +10 -0
  28. data/templates/default/chef_tags/html/see.erb +8 -0
  29. data/templates/default/chef_tags/html/tag.erb +20 -0
  30. data/templates/default/chef_tags/setup.rb +43 -0
  31. data/templates/default/{action/html/action_summary.erb → cookbook/html/dependencies.erb} +7 -6
  32. data/templates/default/cookbook/html/libraries.erb +4 -2
  33. data/templates/default/cookbook/html/recipes.erb +1 -1
  34. data/templates/default/cookbook/html/setup.rb +18 -14
  35. data/templates/default/fulldoc/html/css/bootstrap.min.css +5 -0
  36. data/templates/default/fulldoc/html/css/common.css +146 -0
  37. data/templates/default/fulldoc/html/full_list_cookbooks.erb +6 -8
  38. data/templates/default/fulldoc/html/full_list_definitions.erb +9 -9
  39. data/templates/default/fulldoc/html/full_list_recipes.erb +5 -5
  40. data/templates/default/fulldoc/html/full_list_resources.erb +5 -5
  41. data/templates/default/fulldoc/html/js/app.js +213 -0
  42. data/templates/default/fulldoc/html/js/bootstrap.min.js +7 -0
  43. data/templates/default/fulldoc/html/js/d3.js +5 -0
  44. data/templates/default/fulldoc/html/js/jquery.js +4 -0
  45. data/templates/default/fulldoc/html/setup.rb +34 -24
  46. data/templates/default/layout/html/setup.rb +19 -9
  47. data/templates/default/provider/html/providers_summary.erb +4 -1
  48. data/templates/default/provider/html/setup.rb +2 -1
  49. data/templates/default/recipe/html/recipe_list.erb +1 -1
  50. data/templates/default/recipe/html/setup.rb +1 -1
  51. data/templates/default/resource/html/actions.erb +1 -1
  52. data/templates/default/resource/html/setup.rb +1 -1
  53. metadata +64 -55
  54. data/templates/default/action/html/action_list.erb +0 -42
  55. data/templates/default/action/html/source.erb +0 -34
  56. data/templates/default/chef/html/docstring.erb +0 -25
  57. data/templates/default/layout/html/cookbook_table.erb +0 -46
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 121954baf88b0feaee034138ea9e36c56d986abb
4
+ data.tar.gz: 7948080f74a71041f0cb44cbf9838de8fd914a05
5
+ SHA512:
6
+ metadata.gz: 4e0e4fbe640a607a008764970fbf6a6f4f01a2e857f93051763c943e6d0bdee14a18ee39d81ba4f5b2c5eb308b9820dd1d9823b229deee530bd90de95628c6dd
7
+ data.tar.gz: f124b5a46a840d651aa07c8490a02fc765d8edbf39633fb81c1f26751141e8c66406dee7ec7ca4b281b8f28d59739b7648664dd61eaf425919fc5c1065637dd0
@@ -28,6 +28,7 @@ require 'yard-chef/code_objects/provider_object'
28
28
  require 'yard-chef/code_objects/recipe_object'
29
29
  require 'yard-chef/code_objects/attribute_object'
30
30
  require 'yard-chef/code_objects/action_object'
31
+ require 'yard-chef/code_objects/dependency_object'
31
32
 
32
33
  require 'yard-chef/handlers/base'
33
34
  require 'yard-chef/handlers/action'
@@ -36,6 +37,7 @@ require 'yard-chef/handlers/define'
36
37
  require 'yard-chef/handlers/actions'
37
38
  require 'yard-chef/handlers/cookbook'
38
39
  require 'yard-chef/handlers/recipe'
40
+ require 'yard-chef/handlers/dependency'
39
41
 
40
42
  module YARD::CodeObjects::Chef
41
43
  # Since 'recipe' files do not have a specific keyword that can be matched,
@@ -44,21 +46,20 @@ module YARD::CodeObjects::Chef
44
46
  # be taken care of in the handler.
45
47
  # TODO: Investigate if YARD handlers can be invoked if parser is in a
46
48
  # specific directory.
47
- YARD::Parser::SourceParser.before_parse_list do |files, globals|
49
+ YARD::Parser::SourceParser.before_parse_list do |files, _globals|
48
50
  files.each do |file|
49
51
  path_arr = File.expand_path(file).to_s.split('/')
50
- unless (index = path_arr.index('recipes')).nil?
51
- # Cookbook name can be derived from file path
52
- # cookbook/<cookbook_name>/recipes/recipe_name.rb
53
- cookbook_name = path_arr[index - 1]
54
- cookbook = ChefObject.register(CHEF, cookbook_name, :cookbook)
52
+ next if (index = path_arr.index('recipes')).nil?
53
+ # Cookbook name can be derived from file path
54
+ # cookbook/<cookbook_name>/recipes/recipe_name.rb
55
+ cookbook_name = path_arr[index - 1]
56
+ cookbook = ChefObject.register(CHEF, cookbook_name, :cookbook)
55
57
 
56
- recipe_name = path_arr.last.to_s.sub('.rb','')
57
- recipe = ChefObject.register(cookbook, recipe_name, :recipe)
58
+ recipe_name = path_arr.last.to_s.sub('.rb', '')
59
+ recipe = ChefObject.register(cookbook, recipe_name, :recipe)
58
60
 
59
- recipe.source = IO.read(file)
60
- recipe.add_file(file, 1)
61
- end
61
+ recipe.source = IO.read(file)
62
+ recipe.add_file(file, 1)
62
63
  end
63
64
  end
64
65
 
@@ -39,6 +39,49 @@ module YARD::CodeObjects
39
39
  #
40
40
  def initialize(namespace, name)
41
41
  super(namespace, name)
42
+ @kind_of = ''
43
+ @default = ''
44
+ end
45
+
46
+ # Returns JSON representation of attribute name
47
+ #
48
+ # @return [String] JSON string
49
+ def to_json
50
+ json_string = " {\n"
51
+ # default[:cluster][:config][:openstack][:volume_default_type]
52
+ if name =~ /(.+?)(\[.+\])/
53
+ # "default"
54
+ attribute_type = Regexp.last_match(1)
55
+ # [:cluster][:config][:openstack][:volume_default_type]
56
+ json_string += " \"#{attribute_type}_attributes\": {\n ...\n"
57
+ deepness = 2
58
+ attrs_tree = Regexp.last_match(2).split('[')
59
+ while (attr = attrs_tree.shift)
60
+ next if attr.empty?
61
+ attr = attr.gsub(/[:"'](.+?)["']?\]/, '\\1')
62
+ # Indent
63
+ json_string += (' ' * (deepness + 2) * 2)
64
+ # Attr name
65
+ json_string += "\"#{attr}\""
66
+ if attrs_tree.empty?
67
+ json_string += ": \"VALUE\"\n"
68
+ else
69
+ # New branch
70
+ json_string += ": {\n" unless attrs_tree.empty?
71
+ deepness += 1
72
+ end
73
+ end
74
+
75
+ # Closing brackets
76
+ deepness -= 1
77
+ deepness.times do |d|
78
+ # Indent
79
+ json_string += (' ' * (deepness - d + 2) * 2)
80
+ # Attr name
81
+ json_string += "}\n"
82
+ end
83
+ end
84
+ json_string + " ...\n }\n"
42
85
  end
43
86
  end
44
87
  end
@@ -70,8 +70,8 @@ module YARD::CodeObjects
70
70
  element_obj = YARD::Registry.resolve(:root, "#{namespace}::#{name}")
71
71
  if element_obj.nil?
72
72
  element_obj = element.new(namespace, name)
73
- log.info "Created [#{type.to_s.capitalize}]" +
74
- " #{element_obj.name} => #{element_obj.namespace}"
73
+ log.info "Created [#{type.to_s.capitalize}]" \
74
+ " #{element_obj.name} => #{element_obj.namespace}"
75
75
  end
76
76
  element_obj
77
77
  else
@@ -87,7 +87,7 @@ module YARD::CodeObjects
87
87
  #
88
88
  def children_by_type(type)
89
89
  children = YARD::Registry.all(type)
90
- children.reject { |child| child.parent != self }
90
+ children.select { |child| child.parent == self }
91
91
  end
92
92
 
93
93
  # Gets all Chef cookbooks.
@@ -96,13 +96,21 @@ module YARD::CodeObjects
96
96
  children_by_type(:method)
97
97
  end
98
98
 
99
+ # Dependencies of the cookbook.
100
+ #
101
+ # @return [Array<MethodObject>] dependencies of the cookbook
102
+ #
103
+ def dependencies
104
+ children_by_type(:dependency)
105
+ end
106
+
99
107
  # Libraries defined in the cookbook.
100
108
  #
101
109
  # @return [Array<ModuleObject>] libraries in the cookbook
102
110
  #
103
111
  def libraries
104
112
  modules = YARD::Registry.all(:module)
105
- modules.select { |lib| !lib.parent.root? && lib.file =~ /#{@name}/ }
113
+ modules.select { |lib| lib.file.split('/').include?(@name.to_s) }
106
114
  end
107
115
  end
108
116
  end
@@ -0,0 +1,52 @@
1
+ # Copyright (c) 2015 Aleksey Hariton
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # 'Software'), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'yard'
23
+
24
+ module YARD::CodeObjects
25
+ module Chef
26
+ # A DependencyObject represents a dependencies of a chef cookbook.
27
+ #
28
+ class DependencyObject < ChefObject
29
+ register_element :dependency
30
+
31
+ # Creates a new instance of DependencyObject.
32
+ #
33
+ # @param namespace [NamespaceObject] namespace to which the recipe belongs
34
+ # @param name [String] name of the recipe
35
+ #
36
+ # @return [DependencyObject] the newly created DependencyObject
37
+ #
38
+ def initialize(namespace, name)
39
+ super(namespace, name)
40
+ @docstring = ''
41
+ end
42
+
43
+ # Prefixes dependency name with the name of the cookbook.
44
+ #
45
+ # @return [String] recipe name
46
+ #
47
+ def name
48
+ @name.to_s
49
+ end
50
+ end
51
+ end
52
+ end
@@ -39,6 +39,7 @@ module YARD::CodeObjects
39
39
  #
40
40
  def initialize(namespace, name)
41
41
  super(namespace, name)
42
+ @description = ''
42
43
  end
43
44
 
44
45
  # Constructs class name for the lightweight provider.
@@ -54,7 +55,7 @@ module YARD::CodeObjects
54
55
  else
55
56
  name = @name.to_s.capitalize
56
57
  end
57
- namespace = @namespace.to_s.split('::').map { |str| str.capitalize }
58
+ namespace = @namespace.to_s.split('::').map(&:capitalize)
58
59
  "#{namespace.join('::')}::#{name}"
59
60
  end
60
61
 
@@ -65,12 +66,11 @@ module YARD::CodeObjects
65
66
  def map_resource(file)
66
67
  file_handle = File.open(File.expand_path(file), 'r')
67
68
  file_handle.readlines.each do |line|
68
- if line =~ /#\s@resource/
69
- resource_name = line.split(%r{@resource })[1].strip
70
- @resource = ChefObject.register(RESOURCE, resource_name, :resource)
71
- @resource.providers.push(self) unless @resource.providers.include?(self)
72
- break
73
- end
69
+ next unless line =~ /#\s@resource/
70
+ resource_name = line.split(/@resource /)[1].strip
71
+ @resource = ChefObject.register(RESOURCE, resource_name, :resource)
72
+ @resource.providers.push(self) unless @resource.providers.include?(self)
73
+ break
74
74
  end
75
75
  end
76
76
 
@@ -38,6 +38,7 @@ module YARD::CodeObjects
38
38
  #
39
39
  def initialize(namespace, name)
40
40
  super(namespace, name)
41
+ @short_desc = ''
41
42
  end
42
43
 
43
44
  # Prefixes recipe name with the name of the cookbook.
@@ -45,7 +46,7 @@ module YARD::CodeObjects
45
46
  # @return [String] recipe name
46
47
  #
47
48
  def name
48
- self.parent.name.to_s << '::' << @name.to_s
49
+ parent.name.to_s << '::' << @name.to_s
49
50
  end
50
51
  end
51
52
  end
@@ -56,7 +56,7 @@ module YARD::CodeObjects
56
56
  name = @name.to_s.capitalize
57
57
  end
58
58
 
59
- namespace = @namespace.to_s.split('::').map { |str| str.capitalize }
59
+ namespace = @namespace.to_s.split('::').map(&:capitalize)
60
60
  "#{namespace.join('::')}::#{name}"
61
61
  end
62
62
 
@@ -42,7 +42,7 @@ module YARD::Handlers
42
42
  # if multiple actions listed in same line, split the actions and
43
43
  # register them
44
44
  if statement.first_line =~ /,/
45
- statement.first_line.split(%r{,?\s*:}).each do |action|
45
+ statement.first_line.split(/,?\s*:/).each do |_action|
46
46
  action = ChefObject.register(resource_obj, name, :action)
47
47
  end
48
48
  else
@@ -50,7 +50,7 @@ module YARD::Handlers
50
50
  action.docstring = statement.docstring
51
51
  end
52
52
 
53
- log.info "Found [Actions] in #{parser.file.to_s}"
53
+ log.info "Found [Actions] in #{parser.file}"
54
54
  end
55
55
  end
56
56
  end
@@ -26,14 +26,17 @@ module YARD::Handlers
26
26
  # Handles "attributes" in cookbook metadata and lightweight resource.
27
27
  #
28
28
  class AttributeHandler < Base
29
+ MATCH = /^\s*(default|force_default|normal|override|force_override)(\[.+?\])\s*=\s*(.+)/m
29
30
  handles method_call(:attribute)
31
+ handles MATCH
30
32
 
31
33
  # Process "attribute" keyword.
32
34
  #
33
35
  def process
36
+ path_array = parser.file.to_s.split('/')
34
37
  # If file path includes metadata then handle cookbook attributes
35
38
  # else handle resource attributes
36
- if parser.file =~ /metadata\.rb/
39
+ if path_array.include?('metadata.rb') || path_array.include?('attributes')
37
40
  namespace = cookbook
38
41
  else
39
42
  namespace = lwrp
@@ -46,9 +49,13 @@ module YARD::Handlers
46
49
  end
47
50
 
48
51
  # Register attribute if not already registered
49
- attrib_obj = ChefObject.register(namespace, name, :attribute)
52
+ if path_array.include? 'attributes'
53
+ statement.source =~ MATCH
54
+ attrib_obj = ChefObject.register(namespace, "#{Regexp.last_match(1)}#{Regexp.last_match(2)}", :attribute)
55
+ else
56
+ attrib_obj = ChefObject.register(namespace, name, :attribute)
57
+ end
50
58
  attrib_obj.source = statement.source
51
- attrib_obj.docstring = docstring
52
59
  attrib_obj.add_file(statement.file, statement.line)
53
60
  end
54
61
 
@@ -58,23 +65,45 @@ module YARD::Handlers
58
65
  # @return [YARD::Docstring] docstring for the attribute
59
66
  #
60
67
  def docstring
61
- description = ""
68
+ description = ''
62
69
  path_array = parser.file.to_s.split('/')
70
+ # Parse docstring
63
71
  if path_array.include?('metadata.rb')
64
72
  # Suppose :description string have concatenation operator '+' then
65
73
  # YARD builds an abstract syntax tree (AST). We need to traverse the
66
74
  # tree to get the whole description string
67
75
  statement.parameters[1].children.each do |ast_node|
68
- if ast_node.jump(:ident).source == "description"
69
- ast_node.traverse do |child|
70
- description << child.jump(:string_content).source if child.type == :string_content
71
- end
76
+ next unless ast_node.jump(:ident).source == 'description'
77
+ ast_node.traverse do |child|
78
+ description << child.jump(:string_content).source if child.type == :string_content
72
79
  end
73
80
  end
74
81
  else
75
82
  description = statement.comments
76
83
  end
77
- YARD::DocstringParser.new.parse(description).to_docstring
84
+ attrib_obj.docstring = YARD::DocstringParser.new.parse(description).to_docstring
85
+ is_kind_of = ''
86
+ is_default = ''
87
+ if path_array.include? 'attributes'
88
+ statement.source =~ MATCH
89
+ is_default = Regexp.last_match(3)
90
+ else
91
+ statement.parameters.each do |n|
92
+ next unless (n.is_a? YARD::Parser::Ruby::AstNode) && (n.source =~ /(default|kind_of)/)
93
+ n.each do |node|
94
+ if node.source =~ /default/
95
+ m = node.source.match(/\W+?\s(.*)/)
96
+ is_default = m[1] if m
97
+ end
98
+ if node.source =~ /kind_of/
99
+ m = node.source.match(/\W+?\s(.*)/)
100
+ is_kind_of = m[1] if m
101
+ end
102
+ end
103
+ end
104
+ end
105
+ attrib_obj.kind_of = is_kind_of
106
+ attrib_obj.default = is_default.split("\n").map { |s| " #{s}" }.join("\n")
78
107
  end
79
108
  end
80
109
  end
@@ -39,13 +39,13 @@ module YARD::Handlers
39
39
  # @return [CookbookObject] the CookbookObject
40
40
  #
41
41
  def cookbook
42
- cookbook_name = ""
42
+ cookbook_name = ''
43
43
  path_array = File.expand_path(statement.file).to_s.split('/')
44
- if path_array.include?('metadata.rb')
45
- cookbook_name = path_array[path_array.index('metadata.rb') - 1]
46
- else
47
- cookbook_name = path_array[path_array.length - 3]
48
- end
44
+ cookbook_name = if path_array.include?('metadata.rb')
45
+ path_array[path_array.index('metadata.rb') - 1]
46
+ else
47
+ path_array[path_array.length - 3]
48
+ end
49
49
  ChefObject.register(CHEF, cookbook_name, :cookbook)
50
50
  end
51
51
 
@@ -57,23 +57,23 @@ module YARD::Handlers
57
57
  #
58
58
  def lwrp
59
59
  path_array = File.expand_path(statement.file).to_s.split('/')
60
- if path_array.include?("resources")
60
+ if path_array.include?('resources')
61
61
  type = RESOURCE
62
62
  type_sym = :resource
63
- elsif path_array.include?("providers")
63
+ elsif path_array.include?('providers')
64
64
  type = PROVIDER
65
65
  type_sym = :provider
66
66
  else
67
67
  raise "Invalid LWRP type #{@path_array.join(',')}"
68
68
  end
69
- file_name = path_array.last.to_s.sub('.rb','')
69
+ file_name = path_array.last.to_s.sub('.rb', '')
70
70
 
71
71
  cookbook_obj = cookbook
72
- if file_name == "default"
73
- lwrp_name = cookbook_obj.name
74
- else
75
- lwrp_name = "#{cookbook_obj.name}_#{file_name}"
76
- end
72
+ lwrp_name = if file_name == 'default'
73
+ cookbook_obj.name
74
+ else
75
+ "#{cookbook_obj.name}_#{file_name}"
76
+ end
77
77
  ChefObject.register(type, lwrp_name, type_sym)
78
78
  end
79
79
  end
@@ -60,11 +60,21 @@ module YARD::Handlers
60
60
  # @return [String] the method name
61
61
  #
62
62
  def name
63
- string = ""
64
- # YARD builds an abstract syntax tree (AST) which we need to traverse
65
- # to obtain the complete docstring
66
- statement.parameters.first.traverse do |child|
67
- string << child.jump(:string_content).source if child.type == :string_content
63
+ string = ''
64
+ value = statement.parameters.first
65
+ if value.is_a?(YARD::Parser::Ruby::MethodCallNode)
66
+ # The content is code, so evaluate it in the correct directory
67
+ # This handles ruby code like File.read in metadata.rb
68
+ current_directory = Dir.getwd
69
+ Dir.chdir(File.expand_path(File.dirname(statement.file)))
70
+ string << eval(value.source)
71
+ Dir.chdir current_directory
72
+ else
73
+ # YARD builds an abstract syntax tree (AST) which we need to traverse
74
+ # to obtain the complete docstring
75
+ value.traverse do |child|
76
+ string << child.jump(:string_content).source if child.type == :string_content
77
+ end
68
78
  end
69
79
  string
70
80
  end
@@ -77,17 +87,17 @@ module YARD::Handlers
77
87
  type = ''
78
88
  string = ''
79
89
  readme_path = base_dir + '/README.md'
80
- if File.exists?(readme_path)
90
+ if File.exist?(readme_path)
81
91
  type = :markdown
82
92
  string = IO.read(readme_path)
83
93
  else
84
94
  readme_path = base_dir + '/README.rdoc'
85
- if File.exists?(readme_path)
95
+ if File.exist?(readme_path)
86
96
  type = :rdoc
87
97
  string = IO.read(readme_path)
88
98
  end
89
99
  end
90
- return YARD::DocstringParser.new.parse(string).to_docstring, type
100
+ [YARD::DocstringParser.new.parse(string).to_docstring, type]
91
101
  end
92
102
  end
93
103
  end