Skip to content

Instantly share code, notes, and snippets.

@jtimberman
Created July 7, 2012 02:56
Show Gist options
  • Select an option

  • Save jtimberman/3064090 to your computer and use it in GitHub Desktop.

Select an option

Save jtimberman/3064090 to your computer and use it in GitHub Desktop.
save this as ~/.chef/plugins/knife/cookbook_test.rb and it will be used by 'knife cookbook test'
# NOTE: The foodcritic args option (--lint-args) has not been tested
#
# Author:: Adam Jacob (<adam@opscode.com>)
# Author:: Matthew Kent (<mkent@magoazul.com>)
# Author:: Joshua Timberman (<joshua@opscode.com>)
# Copyright:: Copyright (c) 2009-2012 Opscode, Inc.
# Copyright:: Copyright (c) 2010 Matthew Kent
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/knife'
module KnifePlugins
class Knife
class CookbookTest < Chef::Knife
deps do
require 'chef/checksum_cache'
require 'chef/cookbook/syntax_check'
include Chef::Mixin::ShellOut
end
banner "knife cookbook test [COOKBOOKS...] (options)"
option :cookbook_path,
:short => "-o PATH:PATH",
:long => "--cookbook-path PATH:PATH",
:description => "A colon-separated path to look for cookbooks in",
:proc => lambda { |o| o.split(":") }
option :all,
:short => "-a",
:long => "--all",
:description => "Test all cookbooks, rather than just a single cookbook"
option :foodcritic,
:short => "-L",
:long => "--lint",
:description => "Include lint testing (foodcritic)",
:default => false
option :foodcritic_args,
:long => "--lint-args",
:description => "Comma-separated string of options to pass into lint tester (foodcritic)",
:default => nil
def run
config[:cookbook_path] ||= Chef::Config[:cookbook_path]
checked_a_cookbook = false
if config[:all]
cookbook_loader.each do |key, cookbook|
checked_a_cookbook = true
test_cookbook(key)
end
else
@name_args.each do |cb|
puts "checking #{cb}"
next unless cookbook_loader.cookbook_exists?(cb)
checked_a_cookbook = true
test_cookbook(cb)
end
end
unless checked_a_cookbook
ui.warn("No cookbooks to test in #{Array(config[:cookbook_path]).join(',')} - is your cookbook path misconfigured?")
end
end
def test_cookbook(cookbook)
ui.info("Running syntax check on #{cookbook}")
Array(config[:cookbook_path]).reverse.each do |path|
syntax_checker = Chef::Cookbook::SyntaxCheck.for_cookbook(cookbook, path)
test_ruby(syntax_checker)
test_templates(syntax_checker)
test_lint(cookbook) if config[:foodcritic]
end
end
def test_ruby(syntax_checker)
ui.info("Validating ruby files")
exit(1) unless syntax_checker.validate_ruby_files
end
def test_templates(syntax_checker)
ui.info("Validating templates")
exit(1) unless syntax_checker.validate_templates
end
def test_lint(cookbook)
lint_target = File.join(config[:cookbook_path], cookbook)
ui.info("Running lint check on #{cookbook}")
foodcritic_args = lint_args(config[:foodcritic_args]) if config[:foodcritic_args]
result = shell_out("sh -c 'foodcritic #{foodcritic_args} #{lint_target}'")
result.stdout.each_line {|l| ui.info(l)}
result.error!
true
rescue Mixlib::ShellOut::ShellCommandFailed
ui.fatal("Could not execute lint checker \`foodcritic\`")
ui.fatal("Try installing the \`foodcritic\` gem and try again")
result.stderr.each_line {|l| ui.fatal(l.chomp)}
false
end
def lint_args(foodcritic_args)
foodcritic_args.split(/,/).join(" ")
end
def cookbook_loader
@cookbook_loader ||= Chef::CookbookLoader.new(config[:cookbook_path])
end
end
end
end
@acrmp

acrmp commented Jul 7, 2012

Copy link
Copy Markdown

This looks awesome. Thanks Joshua.

Commas can be used when specifying foodcritic rules to apply so we might want to use a different delimiter for lint-args.

Cheers,

Andrew.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment