chef-dk 0.3.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +4 -4
  3. data/README.md +4 -4
  4. data/lib/chef-dk/builtin_commands.rb +4 -0
  5. data/lib/chef-dk/chef_runner.rb +7 -1
  6. data/lib/chef-dk/command/exec.rb +9 -0
  7. data/lib/chef-dk/command/export.rb +132 -0
  8. data/lib/chef-dk/command/generator_commands.rb +1 -1
  9. data/lib/chef-dk/command/generator_commands/app.rb +8 -0
  10. data/lib/chef-dk/command/generator_commands/base.rb +46 -4
  11. data/lib/chef-dk/command/generator_commands/cookbook.rb +8 -0
  12. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +1 -0
  13. data/lib/chef-dk/command/push.rb +3 -6
  14. data/lib/chef-dk/command/shell_init.rb +28 -5
  15. data/lib/chef-dk/command/update.rb +106 -0
  16. data/lib/chef-dk/command/verify.rb +72 -0
  17. data/lib/chef-dk/component_test.rb +12 -1
  18. data/lib/chef-dk/configurable.rb +52 -0
  19. data/lib/chef-dk/cookbook_metadata.rb +10 -1
  20. data/lib/chef-dk/cookbook_profiler/git.rb +1 -1
  21. data/lib/chef-dk/exceptions.rb +17 -2
  22. data/lib/chef-dk/helpers.rb +2 -2
  23. data/lib/chef-dk/policyfile/community_cookbook_source.rb +1 -1
  24. data/lib/chef-dk/policyfile/dsl.rb +7 -0
  25. data/lib/chef-dk/policyfile/uploader.rb +25 -4
  26. data/lib/chef-dk/policyfile_compiler.rb +21 -1
  27. data/lib/chef-dk/policyfile_lock.rb +5 -0
  28. data/lib/chef-dk/policyfile_services/export_repo.rb +194 -0
  29. data/lib/chef-dk/policyfile_services/install.rb +8 -2
  30. data/lib/chef-dk/policyfile_services/push.rb +4 -1
  31. data/lib/chef-dk/service_exceptions.rb +6 -0
  32. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +1 -1
  33. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +1 -1
  34. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/README.md +1 -1
  35. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +2 -2
  36. data/lib/chef-dk/skeletons/code_generator/files/default/serverspec_spec_helper.rb +3 -0
  37. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +1 -7
  38. data/lib/chef-dk/skeletons/code_generator/metadata.rb +1 -1
  39. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +31 -1
  40. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +32 -2
  41. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +18 -0
  42. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -0
  43. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +23 -0
  44. data/lib/chef-dk/skeletons/code_generator/templates/default/serverspec_default_spec.rb.erb +12 -0
  45. data/lib/chef-dk/version.rb +1 -1
  46. data/lib/kitchen/provisioner/policyfile_zero.rb +149 -0
  47. data/spec/shared/a_file_generator.rb +1 -0
  48. data/spec/shared/command_with_ui_object.rb +11 -0
  49. data/spec/shared/custom_generator_cookbook.rb +117 -0
  50. data/spec/unit/chef_runner_spec.rb +26 -0
  51. data/spec/unit/command/exec_spec.rb +46 -5
  52. data/spec/unit/command/export_spec.rb +176 -0
  53. data/spec/unit/command/generator_commands/app_spec.rb +38 -0
  54. data/spec/unit/command/generator_commands/cookbook_spec.rb +37 -28
  55. data/spec/unit/command/generator_commands/recipe_spec.rb +4 -2
  56. data/spec/unit/command/install_spec.rb +3 -6
  57. data/spec/unit/command/push_spec.rb +3 -6
  58. data/spec/unit/command/shell_init_spec.rb +77 -49
  59. data/spec/unit/command/update_spec.rb +155 -0
  60. data/spec/unit/command/verify_spec.rb +22 -7
  61. data/spec/unit/cookbook_metadata_spec.rb +44 -8
  62. data/spec/unit/cookbook_profiler/git_spec.rb +12 -0
  63. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +1 -1
  64. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +1 -1
  65. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +1 -1
  66. data/spec/unit/fixtures/cookbooks_api/small_universe.json +667 -667
  67. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
  68. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +1 -1
  69. data/spec/unit/fixtures/example_cookbook/Berksfile +1 -1
  70. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -0
  71. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -0
  72. data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -0
  73. data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -0
  74. data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -0
  75. data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -0
  76. data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -0
  77. data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -0
  78. data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -0
  79. data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -0
  80. data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -0
  81. data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -0
  82. data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -0
  83. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +1 -1
  84. data/spec/unit/policyfile/community_cookbook_source_spec.rb +2 -2
  85. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +3 -3
  86. data/spec/unit/policyfile/uploader_spec.rb +61 -25
  87. data/spec/unit/policyfile_demands_spec.rb +47 -0
  88. data/spec/unit/policyfile_evaluation_spec.rb +1 -1
  89. data/spec/unit/policyfile_lock_build_spec.rb +60 -3
  90. data/spec/unit/policyfile_services/export_repo_spec.rb +321 -0
  91. data/spec/unit/policyfile_services/install_spec.rb +20 -1
  92. data/spec/unit/policyfile_services/push_spec.rb +36 -9
  93. metadata +53 -38
  94. data/lib/chef-dk/skeletons/code_generator/files/default/converge_spec.rb +0 -9
  95. data/lib/chef-dk/skeletons/code_generator/templates/default/default_recipe.rb.erb +0 -5
@@ -0,0 +1,176 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2014 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'spec_helper'
19
+ require 'shared/command_with_ui_object'
20
+ require 'chef-dk/command/export'
21
+
22
+ describe ChefDK::Command::Export do
23
+
24
+ it_behaves_like "a command with a UI object"
25
+
26
+ let(:params) { [] }
27
+
28
+ let(:command) do
29
+ described_class.new
30
+ end
31
+
32
+ let(:policyfile_lock) do
33
+ instance_double(ChefDK::PolicyfileLock, name: "example-policy")
34
+ end
35
+
36
+ let(:export_service) do
37
+ instance_double(ChefDK::PolicyfileServices::ExportRepo,
38
+ policyfile_lock: policyfile_lock)
39
+ end
40
+
41
+ context "after evaluating params" do
42
+
43
+ let(:params) { [ "path/to/export" ] }
44
+
45
+ before do
46
+ command.apply_params!(params)
47
+ end
48
+
49
+ it "disables debug by default" do
50
+ expect(command.debug?).to be(false)
51
+ end
52
+
53
+ context "when debug mode is set" do
54
+
55
+ let(:params) { [ "path/to/export", "-D" ] }
56
+
57
+ it "enables debug" do
58
+ expect(command.debug?).to be(true)
59
+ end
60
+ end
61
+
62
+ context "when the path to the exported repo is given" do
63
+
64
+ let(:params) { [ "path/to/export" ] }
65
+
66
+ it "configures the export service with the export path" do
67
+ expect(command.export_service.export_dir).to eq(File.expand_path("path/to/export"))
68
+ end
69
+
70
+ it "uses the default policyfile name" do
71
+ expect(command.export_service.policyfile_filename).to eq(File.expand_path("Policyfile.rb"))
72
+ end
73
+
74
+ end
75
+
76
+ context "when a Policyfile relative path and export path are given" do
77
+
78
+ let(:params) { [ "CustomNamedPolicy.rb", "path/to/export" ] }
79
+
80
+ it "configures the export service with the export path" do
81
+ expect(command.export_service.export_dir).to eq(File.expand_path("path/to/export"))
82
+ end
83
+
84
+ it "configures the export service with the policyfile relative path" do
85
+ expect(command.export_service.policyfile_filename).to eq(File.expand_path("CustomNamedPolicy.rb"))
86
+ end
87
+ end
88
+ end
89
+
90
+ describe "running the export" do
91
+
92
+ let(:params) { [ "/path/to/export" ] }
93
+
94
+ let(:ui) { TestHelpers::TestUI.new }
95
+
96
+ before do
97
+ command.ui = ui
98
+ allow(command).to receive(:export_service).and_return(export_service)
99
+ end
100
+
101
+ context "with no arguments" do
102
+
103
+ it "exits non-zero and prints a help message" do
104
+ expect(command.run).to eq(1)
105
+ end
106
+
107
+ end
108
+
109
+ context "when the command is successful" do
110
+
111
+ before do
112
+ expect(export_service).to receive(:run)
113
+ end
114
+
115
+ it "returns 0" do
116
+ expect(command.run(params)).to eq(0)
117
+ end
118
+ end
119
+
120
+ context "when the command is unsuccessful" do
121
+
122
+ let(:backtrace) { caller[0...3] }
123
+
124
+ let(:cause) do
125
+ e = StandardError.new("some operation failed")
126
+ e.set_backtrace(backtrace)
127
+ e
128
+ end
129
+
130
+ let(:exception) do
131
+ ChefDK::PolicyfileExportRepoError.new("export failed", cause)
132
+ end
133
+
134
+ before do
135
+ expect(export_service).to receive(:run).and_raise(exception)
136
+ end
137
+
138
+ it "returns 1" do
139
+ expect(command.run(params)).to eq(1)
140
+ end
141
+
142
+ it "displays the exception and cause" do
143
+ expected_error_text=<<-E
144
+ Error: export failed
145
+ Reason: (StandardError) some operation failed
146
+
147
+ E
148
+
149
+ command.run(params)
150
+ expect(ui.output).to eq(expected_error_text)
151
+ end
152
+
153
+ context "and debug is enabled" do
154
+
155
+ let(:params) { [ "path/to/export", "-D"] }
156
+
157
+ it "displays the exception and cause with backtrace" do
158
+ expected_error_text=<<-E
159
+ Error: export failed
160
+ Reason: (StandardError) some operation failed
161
+
162
+
163
+ E
164
+
165
+ expected_error_text << backtrace.join("\n") << "\n"
166
+
167
+ command.run(params)
168
+ expect(ui.output).to eq(expected_error_text)
169
+ end
170
+ end
171
+
172
+ end
173
+
174
+ end
175
+ end
176
+
@@ -16,6 +16,7 @@
16
16
  #
17
17
 
18
18
  require 'spec_helper'
19
+ require 'shared/custom_generator_cookbook'
19
20
  require 'chef-dk/command/generator_commands/app'
20
21
 
21
22
  describe ChefDK::Command::GeneratorCommands::App do
@@ -29,12 +30,23 @@ describe ChefDK::Command::GeneratorCommands::App do
29
30
  %w[
30
31
  .gitignore
31
32
  .kitchen.yml
33
+ test
34
+ test/integration
35
+ test/integration/default
36
+ test/integration/default/serverspec
37
+ test/integration/default/serverspec/default_spec.rb
38
+ test/integration/default/serverspec/spec_helper.rb
32
39
  README.md
33
40
  cookbooks/new_app/Berksfile
34
41
  cookbooks/new_app/chefignore
35
42
  cookbooks/new_app/metadata.rb
36
43
  cookbooks/new_app/recipes
37
44
  cookbooks/new_app/recipes/default.rb
45
+ cookbooks/new_app/spec
46
+ cookbooks/new_app/spec/spec_helper.rb
47
+ cookbooks/new_app/spec/unit
48
+ cookbooks/new_app/spec/unit/recipes
49
+ cookbooks/new_app/spec/unit/recipes/default_spec.rb
38
50
  ]
39
51
  end
40
52
 
@@ -54,6 +66,14 @@ describe ChefDK::Command::GeneratorCommands::App do
54
66
  ChefDK::Generator.reset
55
67
  end
56
68
 
69
+ include_examples "custom generator cookbook" do
70
+
71
+ let(:generator_arg) { "new_app" }
72
+
73
+ let(:generator_name) { "app" }
74
+
75
+ end
76
+
57
77
  context "when given the name of the cookbook to generate" do
58
78
 
59
79
  before do
@@ -67,6 +87,7 @@ describe ChefDK::Command::GeneratorCommands::App do
67
87
  expect(generator_context.app_name).to eq("new_app")
68
88
  expect(generator_context.cookbook_root).to eq(File.join(Dir.pwd, "new_app", "cookbooks"))
69
89
  expect(generator_context.cookbook_name).to eq("new_app")
90
+ expect(generator_context.recipe_name).to eq("default")
70
91
  end
71
92
 
72
93
  describe "generated files" do
@@ -110,6 +131,14 @@ describe ChefDK::Command::GeneratorCommands::App do
110
131
  end
111
132
  end
112
133
 
134
+ describe "test/integration/default/serverspec/default_spec.rb" do
135
+ let(:file) { File.join(tempdir, "new_app", "test", "integration", "default", "serverspec", "default_spec.rb") }
136
+
137
+ include_examples "a generated file", :cookbook_name do
138
+ let(:line) { "describe 'new_app::default' do" }
139
+ end
140
+ end
141
+
113
142
  describe "cookbooks/new_app/metadata.rb" do
114
143
  let(:file) { File.join(tempdir, "new_app", "cookbooks", "new_app", "metadata.rb") }
115
144
 
@@ -125,6 +154,15 @@ describe ChefDK::Command::GeneratorCommands::App do
125
154
  let(:line) { "# Cookbook Name:: new_app" }
126
155
  end
127
156
  end
157
+
158
+ describe "cookbooks/new_app/spec/unit/recipes/default_spec.rb" do
159
+ let(:file) { File.join(tempdir, "new_app", "cookbooks", "new_app", "spec", "unit", "recipes", "default_spec.rb") }
160
+
161
+ include_examples "a generated file", :cookbook_name do
162
+ let(:line) { "describe \'new_app::default\' do" }
163
+ end
164
+ end
165
+
128
166
  end
129
167
  end
130
168
  end
@@ -16,6 +16,7 @@
16
16
  #
17
17
 
18
18
  require 'spec_helper'
19
+ require 'shared/custom_generator_cookbook'
19
20
  require 'chef-dk/command/generator_commands/cookbook'
20
21
 
21
22
  describe ChefDK::Command::GeneratorCommands::Cookbook do
@@ -29,12 +30,23 @@ describe ChefDK::Command::GeneratorCommands::Cookbook do
29
30
  %w[
30
31
  .gitignore
31
32
  .kitchen.yml
33
+ test
34
+ test/integration
35
+ test/integration/default
36
+ test/integration/default/serverspec
37
+ test/integration/default/serverspec/default_spec.rb
38
+ test/integration/default/serverspec/spec_helper.rb
32
39
  Berksfile
33
40
  chefignore
34
41
  metadata.rb
35
42
  README.md
36
43
  recipes
37
44
  recipes/default.rb
45
+ spec
46
+ spec/spec_helper.rb
47
+ spec/unit
48
+ spec/unit/recipes
49
+ spec/unit/recipes/default_spec.rb
38
50
  ]
39
51
  end
40
52
 
@@ -58,6 +70,14 @@ describe ChefDK::Command::GeneratorCommands::Cookbook do
58
70
  ChefDK::Generator.reset
59
71
  end
60
72
 
73
+ include_examples "custom generator cookbook" do
74
+
75
+ let(:generator_arg) { "new_cookbook" }
76
+
77
+ let(:generator_name) { "cookbook" }
78
+
79
+ end
80
+
61
81
  it "configures the chef runner" do
62
82
  expect(cookbook_generator.chef_runner).to be_a(ChefDK::ChefRunner)
63
83
  expect(cookbook_generator.chef_runner.cookbook_path).to eq(File.expand_path('lib/chef-dk/skeletons', project_root))
@@ -97,6 +117,7 @@ describe ChefDK::Command::GeneratorCommands::Cookbook do
97
117
  cookbook_generator.setup_context
98
118
  expect(generator_context.cookbook_root).to eq(Dir.pwd)
99
119
  expect(generator_context.cookbook_name).to eq("new_cookbook")
120
+ expect(generator_context.recipe_name).to eq("default")
100
121
  end
101
122
 
102
123
  it "creates a new cookbook" do
@@ -139,6 +160,14 @@ describe ChefDK::Command::GeneratorCommands::Cookbook do
139
160
  end
140
161
  end
141
162
 
163
+ describe "test/integration/default/serverspec/default_spec.rb" do
164
+ let(:file) { File.join(tempdir, "new_cookbook", "test", "integration", "default", "serverspec", "default_spec.rb") }
165
+
166
+ include_examples "a generated file", :cookbook_name do
167
+ let(:line) { "describe 'new_cookbook::default' do" }
168
+ end
169
+ end
170
+
142
171
  describe "metadata.rb" do
143
172
  let(:file) { File.join(tempdir, "new_cookbook", "metadata.rb") }
144
173
 
@@ -155,6 +184,14 @@ describe ChefDK::Command::GeneratorCommands::Cookbook do
155
184
  end
156
185
  end
157
186
 
187
+ describe "spec/unit/recipes/default_spec.rb" do
188
+ let(:file) { File.join(tempdir, "new_cookbook", "spec", "unit", "recipes", "default_spec.rb") }
189
+
190
+ include_examples "a generated file", :cookbook_name do
191
+ let(:line) { "describe \'new_cookbook::default\' do" }
192
+ end
193
+ end
194
+
158
195
  end
159
196
 
160
197
  context "when given the path to the cookbook to generate" do
@@ -173,34 +210,6 @@ describe ChefDK::Command::GeneratorCommands::Cookbook do
173
210
 
174
211
  end
175
212
 
176
- context "when given a generator-cookbook path" do
177
- let(:generator_cookbook_path) { File.join(tempdir, 'a_generator_cookbook') }
178
- let(:argv) { ["new_cookbook", "--generator-cookbook", generator_cookbook_path] }
179
-
180
- before do
181
- reset_tempdir
182
- end
183
-
184
- it "configures the generator context" do
185
- cookbook_generator.read_and_validate_params
186
- cookbook_generator.setup_context
187
- expect(generator_context.cookbook_root).to eq(Dir.pwd)
188
- expect(generator_context.cookbook_name).to eq("new_cookbook")
189
- expect(cookbook_generator.chef_runner.cookbook_path).to eq(generator_cookbook_path)
190
- end
191
-
192
- it "creates a new cookbook" do
193
- Dir.chdir(tempdir) do
194
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
195
- cookbook_generator.run
196
- end
197
- generated_files = Dir.glob("#{tempdir}/new_cookbook/**/*", File::FNM_DOTMATCH)
198
- expected_cookbook_files.each do |expected_file|
199
- expect(generated_files).to include(expected_file)
200
- end
201
- end
202
- end
203
-
204
213
  context "when given generic arguments to populate the generator context" do
205
214
  let(:argv) { [ "new_cookbook", "--generator-arg", "key1=value1", "-a", "key2=value2", "-a", " key3 = value3 " ] }
206
215
 
@@ -24,9 +24,11 @@ describe ChefDK::Command::GeneratorCommands::Recipe do
24
24
  include_examples "a file generator" do
25
25
 
26
26
  let(:generator_name) { "recipe" }
27
- let(:generated_files) { [ "recipes/new_recipe.rb" ] }
27
+ let(:generated_files) { [ "recipes/new_recipe.rb",
28
+ "spec/spec_helper.rb",
29
+ "spec/unit/recipes/new_recipe_spec.rb" ] }
28
30
  let(:new_file_name) { "new_recipe" }
29
31
 
30
32
  end
31
- end
32
33
 
34
+ end
@@ -16,10 +16,13 @@
16
16
  #
17
17
 
18
18
  require 'spec_helper'
19
+ require 'shared/command_with_ui_object'
19
20
  require 'chef-dk/command/install'
20
21
 
21
22
  describe ChefDK::Command::Install do
22
23
 
24
+ it_behaves_like "a command with a UI object"
25
+
23
26
  let(:params) { [] }
24
27
 
25
28
  let(:command) do
@@ -34,12 +37,6 @@ describe ChefDK::Command::Install do
34
37
  expect(command.debug?).to be(false)
35
38
  end
36
39
 
37
- it "configures a default UI component" do
38
- ui = command.ui
39
- expect(ui.out_stream).to eq($stdout)
40
- expect(ui.err_stream).to eq($stderr)
41
- end
42
-
43
40
  context "when debug mode is set" do
44
41
 
45
42
  let(:params) { [ "-D" ] }
@@ -16,10 +16,13 @@
16
16
  #
17
17
 
18
18
  require 'spec_helper'
19
+ require 'shared/command_with_ui_object'
19
20
  require 'chef-dk/command/push'
20
21
 
21
22
  describe ChefDK::Command::Push do
22
23
 
24
+ it_behaves_like "a command with a UI object"
25
+
23
26
  let(:policy_group) { "dev" }
24
27
 
25
28
  let(:params) { [policy_group] }
@@ -51,12 +54,6 @@ describe ChefDK::Command::Push do
51
54
  expect(command.debug?).to be(false)
52
55
  end
53
56
 
54
- it "configures a default UI component" do
55
- ui = command.ui
56
- expect(ui.out_stream).to eq($stdout)
57
- expect(ui.err_stream).to eq($stderr)
58
- end
59
-
60
57
  describe "when configuring components that depend on chef config" do
61
58
 
62
59
  before do
@@ -30,84 +30,112 @@ describe ChefDK::Command::ShellInit do
30
30
  end
31
31
  end
32
32
 
33
- before do
34
- stub_const("File::PATH_SEPARATOR", ':')
35
- end
33
+ shared_context "shell init script" do |shell|
34
+ let(:user_bin_dir) { File.expand_path(File.join(Gem.user_dir, 'bin')) }
35
+ let(:expected_path) { [omnibus_bin_dir, user_bin_dir, omnibus_embedded_bin_dir, ENV['PATH']].join(File::PATH_SEPARATOR) }
36
+ let(:expected_gem_root) { Gem.default_dir.to_s }
37
+ let(:expected_gem_home) { Gem.user_dir }
38
+ let(:expected_gem_path) { Gem.path.join(File::PATH_SEPARATOR) }
39
+
40
+ context "with no explicit omnibus directory" do
41
+
42
+ let(:omnibus_bin_dir) { "/foo/bin" }
43
+ let(:omnibus_embedded_bin_dir) { "/foo/embedded/bin" }
44
+ let(:argv) { [shell] }
45
+
46
+ before do
47
+ allow(command_instance).to receive(:omnibus_embedded_bin_dir).and_return(omnibus_embedded_bin_dir)
48
+ allow(command_instance).to receive(:omnibus_bin_dir).and_return(omnibus_bin_dir)
49
+ end
36
50
 
37
- let(:argv) { ['bash'] }
51
+ it "emits a script to add ChefDK's ruby to the shell environment" do
52
+ command_instance.run(argv)
53
+ expect(stdout_io.string).to eq(expected_environment_commands)
54
+ end
55
+ end
38
56
 
39
- let(:user_bin_dir) { File.expand_path(File.join(Gem.user_dir, 'bin')) }
57
+ context "with an explicit omnibus directory as an argument" do
40
58
 
41
- let(:expected_path) { [omnibus_bin_dir, user_bin_dir, omnibus_embedded_bin_dir, ENV['PATH']].join(File::PATH_SEPARATOR) }
59
+ let(:omnibus_root) { File.join(fixtures_path, "eg_omnibus_dir/valid/") }
60
+ let(:omnibus_bin_dir) { File.join(omnibus_root, "bin") }
61
+ let(:omnibus_embedded_bin_dir) { File.join(omnibus_root, "embedded/bin") }
42
62
 
43
- let(:expected_gem_root) { Gem.default_dir.to_s }
63
+ let(:argv) { [shell, "--omnibus-dir", omnibus_root] }
44
64
 
45
- let(:expected_gem_home) { Gem.user_dir }
65
+ it "emits a script to add ChefDK's ruby to the shell environment" do
66
+ command_instance.run(argv)
67
+ expect(stdout_io.string).to eq(expected_environment_commands)
68
+ end
69
+ end
70
+ end
46
71
 
47
- let(:expected_gem_path) { Gem.path.join(':') }
72
+ shared_examples "a posix shell script" do |shell|
73
+ before do
74
+ stub_const("File::PATH_SEPARATOR", ':')
75
+ end
48
76
 
49
- let(:expected_environment_commands) do
50
- <<-EOH
51
- export PATH=#{expected_path}
77
+ let(:expected_environment_commands) do
78
+ <<-EOH
79
+ export PATH="#{expected_path}"
52
80
  export GEM_ROOT="#{expected_gem_root}"
53
- export GEM_HOME=#{expected_gem_home}
54
- export GEM_PATH=#{expected_gem_path}
81
+ export GEM_HOME="#{expected_gem_home}"
82
+ export GEM_PATH="#{expected_gem_path}"
55
83
  EOH
84
+ end
85
+ include_context "shell init script", shell
56
86
  end
57
87
 
58
- context "with no explicit omnibus directory" do
59
-
60
- let(:omnibus_bin_dir) { "/foo/bin" }
61
- let(:omnibus_embedded_bin_dir) { "/foo/embedded/bin" }
62
-
88
+ shared_examples "a powershell script" do |shell|
63
89
  before do
64
- allow(command_instance).to receive(:omnibus_embedded_bin_dir).and_return(omnibus_embedded_bin_dir)
65
- allow(command_instance).to receive(:omnibus_bin_dir).and_return(omnibus_bin_dir)
90
+ stub_const("File::PATH_SEPARATOR", ';')
66
91
  end
67
92
 
68
- it "emits a script to add ChefDK's ruby to the shell environment" do
69
- command_instance.run(argv)
70
- expect(stdout_io.string).to eq(expected_environment_commands)
93
+ let(:expected_environment_commands) do
94
+ <<-EOH
95
+ $env:PATH="#{expected_path}"
96
+ $env:GEM_ROOT="#{expected_gem_root}"
97
+ $env:GEM_HOME="#{expected_gem_home}"
98
+ $env:GEM_PATH="#{expected_gem_path}"
99
+ EOH
71
100
  end
101
+ include_context "shell init script", shell
102
+ end
72
103
 
73
- context "when no shell is specified" do
74
-
75
- let(:argv) { [] }
76
-
77
- it "exits with an error message" do
78
- expect(command_instance.run(argv)).to eq(1)
79
- expect(stderr_io.string).to include("Please specify what shell you are using")
80
- end
81
-
104
+ ['bash', 'sh', 'zsh'].each do |shell|
105
+ context "for #{shell}" do
106
+ it_behaves_like "a posix shell script", shell
82
107
  end
108
+ end
83
109
 
84
- context "when an unsupported shell is specified" do
110
+ ['powershell', 'posh'].each do |shell|
111
+ context "for #{shell}" do
112
+ it_behaves_like "a powershell script", shell
113
+ end
114
+ end
85
115
 
86
- let(:argv) { ['nosuchsh'] }
116
+ context "when no shell is specified" do
87
117
 
88
- it "exits with an error message" do
89
- expect(command_instance.run(argv)).to eq(1)
90
- expect(stderr_io.string).to include("Shell `nosuchsh' is not currently supported")
91
- expect(stderr_io.string).to include("Supported shells are: bash zsh sh")
92
- end
118
+ let(:argv) { [] }
93
119
 
120
+ it "exits with an error message" do
121
+ expect(command_instance.run(argv)).to eq(1)
122
+ expect(stderr_io.string).to include("Please specify what shell you are using")
94
123
  end
95
124
 
96
125
  end
97
126
 
98
- context "with an explicit omnibus directory as an argument" do
127
+ context "when an unsupported shell is specified" do
99
128
 
100
- let(:omnibus_root) { File.join(fixtures_path, "eg_omnibus_dir/valid/") }
101
- let(:omnibus_bin_dir) { File.join(omnibus_root, "bin") }
102
- let(:omnibus_embedded_bin_dir) { File.join(omnibus_root, "embedded/bin") }
129
+ let(:argv) { ['nosuchsh'] }
103
130
 
104
- let(:argv) { ["bash", "--omnibus-dir", omnibus_root] }
105
-
106
- it "emits a script to add ChefDK's ruby to the shell environment" do
107
- command_instance.run(argv)
108
- expect(stdout_io.string).to eq(expected_environment_commands)
131
+ it "exits with an error message" do
132
+ expect(command_instance.run(argv)).to eq(1)
133
+ expect(stderr_io.string).to include("Shell `nosuchsh' is not currently supported")
134
+ expect(stderr_io.string).to include("Supported shells are: bash zsh sh powershell posh")
109
135
  end
136
+
110
137
  end
111
138
 
139
+
112
140
  end
113
141