chef-dk 0.2.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 (142) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +192 -0
  3. data/LICENSE +201 -0
  4. data/README.md +198 -0
  5. data/Rakefile +18 -0
  6. data/bin/chef +25 -0
  7. data/lib/chef-dk.rb +19 -0
  8. data/lib/chef-dk/builtin_commands.rb +31 -0
  9. data/lib/chef-dk/chef_runner.rb +83 -0
  10. data/lib/chef-dk/cli.rb +135 -0
  11. data/lib/chef-dk/command/base.rb +71 -0
  12. data/lib/chef-dk/command/exec.rb +33 -0
  13. data/lib/chef-dk/command/gem.rb +47 -0
  14. data/lib/chef-dk/command/generate.rb +97 -0
  15. data/lib/chef-dk/command/generator_commands.rb +417 -0
  16. data/lib/chef-dk/command/shell_init.rb +80 -0
  17. data/lib/chef-dk/command/verify.rb +226 -0
  18. data/lib/chef-dk/commands_map.rb +115 -0
  19. data/lib/chef-dk/component_test.rb +142 -0
  20. data/lib/chef-dk/cookbook_metadata.rb +36 -0
  21. data/lib/chef-dk/cookbook_omnifetch.rb +29 -0
  22. data/lib/chef-dk/cookbook_profiler/git.rb +95 -0
  23. data/lib/chef-dk/cookbook_profiler/identifiers.rb +79 -0
  24. data/lib/chef-dk/cookbook_profiler/null_scm.rb +32 -0
  25. data/lib/chef-dk/exceptions.rb +46 -0
  26. data/lib/chef-dk/generator.rb +70 -0
  27. data/lib/chef-dk/helpers.rb +95 -0
  28. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +46 -0
  29. data/lib/chef-dk/policyfile/community_cookbook_source.rb +84 -0
  30. data/lib/chef-dk/policyfile/cookbook_sources.rb +20 -0
  31. data/lib/chef-dk/policyfile/cookbook_spec.rb +96 -0
  32. data/lib/chef-dk/policyfile/dsl.rb +148 -0
  33. data/lib/chef-dk/policyfile/null_cookbook_source.rb +37 -0
  34. data/lib/chef-dk/policyfile_compiler.rb +217 -0
  35. data/lib/chef-dk/policyfile_lock.rb +243 -0
  36. data/lib/chef-dk/shell_out.rb +36 -0
  37. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +3 -0
  38. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +96 -0
  39. data/lib/chef-dk/skeletons/code_generator/files/default/converge_spec.rb +9 -0
  40. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +16 -0
  41. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +8 -0
  42. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -0
  43. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +65 -0
  44. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +12 -0
  45. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +50 -0
  46. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +24 -0
  47. data/lib/chef-dk/skeletons/code_generator/recipes/lwrp.rb +23 -0
  48. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +9 -0
  49. data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -0
  50. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -0
  51. data/lib/chef-dk/skeletons/code_generator/templates/default/attribute.rb.erb +0 -0
  52. data/lib/chef-dk/skeletons/code_generator/templates/default/cookbook_file.erb +0 -0
  53. data/lib/chef-dk/skeletons/code_generator/templates/default/default_recipe.rb.erb +8 -0
  54. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +16 -0
  55. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +8 -0
  56. data/lib/chef-dk/skeletons/code_generator/templates/default/provider.rb.erb +0 -0
  57. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +0 -0
  58. data/lib/chef-dk/skeletons/code_generator/templates/default/resource.rb.erb +0 -0
  59. data/lib/chef-dk/skeletons/code_generator/templates/default/template.erb +0 -0
  60. data/lib/chef-dk/version.rb +20 -0
  61. data/spec/shared/setup_git_cookbooks.rb +53 -0
  62. data/spec/spec_helper.rb +32 -0
  63. data/spec/test_helpers.rb +59 -0
  64. data/spec/unit/chef_runner_spec.rb +70 -0
  65. data/spec/unit/cli_spec.rb +151 -0
  66. data/spec/unit/command/base_spec.rb +88 -0
  67. data/spec/unit/command/exec_spec.rb +123 -0
  68. data/spec/unit/command/generate_spec.rb +102 -0
  69. data/spec/unit/command/generator_commands_spec.rb +504 -0
  70. data/spec/unit/command/shell_init_spec.rb +109 -0
  71. data/spec/unit/command/verify_spec.rb +311 -0
  72. data/spec/unit/commands_map_spec.rb +57 -0
  73. data/spec/unit/component_test_spec.rb +126 -0
  74. data/spec/unit/cookbook_metadata_spec.rb +62 -0
  75. data/spec/unit/cookbook_profiler/git_spec.rb +127 -0
  76. data/spec/unit/cookbook_profiler/identifiers_spec.rb +79 -0
  77. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -0
  78. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -0
  79. data/spec/unit/fixtures/command/cli_test_command.rb +26 -0
  80. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -0
  81. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -0
  82. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -0
  83. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -0
  84. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -0
  85. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -0
  86. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -0
  87. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -0
  88. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -0
  89. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -0
  90. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -0
  91. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -0
  92. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -0
  93. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -0
  94. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -0
  95. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -0
  96. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -0
  97. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -0
  98. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -0
  99. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1322 -0
  100. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -0
  101. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -0
  102. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +36 -0
  103. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -0
  104. data/spec/unit/fixtures/dev_cookbooks/bar-cookbook.gitbundle +0 -0
  105. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/bin/.keep +0 -0
  106. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/.keep +0 -0
  107. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/bin/.keep +0 -0
  108. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/bin/.keep +0 -0
  109. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/berkshelf/.keep +0 -0
  110. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/test-kitchen/.keep +0 -0
  111. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/bin/.keep +0 -0
  112. data/spec/unit/fixtures/eg_omnibus_dir/valid/bin/.keep +0 -0
  113. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -0
  114. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -0
  115. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef-dk/.keep +0 -0
  116. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -0
  117. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -0
  118. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/bin/.keep +0 -0
  119. data/spec/unit/fixtures/example_app/Policyfile.rb +0 -0
  120. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -0
  121. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -0
  122. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -0
  123. data/spec/unit/fixtures/example_cookbook/README.md +4 -0
  124. data/spec/unit/fixtures/example_cookbook/chefignore +96 -0
  125. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -0
  126. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -0
  127. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -0
  128. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -0
  129. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -0
  130. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -0
  131. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -0
  132. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -0
  133. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -0
  134. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +34 -0
  135. data/spec/unit/policyfile/community_cookbook_source_spec.rb +51 -0
  136. data/spec/unit/policyfile/cookbook_spec_spec.rb +200 -0
  137. data/spec/unit/policyfile/null_cookbook_source_spec.rb +35 -0
  138. data/spec/unit/policyfile_builder_spec.rb +489 -0
  139. data/spec/unit/policyfile_demands_spec.rb +484 -0
  140. data/spec/unit/policyfile_evaluation_spec.rb +284 -0
  141. data/spec/unit/shell_out_spec.rb +34 -0
  142. metadata +422 -0
@@ -0,0 +1,151 @@
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 'stringio'
20
+ require 'chef-dk/cli'
21
+ require 'unit/fixtures/command/cli_test_command'
22
+
23
+ describe ChefDK::CLI do
24
+
25
+ let(:argv) { [] }
26
+
27
+ # Setup a new commands map so we control what subcommands exist. Otherwise
28
+ # we'd have to update this test for every new subcommand we add or code the
29
+ # tests defensively.
30
+ let(:commands_map) { ChefDK::CommandsMap.new }
31
+
32
+ let(:stdout_io) { StringIO.new }
33
+ let(:stderr_io) { StringIO.new }
34
+
35
+ def stdout
36
+ stdout_io.string
37
+ end
38
+
39
+ def stderr
40
+ stderr_io.string
41
+ end
42
+
43
+ let(:base_help_message) do
44
+ <<-E
45
+ Usage:
46
+ chef -h/--help
47
+ chef -v/--version
48
+ chef command [arguments...] [options...]
49
+
50
+
51
+ Available Commands:
52
+ verify Test the embedded ChefDK applications
53
+ gem Runs the `gem` command in context of the embedded ruby
54
+ example Example subcommand for testing
55
+ E
56
+ end
57
+
58
+ let(:version_message) { "Chef Development Kit Version: #{ChefDK::VERSION}\n" }
59
+
60
+ def run_cli(expected_exit_code)
61
+ cli.should_receive(:exit).with(expected_exit_code)
62
+ cli.run
63
+ end
64
+
65
+ subject(:cli) do
66
+ ChefDK::CLI.new(argv).tap do |c|
67
+ c.stub(:commands_map).and_return(commands_map)
68
+ c.stub(:stdout).and_return(stdout_io)
69
+ c.stub(:stderr).and_return(stderr_io)
70
+ end
71
+ end
72
+
73
+ before do
74
+ commands_map.builtin "verify", :Verify, desc: "Test the embedded ChefDK applications"
75
+
76
+ commands_map.builtin "gem", :GemForwarder, require_path: "chef-dk/command/gem",
77
+ desc: "Runs the `gem` command in context of the embedded ruby"
78
+
79
+ commands_map.builtin "example", :TestCommand, require_path: "unit/fixtures/command/cli_test_command",
80
+ desc: "Example subcommand for testing"
81
+ end
82
+
83
+ context "given no arguments or options" do
84
+
85
+ it "prints the help output" do
86
+ run_cli(0)
87
+ expect(stdout).to eq(base_help_message)
88
+ end
89
+
90
+ end
91
+
92
+ context "given -h" do
93
+ let(:argv) { %w[-h] }
94
+
95
+ it "prints the help output" do
96
+ run_cli(0)
97
+ expect(stdout).to eq(base_help_message)
98
+ end
99
+ end
100
+
101
+ context "given -v" do
102
+ let(:argv) { %w[-v] }
103
+
104
+ it "prints the version" do
105
+ run_cli(0)
106
+ expect(stdout).to eq(version_message)
107
+ end
108
+ end
109
+
110
+ context "given an invalid/unknown subcommand" do
111
+ let(:argv) { %w[ancient-aliens] }
112
+
113
+ it "prints an 'unknown command' message and the help output" do
114
+ expected_err = "Unknown command `ancient-aliens'.\n"
115
+
116
+ run_cli(1)
117
+
118
+ expect(stderr).to eq(expected_err)
119
+ expect(stdout).to eq(base_help_message)
120
+ end
121
+
122
+ end
123
+
124
+ context "given a valid subcommand" do
125
+ let(:argv) { %w[example with some args --and-an-option] }
126
+
127
+ def test_result
128
+ ChefDK::Command::TestCommand.test_result
129
+ end
130
+
131
+ before do
132
+ ChefDK::Command::TestCommand.reset!
133
+ end
134
+
135
+ it "runs the subcommand" do
136
+ run_cli(23)
137
+ expect(test_result[:status]).to eq(:success)
138
+ end
139
+
140
+ it "exits with the return code given by the subcommand" do
141
+ run_cli(23)
142
+ end
143
+
144
+ it "passes arguments and options to the subcommand" do
145
+ params = %w[with some args --and-an-option]
146
+ run_cli(23)
147
+ expect(test_result[:params]).to eq(params)
148
+ end
149
+ end
150
+
151
+ end
@@ -0,0 +1,88 @@
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 'chef-dk/command/verify'
20
+
21
+ describe ChefDK::Command::Base do
22
+ class TestCommand < ChefDK::Command::Base
23
+ banner "use me please"
24
+
25
+ option :user,
26
+ :short => "-u",
27
+ :long => "--user",
28
+ :description => "If the user exists",
29
+ :boolean => true
30
+
31
+ def run(params)
32
+ parse_options(params)
33
+ msg("thanks for passing me #{config[:user]}")
34
+ end
35
+ end
36
+
37
+ let(:stdout_io) { StringIO.new }
38
+ let(:command_instance) { TestCommand.new() }
39
+
40
+ def stdout
41
+ stdout_io.string
42
+ end
43
+
44
+ before do
45
+ command_instance.stub(:stdout).and_return(stdout_io)
46
+ end
47
+
48
+
49
+ def run_command(options)
50
+ command_instance.run_with_default_options(options)
51
+ end
52
+
53
+ it "should print the banner for -h" do
54
+ run_command(["-h"])
55
+ expect(stdout).to include("use me please\n")
56
+ end
57
+
58
+ it "should print the banner for --help" do
59
+ run_command(["--help"])
60
+ expect(stdout).to include("use me please\n")
61
+ end
62
+
63
+ it "prints the options along with the banner when displaying the help message" do
64
+ run_command(["--help"])
65
+ expect(stdout).to include("-u, --user If the user exists")
66
+ end
67
+
68
+ it "should print the version for -v" do
69
+ run_command(["-v"])
70
+ expect(stdout).to eq("Chef Development Kit Version: #{ChefDK::VERSION}\n")
71
+ end
72
+
73
+ it "should print the version for --version" do
74
+ run_command(["--version"])
75
+ expect(stdout).to eq("Chef Development Kit Version: #{ChefDK::VERSION}\n")
76
+ end
77
+
78
+ it "should run the command passing in the custom options for long custom options" do
79
+ run_command(["--user"])
80
+ expect(stdout).to eq("thanks for passing me true\n")
81
+ end
82
+
83
+ it "should run the command passing in the custom options for short custom options" do
84
+ run_command(["-u"])
85
+ expect(stdout).to eq("thanks for passing me true\n")
86
+ end
87
+
88
+ end
@@ -0,0 +1,123 @@
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 'chef-dk/command/exec'
20
+
21
+ describe ChefDK::Command::Exec do
22
+ let(:command_instance) { ChefDK::Command::Exec.new() }
23
+
24
+ let(:command_options) { [] }
25
+
26
+ def run_command
27
+ command_instance.run(command_options)
28
+ end
29
+
30
+ it "has a usage banner" do
31
+ expect(command_instance.banner).to eq("Usage: chef exec SYSTEM_COMMAND")
32
+ end
33
+
34
+ describe "when locating omnibus directory" do
35
+ it "should find omnibus bin directory from ruby path" do
36
+ Gem.stub(:ruby).and_return(File.join(fixtures_path, "eg_omnibus_dir/valid/embedded/bin/ruby"))
37
+ expect(command_instance.omnibus_bin_dir).to include("eg_omnibus_dir/valid/bin")
38
+ end
39
+
40
+ it "should find omnibus embedded bin directory from ruby path" do
41
+ Gem.stub(:ruby).and_return(File.join(fixtures_path, "eg_omnibus_dir/valid/embedded/bin/ruby"))
42
+ expect(command_instance.omnibus_embedded_bin_dir).to include("eg_omnibus_dir/valid/embedded/bin")
43
+ end
44
+
45
+ it "should raise OmnibusInstallNotFound if directory is not looking like omnibus" do
46
+ Gem.stub(:ruby).and_return(File.join(fixtures_path,".rbenv/versions/2.1.1/bin/ruby"))
47
+ expect{command_instance.omnibus_bin_dir}.to raise_error(ChefDK::OmnibusInstallNotFound)
48
+ end
49
+
50
+ it "should raise OmnibusInstallNotFound if directory is not looking like omnibus" do
51
+ Gem.stub(:ruby).and_return(File.join(fixtures_path,".rbenv/versions/2.1.1/bin/ruby"))
52
+ expect{command_instance.omnibus_embedded_bin_dir}.to raise_error(ChefDK::OmnibusInstallNotFound)
53
+ end
54
+ end
55
+
56
+ describe "when running exec command" do
57
+ let(:ruby_path) { File.join(fixtures_path, "eg_omnibus_dir/valid/embedded/bin/ruby") }
58
+
59
+ before do
60
+ Gem.stub(:ruby).and_return(ruby_path)
61
+ end
62
+
63
+ context "when running exec env" do
64
+ let(:command_options) { %w{gem list} }
65
+
66
+ let(:user_bin_dir) { File.expand_path(File.join(Gem.user_dir, 'bin')) }
67
+
68
+ let(:omnibus_embedded_bin_dir) { "/foo/embedded/bin" }
69
+
70
+ let(:omnibus_bin_dir) { "/foo/bin" }
71
+
72
+ let(:expected_env) do
73
+ {
74
+ 'PATH' => "#{omnibus_bin_dir}:#{user_bin_dir}:#{omnibus_embedded_bin_dir}:#{ENV['PATH']}",
75
+ 'GEM_ROOT' => Gem.default_dir.inspect,
76
+ 'GEM_HOME' => ENV['GEM_HOME'],
77
+ 'GEM_PATH' => Gem.path.join(':'),
78
+ }
79
+ end
80
+
81
+ before do
82
+ command_instance.stub(:omnibus_embedded_bin_dir).and_return(omnibus_embedded_bin_dir)
83
+ command_instance.stub(:omnibus_bin_dir).and_return(omnibus_bin_dir)
84
+ end
85
+
86
+ it "should call exec to fire off the command with the correct environment" do
87
+ expect(command_instance).to receive(:exec).with(expected_env, *command_options)
88
+ expect{ run_command }.to raise_error # XXX: this isn't a test we just need to swallow the exception
89
+ end
90
+ end
91
+
92
+ context "when running command that does not exist" do
93
+ let(:command_options) { %w{chef_rules_everything_aroundme} }
94
+
95
+ let(:user_bin_dir) { File.expand_path(File.join(Gem.user_dir, 'bin')) }
96
+
97
+ let(:omnibus_bin_dir) { "/foo/bin" }
98
+
99
+ let(:omnibus_embedded_bin_dir) { "/foo/embedded/bin" }
100
+
101
+ let(:expected_env) do
102
+ {
103
+ 'PATH' => "#{omnibus_bin_dir}:#{user_bin_dir}:#{omnibus_embedded_bin_dir}:#{ENV['PATH']}",
104
+ 'GEM_ROOT' => Gem.default_dir.inspect,
105
+ 'GEM_HOME' => Gem.paths.home,
106
+ 'GEM_PATH' => Gem.path.join(':'),
107
+ }
108
+ end
109
+
110
+ before do
111
+ command_instance.stub(:omnibus_embedded_bin_dir).and_return(omnibus_embedded_bin_dir)
112
+ command_instance.stub(:omnibus_bin_dir).and_return(omnibus_bin_dir)
113
+ end
114
+
115
+ it "should raise Errno::ENOENT" do
116
+ # XXX: this doesn't really test much, but really calling exec will never return to rspec
117
+ expect(command_instance).to receive(:exec).with(expected_env, *command_options).and_raise(Errno::ENOENT)
118
+ expect{ run_command }.to raise_error(Errno::ENOENT)
119
+ end
120
+ end
121
+ end
122
+
123
+ end
@@ -0,0 +1,102 @@
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 "stringio"
20
+ require 'chef-dk/command/generate'
21
+
22
+ class ChefDK::Command::GeneratorCommands::Example
23
+
24
+ def initialize(argv)
25
+ @argv = argv
26
+ end
27
+
28
+ def run
29
+ {:argv => @argv, :ran_cmd => "example"}
30
+ end
31
+ end
32
+
33
+ describe ChefDK::Command::Generate do
34
+
35
+ # Use a subclass so we have a clean slate of defined generators
36
+ let(:generator_class) { Class.new(ChefDK::Command::Generate) }
37
+
38
+ let(:stdout_io) { StringIO.new }
39
+ let(:stderr_io) { StringIO.new }
40
+
41
+ def stdout
42
+ stdout_io.string
43
+ end
44
+
45
+ subject(:generate) do
46
+ g = generator_class.new
47
+ g.stub(:stdout).and_return(stdout_io)
48
+ g.stub(:stderr).and_return(stderr_io)
49
+ g
50
+ end
51
+
52
+ it "has a list of generators" do
53
+ expect(generator_class.generators).to eq([])
54
+ end
55
+
56
+ context "with a generator defined" do
57
+ let(:expected_help_message) do
58
+ <<-E
59
+ Usage: chef generate GENERATOR [options]
60
+
61
+ Available generators:
62
+ example this is a test
63
+ E
64
+ end
65
+
66
+ before do
67
+ generator_class.generator(:example, :Example, "this is a test")
68
+ end
69
+
70
+ it "includes the generator in the list" do
71
+ expect(generator_class).to have(1).generators
72
+ generator_spec = generator_class.generators.first
73
+ expect(generator_spec.name).to eq(:example)
74
+ expect(generator_spec.class_name).to eq(:Example)
75
+ expect(generator_spec.description).to eq("this is a test")
76
+ end
77
+
78
+ it "includes the generator in the help output" do
79
+ expect(generator_class.banner).to eq(expected_help_message)
80
+ end
81
+
82
+ it "prints usage when running an unknown generator" do
83
+ generate.run(%w[ancient-aliens])
84
+ expect(stdout).to include(expected_help_message)
85
+ end
86
+
87
+ it "runs the generator sub-command" do
88
+ result = generate.run(%w[example])
89
+ expect(result[:ran_cmd]).to eq("example")
90
+ end
91
+
92
+ it "removes the subcommand name from argv" do
93
+ result = generate.run(%w[example])
94
+ expect(result[:argv]).to eq([])
95
+ end
96
+
97
+ it "passes extra arguments and options to the subcommand" do
98
+ result = generate.run(%w[example argument_one argument_two --option-one --option-two])
99
+ expect(result[:argv]).to eq(%w[argument_one argument_two --option-one --option-two])
100
+ end
101
+ end
102
+ end