packer-config 0.0.3

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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/.rubocop.yml +340 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +17 -0
  6. data/LICENSE +176 -0
  7. data/README.md +107 -0
  8. data/Rakefile +47 -0
  9. data/TODO.md +8 -0
  10. data/lib/packer-config.rb +181 -0
  11. data/lib/packer/builder.rb +65 -0
  12. data/lib/packer/builders/all.rb +17 -0
  13. data/lib/packer/builders/amazon.rb +214 -0
  14. data/lib/packer/builders/docker.rb +47 -0
  15. data/lib/packer/builders/virtualbox.rb +169 -0
  16. data/lib/packer/dataobject.rb +128 -0
  17. data/lib/packer/envvar.rb +27 -0
  18. data/lib/packer/macro.rb +28 -0
  19. data/lib/packer/postprocessor.rb +77 -0
  20. data/lib/packer/postprocessors/all.rb +16 -0
  21. data/lib/packer/postprocessors/docker.rb +35 -0
  22. data/lib/packer/postprocessors/vagrant.rb +47 -0
  23. data/lib/packer/provisioner.rb +86 -0
  24. data/lib/packer/provisioners/all.rb +16 -0
  25. data/lib/packer/provisioners/file.rb +36 -0
  26. data/lib/packer/provisioners/shell.rb +60 -0
  27. data/packer-config.gemspec +46 -0
  28. data/spec/integration/README.md +14 -0
  29. data/spec/integration/builds/.gitignore +4 -0
  30. data/spec/integration/centos_vagrant_spec.rb +76 -0
  31. data/spec/integration/packer_cache/.gitignore +4 -0
  32. data/spec/integration/scripts/chef.sh +199 -0
  33. data/spec/integration/scripts/cleanup.sh +17 -0
  34. data/spec/integration/scripts/fix-slow-dns.sh +13 -0
  35. data/spec/integration/scripts/hello.sh +3 -0
  36. data/spec/integration/scripts/kickstart/centos-6.5-ks.cfg +71 -0
  37. data/spec/integration/scripts/minimize.sh +9 -0
  38. data/spec/integration/scripts/sshd.sh +6 -0
  39. data/spec/integration/scripts/vagrant.sh +10 -0
  40. data/spec/integration/scripts/vmtools.sh +39 -0
  41. data/spec/packer/builder_spec.rb +39 -0
  42. data/spec/packer/builders/amazon_spec.rb +88 -0
  43. data/spec/packer/builders/docker_spec.rb +25 -0
  44. data/spec/packer/builders/virtualbox_spec.rb +44 -0
  45. data/spec/packer/dataobject_spec.rb +239 -0
  46. data/spec/packer/envvar_spec.rb +38 -0
  47. data/spec/packer/macro_spec.rb +38 -0
  48. data/spec/packer/postprocessor_spec.rb +72 -0
  49. data/spec/packer/postprocessors/docker_import_spec.rb +27 -0
  50. data/spec/packer/postprocessors/docker_push_spec.rb +27 -0
  51. data/spec/packer/postprocessors/vagrant_spec.rb +27 -0
  52. data/spec/packer/provisioner_spec.rb +78 -0
  53. data/spec/packer/provisioners/file_spec.rb +63 -0
  54. data/spec/packer/provisioners/shell_spec.rb +116 -0
  55. data/spec/packer_config_spec.rb +197 -0
  56. data/spec/spec_helper.rb +19 -0
  57. data/spec/unit_helper.rb +15 -0
  58. metadata +220 -0
@@ -0,0 +1,27 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
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
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::PostProcessor::DockerImport do
18
+ let(:postprocessor) do
19
+ Packer::PostProcessor.get_postprocessor(Packer::PostProcessor::DOCKER_IMPORT)
20
+ end
21
+
22
+ describe '#initialize' do
23
+ it 'has a type of shell' do
24
+ expect(postprocessor.data['type']).to eq(Packer::PostProcessor::DOCKER_IMPORT)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
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
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::PostProcessor::DockerPush do
18
+ let(:postprocessor) do
19
+ Packer::PostProcessor.get_postprocessor(Packer::PostProcessor::DOCKER_PUSH)
20
+ end
21
+
22
+ describe '#initialize' do
23
+ it 'has a type of shell' do
24
+ expect(postprocessor.data['type']).to eq(Packer::PostProcessor::DOCKER_PUSH)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
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
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::PostProcessor::Vagrant do
18
+ let(:postprocessor) do
19
+ Packer::PostProcessor.get_postprocessor(Packer::PostProcessor::VAGRANT)
20
+ end
21
+
22
+ describe '#initialize' do
23
+ it 'has a type of shell' do
24
+ expect(postprocessor.data['type']).to eq(Packer::PostProcessor::VAGRANT)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,78 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
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
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::Provisioner do
18
+ PROVISIONER_TYPE = 'shell'
19
+
20
+ let(:provisioner) do
21
+ Packer::Provisioner.new
22
+ end
23
+
24
+ let(:overrides) do
25
+ {
26
+ "key1" => "value1",
27
+ "key2" => "value2"
28
+ }
29
+ end
30
+
31
+ describe '.get_provisioner' do
32
+ it 'returns a provisioner' do
33
+ expect(Packer::Provisioner.get_provisioner(PROVISIONER_TYPE)).to be_a_kind_of(Packer::Provisioner)
34
+ end
35
+
36
+ it 'raises an error when the provisioner type is not recognized' do
37
+ expect { Packer::Provisioner.get_provisioner('unknown-type') }.to raise_error
38
+ end
39
+ end
40
+
41
+ describe '#only' do
42
+ it 'adds an only exception' do
43
+ provisioner.only('thing1')
44
+ expect(provisioner.data['only']).to eq(%w[thing1])
45
+ provisioner.only('thing2')
46
+ expect(provisioner.data['only']).to eq(%w[thing1 thing2])
47
+ end
48
+ end
49
+
50
+ describe '#except' do
51
+ it 'adds an execpt exception' do
52
+ provisioner.except('thing3')
53
+ expect(provisioner.data['except']).to eq(%w[thing3])
54
+ provisioner.except('thing4')
55
+ expect(provisioner.data['except']).to eq(%w[thing3 thing4])
56
+ end
57
+ end
58
+
59
+ describe '#pause_before' do
60
+ it 'adds a pause time' do
61
+ provisioner.pause_before(10)
62
+ expect(provisioner.data['pause_before']).to eq("10")
63
+ provisioner.pause_before("10s")
64
+ expect(provisioner.data['pause_before']).to eq("10s")
65
+ end
66
+ end
67
+
68
+ describe '#override' do
69
+ it 'adds a hash overridef override values to a list of overrides' do
70
+ provisioner.override('build', overrides)
71
+ expect(provisioner.data['override']['build']).to eq(overrides)
72
+ end
73
+
74
+ it 'raises a TypeError when the overrides are not a hash' do
75
+ expect { provisioner.override('build', 10) }.to raise_error
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,63 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
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
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::Provisioner::File do
18
+ let(:provisioner) do
19
+ Packer::Provisioner.get_provisioner('file')
20
+ end
21
+
22
+ let(:some_string) do
23
+ 'some string'
24
+ end
25
+
26
+ let(:some_array_of_ints) do
27
+ [1, 2, 3]
28
+ end
29
+
30
+ describe '#initialize' do
31
+ it 'has a type of file' do
32
+ expect(provisioner.data['type']).to eq('file')
33
+ end
34
+ end
35
+
36
+ describe '#source' do
37
+ it 'accepts a string' do
38
+ provisioner.source(some_string)
39
+ expect(provisioner.data['source']).to eq(some_string)
40
+ provisioner.data.delete('source')
41
+ end
42
+
43
+ it 'converts any argument passed to a string' do
44
+ provisioner.source(some_array_of_ints)
45
+ expect(provisioner.data['source']).to eq(some_array_of_ints.to_s)
46
+ provisioner.data.delete('source')
47
+ end
48
+ end
49
+
50
+ describe '#destination' do
51
+ it 'accepts a string' do
52
+ provisioner.destination(some_string)
53
+ expect(provisioner.data['destination']).to eq(some_string)
54
+ provisioner.data.delete('destination')
55
+ end
56
+
57
+ it 'converts any argument passed to a string' do
58
+ provisioner.destination(some_array_of_ints)
59
+ expect(provisioner.data['destination']).to eq(some_array_of_ints.to_s)
60
+ provisioner.data.delete('destination')
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,116 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
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
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::Provisioner::Shell do
18
+ let(:provisioner) do
19
+ Packer::Provisioner.get_provisioner('shell')
20
+ end
21
+
22
+ let(:some_string) do
23
+ 'some string'
24
+ end
25
+
26
+ let(:some_array_of_strings) do
27
+ %w[commmand1 command2]
28
+ end
29
+
30
+ let(:some_array_of_ints) do
31
+ [1, 2, 3]
32
+ end
33
+
34
+ describe '#initialize' do
35
+ it 'has a type of shell' do
36
+ expect(provisioner.data['type']).to eq('shell')
37
+ end
38
+ end
39
+
40
+ describe '#inline' do
41
+ it 'accepts an array of commands' do
42
+ provisioner.inline(some_array_of_strings)
43
+ expect(provisioner.data['inline']).to eq(some_array_of_strings)
44
+ provisioner.data.delete('inline')
45
+ end
46
+
47
+ it 'converts all commands to strings' do
48
+ provisioner.inline(some_array_of_ints)
49
+ expect(provisioner.data['inline']).to eq(some_array_of_ints.map{ |c| c.to_s })
50
+ provisioner.data.delete('inline')
51
+ end
52
+
53
+ it 'raises an error if the commands argument cannot be made an Array' do
54
+ expect { provisioner.inline(some_string) }.to raise_error
55
+ end
56
+
57
+ it 'raises an error if #script or #scripts method was already called' do
58
+ provisioner.data['script'] = 1
59
+ expect { provisioner.inline(some_array_of_strings) }.to raise_error
60
+ provisioner.data.delete('script')
61
+ provisioner.data['scripts'] = 1
62
+ expect { provisioner.inline(some_array_of_strings) }.to raise_error
63
+ provisioner.data.delete('scripts')
64
+ end
65
+ end
66
+
67
+ describe '#script' do
68
+ it 'accepts a string' do
69
+ provisioner.script(some_string)
70
+ expect(provisioner.data['script']).to eq(some_string)
71
+ provisioner.data.delete('script')
72
+ end
73
+
74
+ it 'converts any argument passed to a string' do
75
+ provisioner.script(some_array_of_ints)
76
+ expect(provisioner.data['script']).to eq(some_array_of_ints.to_s)
77
+ provisioner.data.delete('script')
78
+ end
79
+
80
+ it 'raises an error if #inline or #scripts method was already called' do
81
+ provisioner.data['inline'] = 1
82
+ expect { provisioner.script(some_string) }.to raise_error
83
+ provisioner.data.delete('inline')
84
+ provisioner.data['scripts'] = 1
85
+ expect { provisioner.script(some_string) }.to raise_error
86
+ provisioner.data.delete('scripts')
87
+ end
88
+ end
89
+
90
+ describe '#scripts' do
91
+ it 'accepts an array of commands' do
92
+ provisioner.scripts(some_array_of_strings)
93
+ expect(provisioner.data['scripts']).to eq(some_array_of_strings)
94
+ provisioner.data.delete('scripts')
95
+ end
96
+
97
+ it 'converts all commands to strings' do
98
+ provisioner.scripts(some_array_of_ints)
99
+ expect(provisioner.data['scripts']).to eq(some_array_of_ints.map{ |c| c.to_s })
100
+ provisioner.data.delete('scripts')
101
+ end
102
+
103
+ it 'raises an error if the commands argument cannot be made an Array' do
104
+ expect { provisioner.scripts(some_string) }.to raise_error
105
+ end
106
+
107
+ it 'raises an error if #inline or #script method was already called' do
108
+ provisioner.data['script'] = 1
109
+ expect { provisioner.scripts(some_array_of_strings) }.to raise_error
110
+ provisioner.data.delete('scripts')
111
+ provisioner.data['inline'] = 1
112
+ expect { provisioner.scripts(some_array_of_strings) }.to raise_error
113
+ provisioner.data.delete('scripts')
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,197 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
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
+ require 'spec_helper'
16
+ require 'fakefs/spec_helpers'
17
+
18
+ RSpec.describe Packer::Config do
19
+ let(:config_file) { 'config.json'}
20
+ let(:packer) { Packer::Config.new(config_file) }
21
+ let(:builder_type) { Packer::Builder::VIRTUALBOX_ISO }
22
+ let(:provisioner_type) { Packer::Provisioner::FILE }
23
+ let(:postprocessor_type) { Packer::PostProcessor::VAGRANT }
24
+ let(:json_representation) do
25
+ '{"variables":{"foo":"bar"},"builders":[{"type":"virtualbox-iso"}],"provisioners":[{"type":"file"}],"post-processors":[{"type":"vagrant"}]}'
26
+ end
27
+
28
+ describe '#initialize' do
29
+ it 'returns an instance' do
30
+ expect(packer).to be_a_kind_of(Packer::Config)
31
+ end
32
+ end
33
+
34
+ describe "#validate" do
35
+ it 'returns true for a valid instance' do
36
+ expect(packer.builders).to receive(:length).and_return(1)
37
+ open3 = class_double("Open3").as_stubbed_const(:transfer_nested_constants => true)
38
+ expect(open3).to receive(:capture3).and_return(['output', 'error', 0])
39
+ FakeFS do
40
+ expect(packer.validate).to be_truthy
41
+ end
42
+ end
43
+
44
+ it 'raises an error for an invalid instance' do
45
+ expect(packer.builders).to receive(:length).and_return(0)
46
+ FakeFS do
47
+ expect { packer.validate }.to raise_error
48
+ end
49
+ end
50
+ end
51
+
52
+ describe '#dump' do
53
+ it 'dumps a JSON-formatted configuration' do
54
+ packer.add_builder builder_type
55
+ packer.add_provisioner provisioner_type
56
+ packer.add_postprocessor postprocessor_type
57
+ packer.add_variable 'foo', 'bar'
58
+ expect(packer.dump).to eq(json_representation)
59
+ end
60
+
61
+ it 'raises an error if the format is not recognized' do
62
+ expect { packer.dump 'invalid-format' }.to raise_error
63
+ end
64
+ end
65
+
66
+ describe '#write' do
67
+ it 'writes a JSON-formatted configuration file to disk' do
68
+ packer.add_builder builder_type
69
+ packer.add_provisioner provisioner_type
70
+ packer.add_postprocessor postprocessor_type
71
+ packer.add_variable 'foo', 'bar'
72
+ FakeFS do
73
+ packer.write
74
+ expect(File.read(config_file)).to eq(json_representation)
75
+ end
76
+ end
77
+
78
+ it 'raises an error if the format is not recognized' do
79
+ FakeFS do
80
+ expect { packer.dump 'invalid-format' }.to raise_error
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "#build" do
86
+ it 'returns successfully if the build command returns a successful exit code' do
87
+ expect(packer).to receive(:validate).and_return(true)
88
+ expect(packer).to receive(:write).and_return(true)
89
+ open3 = class_double("Open3").as_stubbed_const(:transfer_nested_constants => true)
90
+ expect(open3).to receive(:capture3).and_return(['output', 'error', 0])
91
+ FakeFS do
92
+ expect(packer.build).to be_truthy
93
+ end
94
+ end
95
+
96
+ it 'raises an error if the data is not valid' do
97
+ expect(packer).to receive(:validate).and_raise(Packer::DataObject::DataValidationError)
98
+ FakeFS do
99
+ expect { packer.build }.to raise_error
100
+ end
101
+ end
102
+
103
+ it 'raises an error if the config cannot be written to disk' do
104
+ expect(packer).to receive(:validate).and_return(true)
105
+ expect(packer).to receive(:write).and_raise(StandardError)
106
+ expect { packer.build }.to raise_error
107
+ end
108
+
109
+ it 'raises an error if the build command returns an unsuccessful exit code' do
110
+ expect(packer).to receive(:validate).and_return(true)
111
+ expect(packer).to receive(:write).and_return(true)
112
+ open3 = class_double("Open3").as_stubbed_const(:transfer_nested_constants => true)
113
+ expect(open3).to receive(:capture3).and_return(['output', 'error', 1])
114
+ FakeFS do
115
+ expect { packer.build }.to raise_error
116
+ end
117
+ end
118
+ end
119
+
120
+ describe "#add_builder" do
121
+ it 'returns a builder for a valid type' do
122
+ expect(packer.add_builder builder_type).to be_a_kind_of(Packer::Builder)
123
+ expect(packer.builders.length).to eq(1)
124
+ packer.builders = []
125
+ end
126
+
127
+ it 'raises an error for an invalid type' do
128
+ expect { packer.add_builder 'invalid' }.to raise_error
129
+ expect(packer.builders.length).to eq(0)
130
+ end
131
+ end
132
+
133
+ describe "#add_provisioner" do
134
+ it 'returns a provisioner for a valid type' do
135
+ expect(packer.add_provisioner provisioner_type).to be_a_kind_of(Packer::Provisioner)
136
+ expect(packer.provisioners.length).to eq(1)
137
+ packer.provisioners = []
138
+ end
139
+
140
+ it 'raises an error for an invalid type' do
141
+ expect { packer.add_provisioner 'invalid' }.to raise_error
142
+ expect(packer.provisioners.length).to eq(0)
143
+ end
144
+ end
145
+
146
+ describe "#add_postprocessor" do
147
+ it 'returns a post-processor for a valid type' do
148
+ expect(packer.add_postprocessor postprocessor_type).to be_a_kind_of(Packer::PostProcessor)
149
+ expect(packer.postprocessors.length).to eq(1)
150
+ packer.postprocessors = []
151
+ end
152
+
153
+ it 'raises an error for an invalid type' do
154
+ expect { packer.add_postprocessor 'invalid' }.to raise_error
155
+ expect(packer.postprocessors.length).to eq(0)
156
+ end
157
+ end
158
+
159
+ describe '#add_variable' do
160
+ it 'adds a new variable key/value pair' do
161
+ expect(packer.variables).to eq({})
162
+ packer.add_variable('key1', 'value1')
163
+ expect(packer.variables).to eq({'key1' => 'value1'})
164
+ packer.add_variable('key2', 'value2')
165
+ expect(packer.variables).to eq({'key1' => 'value1', 'key2' => 'value2'})
166
+ packer.data['variables'] = {}
167
+ end
168
+ end
169
+
170
+ describe '#variable' do
171
+ it 'creates a packer reference to a variable in the configuration' do
172
+ expect(packer.variables).to eq({})
173
+ packer.add_variable('key1', 'value1')
174
+ expect(packer.variable 'key1').to eq('{{user `key1`}}')
175
+ packer.data['variables'] = {}
176
+ end
177
+
178
+ it 'raises an error when the variable has not been defined in the configuration' do
179
+ expect(packer.variables).to eq({})
180
+ expect { packer.variable 'key1' }.to raise_error
181
+ packer.data['variables'] = {}
182
+ end
183
+ end
184
+
185
+ describe '#envvar' do
186
+ it 'creates a packer reference to an environment variable' do
187
+ expect(packer.envvar.TEST).to eq('{{env `TEST`}}')
188
+ end
189
+ end
190
+
191
+ describe '#macro' do
192
+ it 'creates a packer macro reference for any method call' do
193
+ expect(packer.macro.var).to eq('{{ .Var }}')
194
+ end
195
+ end
196
+
197
+ end