chef-dk 0.3.5 → 0.4.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.
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