chefspec 0.2.1 → 0.3.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/chef/knife/cookbook_create_specs.rb +107 -0
- data/lib/chefspec.rb +1 -0
- data/lib/chefspec/matchers/file_content.rb +27 -0
- data/lib/chefspec/matchers/log.rb +1 -0
- data/lib/chefspec/matchers/shared.rb +21 -1
- data/lib/chefspec/monkey_patches/provider.rb +8 -1
- data/lib/chefspec/version.rb +3 -2
- metadata +53 -66
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'chefspec'
|
2
|
+
|
3
|
+
if Chef.const_defined? :Knife
|
4
|
+
module ChefSpec
|
5
|
+
module Knife
|
6
|
+
|
7
|
+
# Knife plugin to create placeholder specs.
|
8
|
+
#
|
9
|
+
# $ knife cookbook create -o . my_new_cookbook
|
10
|
+
# $ knife cookbook create_specs -o . my_new_cookbook
|
11
|
+
# $ rspec my_new_cookbook
|
12
|
+
#
|
13
|
+
# http://help.opscode.com/kb/knife/manage-cookbooks-with-knife
|
14
|
+
class CookbookCreateSpecs < Chef::Knife
|
15
|
+
|
16
|
+
# Implemented as a separate knife command rather than extending the knife built-in create_cookbook_command.
|
17
|
+
# Extension may arguably have been better from the end user perspective but would be much more brittle.
|
18
|
+
|
19
|
+
banner "knife cookbook create_specs COOKBOOK (options)"
|
20
|
+
|
21
|
+
option :cookbook_path,
|
22
|
+
:short => "-o PATH",
|
23
|
+
:long => "--cookbook-path PATH",
|
24
|
+
:description => "The directory where the cookbook specs will be created"
|
25
|
+
|
26
|
+
# Invoke this command and create the new specs
|
27
|
+
def run
|
28
|
+
self.config = Chef::Config.merge!(config)
|
29
|
+
if @name_args.empty?
|
30
|
+
show_usage
|
31
|
+
ui.fatal("You must specify a cookbook name")
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
if default_cookbook_path_empty? && parameter_empty?(config[:cookbook_path])
|
36
|
+
raise ArgumentError, "Default cookbook_path is not specified in the knife.rb config file, and a value to -o is not provided. Nowhere to write the new cookbook to."
|
37
|
+
end
|
38
|
+
|
39
|
+
create_specs(Array(config[:cookbook_path]).first, @name_args.first)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# Has a default cookbook path been set?
|
45
|
+
#
|
46
|
+
# @return [Boolean] True if cookbook path has been set in the Chef config.
|
47
|
+
def default_cookbook_path_empty?
|
48
|
+
Chef::Config[:cookbook_path].nil? || Chef::Config[:cookbook_path].empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
# Create placeholder specs for the cookbook.
|
52
|
+
#
|
53
|
+
# @param [String] dir The directory to create the specs in
|
54
|
+
# @param [String] cookbook The name of the cookbook
|
55
|
+
# @param [String] recipe The name of the recipe to create a spec for
|
56
|
+
def create_specs(dir, cookbook)
|
57
|
+
spec_dir = "#{File.join(dir, cookbook, 'spec')}"
|
58
|
+
FileUtils.mkdir_p spec_dir
|
59
|
+
msg("** Creating specs for cookbook: #{cookbook}")
|
60
|
+
existing_recipes(dir, cookbook).each do |recipe|
|
61
|
+
create_spec(spec_dir, cookbook, recipe)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# The list of recipes for a cookbook
|
66
|
+
#
|
67
|
+
# @param [String] dir The directory
|
68
|
+
# @param [String] cookbook The name of the cookbook
|
69
|
+
# @return [Array] The list of recipes for the cookbook
|
70
|
+
def existing_recipes(dir, cookbook)
|
71
|
+
Dir[File.join(dir, cookbook, 'recipes/*.rb')].map{|recipe| File.basename recipe, '.rb'}
|
72
|
+
end
|
73
|
+
|
74
|
+
# Create a placeholder spec for the cookbook.
|
75
|
+
#
|
76
|
+
# @param [String] spec_dir The directory to create the specs in
|
77
|
+
# @param [String] cookbook The name of the cookbook
|
78
|
+
# @param [String] recipe The name of the recipe to create a spec for
|
79
|
+
def create_spec(spec_dir, cookbook, recipe)
|
80
|
+
unless File.exists?(File.join(spec_dir, "#{recipe}_spec.rb"))
|
81
|
+
open(File.join(spec_dir, "#{recipe}_spec.rb"), "w") do |file|
|
82
|
+
file.puts spec_file_content(cookbook, recipe)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Generate the content for the placeholder spec file.
|
88
|
+
#
|
89
|
+
# @param [String] cookbook The name of the cookbook
|
90
|
+
# @param [String] recipe The name of the recipe
|
91
|
+
def spec_file_content(cookbook, recipe)
|
92
|
+
return <<-EOH
|
93
|
+
require 'chefspec'
|
94
|
+
|
95
|
+
describe '#{cookbook}::#{recipe}' do
|
96
|
+
let (:chef_run) { ChefSpec::ChefRunner.new.converge '#{cookbook}::#{recipe}' }
|
97
|
+
it 'should do something' do
|
98
|
+
pending 'Your recipe examples go here.'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
EOH
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/chefspec.rb
CHANGED
@@ -8,5 +8,6 @@ require 'chefspec/matchers/log'
|
|
8
8
|
require 'chefspec/matchers/package'
|
9
9
|
require 'chefspec/matchers/service'
|
10
10
|
require 'chefspec/matchers/shared'
|
11
|
+
require 'chefspec/matchers/file_content'
|
11
12
|
require 'chefspec/monkey_patches/hash'
|
12
13
|
require 'chefspec/monkey_patches/provider'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'chefspec/matchers/shared'
|
2
|
+
|
3
|
+
module ChefSpec
|
4
|
+
module Matchers
|
5
|
+
RSpec::Matchers.define :create_file_with_content do |path, content|
|
6
|
+
match do |chef_run|
|
7
|
+
chef_run.resources.any? do |resource|
|
8
|
+
if resource.name == path
|
9
|
+
if resource.action.include?(:create) || resource.action.include?(:create_if_missing)
|
10
|
+
case resource_type(resource)
|
11
|
+
when 'template'
|
12
|
+
@actual_content = render(resource, chef_run.node)
|
13
|
+
content == @actual_content
|
14
|
+
when 'file'
|
15
|
+
@actual_content = resource.content
|
16
|
+
content == @actual_content
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
failure_message_for_should do |actual|
|
23
|
+
"File content:\n#{@actual_content} does not match expected:\n#{content}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -30,4 +30,24 @@ def define_resource_matchers(actions, resource_types, name_attribute)
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
33
|
-
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Render a template.
|
36
|
+
#
|
37
|
+
# @param [Chef::Resource::Template] template The template to render
|
38
|
+
# @param [Chef::Node] node The node which may be required to render the template
|
39
|
+
# @return [String] The result result of rendering the template
|
40
|
+
def render(template, node)
|
41
|
+
# Duplicates functionality in the Chef Template provider
|
42
|
+
context = {}; context.merge!(template.variables)
|
43
|
+
context[:node] = node
|
44
|
+
Erubis::Eruby.new(IO.read(template_path(template))).evaluate(context)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Given a template, return the path on disk.
|
48
|
+
#
|
49
|
+
# @param [Chef::Resource::Template] template The template
|
50
|
+
# @return [String] The path on disk
|
51
|
+
def template_path(template)
|
52
|
+
File.join("cookbooks/#{template.cookbook || template.cookbook_name}/templates/default", template.source)
|
53
|
+
end
|
@@ -1,9 +1,16 @@
|
|
1
1
|
# Override Chef LWRP creation to remove existing class to avoid redefinition warnings.
|
2
2
|
class Chef
|
3
|
+
# Chef provider for a resource
|
3
4
|
class Provider
|
4
5
|
class << self
|
5
|
-
|
6
|
+
alias_method :old_build_from_file, :build_from_file
|
6
7
|
|
8
|
+
# Override Opscode provider to remove any existing LWRP
|
9
|
+
#
|
10
|
+
# @param [String] cookbook_name The name of the cookbook
|
11
|
+
# @param [String] filename File to load as a LWRP
|
12
|
+
# @param [Chef::RunContext] run_context Context of a Chef Run
|
13
|
+
# @return [Chef::Provider] the created provider
|
7
14
|
def build_from_file(cookbook_name, filename, run_context)
|
8
15
|
remove_existing_lwrp(convert_to_class_name(filename_to_qualified_string(cookbook_name, filename)))
|
9
16
|
old_build_from_file(cookbook_name, filename, run_context)
|
data/lib/chefspec/version.rb
CHANGED
metadata
CHANGED
@@ -1,73 +1,63 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: chefspec
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 2
|
9
|
-
- 1
|
10
|
-
version: 0.2.1
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Andrew Crump
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
12
|
+
date: 2011-10-02 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: chef
|
16
|
+
requirement: &2151873320 !ruby/object:Gem::Requirement
|
22
17
|
none: false
|
23
|
-
requirements:
|
24
|
-
- -
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
hash: 35
|
27
|
-
segments:
|
28
|
-
- 0
|
29
|
-
- 9
|
30
|
-
- 12
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
31
21
|
version: 0.9.12
|
32
22
|
- - ~>
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
|
35
|
-
segments:
|
36
|
-
- 0
|
37
|
-
- 10
|
38
|
-
version: "0.10"
|
39
|
-
name: chef
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '0.10'
|
40
25
|
type: :runtime
|
41
26
|
prerelease: false
|
42
|
-
|
43
|
-
- !ruby/object:Gem::Dependency
|
44
|
-
|
27
|
+
version_requirements: *2151873320
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: erubis
|
30
|
+
requirement: &2151885360 !ruby/object:Gem::Requirement
|
45
31
|
none: false
|
46
|
-
requirements:
|
47
|
-
- -
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
version: 2.6.0
|
32
|
+
requirements:
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: *2151885360
|
39
|
+
- !ruby/object:Gem::Dependency
|
55
40
|
name: rspec
|
41
|
+
requirement: &2151891840 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.6.0
|
56
47
|
type: :runtime
|
57
48
|
prerelease: false
|
58
|
-
|
49
|
+
version_requirements: *2151891840
|
59
50
|
description: Write RSpec examples for Opscode Chef recipes
|
60
51
|
email:
|
61
52
|
executables: []
|
62
|
-
|
63
53
|
extensions: []
|
64
|
-
|
65
54
|
extra_rdoc_files: []
|
66
|
-
|
67
|
-
|
55
|
+
files:
|
56
|
+
- lib/chef/knife/cookbook_create_specs.rb
|
68
57
|
- lib/chefspec/chef_runner.rb
|
69
58
|
- lib/chefspec/matchers/execute.rb
|
70
59
|
- lib/chefspec/matchers/file.rb
|
60
|
+
- lib/chefspec/matchers/file_content.rb
|
71
61
|
- lib/chefspec/matchers/log.rb
|
72
62
|
- lib/chefspec/matchers/package.rb
|
73
63
|
- lib/chefspec/matchers/service.rb
|
@@ -77,37 +67,34 @@ files:
|
|
77
67
|
- lib/chefspec/version.rb
|
78
68
|
- lib/chefspec.rb
|
79
69
|
homepage: http://acrmp.github.com/chefspec
|
80
|
-
licenses:
|
70
|
+
licenses:
|
81
71
|
- MIT
|
82
72
|
post_install_message:
|
83
73
|
rdoc_options: []
|
84
|
-
|
85
|
-
require_paths:
|
74
|
+
require_paths:
|
86
75
|
- lib
|
87
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
77
|
none: false
|
89
|
-
requirements:
|
90
|
-
- -
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
|
93
|
-
segments:
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
segments:
|
94
83
|
- 0
|
95
|
-
|
96
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
hash: 4357686734109657142
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
86
|
none: false
|
98
|
-
requirements:
|
99
|
-
- -
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
|
102
|
-
segments:
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
segments:
|
103
92
|
- 0
|
104
|
-
|
93
|
+
hash: 4357686734109657142
|
105
94
|
requirements: []
|
106
|
-
|
107
95
|
rubyforge_project:
|
108
96
|
rubygems_version: 1.8.6
|
109
97
|
signing_key:
|
110
98
|
specification_version: 3
|
111
|
-
summary: chefspec-0.
|
99
|
+
summary: chefspec-0.3.0
|
112
100
|
test_files: []
|
113
|
-
|