cheffish 1.4.1 → 1.4.2

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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -201
  3. data/README.md +120 -120
  4. data/Rakefile +23 -23
  5. data/lib/chef/provider/chef_acl.rb +439 -439
  6. data/lib/chef/provider/chef_client.rb +53 -53
  7. data/lib/chef/provider/chef_container.rb +55 -55
  8. data/lib/chef/provider/chef_data_bag.rb +55 -55
  9. data/lib/chef/provider/chef_data_bag_item.rb +278 -278
  10. data/lib/chef/provider/chef_environment.rb +83 -83
  11. data/lib/chef/provider/chef_group.rb +83 -83
  12. data/lib/chef/provider/chef_mirror.rb +169 -169
  13. data/lib/chef/provider/chef_node.rb +87 -87
  14. data/lib/chef/provider/chef_organization.rb +155 -155
  15. data/lib/chef/provider/chef_resolved_cookbooks.rb +46 -46
  16. data/lib/chef/provider/chef_role.rb +84 -84
  17. data/lib/chef/provider/chef_user.rb +59 -59
  18. data/lib/chef/provider/private_key.rb +225 -225
  19. data/lib/chef/provider/public_key.rb +88 -88
  20. data/lib/chef/resource/chef_acl.rb +69 -69
  21. data/lib/chef/resource/chef_client.rb +48 -48
  22. data/lib/chef/resource/chef_container.rb +22 -22
  23. data/lib/chef/resource/chef_data_bag.rb +22 -22
  24. data/lib/chef/resource/chef_data_bag_item.rb +121 -121
  25. data/lib/chef/resource/chef_environment.rb +77 -77
  26. data/lib/chef/resource/chef_group.rb +53 -53
  27. data/lib/chef/resource/chef_mirror.rb +52 -52
  28. data/lib/chef/resource/chef_node.rb +22 -22
  29. data/lib/chef/resource/chef_organization.rb +69 -69
  30. data/lib/chef/resource/chef_resolved_cookbooks.rb +35 -35
  31. data/lib/chef/resource/chef_role.rb +110 -110
  32. data/lib/chef/resource/chef_user.rb +56 -56
  33. data/lib/chef/resource/private_key.rb +48 -48
  34. data/lib/chef/resource/public_key.rb +25 -25
  35. data/lib/cheffish/actor_provider_base.rb +131 -131
  36. data/lib/cheffish/basic_chef_client.rb +184 -184
  37. data/lib/cheffish/chef_provider_base.rb +246 -246
  38. data/lib/cheffish/chef_run.rb +162 -162
  39. data/lib/cheffish/chef_run_data.rb +19 -19
  40. data/lib/cheffish/chef_run_listener.rb +30 -30
  41. data/lib/cheffish/key_formatter.rb +113 -113
  42. data/lib/cheffish/merged_config.rb +94 -94
  43. data/lib/cheffish/recipe_dsl.rb +157 -157
  44. data/lib/cheffish/rspec/chef_run_support.rb +83 -83
  45. data/lib/cheffish/rspec/matchers/be_idempotent.rb +16 -16
  46. data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +15 -15
  47. data/lib/cheffish/rspec/matchers/have_updated.rb +37 -37
  48. data/lib/cheffish/rspec/matchers/partially_match.rb +63 -63
  49. data/lib/cheffish/rspec/matchers.rb +4 -4
  50. data/lib/cheffish/rspec/recipe_run_wrapper.rb +78 -59
  51. data/lib/cheffish/rspec/repository_support.rb +108 -108
  52. data/lib/cheffish/rspec.rb +8 -8
  53. data/lib/cheffish/server_api.rb +52 -52
  54. data/lib/cheffish/version.rb +3 -3
  55. data/lib/cheffish/with_pattern.rb +21 -21
  56. data/lib/cheffish.rb +235 -235
  57. data/spec/functional/fingerprint_spec.rb +64 -64
  58. data/spec/functional/merged_config_spec.rb +19 -19
  59. data/spec/functional/server_api_spec.rb +13 -13
  60. data/spec/integration/chef_acl_spec.rb +879 -879
  61. data/spec/integration/chef_client_spec.rb +105 -105
  62. data/spec/integration/chef_container_spec.rb +33 -33
  63. data/spec/integration/chef_group_spec.rb +309 -309
  64. data/spec/integration/chef_mirror_spec.rb +491 -491
  65. data/spec/integration/chef_node_spec.rb +786 -786
  66. data/spec/integration/chef_organization_spec.rb +226 -226
  67. data/spec/integration/chef_role_spec.rb +78 -78
  68. data/spec/integration/chef_user_spec.rb +85 -85
  69. data/spec/integration/private_key_spec.rb +399 -399
  70. data/spec/integration/recipe_dsl_spec.rb +28 -28
  71. data/spec/integration/rspec/converge_spec.rb +183 -183
  72. data/spec/support/key_support.rb +29 -29
  73. data/spec/support/spec_support.rb +15 -15
  74. data/spec/unit/get_private_key_spec.rb +131 -131
  75. data/spec/unit/recipe_run_wrapper_spec.rb +37 -37
  76. metadata +3 -2
@@ -1,16 +1,16 @@
1
- require 'rspec/matchers'
2
-
3
- RSpec::Matchers.define :be_idempotent do
4
- match do |recipe|
5
- @recipe = recipe
6
- recipe.reset
7
- recipe.converge
8
- recipe.up_to_date?
9
- end
10
-
11
- failure_message {
12
- "#{@recipe} is not idempotent! Converging it a second time caused updates.\n#{@recipe.output_for_failure_message}"
13
- }
14
-
15
- supports_block_expectations
16
- end
1
+ require 'rspec/matchers'
2
+
3
+ RSpec::Matchers.define :be_idempotent do
4
+ match do |recipe|
5
+ @recipe = recipe
6
+ recipe.reset
7
+ recipe.converge
8
+ recipe.up_to_date?
9
+ end
10
+
11
+ failure_message {
12
+ "#{@recipe} is not idempotent! Converging it a second time caused updates.\n#{@recipe.output_for_failure_message}"
13
+ }
14
+
15
+ supports_block_expectations
16
+ end
@@ -1,15 +1,15 @@
1
- require 'rspec/matchers'
2
-
3
- RSpec::Matchers.define :emit_no_warnings_or_errors do
4
- match do |recipe|
5
- @recipe = recipe
6
- @warn_err = recipe.logs.lines.select { |l| l =~ /warn|err/i }.join("\n")
7
- @warn_err.empty?
8
- end
9
-
10
- failure_message {
11
- "#{@recipe} emitted warnings and errors!\n#{@warn_err}"
12
- }
13
-
14
- supports_block_expectations
15
- end
1
+ require 'rspec/matchers'
2
+
3
+ RSpec::Matchers.define :emit_no_warnings_or_errors do
4
+ match do |recipe|
5
+ @recipe = recipe
6
+ @warn_err = recipe.logs.lines.select { |l| l =~ /warn|err/i }.join("\n")
7
+ @warn_err.empty?
8
+ end
9
+
10
+ failure_message {
11
+ "#{@recipe} emitted warnings and errors!\n#{@warn_err}"
12
+ }
13
+
14
+ supports_block_expectations
15
+ end
@@ -1,37 +1,37 @@
1
- require 'rspec/matchers'
2
-
3
- RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
4
- match do |recipe|
5
- @recipe = recipe
6
- actual = @recipe.event_sink.events
7
- actual_actions = actual.select { |event, resource, action| event == :resource_updated && resource.to_s == resource_name }.
8
- map { |event, resource, action| action }
9
- expect(actual_actions).to eq(expected_actions)
10
- end
11
-
12
- failure_message do
13
- actual = @recipe.event_sink.events
14
- updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
15
- result = "expected that the chef_run would #{expected_actions.join(',')} #{resource_name}."
16
- if updates.size > 0
17
- result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
18
- else
19
- result << " Nothing was updated."
20
- end
21
- result
22
- end
23
-
24
- failure_message_when_negated do
25
- actual = @recipe.event_sink.events
26
- updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
27
- result = "expected that the chef_run would not #{expected_actions.join(',')} #{resource_name}."
28
- if updates.size > 0
29
- result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
30
- else
31
- result << " Nothing was updated."
32
- end
33
- result
34
- end
35
- end
36
-
37
- RSpec::Matchers.define_negated_matcher :not_have_updated, :have_updated
1
+ require 'rspec/matchers'
2
+
3
+ RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
4
+ match do |recipe|
5
+ @recipe = recipe
6
+ actual = @recipe.event_sink.events
7
+ actual_actions = actual.select { |event, resource, action| event == :resource_updated && resource.to_s == resource_name }.
8
+ map { |event, resource, action| action }
9
+ expect(actual_actions).to eq(expected_actions)
10
+ end
11
+
12
+ failure_message do
13
+ actual = @recipe.event_sink.events
14
+ updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
15
+ result = "expected that the chef_run would #{expected_actions.join(',')} #{resource_name}."
16
+ if updates.size > 0
17
+ result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
18
+ else
19
+ result << " Nothing was updated."
20
+ end
21
+ result
22
+ end
23
+
24
+ failure_message_when_negated do
25
+ actual = @recipe.event_sink.events
26
+ updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
27
+ result = "expected that the chef_run would not #{expected_actions.join(',')} #{resource_name}."
28
+ if updates.size > 0
29
+ result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
30
+ else
31
+ result << " Nothing was updated."
32
+ end
33
+ result
34
+ end
35
+ end
36
+
37
+ RSpec::Matchers.define_negated_matcher :not_have_updated, :have_updated
@@ -1,63 +1,63 @@
1
- module Cheffish
2
- module RSpec
3
- module Matchers
4
- class PartiallyMatch
5
- include ::RSpec::Matchers::Composable
6
-
7
- def initialize(example, expected)
8
- @example = example
9
- @expected = expected
10
- end
11
-
12
- def matches?(actual)
13
- @actual = actual
14
- partially_matches_values(@expected, actual)
15
- end
16
-
17
- def failure_message
18
- "expected #{@actual} to match #{@expected}"
19
- end
20
-
21
- def failure_message_when_negated
22
- "expected #{@actual} not to match #{@expected}"
23
- end
24
-
25
- protected
26
-
27
- def partially_matches_values(expected, actual)
28
- if Hash === actual
29
- return partially_matches_hashes(expected, actual) if Hash === expected || Array === expected
30
- elsif Array === expected && Enumerable === actual && !(Struct === actual)
31
- return partially_matches_arrays(expected, actual)
32
- end
33
-
34
- return true if actual == expected
35
-
36
- begin
37
- expected === actual
38
- rescue ArgumentError
39
- # Some objects, like 0-arg lambdas on 1.9+, raise
40
- # ArgumentError for `expected === actual`.
41
- false
42
- end
43
- end
44
-
45
- def partially_matches_hashes(expected, actual)
46
- expected.all? { |key, value| partially_matches_values(value, actual[key]) }
47
- end
48
-
49
- def partially_matches_arrays(expected, actual)
50
- expected.all? { |e| actual.any? { |a| partially_matches_values(e, a) } }
51
- end
52
- end
53
- end
54
- end
55
- end
56
-
57
- module RSpec
58
- module Matchers
59
- def partially_match(expected)
60
- Cheffish::RSpec::Matchers::PartiallyMatch.new(self, expected)
61
- end
62
- end
63
- end
1
+ module Cheffish
2
+ module RSpec
3
+ module Matchers
4
+ class PartiallyMatch
5
+ include ::RSpec::Matchers::Composable
6
+
7
+ def initialize(example, expected)
8
+ @example = example
9
+ @expected = expected
10
+ end
11
+
12
+ def matches?(actual)
13
+ @actual = actual
14
+ partially_matches_values(@expected, actual)
15
+ end
16
+
17
+ def failure_message
18
+ "expected #{@actual} to match #{@expected}"
19
+ end
20
+
21
+ def failure_message_when_negated
22
+ "expected #{@actual} not to match #{@expected}"
23
+ end
24
+
25
+ protected
26
+
27
+ def partially_matches_values(expected, actual)
28
+ if Hash === actual
29
+ return partially_matches_hashes(expected, actual) if Hash === expected || Array === expected
30
+ elsif Array === expected && Enumerable === actual && !(Struct === actual)
31
+ return partially_matches_arrays(expected, actual)
32
+ end
33
+
34
+ return true if actual == expected
35
+
36
+ begin
37
+ expected === actual
38
+ rescue ArgumentError
39
+ # Some objects, like 0-arg lambdas on 1.9+, raise
40
+ # ArgumentError for `expected === actual`.
41
+ false
42
+ end
43
+ end
44
+
45
+ def partially_matches_hashes(expected, actual)
46
+ expected.all? { |key, value| partially_matches_values(value, actual[key]) }
47
+ end
48
+
49
+ def partially_matches_arrays(expected, actual)
50
+ expected.all? { |e| actual.any? { |a| partially_matches_values(e, a) } }
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ module RSpec
58
+ module Matchers
59
+ def partially_match(expected)
60
+ Cheffish::RSpec::Matchers::PartiallyMatch.new(self, expected)
61
+ end
62
+ end
63
+ end
@@ -1,4 +1,4 @@
1
- require 'cheffish/rspec/matchers/have_updated'
2
- require 'cheffish/rspec/matchers/be_idempotent'
3
- require 'cheffish/rspec/matchers/partially_match'
4
- require 'cheffish/rspec/matchers/emit_no_warnings_or_errors'
1
+ require 'cheffish/rspec/matchers/have_updated'
2
+ require 'cheffish/rspec/matchers/be_idempotent'
3
+ require 'cheffish/rspec/matchers/partially_match'
4
+ require 'cheffish/rspec/matchers/emit_no_warnings_or_errors'
@@ -1,59 +1,78 @@
1
- require 'cheffish/chef_run'
2
-
3
- module Cheffish
4
- module RSpec
5
- class RecipeRunWrapper < ChefRun
6
- def initialize(chef_config, example: nil, &recipe)
7
- super(chef_config)
8
- @recipe = recipe
9
- @example = example || recipe.binding.eval('self')
10
- end
11
-
12
- attr_reader :recipe
13
- attr_reader :example
14
-
15
- def client
16
- if !@client
17
- super
18
- example = self.example
19
-
20
- # Call into the rspec example's let variables and other methods
21
- @client.define_singleton_method(:method_missing) do |name, *args, &block|
22
- # the elimination of a bunch of metaprogramming in 12.4 changed how Chef DSL is defined in code,
23
- # requiring a slight contortion for earlier versions.
24
- if Gem::Version.new(Chef::VERSION) >= Gem::Version.new('12.4') # incompatibility introduced at 2b364df
25
- if example.respond_to?(name)
26
- example.public_send(name, *args, &block)
27
- end
28
- else
29
- begin
30
- super(name, *args, &block)
31
- rescue NameError
32
- if example.respond_to?(name)
33
- example.public_send(name, *args, &block)
34
- else
35
- raise
36
- end
37
- end
38
- end
39
- end
40
- # This is called by respond_to?, and is required to make sure the
41
- # resource knows that we will in fact call the given method.
42
- @client.define_singleton_method(:respond_to_missing?) do |name, include_private = false|
43
- example.respond_to?(name) || super(name, include_private)
44
- end
45
- # Respond true to is_a?(Chef::Provider) so that Chef::Recipe::DSL.build_resource
46
- # will hook resources up to the example let variables as well (via
47
- # enclosing_provider).
48
- # Please don't hurt me
49
- @client.define_singleton_method(:is_a?) do |klass|
50
- klass == Chef::Provider || super(klass)
51
- end
52
-
53
- @client.load_block(&recipe)
54
- end
55
- @client
56
- end
57
- end
58
- end
59
- end
1
+ require 'cheffish/chef_run'
2
+ require 'forwardable'
3
+
4
+ module Cheffish
5
+ module RSpec
6
+ class RecipeRunWrapper < ChefRun
7
+ def initialize(chef_config, example: nil, &recipe)
8
+ super(chef_config)
9
+ @recipe = recipe
10
+ @example = example || recipe.binding.eval('self')
11
+ end
12
+
13
+ attr_reader :recipe
14
+ attr_reader :example
15
+
16
+ def client
17
+ if !@client
18
+ super
19
+ example = self.example
20
+
21
+ #
22
+ # Support for both resources and rspec example's let variables:
23
+ #
24
+ # In 12.4, the elimination of a bunch of metaprogramming in 12.4
25
+ # changed how Chef DSL is defined in code: resource methods are now
26
+ # explicitly defined in `Chef::DSL::Recipe`. In 12.3, no actual
27
+ # methods were defined and `respond_to?(:file)` would return false.
28
+ # If we reach `method_missing` here, it means that we either have a
29
+ # 12.3-ish resource or we want to call a `let` variable.
30
+ #
31
+ @client.instance_eval { @rspec_example = example }
32
+ def @client.method_missing(name, *args, &block)
33
+ # If there is a let variable, call it. This is because in 12.4,
34
+ # the parent class is going to call respond_to?(name) to find out
35
+ # if someone was doing weird things, and then call send(). This
36
+ # would result in an infinite loop, coming right. Back. Here.
37
+ # A fix to chef is incoming, but we still need this if we want to
38
+ # work with Chef 12.4.
39
+ if Gem::Version.new(Chef::VERSION) >= Gem::Version.new('12.4')
40
+ if @rspec_example.respond_to?(name)
41
+ return @rspec_example.public_send(name, *args, &block)
42
+ end
43
+ end
44
+
45
+ # In 12.3 or below, method_missing was the only way to call
46
+ # resources. If we are in 12.4, we still need to call the crazy
47
+ # method_missing metaprogramming because backcompat.
48
+ begin
49
+ super
50
+ rescue NameError
51
+ if @rspec_example.respond_to?(name)
52
+ @rspec_example.public_send(name, *args, &block)
53
+ else
54
+ raise
55
+ end
56
+ end
57
+ end
58
+ # This is called by respond_to?, and is required to make sure the
59
+ # resource knows that we will in fact call the given method.
60
+ def @client.respond_to_missing?(name, include_private = false)
61
+ @rspec_example.respond_to?(name, include_private) || super
62
+ end
63
+
64
+ # Respond true to is_a?(Chef::Provider) so that Chef::Recipe::DSL.build_resource
65
+ # will hook resources up to the example let variables as well (via
66
+ # enclosing_provider).
67
+ # Please don't hurt me
68
+ def @client.is_a?(klass)
69
+ klass == Chef::Provider || super(klass)
70
+ end
71
+
72
+ @client.load_block(&recipe)
73
+ end
74
+ @client
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,108 +1,108 @@
1
- module Cheffish
2
- module RSpec
3
- module RepositorySupport
4
- def when_the_repository(desc, *tags, &block)
5
- context("when the chef repo #{desc}", *tags) do
6
- include_context "with a chef repo"
7
- extend WhenTheRepositoryClassMethods
8
- module_eval(&block)
9
- end
10
- end
11
-
12
- ::RSpec.shared_context "with a chef repo" do
13
- before :each do
14
- raise "Can only create one directory per test" if @repository_dir
15
- @repository_dir = Dir.mktmpdir('chef_repo')
16
- Chef::Config.chef_repo_path = @repository_dir
17
- %w(client cookbook data_bag environment node role user).each do |object_name|
18
- Chef::Config.delete("#{object_name}_path".to_sym)
19
- end
20
- end
21
-
22
- after :each do
23
- if @repository_dir
24
- begin
25
- %w(client cookbook data_bag environment node role user).each do |object_name|
26
- Chef::Config.delete("#{object_name}_path".to_sym)
27
- end
28
- Chef::Config.delete(:chef_repo_path)
29
- FileUtils.remove_entry_secure(@repository_dir)
30
- ensure
31
- @repository_dir = nil
32
- end
33
- end
34
- Dir.chdir(@old_cwd) if @old_cwd
35
- end
36
-
37
- def directory(relative_path, &block)
38
- old_parent_path = @parent_path
39
- @parent_path = path_to(relative_path)
40
- FileUtils.mkdir_p(@parent_path)
41
- instance_eval(&block) if block
42
- @parent_path = old_parent_path
43
- end
44
-
45
- def file(relative_path, contents)
46
- filename = path_to(relative_path)
47
- dir = File.dirname(filename)
48
- FileUtils.mkdir_p(dir) unless dir == '.'
49
- File.open(filename, 'w') do |file|
50
- raw = case contents
51
- when Hash
52
- JSON.pretty_generate(contents)
53
- when Array
54
- contents.join("\n")
55
- else
56
- contents
57
- end
58
- file.write(raw)
59
- end
60
- end
61
-
62
- def symlink(relative_path, relative_dest)
63
- filename = path_to(relative_path)
64
- dir = File.dirname(filename)
65
- FileUtils.mkdir_p(dir) unless dir == '.'
66
- dest_filename = path_to(relative_dest)
67
- File.symlink(dest_filename, filename)
68
- end
69
-
70
- def path_to(relative_path)
71
- File.expand_path(relative_path, (@parent_path || @repository_dir))
72
- end
73
-
74
- def cwd(relative_path)
75
- @old_cwd = Dir.pwd
76
- Dir.chdir(path_to(relative_path))
77
- end
78
-
79
- module WhenTheRepositoryClassMethods
80
- def directory(*args, &block)
81
- before :each do
82
- directory(*args, &block)
83
- end
84
- end
85
-
86
- def file(*args, &block)
87
- before :each do
88
- file(*args, &block)
89
- end
90
- end
91
-
92
- def symlink(*args, &block)
93
- before :each do
94
- symlink(*args, &block)
95
- end
96
- end
97
-
98
- def path_to(*args, &block)
99
- before :each do
100
- file(*args, &block)
101
- end
102
- end
103
- end
104
- end
105
- end
106
-
107
- end
108
- end
1
+ module Cheffish
2
+ module RSpec
3
+ module RepositorySupport
4
+ def when_the_repository(desc, *tags, &block)
5
+ context("when the chef repo #{desc}", *tags) do
6
+ include_context "with a chef repo"
7
+ extend WhenTheRepositoryClassMethods
8
+ module_eval(&block)
9
+ end
10
+ end
11
+
12
+ ::RSpec.shared_context "with a chef repo" do
13
+ before :each do
14
+ raise "Can only create one directory per test" if @repository_dir
15
+ @repository_dir = Dir.mktmpdir('chef_repo')
16
+ Chef::Config.chef_repo_path = @repository_dir
17
+ %w(client cookbook data_bag environment node role user).each do |object_name|
18
+ Chef::Config.delete("#{object_name}_path".to_sym)
19
+ end
20
+ end
21
+
22
+ after :each do
23
+ if @repository_dir
24
+ begin
25
+ %w(client cookbook data_bag environment node role user).each do |object_name|
26
+ Chef::Config.delete("#{object_name}_path".to_sym)
27
+ end
28
+ Chef::Config.delete(:chef_repo_path)
29
+ FileUtils.remove_entry_secure(@repository_dir)
30
+ ensure
31
+ @repository_dir = nil
32
+ end
33
+ end
34
+ Dir.chdir(@old_cwd) if @old_cwd
35
+ end
36
+
37
+ def directory(relative_path, &block)
38
+ old_parent_path = @parent_path
39
+ @parent_path = path_to(relative_path)
40
+ FileUtils.mkdir_p(@parent_path)
41
+ instance_eval(&block) if block
42
+ @parent_path = old_parent_path
43
+ end
44
+
45
+ def file(relative_path, contents)
46
+ filename = path_to(relative_path)
47
+ dir = File.dirname(filename)
48
+ FileUtils.mkdir_p(dir) unless dir == '.'
49
+ File.open(filename, 'w') do |file|
50
+ raw = case contents
51
+ when Hash
52
+ JSON.pretty_generate(contents)
53
+ when Array
54
+ contents.join("\n")
55
+ else
56
+ contents
57
+ end
58
+ file.write(raw)
59
+ end
60
+ end
61
+
62
+ def symlink(relative_path, relative_dest)
63
+ filename = path_to(relative_path)
64
+ dir = File.dirname(filename)
65
+ FileUtils.mkdir_p(dir) unless dir == '.'
66
+ dest_filename = path_to(relative_dest)
67
+ File.symlink(dest_filename, filename)
68
+ end
69
+
70
+ def path_to(relative_path)
71
+ File.expand_path(relative_path, (@parent_path || @repository_dir))
72
+ end
73
+
74
+ def cwd(relative_path)
75
+ @old_cwd = Dir.pwd
76
+ Dir.chdir(path_to(relative_path))
77
+ end
78
+
79
+ module WhenTheRepositoryClassMethods
80
+ def directory(*args, &block)
81
+ before :each do
82
+ directory(*args, &block)
83
+ end
84
+ end
85
+
86
+ def file(*args, &block)
87
+ before :each do
88
+ file(*args, &block)
89
+ end
90
+ end
91
+
92
+ def symlink(*args, &block)
93
+ before :each do
94
+ symlink(*args, &block)
95
+ end
96
+ end
97
+
98
+ def path_to(*args, &block)
99
+ before :each do
100
+ file(*args, &block)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ end
108
+ end
@@ -1,8 +1,8 @@
1
- require 'cheffish/rspec/chef_run_support'
2
- require 'cheffish/rspec/repository_support'
3
- require 'cheffish/rspec/matchers'
4
-
5
- module Cheffish
6
- module RSpec
7
- end
8
- end
1
+ require 'cheffish/rspec/chef_run_support'
2
+ require 'cheffish/rspec/repository_support'
3
+ require 'cheffish/rspec/matchers'
4
+
5
+ module Cheffish
6
+ module RSpec
7
+ end
8
+ end