poise-file 1.0.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 +7 -0
- data/.gitignore +11 -0
- data/.kitchen.yml +3 -0
- data/.travis.yml +64 -0
- data/.yardopts +7 -0
- data/.yo-rc.json +7 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +32 -0
- data/LICENSE +201 -0
- data/README.md +102 -0
- data/Rakefile +17 -0
- data/lib/poise_file.rb +21 -0
- data/lib/poise_file/cheftie.rb +18 -0
- data/lib/poise_file/resources.rb +27 -0
- data/lib/poise_file/resources/poise_file.rb +242 -0
- data/lib/poise_file/version.rb +21 -0
- data/poise-file.gemspec +42 -0
- data/test/cookbook/metadata.rb +18 -0
- data/test/cookbook/recipes/default.rb +36 -0
- data/test/gemfiles/chef-12.1.gemfile +23 -0
- data/test/gemfiles/chef-12.10.gemfile +23 -0
- data/test/gemfiles/chef-12.11.gemfile +23 -0
- data/test/gemfiles/chef-12.12.gemfile +22 -0
- data/test/gemfiles/chef-12.13.gemfile +22 -0
- data/test/gemfiles/chef-12.14.gemfile +19 -0
- data/test/gemfiles/chef-12.15.gemfile +19 -0
- data/test/gemfiles/chef-12.16.gemfile +19 -0
- data/test/gemfiles/chef-12.17.gemfile +19 -0
- data/test/gemfiles/chef-12.18.gemfile +19 -0
- data/test/gemfiles/chef-12.19.gemfile +19 -0
- data/test/gemfiles/chef-12.2.gemfile +23 -0
- data/test/gemfiles/chef-12.3.gemfile +23 -0
- data/test/gemfiles/chef-12.4.gemfile +24 -0
- data/test/gemfiles/chef-12.5.gemfile +23 -0
- data/test/gemfiles/chef-12.6.gemfile +23 -0
- data/test/gemfiles/chef-12.7.gemfile +23 -0
- data/test/gemfiles/chef-12.8.gemfile +23 -0
- data/test/gemfiles/chef-12.9.gemfile +23 -0
- data/test/gemfiles/chef-12.gemfile +19 -0
- data/test/gemfiles/chef-13.0.gemfile +19 -0
- data/test/gemfiles/chef-13.gemfile +19 -0
- data/test/gemfiles/master.gemfile +26 -0
- data/test/integration/default/serverspec/default_spec.rb +54 -0
- data/test/spec/resources/poise_file_spec.rb +328 -0
- data/test/spec/spec_helper.rb +19 -0
- metadata +183 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2017, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
eval_gemfile File.expand_path('../../../Gemfile', __FILE__)
|
18
|
+
|
19
|
+
gem 'chef', '~> 13.0.118'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2017, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
eval_gemfile File.expand_path('../../../Gemfile', __FILE__)
|
18
|
+
|
19
|
+
gem 'chef', '~> 13.0'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2017, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
eval_gemfile File.expand_path('../../../Gemfile', __FILE__)
|
18
|
+
|
19
|
+
gem 'chef', git: 'https://github.com/chef/chef.git'
|
20
|
+
gem 'chefspec', git: 'https://github.com/sethvargo/chefspec.git'
|
21
|
+
gem 'fauxhai', git: 'https://github.com/customink/fauxhai.git'
|
22
|
+
gem 'foodcritic', git: 'https://github.com/foodcritic/foodcritic.git'
|
23
|
+
gem 'halite', git: 'https://github.com/poise/halite.git'
|
24
|
+
gem 'ohai', git: 'https://github.com/chef/ohai.git'
|
25
|
+
gem 'poise', git: 'https://github.com/poise/poise.git'
|
26
|
+
gem 'poise-boiler', git: 'https://github.com/poise/poise-boiler.git'
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2017, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'serverspec'
|
18
|
+
set :backend, :exec
|
19
|
+
|
20
|
+
describe file('/poise_test') do
|
21
|
+
it { is_expected.to be_a_file }
|
22
|
+
its(:content) { is_expected.to eq "I'm a little teapot\n" }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe file('/poise_test.json') do
|
26
|
+
it { is_expected.to be_a_file }
|
27
|
+
its(:content) { is_expected.to eq <<-EOH }
|
28
|
+
[
|
29
|
+
"short and stout",
|
30
|
+
{
|
31
|
+
"here": "is my handle"
|
32
|
+
}
|
33
|
+
]
|
34
|
+
EOH
|
35
|
+
end
|
36
|
+
|
37
|
+
describe file('/poise_test.yml') do
|
38
|
+
it { is_expected.to be_a_file }
|
39
|
+
its(:content) { is_expected.to eq <<-EOH }
|
40
|
+
---
|
41
|
+
here: is my spout
|
42
|
+
when:
|
43
|
+
- I
|
44
|
+
- get
|
45
|
+
- all
|
46
|
+
- steamed
|
47
|
+
- up
|
48
|
+
EOH
|
49
|
+
end
|
50
|
+
|
51
|
+
describe file('/poise_test_pattern') do
|
52
|
+
it { is_expected.to be_a_file }
|
53
|
+
its(:content) { is_expected.to eq "I must yell\ntip me over\n" }
|
54
|
+
end
|
@@ -0,0 +1,328 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2017, Noah Kantrowitz
|
3
|
+
#
|
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
|
+
|
20
|
+
describe PoiseFile::Resources::PoiseFile do
|
21
|
+
step_into(:poise_file)
|
22
|
+
let(:existing_content) { nil }
|
23
|
+
around do |ex|
|
24
|
+
Dir.mktmpdir('poise_file') do |path|
|
25
|
+
ex.metadata[:poise_file_temp_path] = path
|
26
|
+
default_attributes['temp_path'] = path
|
27
|
+
IO.write("#{temp_path}/test.txt", existing_content) if existing_content
|
28
|
+
ex.run
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:temp_path) do |example|
|
33
|
+
example.metadata[:poise_file_temp_path]
|
34
|
+
end
|
35
|
+
|
36
|
+
subject do
|
37
|
+
# Actually write out the file.
|
38
|
+
run_chef
|
39
|
+
# Lazy load any requested file.
|
40
|
+
Hash.new {|has, key| IO.read("#{temp_path}/#{key}") }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'formats' do
|
44
|
+
context 'with a .json path' do
|
45
|
+
recipe(subject: false) do
|
46
|
+
poise_file "#{node['temp_path']}/test.json" do
|
47
|
+
content foo: 'bar'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
its(['test.json']) { is_expected.to eq %Q({\n "foo": "bar"\n}\n) }
|
52
|
+
end # /context with a .json path
|
53
|
+
|
54
|
+
context 'with a .json path but string content' do
|
55
|
+
recipe(subject: false) do
|
56
|
+
poise_file "#{node['temp_path']}/test.json" do
|
57
|
+
content "foo\nbar\n"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
its(['test.json']) { is_expected.to eq "foo\nbar\n" }
|
62
|
+
end # /context with a .json path but string content
|
63
|
+
|
64
|
+
context 'with a .yaml path' do
|
65
|
+
recipe(subject: false) do
|
66
|
+
poise_file "#{node['temp_path']}/test.yaml" do
|
67
|
+
content 'foo' => 'bar'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
its(['test.yaml']) { is_expected.to eq %Q(---\nfoo: bar\n) }
|
72
|
+
end # /context with a .yaml path
|
73
|
+
|
74
|
+
context 'with a .yml path' do
|
75
|
+
recipe(subject: false) do
|
76
|
+
poise_file "#{node['temp_path']}/test.yml" do
|
77
|
+
content 'foo' => 'bar'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
its(['test.yml']) { is_expected.to eq %Q(---\nfoo: bar\n) }
|
82
|
+
end # /context with a .yml path
|
83
|
+
|
84
|
+
context 'with a .txt path' do
|
85
|
+
recipe(subject: false) do
|
86
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
87
|
+
content 'foo' => 'bar'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
its(['test.txt']) { is_expected.to eq %Q({"foo"=>"bar"}) }
|
92
|
+
end # /context with a .txt path
|
93
|
+
|
94
|
+
context 'with node attributes' do
|
95
|
+
recipe(subject: false) do
|
96
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
97
|
+
content node['network']
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
its(['test.txt']) { is_expected.to match /\A\{.*\}\Z/ }
|
102
|
+
end # /context with node attributes
|
103
|
+
|
104
|
+
context 'with an invalid format' do
|
105
|
+
recipe do
|
106
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
107
|
+
content "this is a test\n"
|
108
|
+
format :other
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
it { expect { run_chef }.to raise_error ArgumentError }
|
113
|
+
end # /context with an invalid format
|
114
|
+
end # /describe formats
|
115
|
+
|
116
|
+
describe 'patterns' do
|
117
|
+
describe 'replace' do
|
118
|
+
context 'with a simple pattern' do
|
119
|
+
let(:existing_content) { "this is\na test\n" }
|
120
|
+
recipe(subject: false) do
|
121
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
122
|
+
content "this is not\n"
|
123
|
+
pattern '^this is$'
|
124
|
+
pattern_location :replace
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
its(['test.txt']) { is_expected.to eq "this is not\na test\n" }
|
129
|
+
end # /context with a simple pattern
|
130
|
+
|
131
|
+
context 'with a replacement without a newline' do
|
132
|
+
let(:existing_content) { "this is\na test\n" }
|
133
|
+
recipe(subject: false) do
|
134
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
135
|
+
content "this is not"
|
136
|
+
pattern '^this is$'
|
137
|
+
pattern_location :replace
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
its(['test.txt']) { is_expected.to eq "this is not\na test\n" }
|
142
|
+
end # /context with a replacement without a newline
|
143
|
+
|
144
|
+
context 'with a pattern that does not match' do
|
145
|
+
let(:existing_content) { "this is\na test\n" }
|
146
|
+
recipe(subject: false) do
|
147
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
148
|
+
content "this is not"
|
149
|
+
pattern '^this was$'
|
150
|
+
pattern_location :replace
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
its(['test.txt']) { is_expected.to eq "this is\na test\n" }
|
155
|
+
end # /context with a pattern that does not match
|
156
|
+
end # /describe replace
|
157
|
+
|
158
|
+
describe 'replace_or_add' do
|
159
|
+
context 'with a simple pattern' do
|
160
|
+
let(:existing_content) { "this is\na test\n" }
|
161
|
+
recipe(subject: false) do
|
162
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
163
|
+
content "this is not\n"
|
164
|
+
pattern '^this is$'
|
165
|
+
pattern_location :replace_or_add
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
its(['test.txt']) { is_expected.to eq "this is not\na test\n" }
|
170
|
+
end # /context with a simple pattern
|
171
|
+
|
172
|
+
context 'with a patten that does not match' do
|
173
|
+
let(:existing_content) { "this is\na test\n" }
|
174
|
+
recipe(subject: false) do
|
175
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
176
|
+
content "this is not\n"
|
177
|
+
pattern '^this was$'
|
178
|
+
pattern_location :replace_or_add
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
its(['test.txt']) { is_expected.to eq "this is\na test\nthis is not\n" }
|
183
|
+
end # /context with a patten that does not match
|
184
|
+
|
185
|
+
context 'with a file that does not exist' do
|
186
|
+
recipe(subject: false) do
|
187
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
188
|
+
content "this is not\n"
|
189
|
+
pattern '^this was$'
|
190
|
+
pattern_location :replace_or_add
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
its(['test.txt']) { is_expected.to eq "this is not\n" }
|
195
|
+
end # /context with a file that does not exist
|
196
|
+
end # /describe replace_or_add
|
197
|
+
|
198
|
+
describe 'before' do
|
199
|
+
context 'with a simple pattern' do
|
200
|
+
let(:existing_content) { "this is\na test\n" }
|
201
|
+
recipe(subject: false) do
|
202
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
203
|
+
content "probably\n"
|
204
|
+
pattern '^a test$'
|
205
|
+
pattern_location :before
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
its(['test.txt']) { is_expected.to eq "this is\nprobably\na test\n" }
|
210
|
+
end # /context with a simple pattern
|
211
|
+
|
212
|
+
context 'with a pattern that already matches' do
|
213
|
+
let(:existing_content) { "this is\nprobably\na test\n" }
|
214
|
+
recipe(subject: false) do
|
215
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
216
|
+
content "probably\n"
|
217
|
+
pattern '^a test$'
|
218
|
+
pattern_location :before
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
its(['test.txt']) { is_expected.to eq "this is\nprobably\na test\n" }
|
223
|
+
end # /context with a pattern that already matches
|
224
|
+
|
225
|
+
context 'with a pattern that does not match' do
|
226
|
+
let(:existing_content) { "this is\na test\n" }
|
227
|
+
recipe(subject: false) do
|
228
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
229
|
+
content "probably\n"
|
230
|
+
pattern '^not a test$'
|
231
|
+
pattern_location :before
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
its(['test.txt']) { is_expected.to eq "this is\na test\n" }
|
236
|
+
end # /context with a pattern that does not match
|
237
|
+
end # /describe before
|
238
|
+
|
239
|
+
describe 'after' do
|
240
|
+
context 'with a simple pattern' do
|
241
|
+
let(:existing_content) { "this is\na test\n" }
|
242
|
+
recipe(subject: false) do
|
243
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
244
|
+
content "probably\n"
|
245
|
+
pattern '^a test$'
|
246
|
+
pattern_location :after
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
its(['test.txt']) { is_expected.to eq "this is\na test\nprobably\n" }
|
251
|
+
end # /context with a simple pattern
|
252
|
+
|
253
|
+
context 'with a pattern that already matches' do
|
254
|
+
let(:existing_content) { "this is\na test\nprobably\n" }
|
255
|
+
recipe(subject: false) do
|
256
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
257
|
+
content "probably\n"
|
258
|
+
pattern '^a test$'
|
259
|
+
pattern_location :after
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
its(['test.txt']) { is_expected.to eq "this is\na test\nprobably\n" }
|
264
|
+
end # /context with a pattern that already matches
|
265
|
+
|
266
|
+
context 'with a pattern that does not match' do
|
267
|
+
let(:existing_content) { "this is\na test\n" }
|
268
|
+
recipe(subject: false) do
|
269
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
270
|
+
content "probably\n"
|
271
|
+
pattern '^not a test$'
|
272
|
+
pattern_location :after
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
its(['test.txt']) { is_expected.to eq "this is\na test\n" }
|
277
|
+
end # /context with a pattern that does not match
|
278
|
+
end # /describe after
|
279
|
+
|
280
|
+
context 'with a proc pattern' do
|
281
|
+
let(:existing_content) { "this is\na test\n" }
|
282
|
+
recipe(subject: false) do
|
283
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
284
|
+
content "this is not"
|
285
|
+
pattern proc {|existing_content| existing_content.gsub(/t/, 'q') }
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
its(['test.txt']) { is_expected.to eq "qhis is\na qesq\n" }
|
290
|
+
end # /context with a proc pattern
|
291
|
+
|
292
|
+
context 'with a RegExp pattern' do
|
293
|
+
let(:existing_content) { "this is\na test\n" }
|
294
|
+
recipe(subject: false) do
|
295
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
296
|
+
content "this is not\n"
|
297
|
+
pattern(/^this is$/)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
its(['test.txt']) { is_expected.to eq "this is not\n\na test\n" }
|
302
|
+
end # /context with a RegExp pattern
|
303
|
+
|
304
|
+
context 'with an invalid pattern_location' do
|
305
|
+
recipe do
|
306
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
307
|
+
content "this is a test\n"
|
308
|
+
pattern 'asdf'
|
309
|
+
pattern_location :other
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
it { expect { run_chef }.to raise_error ArgumentError }
|
314
|
+
end # /context with an invalid pattern_location
|
315
|
+
end # /describe patterns
|
316
|
+
|
317
|
+
context 'with both a format and a pattern' do
|
318
|
+
recipe do
|
319
|
+
poise_file "#{node['temp_path']}/test.txt" do
|
320
|
+
content "this is a test\n"
|
321
|
+
format :json
|
322
|
+
pattern 'asdf'
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
it { expect { run_chef }.to raise_error ArgumentError }
|
327
|
+
end # /context with both a format and a pattern
|
328
|
+
end
|