foodcritic 0.3.0 → 0.4.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.
- data/lib/foodcritic.rb +1 -0
- data/lib/foodcritic/dsl.rb +3 -0
- data/lib/foodcritic/helpers.rb +21 -13
- data/lib/foodcritic/linter.rb +2 -2
- data/lib/foodcritic/rules.rb +35 -2
- data/lib/foodcritic/version.rb +1 -1
- metadata +12 -12
data/lib/foodcritic.rb
CHANGED
data/lib/foodcritic/dsl.rb
CHANGED
data/lib/foodcritic/helpers.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'nokogiri'
|
2
|
-
require 'xmlsimple'
|
3
2
|
|
4
3
|
module FoodCritic
|
5
4
|
|
@@ -12,7 +11,7 @@ module FoodCritic
|
|
12
11
|
# @return [Hash] Hash with the matched node name and position with the recipe
|
13
12
|
def match(node)
|
14
13
|
pos = node.xpath('descendant::pos').first
|
15
|
-
{:matched => node.name, :line => pos['line'], :column => pos['column']}
|
14
|
+
{:matched => node.respond_to?(:name) ? node.name : '', :line => pos['line'], :column => pos['column']}
|
16
15
|
end
|
17
16
|
|
18
17
|
# Does the specified recipe check for Chef Solo?
|
@@ -71,7 +70,7 @@ module FoodCritic
|
|
71
70
|
# @return [Hash] The resource attributes
|
72
71
|
def resource_attributes(resource)
|
73
72
|
atts = {:name => resource_name(resource)}
|
74
|
-
resource.xpath('do_block/descendant::command').each do |att|
|
73
|
+
resource.xpath('do_block/descendant::command[count(ancestor::do_block) = 1]').each do |att|
|
75
74
|
if att.xpath('descendant::symbol').empty?
|
76
75
|
att_value = att.xpath('string(descendant::tstring_content/@value)')
|
77
76
|
else
|
@@ -144,26 +143,35 @@ module FoodCritic
|
|
144
143
|
node.respond_to?(:length) and node.length == 2 and node.respond_to?(:all?) and node.all?{|child| child.respond_to?(:to_i)}
|
145
144
|
end
|
146
145
|
|
147
|
-
# Recurse the nested arrays provided by Ripper to create
|
146
|
+
# Recurse the nested arrays provided by Ripper to create a tree we can more easily apply expressions to.
|
148
147
|
#
|
149
|
-
# @param [
|
150
|
-
# @
|
151
|
-
|
152
|
-
|
148
|
+
# @param [Hash] node The AST
|
149
|
+
# @param [Nokogiri::XML::Document] doc The document being constructed
|
150
|
+
# @param [Nokogiri::XML::Node] xml_node The current node
|
151
|
+
# @return [Nokogiri::XML::Node] The XML representation
|
152
|
+
def build_xml(node, doc = nil, xml_node=nil)
|
153
|
+
if doc.nil?
|
154
|
+
doc = Nokogiri::XML('<opt></opt>')
|
155
|
+
xml_node = doc.root
|
156
|
+
end
|
153
157
|
if node.respond_to?(:each)
|
154
158
|
node.drop(1).each do |child|
|
155
159
|
if position_node?(child)
|
156
|
-
|
160
|
+
pos = Nokogiri::XML::Node.new("pos", doc)
|
161
|
+
pos['line'] = child.first.to_s
|
162
|
+
pos['column'] = child[1].to_s
|
163
|
+
xml_node.add_child(pos)
|
157
164
|
else
|
158
165
|
if child.respond_to?(:first)
|
159
|
-
|
166
|
+
n = Nokogiri::XML::Node.new(child.first.to_s.gsub(/[^a-z_]/, ''), doc)
|
167
|
+
xml_node.add_child(build_xml(child, doc, n))
|
160
168
|
else
|
161
|
-
|
169
|
+
xml_node['value'] = child.to_s unless child.nil?
|
162
170
|
end
|
163
171
|
end
|
164
172
|
end
|
165
173
|
end
|
166
|
-
|
174
|
+
xml_node
|
167
175
|
end
|
168
176
|
|
169
177
|
# Read the AST for the given Ruby file
|
@@ -171,7 +179,7 @@ module FoodCritic
|
|
171
179
|
# @param [String] file The file to read
|
172
180
|
# @return [Nokogiri::XML::Node] The recipe AST
|
173
181
|
def read_file(file)
|
174
|
-
|
182
|
+
build_xml(Ripper::SexpBuilder.new(IO.read(file)).parse)
|
175
183
|
end
|
176
184
|
|
177
185
|
end
|
data/lib/foodcritic/linter.rb
CHANGED
@@ -21,8 +21,8 @@ module FoodCritic
|
|
21
21
|
files_to_process(cookbook_path).each do |file|
|
22
22
|
ast = read_file(file)
|
23
23
|
@rules.each do |rule|
|
24
|
-
matches = rule.recipe.yield(ast,
|
25
|
-
matches.each{|match| warnings << Warning.new(rule,
|
24
|
+
matches = rule.recipe.yield(ast, file)
|
25
|
+
matches.each{|match| warnings << Warning.new(rule, {:filename => file}.merge(match))} unless matches.nil?
|
26
26
|
end
|
27
27
|
end
|
28
28
|
Review.new(warnings)
|
data/lib/foodcritic/rules.rb
CHANGED
@@ -49,12 +49,45 @@ end
|
|
49
49
|
rule "FC007", "Ensure recipe dependencies are reflected in cookbook metadata" do
|
50
50
|
description "You are including a recipe that is not in the current cookbook and not defined as a dependency in your cookbook metadata."
|
51
51
|
recipe do |ast,filename|
|
52
|
-
metadata_path = File.join(File.dirname(filename), '..', 'metadata.rb')
|
52
|
+
metadata_path = Pathname.new(File.join(File.dirname(filename), '..', 'metadata.rb')).cleanpath
|
53
53
|
next unless File.exists? metadata_path
|
54
54
|
undeclared = included_recipes(ast).keys.map{|recipe|recipe.split('::').first} - [cookbook_name(filename)] -
|
55
55
|
declared_dependencies(read_file(metadata_path))
|
56
56
|
included_recipes(ast).map do |recipe, resource|
|
57
|
-
match(resource) if undeclared.include?(recipe) || undeclared.any?{|u| recipe.start_with?("#{u}::")}
|
57
|
+
match(resource).merge(:filename => metadata_path) if undeclared.include?(recipe) || undeclared.any?{|u| recipe.start_with?("#{u}::")}
|
58
58
|
end.compact
|
59
59
|
end
|
60
60
|
end
|
61
|
+
|
62
|
+
rule "FC008", "Generated cookbook metadata needs updating" do
|
63
|
+
description "The cookbook metadata for this cookbook is boilerplate output from knife generate cookbook and needs updating with the real details of your cookbook."
|
64
|
+
recipe do |ast,filename|
|
65
|
+
metadata_path = Pathname.new(File.join(File.dirname(filename), '..', 'metadata.rb')).cleanpath
|
66
|
+
next unless File.exists? metadata_path
|
67
|
+
md = read_file(metadata_path)
|
68
|
+
{'maintainer' => 'YOUR_COMPANY_NAME', 'maintainer_email' => 'YOUR_EMAIL'}.map do |field,value|
|
69
|
+
md.xpath(%Q{//command[ident/@value='#{field}']/descendant::tstring_content[@value='#{value}']}).map do |m|
|
70
|
+
match(m).merge(:filename => metadata_path)
|
71
|
+
end
|
72
|
+
end.flatten
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
rule "FC009", "Resource attribute not recognised" do
|
77
|
+
description "You appear to be using an unrecognised attribute on a standard Chef resource. Please check for typos."
|
78
|
+
recipe do |ast|
|
79
|
+
matches = []
|
80
|
+
resource_attributes_by_type(ast).each do |type,resources|
|
81
|
+
if Chef::Resource.const_defined?(convert_to_class_name(type))
|
82
|
+
allowed_atts = Chef::Resource.const_get(convert_to_class_name(type)).public_instance_methods(true)
|
83
|
+
resources.each do |resource|
|
84
|
+
invalid_atts = resource.keys.map{|att|att.to_sym} - allowed_atts
|
85
|
+
unless invalid_atts.empty?
|
86
|
+
matches << match(find_resources(ast, type).find{|res|resource_attributes(res).include?(invalid_atts.first.to_s)})
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
matches
|
92
|
+
end
|
93
|
+
end
|
data/lib/foodcritic/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foodcritic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,30 +9,30 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement: &
|
15
|
+
name: chef
|
16
|
+
requirement: &2153103960 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 0.10.4
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2153103960
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
|
-
name:
|
27
|
-
requirement: &
|
26
|
+
name: nokogiri
|
27
|
+
requirement: &2153103180 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 1.
|
32
|
+
version: 1.5.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2153103180
|
36
36
|
description: Lint tool for Opscode Chef cookbooks.
|
37
37
|
email:
|
38
38
|
executables:
|
@@ -69,12 +69,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
69
|
version: '0'
|
70
70
|
segments:
|
71
71
|
- 0
|
72
|
-
hash:
|
72
|
+
hash: 1643437083715464422
|
73
73
|
requirements: []
|
74
74
|
rubyforge_project:
|
75
75
|
rubygems_version: 1.8.10
|
76
76
|
signing_key:
|
77
77
|
specification_version: 3
|
78
|
-
summary: foodcritic-0.
|
78
|
+
summary: foodcritic-0.4.0
|
79
79
|
test_files: []
|
80
80
|
has_rdoc:
|