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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +4 -4
- data/README.md +4 -4
- data/lib/chef-dk/builtin_commands.rb +4 -0
- data/lib/chef-dk/chef_runner.rb +7 -1
- data/lib/chef-dk/command/exec.rb +9 -0
- data/lib/chef-dk/command/export.rb +132 -0
- data/lib/chef-dk/command/generator_commands.rb +1 -1
- data/lib/chef-dk/command/generator_commands/app.rb +8 -0
- data/lib/chef-dk/command/generator_commands/base.rb +46 -4
- data/lib/chef-dk/command/generator_commands/cookbook.rb +8 -0
- data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +1 -0
- data/lib/chef-dk/command/push.rb +3 -6
- data/lib/chef-dk/command/shell_init.rb +28 -5
- data/lib/chef-dk/command/update.rb +106 -0
- data/lib/chef-dk/command/verify.rb +72 -0
- data/lib/chef-dk/component_test.rb +12 -1
- data/lib/chef-dk/configurable.rb +52 -0
- data/lib/chef-dk/cookbook_metadata.rb +10 -1
- data/lib/chef-dk/cookbook_profiler/git.rb +1 -1
- data/lib/chef-dk/exceptions.rb +17 -2
- data/lib/chef-dk/helpers.rb +2 -2
- data/lib/chef-dk/policyfile/community_cookbook_source.rb +1 -1
- data/lib/chef-dk/policyfile/dsl.rb +7 -0
- data/lib/chef-dk/policyfile/uploader.rb +25 -4
- data/lib/chef-dk/policyfile_compiler.rb +21 -1
- data/lib/chef-dk/policyfile_lock.rb +5 -0
- data/lib/chef-dk/policyfile_services/export_repo.rb +194 -0
- data/lib/chef-dk/policyfile_services/install.rb +8 -2
- data/lib/chef-dk/policyfile_services/push.rb +4 -1
- data/lib/chef-dk/service_exceptions.rb +6 -0
- data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +1 -1
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +1 -1
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/README.md +1 -1
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +2 -2
- data/lib/chef-dk/skeletons/code_generator/files/default/serverspec_spec_helper.rb +3 -0
- data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +1 -7
- data/lib/chef-dk/skeletons/code_generator/metadata.rb +1 -1
- data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +31 -1
- data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +32 -2
- data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +18 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +23 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/serverspec_default_spec.rb.erb +12 -0
- data/lib/chef-dk/version.rb +1 -1
- data/lib/kitchen/provisioner/policyfile_zero.rb +149 -0
- data/spec/shared/a_file_generator.rb +1 -0
- data/spec/shared/command_with_ui_object.rb +11 -0
- data/spec/shared/custom_generator_cookbook.rb +117 -0
- data/spec/unit/chef_runner_spec.rb +26 -0
- data/spec/unit/command/exec_spec.rb +46 -5
- data/spec/unit/command/export_spec.rb +176 -0
- data/spec/unit/command/generator_commands/app_spec.rb +38 -0
- data/spec/unit/command/generator_commands/cookbook_spec.rb +37 -28
- data/spec/unit/command/generator_commands/recipe_spec.rb +4 -2
- data/spec/unit/command/install_spec.rb +3 -6
- data/spec/unit/command/push_spec.rb +3 -6
- data/spec/unit/command/shell_init_spec.rb +77 -49
- data/spec/unit/command/update_spec.rb +155 -0
- data/spec/unit/command/verify_spec.rb +22 -7
- data/spec/unit/cookbook_metadata_spec.rb +44 -8
- data/spec/unit/cookbook_profiler/git_spec.rb +12 -0
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +1 -1
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +1 -1
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +1 -1
- data/spec/unit/fixtures/cookbooks_api/small_universe.json +667 -667
- data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
- data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +1 -1
- data/spec/unit/fixtures/example_cookbook/Berksfile +1 -1
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -0
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -0
- data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -0
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +1 -1
- data/spec/unit/policyfile/community_cookbook_source_spec.rb +2 -2
- data/spec/unit/policyfile/cookbook_location_specification_spec.rb +3 -3
- data/spec/unit/policyfile/uploader_spec.rb +61 -25
- data/spec/unit/policyfile_demands_spec.rb +47 -0
- data/spec/unit/policyfile_evaluation_spec.rb +1 -1
- data/spec/unit/policyfile_lock_build_spec.rb +60 -3
- data/spec/unit/policyfile_services/export_repo_spec.rb +321 -0
- data/spec/unit/policyfile_services/install_spec.rb +20 -1
- data/spec/unit/policyfile_services/push_spec.rb +36 -9
- metadata +53 -38
- data/lib/chef-dk/skeletons/code_generator/files/default/converge_spec.rb +0 -9
- data/lib/chef-dk/skeletons/code_generator/templates/default/default_recipe.rb.erb +0 -5
|
@@ -2,7 +2,25 @@
|
|
|
2
2
|
context = ChefDK::Generator.context
|
|
3
3
|
cookbook_dir = File.join(context.cookbook_root, context.cookbook_name)
|
|
4
4
|
recipe_path = File.join(cookbook_dir, "recipes", "#{context.new_file_basename}.rb")
|
|
5
|
+
spec_helper_path = File.join(cookbook_dir, "spec", "spec_helper.rb")
|
|
6
|
+
spec_path = File.join(cookbook_dir, "spec", "unit", "recipes", "#{context.new_file_basename}_spec.rb")
|
|
5
7
|
|
|
8
|
+
# Chefspec
|
|
9
|
+
directory "#{cookbook_dir}/spec/unit/recipes" do
|
|
10
|
+
recursive true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
cookbook_file spec_helper_path do
|
|
14
|
+
action :create_if_missing
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
template spec_path do
|
|
18
|
+
source "recipe_spec.rb.erb"
|
|
19
|
+
helpers(ChefDK::Generator::TemplateHelper)
|
|
20
|
+
action :create_if_missing
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Recipe
|
|
6
24
|
template recipe_path do
|
|
7
25
|
source "recipe.rb.erb"
|
|
8
26
|
helpers(ChefDK::Generator::TemplateHelper)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Cookbook Name:: <%= cookbook_name %>
|
|
3
|
+
# Spec:: default
|
|
4
|
+
#
|
|
5
|
+
<%= license_description('#') %>
|
|
6
|
+
|
|
7
|
+
require 'spec_helper'
|
|
8
|
+
|
|
9
|
+
describe '<%= cookbook_name %>::<%= recipe_name %>' do
|
|
10
|
+
|
|
11
|
+
context 'When all attributes are default, on an unspecified platform' do
|
|
12
|
+
|
|
13
|
+
let(:chef_run) do
|
|
14
|
+
runner = ChefSpec::ServerRunner.new
|
|
15
|
+
runner.converge(described_recipe)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'converges successfully' do
|
|
19
|
+
chef_run # This should not raise an error
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/chef-dk/version.rb
CHANGED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2013, Fletcher Nichol
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
require "kitchen/provisioner/chef_base"
|
|
20
|
+
|
|
21
|
+
# TODO: chef-dk and kitchen can only co-exist if kitchen and chef-dk agree on
|
|
22
|
+
# the version of mixlib-shellout to use. Kitchen currently locked at 1.x,
|
|
23
|
+
# chef-dk is on 2.x
|
|
24
|
+
require 'chef-dk/policyfile_services/export_repo'
|
|
25
|
+
|
|
26
|
+
module Kitchen
|
|
27
|
+
|
|
28
|
+
module Provisioner
|
|
29
|
+
|
|
30
|
+
# Policyfile + Chef Zero provisioner.
|
|
31
|
+
#
|
|
32
|
+
# @author Daniel DeLeo <dan@chef.io>
|
|
33
|
+
class PolicyfileZero < ChefBase
|
|
34
|
+
|
|
35
|
+
# This provsioner will forcibly set the following config options:
|
|
36
|
+
# * `use_policyfile`: `true`
|
|
37
|
+
# * `versioned_cookbooks`: `true`
|
|
38
|
+
# * `deployment_group`: `POLICY_NAME-local`
|
|
39
|
+
# Since it makes no sense to modify these, they are hardcoded elsewhere.
|
|
40
|
+
default_config :client_rb, {}
|
|
41
|
+
default_config :ruby_bindir, "/opt/chef/embedded/bin"
|
|
42
|
+
|
|
43
|
+
# Policyfile mode does not support the `-j dna.json` option to
|
|
44
|
+
# `chef-client`.
|
|
45
|
+
default_config :json_attributes, false
|
|
46
|
+
default_config :chef_zero_port, 8889
|
|
47
|
+
|
|
48
|
+
default_config :chef_client_path do |provisioner|
|
|
49
|
+
File.join(provisioner[:chef_omnibus_root], %w[bin chef-client])
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Emit a warning that Policyfile stuff is still experimental.
|
|
53
|
+
#
|
|
54
|
+
# (see Base#finalize_config!)
|
|
55
|
+
def finalize_config!(*args)
|
|
56
|
+
super
|
|
57
|
+
banner("Using experimental policyfile mode for chef-client")
|
|
58
|
+
warn("The Policyfile feature is under active development.")
|
|
59
|
+
warn("For best results, always use the latest chef-client version")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# (see Base#create_sandbox)
|
|
63
|
+
def create_sandbox
|
|
64
|
+
super
|
|
65
|
+
prepare_validation_pem
|
|
66
|
+
prepare_client_rb
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# (see Base#run_command)
|
|
70
|
+
def run_command
|
|
71
|
+
level = config[:log_level] == :info ? :auto : config[:log_level]
|
|
72
|
+
chef_client_bin = sudo(config[:chef_client_path])
|
|
73
|
+
|
|
74
|
+
cmd = "#{chef_client_bin} --local-mode"
|
|
75
|
+
args = [
|
|
76
|
+
"--config #{config[:root_path]}/client.rb",
|
|
77
|
+
"--log_level #{level}",
|
|
78
|
+
"--force-formatter",
|
|
79
|
+
"--no-color"
|
|
80
|
+
]
|
|
81
|
+
if config[:chef_zero_port]
|
|
82
|
+
args << "--chef-zero-port #{config[:chef_zero_port]}"
|
|
83
|
+
end
|
|
84
|
+
if config[:log_file]
|
|
85
|
+
args << "--logfile #{config[:log_file]}"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
Util.wrap_command([cmd, *args].join(" "))
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
# Overrides behavior of parent class so that dna.json isn't created; we
|
|
94
|
+
# don't need it.
|
|
95
|
+
#
|
|
96
|
+
# @api private
|
|
97
|
+
def prepare_json
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Copies the policyfile's cookbooks to the sandbox.
|
|
101
|
+
#
|
|
102
|
+
# @api private
|
|
103
|
+
def prepare_cookbooks
|
|
104
|
+
Kitchen.mutex.synchronize do
|
|
105
|
+
policy_exporter.run
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# An instance of ChefDK::PolicyfileServices::ExportRepo, configured with
|
|
110
|
+
# the sandbox path. Calling `#run` on this copies the cookbooks to the
|
|
111
|
+
# sandbox. Calling `#policy_name` returns the policy's name.
|
|
112
|
+
#
|
|
113
|
+
# @api private
|
|
114
|
+
def policy_exporter
|
|
115
|
+
@policy_exporter ||= ChefDK::PolicyfileServices::ExportRepo.new(export_dir: sandbox_path)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Writes a fake (but valid) validation.pem into the sandbox directory.
|
|
119
|
+
#
|
|
120
|
+
# @api private
|
|
121
|
+
def prepare_validation_pem
|
|
122
|
+
info("Preparing validation.pem")
|
|
123
|
+
debug("Using a dummy validation.pem")
|
|
124
|
+
|
|
125
|
+
source = File.join(Kitchen.source_root, %w[support dummy-validation.pem])
|
|
126
|
+
FileUtils.cp(source, File.join(sandbox_path, "validation.pem"))
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Writes a client.rb configuration file to the sandbox directory.
|
|
130
|
+
#
|
|
131
|
+
# @api private
|
|
132
|
+
def prepare_client_rb
|
|
133
|
+
data = default_config_rb.merge(config[:client_rb])
|
|
134
|
+
|
|
135
|
+
data["use_policyfile"] = true
|
|
136
|
+
data["versioned_cookbooks"] = true
|
|
137
|
+
data["deployment_group"] = "#{policy_exporter.policy_name}-local"
|
|
138
|
+
|
|
139
|
+
info("Preparing client.rb")
|
|
140
|
+
debug("Creating client.rb from #{data.inspect}")
|
|
141
|
+
|
|
142
|
+
File.open(File.join(sandbox_path, "client.rb"), "wb") do |file|
|
|
143
|
+
file.write(format_config_file(data))
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
@@ -63,6 +63,7 @@ shared_examples_for "a file generator" do
|
|
|
63
63
|
expect(generator_context.cookbook_root).to eq(expected_cookbook_root)
|
|
64
64
|
expect(generator_context.cookbook_name).to eq(cookbook_name)
|
|
65
65
|
expect(generator_context.new_file_basename).to eq(new_file_name)
|
|
66
|
+
expect(generator_context.recipe_name).to eq(new_file_name)
|
|
66
67
|
end
|
|
67
68
|
end
|
|
68
69
|
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
|
|
2
|
+
# Required `let` bindings:
|
|
3
|
+
# * `generator_name` in lowercase, e.g., "cookbook", "app"
|
|
4
|
+
# * `generator_arg`: argument to the generator command
|
|
5
|
+
# * `expected_cookbook_files`: a list of files the generator should create
|
|
6
|
+
shared_examples_for "custom generator cookbook" do
|
|
7
|
+
|
|
8
|
+
context "when given a generator-cookbook path" do
|
|
9
|
+
|
|
10
|
+
let(:default_generator_cookbook_path) { File.expand_path('lib/chef-dk/skeletons/code_generator', project_root) }
|
|
11
|
+
|
|
12
|
+
let(:generator_cookbook_path) { File.join(tempdir, 'a_generator_cookbook') }
|
|
13
|
+
|
|
14
|
+
let(:argv) { [generator_arg, "--generator-cookbook", generator_cookbook_path] }
|
|
15
|
+
|
|
16
|
+
subject(:code_generator) { described_class.new(argv) }
|
|
17
|
+
|
|
18
|
+
before do
|
|
19
|
+
reset_tempdir
|
|
20
|
+
code_generator.read_and_validate_params
|
|
21
|
+
allow(code_generator.config_loader).to receive(:load)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "configures the generator context" do
|
|
25
|
+
code_generator.setup_context
|
|
26
|
+
expect(generator_context.cookbook_name).to eq(generator_arg)
|
|
27
|
+
expect(code_generator.chef_runner.cookbook_path).to eq(tempdir)
|
|
28
|
+
expect(code_generator.chef_runner.run_list).to eq(["recipe[a_generator_cookbook::#{generator_name}]"])
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "when the generator cookbook is configured in a configuration file" do
|
|
32
|
+
|
|
33
|
+
let(:argv) { [generator_arg] }
|
|
34
|
+
|
|
35
|
+
let(:chefdk_config) { double("Mixlib::Config context for ChefDK", generator_cookbook: generator_cookbook_path) }
|
|
36
|
+
|
|
37
|
+
before do
|
|
38
|
+
allow(code_generator).to receive(:chefdk_config).and_return(chefdk_config)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "configures the generator context" do
|
|
42
|
+
code_generator.setup_context
|
|
43
|
+
expect(generator_context.cookbook_name).to eq(generator_arg)
|
|
44
|
+
expect(code_generator.chef_runner.cookbook_path).to eq(tempdir)
|
|
45
|
+
expect(code_generator.chef_runner.run_list).to eq(["recipe[a_generator_cookbook::#{generator_name}]"])
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context "with an invalid generator-cookbook path" do
|
|
50
|
+
|
|
51
|
+
it "fails with an informative error" do
|
|
52
|
+
Dir.chdir(tempdir) do
|
|
53
|
+
allow(code_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
|
|
54
|
+
allow(code_generator).to receive(:stderr).and_return(stderr_io)
|
|
55
|
+
expect(code_generator.run).to eq(1)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
cookbook_path = File.dirname(generator_cookbook_path)
|
|
59
|
+
expected_msg = %Q(ERROR: Could not find cookbook(s) to satisfy run list ["recipe[a_generator_cookbook::#{generator_name}]"] in #{cookbook_path})
|
|
60
|
+
|
|
61
|
+
expect(stderr_io.string).to include(expected_msg)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context "with a generator-cookbook path to a specific cookbook" do
|
|
67
|
+
|
|
68
|
+
let(:metadata_file) { File.join(generator_cookbook_path, "metadata.rb") }
|
|
69
|
+
|
|
70
|
+
before do
|
|
71
|
+
FileUtils.cp_r(default_generator_cookbook_path, generator_cookbook_path)
|
|
72
|
+
|
|
73
|
+
# have to update metadata with the correct name
|
|
74
|
+
IO.binwrite(metadata_file, "name 'a_generator_cookbook'")
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "creates the new files" do
|
|
78
|
+
expect(code_generator.chef_runner.cookbook_path).to eq(tempdir)
|
|
79
|
+
expect(code_generator.chef_runner.run_list).to eq(["recipe[a_generator_cookbook::#{generator_name}]"])
|
|
80
|
+
|
|
81
|
+
Dir.chdir(tempdir) do
|
|
82
|
+
allow(code_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
|
|
83
|
+
code_generator.run
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "with a generator-cookbook path to a directory containing a 'code_generator' cookbook" do
|
|
90
|
+
|
|
91
|
+
before do
|
|
92
|
+
FileUtils.mkdir_p(generator_cookbook_path)
|
|
93
|
+
FileUtils.cp_r(default_generator_cookbook_path, generator_cookbook_path)
|
|
94
|
+
|
|
95
|
+
allow(code_generator).to receive(:stderr).and_return(stderr_io)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "creates the new_files (and warns about deprecated usage)" do
|
|
99
|
+
allow(code_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
|
|
100
|
+
|
|
101
|
+
Dir.chdir(tempdir) do
|
|
102
|
+
code_generator.run
|
|
103
|
+
end
|
|
104
|
+
generated_files = Dir.glob("#{tempdir}/#{generator_arg}/**/*", File::FNM_DOTMATCH)
|
|
105
|
+
expected_cookbook_files.each do |expected_file|
|
|
106
|
+
expect(generated_files).to include(expected_file)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
code_generator_path = File.join(generator_cookbook_path, "code_generator")
|
|
110
|
+
warning_message = "WARN: Please configure the generator cookbook by giving the full path to the desired cookbook (like '#{code_generator_path}')"
|
|
111
|
+
|
|
112
|
+
expect(stderr_io.string).to include(warning_message)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
@@ -72,6 +72,32 @@ describe ChefDK::ChefRunner do
|
|
|
72
72
|
expect(test_state[:loaded_recipes]).to eq([ "recipe_one", "recipe_two" ])
|
|
73
73
|
expect(test_state[:converged_recipes]).to eq([ "recipe_one", "recipe_two" ])
|
|
74
74
|
end
|
|
75
|
+
|
|
76
|
+
context "when the embedded chef run fails" do
|
|
77
|
+
|
|
78
|
+
let(:embedded_runner) { instance_double("Chef::Runner") }
|
|
79
|
+
|
|
80
|
+
before do
|
|
81
|
+
allow(Chef::Runner).to receive(:new).and_return(embedded_runner)
|
|
82
|
+
allow(embedded_runner).to receive(:converge).and_raise("oops")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "wraps the exception in a ChefConvergeError" do
|
|
86
|
+
expect { chef_runner.converge }.to raise_error(ChefDK::ChefConvergeError)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context "when cookbook_path is relative" do
|
|
92
|
+
|
|
93
|
+
let(:default_cookbook_path) { "~/heres_some_cookbooks" }
|
|
94
|
+
|
|
95
|
+
it "expands the path" do
|
|
96
|
+
expect(chef_runner.cookbook_path).to eq(File.expand_path(default_cookbook_path))
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
|
|
75
101
|
end
|
|
76
102
|
|
|
77
103
|
|
|
@@ -24,7 +24,7 @@ describe ChefDK::Command::Exec do
|
|
|
24
24
|
let(:command_options) { [] }
|
|
25
25
|
|
|
26
26
|
def run_command
|
|
27
|
-
command_instance.
|
|
27
|
+
command_instance.run_with_default_options(command_options)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
it "has a usage banner" do
|
|
@@ -76,11 +76,11 @@ describe ChefDK::Command::Exec do
|
|
|
76
76
|
|
|
77
77
|
let(:expected_PATH) { [omnibus_bin_dir, user_bin_dir, omnibus_embedded_bin_dir, ENV['PATH']].join(File::PATH_SEPARATOR) }
|
|
78
78
|
|
|
79
|
-
let(:expected_GEM_ROOT) { Gem.default_dir
|
|
79
|
+
let(:expected_GEM_ROOT) { Gem.default_dir }
|
|
80
80
|
|
|
81
81
|
let(:expected_GEM_HOME) { Gem.user_dir }
|
|
82
82
|
|
|
83
|
-
let(:expected_GEM_PATH) { Gem.path.join(
|
|
83
|
+
let(:expected_GEM_PATH) { Gem.path.join(File::PATH_SEPARATOR) }
|
|
84
84
|
|
|
85
85
|
before do
|
|
86
86
|
allow(command_instance).to receive(:omnibus_embedded_bin_dir).and_return(omnibus_embedded_bin_dir)
|
|
@@ -97,6 +97,47 @@ describe ChefDK::Command::Exec do
|
|
|
97
97
|
expect{ run_command }.to raise_error # XXX: this isn't a test we just need to swallow the exception
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
+
['-v', '--version', '-h', '--help'].each do |switch|
|
|
101
|
+
context "when running a command with #{switch}" do
|
|
102
|
+
let(:command_options) { %W[gem list #{switch}] }
|
|
103
|
+
|
|
104
|
+
it "should call exec to fire off the command with the correct environment" do
|
|
105
|
+
expect(ENV).to receive(:[]=).with("PATH", expected_PATH)
|
|
106
|
+
expect(ENV).to receive(:[]=).with("GEM_ROOT", expected_GEM_ROOT)
|
|
107
|
+
expect(ENV).to receive(:[]=).with("GEM_HOME", expected_GEM_HOME)
|
|
108
|
+
expect(ENV).to receive(:[]=).with("GEM_PATH", expected_GEM_PATH)
|
|
109
|
+
|
|
110
|
+
expect(command_instance).to receive(:exec).with(*command_options)
|
|
111
|
+
expect{ run_command }.to raise_error # XXX: this isn't a test we just need to swallow the exception
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
['-h', '--help'].each do |switch|
|
|
117
|
+
context "when running a exec with #{switch} and things after it" do
|
|
118
|
+
let(:command_options) { %W[#{switch} gem] }
|
|
119
|
+
|
|
120
|
+
it "should call not call exec, but it should print the banner" do
|
|
121
|
+
allow(command_instance).to receive(:msg)
|
|
122
|
+
expect(ENV).not_to receive(:[]=)
|
|
123
|
+
expect(command_instance).to receive(:banner)
|
|
124
|
+
expect(command_instance).not_to receive(:exec)
|
|
125
|
+
run_command
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
context "when running a exec with #{switch}" do
|
|
130
|
+
let(:command_options) { ["#{switch}"] }
|
|
131
|
+
|
|
132
|
+
it "should call not call exec, but it should print the banner" do
|
|
133
|
+
allow(command_instance).to receive(:msg)
|
|
134
|
+
expect(ENV).not_to receive(:[]=)
|
|
135
|
+
expect(command_instance).to receive(:banner)
|
|
136
|
+
expect(command_instance).not_to receive(:exec)
|
|
137
|
+
run_command
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
100
141
|
end
|
|
101
142
|
|
|
102
143
|
context "when running command that does not exist" do
|
|
@@ -110,11 +151,11 @@ describe ChefDK::Command::Exec do
|
|
|
110
151
|
|
|
111
152
|
let(:expected_PATH) { [omnibus_bin_dir, user_bin_dir, omnibus_embedded_bin_dir, ENV['PATH']].join(File::PATH_SEPARATOR) }
|
|
112
153
|
|
|
113
|
-
let(:expected_GEM_ROOT) { Gem.default_dir
|
|
154
|
+
let(:expected_GEM_ROOT) { Gem.default_dir }
|
|
114
155
|
|
|
115
156
|
let(:expected_GEM_HOME) { Gem.user_dir }
|
|
116
157
|
|
|
117
|
-
let(:expected_GEM_PATH) { Gem.path.join(
|
|
158
|
+
let(:expected_GEM_PATH) { Gem.path.join(File::PATH_SEPARATOR) }
|
|
118
159
|
|
|
119
160
|
|
|
120
161
|
before do
|