Skip to content
This repository has been archived by the owner on Sep 19, 2020. It is now read-only.

Commit

Permalink
Directory handling changes and cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Crump committed Nov 30, 2011
1 parent ca5a545 commit 4443d9b
Show file tree
Hide file tree
Showing 9 changed files with 21 additions and 17 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
@@ -1,3 +1,3 @@
## 0.1.0 (27th November, 2011)
## 0.1.0 (30th November, 2011)

Initial version.
2 changes: 1 addition & 1 deletion README.md
@@ -1,6 +1,6 @@
# Food Critic

Food Critic is a lint tool for Chef cookbooks. It requires Ruby 1.9.3.
Food Critic is a lint tool for Chef cookbooks. It requires Ruby 1.9.3. It doesn't do very much at the moment.

# Building

Expand Down
4 changes: 4 additions & 0 deletions bin/foodcritic
@@ -1,4 +1,8 @@
#!/usr/bin/env ruby
require 'foodcritic'
unless ARGV.length == 1 and Dir.exists?(ARGV[0])
STDERR.puts 'foodcritic [cookbook_path]'
exit 1
end
review = FoodCritic::Linter.new.check(ARGV[0])
puts review unless review.warnings.empty?
2 changes: 1 addition & 1 deletion features/step_definitions/cookbook_steps.rb
Expand Up @@ -29,7 +29,7 @@
end

Then /^the (?:[a-z ]+) warning ([0-9]+) should be displayed( against the attributes file)?$/ do |code, atts|
expect_warning("FC#{code}", atts.nil? ? {} : {:file => 'attributes/default.rb'})
expect_warning("FC#{code}", atts.nil? ? {} : {:file => 'cookbooks/example/attributes/default.rb'})
end

Then /^the node access warning 001 should be displayed for each match$/ do
Expand Down
2 changes: 1 addition & 1 deletion features/support/lint_helpers.rb
Expand Up @@ -15,7 +15,7 @@ def run_lint
end

def expect_warning(code, options={})
opt = {:line => 1, :expect_warning => true, :file => 'recipes/default.rb'}.merge!(options)
opt = {:line => 1, :expect_warning => true, :file => 'cookbooks/example/recipes/default.rb'}.merge!(options)
warning_text = case code
when 'FC001' then
'Use symbols in preference to strings to access node attributes'
Expand Down
4 changes: 2 additions & 2 deletions lib/foodcritic/dsl.rb
Expand Up @@ -18,14 +18,14 @@ def rule(code, name, &block)

# Set the rule description
#
# @param [String] Set the rule description.
# @param [String] description Set the rule description.
def description(description)
rules.last.description = description
end

# Define a matcher that will be passed the AST with this method.
#
# @param [block] Your implemented matcher that returns a match Hash.
# @param [block] block Your implemented matcher that returns a match Hash.
def recipe(&block)
rules.last.recipe = block
end
Expand Down
16 changes: 8 additions & 8 deletions lib/foodcritic/helpers.rb
Expand Up @@ -11,7 +11,7 @@ module Helpers
def ast(type, node)
result = []
result = [node] if node.first == type
node.each { |node| result += ast(type, node) if node.respond_to?(:each) }
node.each { |n| result += ast(type, n) if n.respond_to?(:each) }
result
end

Expand All @@ -20,10 +20,10 @@ def ast(type, node)
# @param [Array] ast The AST of the cookbook recipe to check.
# @return [Boolean] True if there is a test for Chef::Config[:solo] in the recipe
def checks_for_chef_solo?(ast)
arefs = self.ast(:aref, ast)
arefs = ast(:aref, ast)
arefs.any? do |aref|
self.ast(:@const, aref).map { |const| const[1] } == ['Chef', 'Config'] and
self.ast(:@ident, self.ast(:symbol, aref)).map { |sym| sym.drop(1).first }.include? 'solo'
ast(:@const, aref).map { |const| const[1] } == ['Chef', 'Config'] and
ast(:@ident, ast(:symbol, aref)).map { |sym| sym.drop(1).first }.include? 'solo'
end
end

Expand All @@ -33,14 +33,14 @@ def checks_for_chef_solo?(ast)
# @param [Array] ast The AST of the cookbook recipe to check
# @param [String] type The type of resource to look for (or nil for all resources)
def find_resources(ast, type = nil)
self.ast(:method_add_block, ast).find_all do |resource|
ast(:method_add_block, ast).find_all do |resource|
resource[1][0] == :command and resource[1][1][0] == :@ident and (type.nil? || resource[1][1][1] == type)
end
end

# Return the type, e.g. 'package' for a given resource
#
# @param [Array] The resource AST
# @param [Array] resource The resource AST
# @return [String] The type of resource
def resource_type(resource)
resource[1][1][1]
Expand All @@ -59,9 +59,9 @@ def resource_name(resource)
# @param [Array] resource The resource AST to lookup the attribute under
# @return [String] The attribute value for the specified attribute
def resource_attribute(name, resource)
cmd = self.ast(:command, self.ast(:do_block, resource))
cmd = ast(:command, ast(:do_block, resource))
atts = cmd.find_all { |att| ast(:@ident, att).flatten.drop(1).first == name }
value = self.ast(:@tstring_content, atts).flatten.drop(1)
value = ast(:@tstring_content, atts).flatten.drop(1)
unless value.empty?
return value.first
end
Expand Down
4 changes: 2 additions & 2 deletions lib/foodcritic/linter.rb
Expand Up @@ -20,7 +20,7 @@ def check(cookbook_path)
ast = Ripper::SexpBuilder.new(IO.read(file)).parse
@rules.each do |rule|
rule.recipe.yield(ast).each do |match|
warnings << Warning.new(rule, match.merge({:filename => file.gsub(/^#{Regexp.escape(ARGV[0])}/, '')}))
warnings << Warning.new(rule, match.merge({:filename => file}))
end
end
end
Expand All @@ -40,7 +40,7 @@ def load_rules
# @return [Array] The files underneath the provided directory to be processed.
def files_to_process(dir)
return [dir] unless File.directory? dir
Dir.glob(File.join(dir, '{attributes,recipes}/*.rb'))
Dir.glob(File.join(dir, '{attributes,recipes}/*.rb')) + Dir.glob(File.join(dir, '*/{attributes,recipes}/*.rb'))
end

end
Expand Down
2 changes: 1 addition & 1 deletion lib/foodcritic/rules.rb
Expand Up @@ -72,7 +72,7 @@
# do all of the attributes for all resources of a given type match apart aside from one?
resource_attributes_by_type(ast).each do |type, resource_atts|
sorted_atts = resource_atts.map{|atts| atts.to_a.sort{|x,y| x.first.to_s <=> y.first.to_s }}
if sorted_atts.all?{|att| (att - sorted_atts.inject{|atts,att| atts & att}).length == 1}
if sorted_atts.all?{|att| (att - sorted_atts.inject{|atts,a| atts & a}).length == 1}
first_resource = ast(:@ident, find_resources(ast, type).first).first[2]
matches << {:matched => type, :line => first_resource[0], :column => first_resource[1]}
end
Expand Down

0 comments on commit 4443d9b

Please sign in to comment.