chef-config 12.4.3 → 12.5.0.alpha.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 04318bb1957964ab7a38dc8ef6c700cff7594ddb
4
- data.tar.gz: 7af1c612414e25cd40cd01e0b5ad77d4e764d731
3
+ metadata.gz: 2347fb5ae0e3e633f6147f5dc882b304e151aa95
4
+ data.tar.gz: 08d2e27cff0117c90f66d1480a9c25ecc36b5e34
5
5
  SHA512:
6
- metadata.gz: b1702f92959f4031d59d5f7835025b27309dccf736752b751a9ef509a61116f86e4d3a46d5aebbcd1bd94aea008e810fa50a57a89d07af1892660468a00a658b
7
- data.tar.gz: de1b0c12333199c52de7b306bc7d943dbd7341c6de5c5f55bdbdf4d1f926aebdbbac5f3dd2342a758bf2eaa9a011eb2ace9ec4c960540136661e5d4f3cb3d889
6
+ metadata.gz: 7a3346f2a58de6eb58d17d916b13e590ec863e42d7408de0968d7df5a83e3a3872a507b8387571ee9c8cd52caaa2eabc9b34261dfcc5be27b56a25acaa056646
7
+ data.tar.gz: ba017cd8a5a5ccb7b221f5d352c0b6926aa4a8e21ece21b9b1fa5d9efd595a6c28abf4783157b0e90accd9be0955533b711a98f8e162d669a734c7599a843f0c
@@ -739,6 +739,3 @@ module ChefConfig
739
739
  end
740
740
  end
741
741
  end
742
-
743
-
744
-
@@ -20,7 +20,7 @@ require 'chef-config/logger'
20
20
 
21
21
  module ChefConfig
22
22
 
23
- class InvalidPath < StandardError
24
- end
23
+ class ConfigurationError < ArgumentError; end
24
+ class InvalidPath < StandardError; end
25
25
 
26
26
  end
@@ -20,6 +20,6 @@
20
20
  #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
21
21
 
22
22
  module ChefConfig
23
- VERSION = '12.4.3'
23
+ VERSION = '12.5.0.alpha.0'
24
24
  end
25
25
 
@@ -0,0 +1,179 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@chef.io>)
3
+ # Copyright:: Copyright (c) 2014 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef-config/config'
20
+ require 'chef-config/exceptions'
21
+ require 'chef-config/logger'
22
+ require 'chef-config/path_helper'
23
+ require 'chef-config/windows'
24
+
25
+ module ChefConfig
26
+ class WorkstationConfigLoader
27
+
28
+ # Path to a config file requested by user, (e.g., via command line option). Can be nil
29
+ attr_accessor :explicit_config_file
30
+
31
+ # TODO: initialize this with a logger for Chef and Knife
32
+ def initialize(explicit_config_file, logger=nil)
33
+ @explicit_config_file = explicit_config_file
34
+ @chef_config_dir = nil
35
+ @config_location = nil
36
+ @logger = logger || NullLogger.new
37
+ end
38
+
39
+ def no_config_found?
40
+ config_location.nil?
41
+ end
42
+
43
+ def config_location
44
+ @config_location ||= (explicit_config_file || locate_local_config)
45
+ end
46
+
47
+ def chef_config_dir
48
+ if @chef_config_dir.nil?
49
+ @chef_config_dir = false
50
+ full_path = working_directory.split(File::SEPARATOR)
51
+ (full_path.length - 1).downto(0) do |i|
52
+ candidate_directory = File.join(full_path[0..i] + [".chef"])
53
+ if File.exist?(candidate_directory) && File.directory?(candidate_directory)
54
+ @chef_config_dir = candidate_directory
55
+ break
56
+ end
57
+ end
58
+ end
59
+ @chef_config_dir
60
+ end
61
+
62
+ def load
63
+ # Ignore it if there's no explicit_config_file and can't find one at a
64
+ # default path.
65
+ return false if config_location.nil?
66
+
67
+ if explicit_config_file && !path_exists?(config_location)
68
+ raise ChefConfig::ConfigurationError, "Specified config file #{config_location} does not exist"
69
+ end
70
+
71
+ # Have to set Config.config_file b/c other config is derived from it.
72
+ Config.config_file = config_location
73
+ read_config(IO.read(config_location), config_location)
74
+ end
75
+
76
+ # (Private API, public for test purposes)
77
+ def env
78
+ ENV
79
+ end
80
+
81
+ # (Private API, public for test purposes)
82
+ def path_exists?(path)
83
+ Pathname.new(path).expand_path.exist?
84
+ end
85
+
86
+ private
87
+
88
+ def have_config?(path)
89
+ if path_exists?(path)
90
+ logger.info("Using config at #{path}")
91
+ true
92
+ else
93
+ logger.debug("Config not found at #{path}, trying next option")
94
+ false
95
+ end
96
+ end
97
+
98
+ def locate_local_config
99
+ candidate_configs = []
100
+
101
+ # Look for $KNIFE_HOME/knife.rb (allow multiple knives config on same machine)
102
+ if env['KNIFE_HOME']
103
+ candidate_configs << File.join(env['KNIFE_HOME'], 'config.rb')
104
+ candidate_configs << File.join(env['KNIFE_HOME'], 'knife.rb')
105
+ end
106
+ # Look for $PWD/knife.rb
107
+ if Dir.pwd
108
+ candidate_configs << File.join(Dir.pwd, 'config.rb')
109
+ candidate_configs << File.join(Dir.pwd, 'knife.rb')
110
+ end
111
+ # Look for $UPWARD/.chef/knife.rb
112
+ if chef_config_dir
113
+ candidate_configs << File.join(chef_config_dir, 'config.rb')
114
+ candidate_configs << File.join(chef_config_dir, 'knife.rb')
115
+ end
116
+ # Look for $HOME/.chef/knife.rb
117
+ PathHelper.home('.chef') do |dot_chef_dir|
118
+ candidate_configs << File.join(dot_chef_dir, 'config.rb')
119
+ candidate_configs << File.join(dot_chef_dir, 'knife.rb')
120
+ end
121
+
122
+ candidate_configs.find do | candidate_config |
123
+ have_config?(candidate_config)
124
+ end
125
+ end
126
+
127
+ def working_directory
128
+ a = if ChefConfig.windows?
129
+ env['CD']
130
+ else
131
+ env['PWD']
132
+ end || Dir.pwd
133
+
134
+ a
135
+ end
136
+
137
+ def read_config(config_content, config_file_path)
138
+ Config.from_string(config_content, config_file_path)
139
+ rescue SignalException
140
+ raise
141
+ rescue SyntaxError => e
142
+ message = ""
143
+ message << "You have invalid ruby syntax in your config file #{config_file_path}\n\n"
144
+ message << "#{e.class.name}: #{e.message}\n"
145
+ if file_line = e.message[/#{Regexp.escape(config_file_path)}:[\d]+/]
146
+ line = file_line[/:([\d]+)$/, 1].to_i
147
+ message << highlight_config_error(config_file_path, line)
148
+ end
149
+ raise ChefConfig::ConfigurationError, message
150
+ rescue Exception => e
151
+ message = "You have an error in your config file #{config_file_path}\n\n"
152
+ message << "#{e.class.name}: #{e.message}\n"
153
+ filtered_trace = e.backtrace.grep(/#{Regexp.escape(config_file_path)}/)
154
+ filtered_trace.each {|bt_line| message << " " << bt_line << "\n" }
155
+ if !filtered_trace.empty?
156
+ line_nr = filtered_trace.first[/#{Regexp.escape(config_file_path)}:([\d]+)/, 1]
157
+ message << highlight_config_error(config_file_path, line_nr.to_i)
158
+ end
159
+ raise ChefConfig::ConfigurationError, message
160
+ end
161
+
162
+
163
+ def highlight_config_error(file, line)
164
+ config_file_lines = []
165
+ IO.readlines(file).each_with_index {|l, i| config_file_lines << "#{(i + 1).to_s.rjust(3)}: #{l.chomp}"}
166
+ if line == 1
167
+ lines = config_file_lines[0..3]
168
+ else
169
+ lines = config_file_lines[Range.new(line - 2, line)]
170
+ end
171
+ "Relevant file content:\n" + lines.join("\n") + "\n"
172
+ end
173
+
174
+ def logger
175
+ @logger
176
+ end
177
+
178
+ end
179
+ end
@@ -0,0 +1,291 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@getchef.com>)
3
+ # Copyright:: Copyright (c) 2014 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'spec_helper'
20
+ require 'tempfile'
21
+
22
+ require 'chef-config/exceptions'
23
+ require 'chef-config/windows'
24
+ require 'chef-config/workstation_config_loader'
25
+
26
+ RSpec.describe ChefConfig::WorkstationConfigLoader do
27
+
28
+ let(:explicit_config_location) { nil }
29
+
30
+ let(:env) { {} }
31
+
32
+ let(:config_loader) do
33
+ described_class.new(explicit_config_location).tap do |c|
34
+ allow(c).to receive(:env).and_return(env)
35
+ end
36
+ end
37
+
38
+ # Test methods that do I/O or reference external state which are stubbed out
39
+ # elsewhere.
40
+ describe "external dependencies" do
41
+ let(:config_loader) { described_class.new(nil) }
42
+
43
+ it "delegates to ENV for env" do
44
+ expect(config_loader.env).to equal(ENV)
45
+ end
46
+
47
+ it "tests a path's existence" do
48
+ expect(config_loader.path_exists?('/nope/nope/nope/nope/frab/jab/nab')).to be(false)
49
+ expect(config_loader.path_exists?(__FILE__)).to be(true)
50
+ end
51
+
52
+ end
53
+
54
+ describe "locating the config file" do
55
+ context "without an explicit config" do
56
+
57
+ before do
58
+ allow(config_loader).to receive(:path_exists?).with(an_instance_of(String)).and_return(false)
59
+ end
60
+
61
+ it "has no config if HOME is not set" do
62
+ expect(config_loader.config_location).to be(nil)
63
+ expect(config_loader.no_config_found?).to be(true)
64
+ end
65
+
66
+ context "when HOME is set and contains a knife.rb" do
67
+
68
+ let(:home) { "/Users/example.user" }
69
+
70
+ before do
71
+ allow(ChefConfig::PathHelper).to receive(:home).with('.chef').and_yield(File.join(home, '.chef'))
72
+ allow(config_loader).to receive(:path_exists?).with("#{home}/.chef/knife.rb").and_return(true)
73
+ end
74
+
75
+ it "uses the config in HOME/.chef/knife.rb" do
76
+ expect(config_loader.config_location).to eq("#{home}/.chef/knife.rb")
77
+ end
78
+
79
+ context "and has a config.rb" do
80
+
81
+ before do
82
+ allow(config_loader).to receive(:path_exists?).with("#{home}/.chef/config.rb").and_return(true)
83
+ end
84
+
85
+ it "uses the config in HOME/.chef/config.rb" do
86
+ expect(config_loader.config_location).to eq("#{home}/.chef/config.rb")
87
+ end
88
+
89
+ context "and/or a parent dir contains a .chef dir" do
90
+
91
+ let(:env_pwd) { "/path/to/cwd" }
92
+
93
+ before do
94
+ if ChefConfig.windows?
95
+ env["CD"] = env_pwd
96
+ else
97
+ env["PWD"] = env_pwd
98
+ end
99
+
100
+ allow(config_loader).to receive(:path_exists?).with("#{env_pwd}/.chef/knife.rb").and_return(true)
101
+ allow(File).to receive(:exist?).with("#{env_pwd}/.chef").and_return(true)
102
+ allow(File).to receive(:directory?).with("#{env_pwd}/.chef").and_return(true)
103
+ end
104
+
105
+ it "prefers the config from parent_dir/.chef" do
106
+ expect(config_loader.config_location).to eq("#{env_pwd}/.chef/knife.rb")
107
+ end
108
+
109
+ context "and the parent dir's .chef dir has a config.rb" do
110
+
111
+ before do
112
+ allow(config_loader).to receive(:path_exists?).with("#{env_pwd}/.chef/config.rb").and_return(true)
113
+ end
114
+
115
+ it "prefers the config from parent_dir/.chef" do
116
+ expect(config_loader.config_location).to eq("#{env_pwd}/.chef/config.rb")
117
+ end
118
+
119
+ context "and/or the current working directory contains a .chef dir" do
120
+
121
+ let(:cwd) { Dir.pwd }
122
+
123
+ before do
124
+ allow(config_loader).to receive(:path_exists?).with("#{cwd}/knife.rb").and_return(true)
125
+ end
126
+
127
+ it "prefers a knife.rb located in the cwd" do
128
+ expect(config_loader.config_location).to eq("#{cwd}/knife.rb")
129
+ end
130
+
131
+ context "and the CWD's .chef dir has a config.rb" do
132
+
133
+ before do
134
+ allow(config_loader).to receive(:path_exists?).with("#{cwd}/config.rb").and_return(true)
135
+ end
136
+
137
+ it "prefers a config located in the cwd" do
138
+ expect(config_loader.config_location).to eq("#{cwd}/config.rb")
139
+ end
140
+
141
+
142
+ context "and/or KNIFE_HOME is set" do
143
+
144
+ let(:knife_home) { "/path/to/knife/home" }
145
+
146
+ before do
147
+ env["KNIFE_HOME"] = knife_home
148
+ allow(config_loader).to receive(:path_exists?).with("#{knife_home}/knife.rb").and_return(true)
149
+ end
150
+
151
+ it "prefers a knife located in KNIFE_HOME" do
152
+ expect(config_loader.config_location).to eq("/path/to/knife/home/knife.rb")
153
+ end
154
+
155
+ context "and KNIFE_HOME contains a config.rb" do
156
+
157
+ before do
158
+ env["KNIFE_HOME"] = knife_home
159
+ allow(config_loader).to receive(:path_exists?).with("#{knife_home}/config.rb").and_return(true)
160
+ end
161
+
162
+ it "prefers a config.rb located in KNIFE_HOME" do
163
+ expect(config_loader.config_location).to eq("/path/to/knife/home/config.rb")
164
+ end
165
+
166
+ end
167
+
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ context "when the current working dir is inside a symlinked directory" do
177
+ before do
178
+ # pwd according to your shell is /home/someuser/prod/chef-repo, but
179
+ # chef-repo is a symlink to /home/someuser/codes/chef-repo
180
+ env["CD"] = "/home/someuser/prod/chef-repo" # windows
181
+ env["PWD"] = "/home/someuser/prod/chef-repo" # unix
182
+
183
+ allow(Dir).to receive(:pwd).and_return("/home/someuser/codes/chef-repo")
184
+ end
185
+
186
+ it "loads the config from the non-dereferenced directory path" do
187
+ expect(File).to receive(:exist?).with("/home/someuser/prod/chef-repo/.chef").and_return(false)
188
+ expect(File).to receive(:exist?).with("/home/someuser/prod/.chef").and_return(true)
189
+ expect(File).to receive(:directory?).with("/home/someuser/prod/.chef").and_return(true)
190
+
191
+ expect(config_loader).to receive(:path_exists?).with("/home/someuser/prod/.chef/knife.rb").and_return(true)
192
+
193
+ expect(config_loader.config_location).to eq("/home/someuser/prod/.chef/knife.rb")
194
+ end
195
+ end
196
+ end
197
+
198
+ context "when given an explicit config to load" do
199
+
200
+ let(:explicit_config_location) { "/path/to/explicit/config.rb" }
201
+
202
+ it "prefers the explicit config" do
203
+ expect(config_loader.config_location).to eq(explicit_config_location)
204
+ end
205
+
206
+ end
207
+ end
208
+
209
+
210
+ describe "loading the config file" do
211
+
212
+ context "when no explicit config is specifed and no implicit config is found" do
213
+
214
+ before do
215
+ allow(config_loader).to receive(:path_exists?).with(an_instance_of(String)).and_return(false)
216
+ end
217
+
218
+ it "skips loading" do
219
+ expect(config_loader.config_location).to be(nil)
220
+ expect(config_loader.load).to be(false)
221
+ end
222
+
223
+ end
224
+
225
+ context "when an explicit config is given but it doesn't exist" do
226
+
227
+ let(:explicit_config_location) { "/nope/nope/nope/frab/jab/nab" }
228
+
229
+ it "raises a configuration error" do
230
+ expect { config_loader.load }.to raise_error(ChefConfig::ConfigurationError)
231
+ end
232
+
233
+ end
234
+
235
+ context "when the config file exists" do
236
+
237
+ let(:config_content) { "" }
238
+
239
+ # We need to keep a reference to the tempfile because while #close does
240
+ # not unlink the file, the object being GC'd will.
241
+ let(:tempfile) do
242
+ Tempfile.new("Chef-WorkstationConfigLoader-rspec-test").tap do |t|
243
+ t.print(config_content)
244
+ t.close
245
+ end
246
+ end
247
+
248
+ let(:explicit_config_location) do
249
+ tempfile.path
250
+ end
251
+
252
+ after { File.unlink(explicit_config_location) if File.exist?(explicit_config_location) }
253
+
254
+ context "and is valid" do
255
+
256
+ let(:config_content) { "config_file_evaluated(true)" }
257
+
258
+ it "loads the config" do
259
+ expect(config_loader.load).to be(true)
260
+ expect(ChefConfig::Config.config_file_evaluated).to be(true)
261
+ end
262
+
263
+ it "sets ChefConfig::Config.config_file" do
264
+ config_loader.load
265
+ expect(ChefConfig::Config.config_file).to eq(explicit_config_location)
266
+ end
267
+ end
268
+
269
+ context "and has a syntax error" do
270
+
271
+ let(:config_content) { "{{{{{:{{" }
272
+
273
+ it "raises a ConfigurationError" do
274
+ expect { config_loader.load }.to raise_error(ChefConfig::ConfigurationError)
275
+ end
276
+ end
277
+
278
+ context "and raises a ruby exception during evaluation" do
279
+
280
+ let(:config_content) { ":foo\n:bar\nraise 'oops'\n:baz\n" }
281
+
282
+ it "raises a ConfigurationError" do
283
+ expect { config_loader.load }.to raise_error(ChefConfig::ConfigurationError)
284
+ end
285
+ end
286
+
287
+ end
288
+
289
+ end
290
+
291
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-config
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.4.3
4
+ version: 12.5.0.alpha.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Jacob
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-23 00:00:00.000000000 Z
11
+ date: 2015-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixlib-shellout
@@ -111,9 +111,11 @@ files:
111
111
  - lib/chef-config/path_helper.rb
112
112
  - lib/chef-config/version.rb
113
113
  - lib/chef-config/windows.rb
114
+ - lib/chef-config/workstation_config_loader.rb
114
115
  - spec/spec_helper.rb
115
116
  - spec/unit/config_spec.rb
116
117
  - spec/unit/path_helper_spec.rb
118
+ - spec/unit/workstation_config_loader_spec.rb
117
119
  homepage: https://github.com/chef/chef
118
120
  licenses:
119
121
  - Apache-2.0
@@ -129,12 +131,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
129
131
  version: '0'
130
132
  required_rubygems_version: !ruby/object:Gem::Requirement
131
133
  requirements:
132
- - - ">="
134
+ - - ">"
133
135
  - !ruby/object:Gem::Version
134
- version: '0'
136
+ version: 1.3.1
135
137
  requirements: []
136
138
  rubyforge_project:
137
- rubygems_version: 2.4.5
139
+ rubygems_version: 2.4.4
138
140
  signing_key:
139
141
  specification_version: 4
140
142
  summary: Chef's default configuration and config loading