omnibus 3.1.1 → 3.2.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +71 -0
  3. data/Gemfile +0 -7
  4. data/README.md +108 -36
  5. data/Rakefile +1 -5
  6. data/docs/omnibus-build-cache.md +5 -5
  7. data/features/commands/_deprecated.feature +21 -3
  8. data/features/step_definitions/generator_steps.rb +7 -7
  9. data/lib/omnibus.rb +232 -171
  10. data/lib/omnibus/build_version.rb +2 -2
  11. data/lib/omnibus/builder.rb +38 -19
  12. data/lib/omnibus/cleaner.rb +5 -5
  13. data/lib/omnibus/cleanroom.rb +141 -0
  14. data/lib/omnibus/cli.rb +6 -9
  15. data/lib/omnibus/cli/base.rb +2 -1
  16. data/lib/omnibus/cli/cache.rb +15 -21
  17. data/lib/omnibus/cli/deprecated.rb +40 -4
  18. data/lib/omnibus/cli/publish.rb +61 -0
  19. data/lib/omnibus/config.rb +350 -189
  20. data/lib/omnibus/digestable.rb +131 -0
  21. data/lib/omnibus/exceptions.rb +163 -83
  22. data/lib/omnibus/fetcher.rb +1 -1
  23. data/lib/omnibus/fetchers/net_fetcher.rb +19 -13
  24. data/lib/omnibus/fetchers/path_fetcher.rb +8 -1
  25. data/lib/omnibus/fetchers/s3_cache_fetcher.rb +16 -7
  26. data/lib/omnibus/generator.rb +2 -2
  27. data/lib/omnibus/generator_files/Gemfile.erb +4 -1
  28. data/lib/omnibus/generator_files/README.md.erb +10 -0
  29. data/lib/omnibus/generator_files/{omnibus.rb.example.erb → omnibus.rb.erb} +20 -11
  30. data/lib/omnibus/generator_files/package_scripts/makeselfinst.erb +1 -1
  31. data/lib/omnibus/generator_files/project.rb.erb +2 -2
  32. data/lib/omnibus/generator_files/windows_msi/localization-en-us.wxl.erb +3 -3
  33. data/lib/omnibus/git_cache.rb +192 -0
  34. data/lib/omnibus/health_check.rb +171 -116
  35. data/lib/omnibus/library.rb +4 -2
  36. data/lib/omnibus/logger.rb +60 -1
  37. data/lib/omnibus/null_argumentable.rb +51 -0
  38. data/lib/omnibus/ohai.rb +29 -8
  39. data/lib/omnibus/package.rb +240 -0
  40. data/lib/omnibus/packagers/base.rb +21 -42
  41. data/lib/omnibus/packagers/mac_dmg.rb +5 -5
  42. data/lib/omnibus/packagers/mac_pkg.rb +20 -19
  43. data/lib/omnibus/packagers/windows_msi.rb +7 -7
  44. data/lib/omnibus/project.rb +969 -486
  45. data/lib/omnibus/publisher.rb +76 -0
  46. data/lib/omnibus/publishers/artifactory_publisher.rb +168 -0
  47. data/lib/omnibus/publishers/null_publisher.rb +23 -0
  48. data/lib/omnibus/publishers/s3_publisher.rb +99 -0
  49. data/lib/omnibus/s3_cache.rb +150 -63
  50. data/lib/omnibus/software.rb +749 -321
  51. data/lib/omnibus/{sugar.rb → sugarable.rb} +11 -6
  52. data/lib/omnibus/version.rb +1 -1
  53. data/omnibus.gemspec +8 -8
  54. data/spec/data/complicated/config/projects/angrychef.rb +1 -1
  55. data/spec/data/complicated/config/projects/chef-windows.rb +1 -1
  56. data/spec/data/complicated/config/projects/chef.rb +1 -1
  57. data/spec/data/complicated/config/projects/chefdk-windows.rb +1 -1
  58. data/spec/data/complicated/config/projects/chefdk.rb +1 -1
  59. data/spec/data/complicated/config/software/cacerts.rb +1 -1
  60. data/spec/data/complicated/config/software/chef-client-msi.rb +1 -1
  61. data/spec/data/complicated/config/software/libgcc.rb +1 -1
  62. data/spec/data/complicated/config/software/libiconv.rb +0 -11
  63. data/spec/data/complicated/config/software/libpng.rb +2 -2
  64. data/spec/data/complicated/config/software/openssl.rb +1 -1
  65. data/spec/data/complicated/config/software/ruby.rb +1 -1
  66. data/spec/data/complicated/config/software/runit.rb +4 -4
  67. data/spec/data/projects/chefdk.rb +1 -1
  68. data/spec/data/projects/sample.rb +1 -1
  69. data/spec/data/software/erchef.rb +3 -1
  70. data/spec/functional/packagers/mac_spec.rb +25 -24
  71. data/spec/functional/packagers/windows_spec.rb +21 -20
  72. data/spec/spec_helper.rb +43 -4
  73. data/spec/unit/build_version_spec.rb +14 -16
  74. data/spec/unit/cleanroom_spec.rb +63 -0
  75. data/spec/unit/config_spec.rb +36 -30
  76. data/spec/unit/digestable_spec.rb +38 -0
  77. data/spec/unit/fetchers/net_fetcher_spec.rb +98 -87
  78. data/spec/unit/{install_path_cache_spec.rb → git_cache_spec.rb} +67 -56
  79. data/spec/unit/health_check_spec.rb +73 -0
  80. data/spec/unit/library_spec.rb +166 -159
  81. data/spec/unit/ohai_spec.rb +19 -0
  82. data/spec/unit/omnibus_spec.rb +43 -41
  83. data/spec/unit/package_spec.rb +178 -0
  84. data/spec/unit/packagers/base_spec.rb +17 -47
  85. data/spec/unit/packagers/mac_pkg_spec.rb +104 -126
  86. data/spec/unit/project_spec.rb +176 -25
  87. data/spec/unit/publisher_spec.rb +49 -0
  88. data/spec/unit/publishers/artifactory_publisher_spec.rb +80 -0
  89. data/spec/unit/publishers/s3_publisher_spec.rb +120 -0
  90. data/spec/unit/s3_cacher_spec.rb +84 -19
  91. data/spec/unit/software_spec.rb +397 -170
  92. data/spec/unit/sugarable_spec.rb +43 -0
  93. metadata +62 -50
  94. data/Guardfile +0 -10
  95. data/lib/omnibus/artifact.rb +0 -165
  96. data/lib/omnibus/cli/release.rb +0 -40
  97. data/lib/omnibus/generator_files/Vagrantfile.erb +0 -75
  98. data/lib/omnibus/install_path_cache.rb +0 -105
  99. data/lib/omnibus/overrides.rb +0 -88
  100. data/lib/omnibus/package_release.rb +0 -154
  101. data/lib/omnibus/software_s3_urls.rb +0 -50
  102. data/spec/unit/artifact_spec.rb +0 -91
  103. data/spec/unit/overrides_spec.rb +0 -102
  104. data/spec/unit/package_release_spec.rb +0 -180
  105. data/spec/unit/sugar_spec.rb +0 -17
@@ -3,19 +3,45 @@ require 'ohai'
3
3
 
4
4
  module Omnibus
5
5
  describe Project do
6
- let(:project) do
7
- Omnibus::Project.load(project_path('sample'))
8
- end
6
+ let(:project) { Project.load(project_path('sample')) }
9
7
 
10
8
  subject { project }
11
9
 
10
+ it_behaves_like 'a cleanroom setter', :name, 'chef'
11
+ it_behaves_like 'a cleanroom setter', :friendly_name, 'Chef'
12
+ it_behaves_like 'a cleanroom setter', :msi_parameters, { foo: 'bar' }
13
+ it_behaves_like 'a cleanroom setter', :package_name, 'chef.package'
14
+ it_behaves_like 'a cleanroom setter', :install_dir, '/opt/chef'
15
+ it_behaves_like 'a cleanroom setter', :install_path, '/opt/chef'
16
+ it_behaves_like 'a cleanroom setter', :maintainer, 'Chef Software, Inc'
17
+ it_behaves_like 'a cleanroom setter', :homepage, 'https://getchef.com'
18
+ it_behaves_like 'a cleanroom setter', :description, 'Installs the thing'
19
+ it_behaves_like 'a cleanroom setter', :replaces, 'old-chef'
20
+ it_behaves_like 'a cleanroom setter', :conflict, 'puppet'
21
+ it_behaves_like 'a cleanroom setter', :build_version, '1.2.3'
22
+ it_behaves_like 'a cleanroom setter', :build_iteration, 1
23
+ it_behaves_like 'a cleanroom setter', :mac_pkg_identifier, 'com.getchef'
24
+ it_behaves_like 'a cleanroom setter', :package_user, 'chef'
25
+ it_behaves_like 'a cleanroom setter', :package_group, 'chef'
26
+ it_behaves_like 'a cleanroom setter', :override, 'foo'
27
+ it_behaves_like 'a cleanroom setter', :resources_path, '/path'
28
+ it_behaves_like 'a cleanroom setter', :package_scripts_path, '/path/scripts'
29
+ it_behaves_like 'a cleanroom setter', :dependency, 'libxslt-dev'
30
+ it_behaves_like 'a cleanroom setter', :runtime_dependency, 'libxslt'
31
+ it_behaves_like 'a cleanroom setter', :exclude, 'hamlet'
32
+ it_behaves_like 'a cleanroom setter', :config_file, '/path/to/config.rb'
33
+ it_behaves_like 'a cleanroom setter', :extra_package_file, '/path/to/asset'
34
+ it_behaves_like 'a cleanroom setter', :dependencies, 'a', 'b', 'c'
35
+
36
+ it_behaves_like 'a cleanroom getter', :files_path
37
+
12
38
  describe 'basics' do
13
39
  it 'should return a name' do
14
40
  expect(project.name).to eq('sample')
15
41
  end
16
42
 
17
- it 'should return an install path' do
18
- expect(project.install_path).to eq('/sample')
43
+ it 'should return an install_dir' do
44
+ expect(project.install_dir).to eq('/sample')
19
45
  end
20
46
 
21
47
  it 'should return a maintainer' do
@@ -47,11 +73,36 @@ module Omnibus
47
73
  end
48
74
  end
49
75
 
76
+ describe '#dirty!' do
77
+ it 'dirties the cache' do
78
+ subject.instance_variable_set(:@dirty, nil)
79
+ subject.dirty!
80
+ expect(subject).to be_dirty
81
+ end
82
+ end
83
+
84
+ describe '#dirty?' do
85
+ it 'returns true by default' do
86
+ subject.instance_variable_set(:@dirty, nil)
87
+ expect(subject).to_not be_dirty
88
+ end
89
+
90
+ it 'returns true when the cache is dirty' do
91
+ subject.instance_variable_set(:@dirty, true)
92
+ expect(subject).to be_dirty
93
+ end
94
+
95
+ it 'returns false when the cache is not dirty' do
96
+ subject.instance_variable_set(:@dirty, false)
97
+ expect(subject).to_not be_dirty
98
+ end
99
+ end
100
+
50
101
  describe '#<=>' do
51
102
  it 'compares projects by name' do
52
103
  list = [
53
104
  project,
54
- Omnibus::Project.load(project_path('chefdk')),
105
+ Project.load(project_path('chefdk')),
55
106
  ]
56
107
  expect(list.sort.map(&:name)).to eq(%w(chefdk sample))
57
108
  end
@@ -60,9 +111,7 @@ module Omnibus
60
111
  describe '#iteration' do
61
112
  let(:fauxhai_options) { Hash.new }
62
113
 
63
- before do
64
- stub_ohai(Fauxhai.mock(fauxhai_options).data)
65
- end
114
+ before { stub_ohai(fauxhai_options) }
66
115
 
67
116
  context 'when on RHEL' do
68
117
  let(:fauxhai_options) { { platform: 'redhat', version: '6.4' } }
@@ -102,35 +151,137 @@ module Omnibus
102
151
  end
103
152
 
104
153
  describe '#overrides' do
105
- let(:project) { Omnibus::Project.load(project_path('chefdk')) }
154
+ let(:project) { Project.load(project_path('chefdk')) }
106
155
 
107
- it 'should set an override for the zlib version' do
108
- expect(project.overrides[:zlib][:version]).to eq('1.2.8')
109
- end
156
+ before { project.overrides.clear }
110
157
 
111
- it 'should access the zlib version through the #override method as well' do
112
- expect(project.override(:zlib)[:version]).to eq('1.2.8')
113
- end
114
158
 
115
159
  it 'should set all the things through #overrides' do
116
- project.overrides(thing: { version: '6.6.6' })
160
+ project.override(:thing, version: '6.6.6')
117
161
  expect(project.override(:zlib)).to be_nil
118
162
  end
119
163
 
120
- it 'should retrieve the things set through #overrides' do
121
- project.overrides(thing: { version: '6.6.6' })
164
+ it 'retrieves the things set through #overrides' do
165
+ project.override(:thing, version: '6.6.6')
122
166
  expect(project.override(:thing)[:version]).to eq('6.6.6')
123
167
  end
168
+ end
124
169
 
125
- it 'should not set other things through setting a single #override' do
126
- project.override(:thing, version: '6.6.6')
127
- expect(project.override(:zlib)[:version]).to eq('1.2.8')
170
+ describe '#platform_version_for_package' do
171
+ before { described_class.send(:public, :platform_version_for_package) }
172
+
173
+ shared_examples 'a version manipulator' do |platform, version, family, expected|
174
+ context "on #{platform}-#{version} (#{family})" do
175
+ before do
176
+ allow(Ohai).to receive(:ohai).and_return(
177
+ 'platform' => platform,
178
+ 'platform_version' => version,
179
+ 'platform_family' => family,
180
+ )
181
+ end
182
+
183
+ it 'returns the correct value' do
184
+ expect(subject.platform_version_for_package).to eq(expected)
185
+ end
186
+ end
128
187
  end
129
188
 
130
- it 'should retrieve the things set through #overrides' do
131
- project.override(:thing, version: '6.6.6')
132
- expect(project.override(:thing)[:version]).to eq('6.6.6')
189
+ it_behaves_like 'a version manipulator', 'arch', '2009.02', 'arch', '2009.02'
190
+ it_behaves_like 'a version manipulator', 'arch', '2014.06.01', 'arch', '2014.06'
191
+ it_behaves_like 'a version manipulator', 'debian', '7.1', 'debian', '7'
192
+ it_behaves_like 'a version manipulator', 'debian', '6.9', 'debian', '6'
193
+ it_behaves_like 'a version manipulator', 'ubuntu', '10.04', 'debian', '10.04'
194
+ it_behaves_like 'a version manipulator', 'ubuntu', '10.04.04', 'debian', '10.04'
195
+ it_behaves_like 'a version manipulator', 'fedora', '11.5', 'fedora', '11'
196
+ it_behaves_like 'a version manipulator', 'freebsd', '10.0', 'fedora', '10'
197
+ it_behaves_like 'a version manipulator', 'rhel', '6.5', 'rhel', '6'
198
+ it_behaves_like 'a version manipulator', 'centos', '5.9.6', 'rhel', '5'
199
+ it_behaves_like 'a version manipulator', 'aix', '7.1', 'aix', '7.1'
200
+ it_behaves_like 'a version manipulator', 'gentoo', '2004.3', 'aix', '2004.3'
201
+ it_behaves_like 'a version manipulator', 'mac_os_x', '10.9.1', 'mac_os_x', '10.9'
202
+ it_behaves_like 'a version manipulator', 'openbsd', '5.4.4', 'openbsd', '5.4'
203
+ it_behaves_like 'a version manipulator', 'slackware', '12.0.1', 'slackware', '12.0'
204
+ it_behaves_like 'a version manipulator', 'solaris', '5.9', 'solaris2', '5.9'
205
+ it_behaves_like 'a version manipulator', 'suse', '5.9', 'suse', '5.9'
206
+ it_behaves_like 'a version manipulator', 'omnios', 'r151010', 'omnios', 'r151010'
207
+ it_behaves_like 'a version manipulator', 'smartos', '20120809T221258Z', 'smartos', '20120809T221258Z'
208
+ it_behaves_like 'a version manipulator', 'windows', '6.1.7600', 'windows', '7'
209
+ it_behaves_like 'a version manipulator', 'windows', '6.1.7601', 'windows', '2008r2'
210
+ it_behaves_like 'a version manipulator', 'windows', '6.2.9200', 'windows', '8'
211
+ it_behaves_like 'a version manipulator', 'windows', '6.3.9200', 'windows', '8.1'
212
+
213
+ context 'given an unknown platform' do
214
+ before do
215
+ allow(Ohai).to receive(:ohai).and_return(
216
+ 'platform' => 'bacon',
217
+ 'platform_version' => '1.crispy',
218
+ 'platform_family' => 'meats',
219
+ )
220
+ end
221
+
222
+ it 'raises an exception' do
223
+ expect { subject.platform_version_for_package }
224
+ .to raise_error(UnknownPlatformFamily)
225
+ end
226
+ end
227
+
228
+ context 'given an unknown windows platform version' do
229
+ before do
230
+ allow(Ohai).to receive(:ohai).and_return(
231
+ 'platform' => 'windows',
232
+ 'platform_version' => '1.2.3',
233
+ 'platform_family' => 'windows',
234
+ )
235
+ end
236
+
237
+ it 'raises an exception' do
238
+ expect { subject.platform_version_for_package }
239
+ .to raise_error(UnknownPlatformVersion)
240
+ end
241
+ end
242
+ end
243
+
244
+ describe '#shasum' do
245
+ context 'when a filepath is given' do
246
+ let(:path) { '/project.rb' }
247
+ let(:file) { double(File) }
248
+
249
+ subject do
250
+ project = described_class.new(path)
251
+ project.name('project')
252
+ project.install_dir('/opt/project')
253
+ project.build_version('1.0.0')
254
+ project
255
+ end
256
+
257
+ before do
258
+ allow(File).to receive(:exist?)
259
+ .with(path)
260
+ .and_return(true)
261
+ allow(File).to receive(:open)
262
+ .with(path)
263
+ .and_return(file)
264
+ end
265
+
266
+ it 'returns the correct shasum' do
267
+ expect(subject.shasum).to eq('8270d9078b577d3bedc2353ba3dc33fda1f8e69db3b7c0b449183a3e0e560d09')
268
+ end
269
+ end
270
+
271
+ context 'when a filepath is not given' do
272
+ subject do
273
+ project = described_class.new
274
+ project.name('project')
275
+ project.install_dir('/opt/project')
276
+ project.build_version('1.0.0')
277
+ project
278
+ end
279
+
280
+ it 'returns the correct shasum' do
281
+ expect(subject.shasum).to eq('545571a6041129f1224741a700c776b960cb093d4260ff6ca78b6a34bc130b45')
282
+ end
133
283
  end
134
284
  end
285
+
135
286
  end
136
287
  end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ module Omnibus
4
+ # Used in the tests
5
+ class FakePublisher; end
6
+
7
+ describe Publisher do
8
+ it { should be_a_kind_of(Logging) }
9
+
10
+ describe '.publish' do
11
+ let(:publisher) { double(described_class) }
12
+
13
+ before { described_class.stub(:new).and_return(publisher) }
14
+
15
+ it 'creates a new instance of the class' do
16
+ expect(described_class).to receive(:new).once
17
+ expect(publisher).to receive(:publish).once
18
+ described_class.publish('/path/to/*.deb')
19
+ end
20
+ end
21
+
22
+ let(:pattern) { '/path/to/files/*.deb' }
23
+ let(:options) { { some_option: true } }
24
+
25
+ subject { described_class.new(pattern, options) }
26
+
27
+ describe '#packages' do
28
+ let(:a) { '/path/to/files/a.deb' }
29
+ let(:b) { '/path/to/files/b.deb' }
30
+ let(:glob) { [a, b] }
31
+
32
+ before { Dir.stub(:glob).with(pattern).and_return(glob) }
33
+
34
+ it 'returns an array' do
35
+ expect(subject.packages).to be_an(Array)
36
+ end
37
+
38
+ it 'returns an array of Package objects' do
39
+ expect(subject.packages.first).to be_a(Package)
40
+ end
41
+ end
42
+
43
+ describe '#publish' do
44
+ it 'is an abstract method' do
45
+ expect { subject.publish }.to raise_error(AbstractMethod)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ module Omnibus
4
+ describe ArtifactoryPublisher do
5
+ let(:path) { '/path/to/files/*.deb' }
6
+
7
+ let(:repository) { 'REPO' }
8
+
9
+ let(:package) do
10
+ double(Package,
11
+ path: '/path/to/files/chef.deb',
12
+ name: 'chef.deb',
13
+ content: 'BINARY',
14
+ validate!: true,
15
+ )
16
+ end
17
+
18
+ let(:metadata) do
19
+ Package::Metadata.new(package,
20
+ name: 'chef',
21
+ friendly_name: 'Chef',
22
+ homepage: 'https://getchef.com',
23
+ version: '11.0.6',
24
+ basename: 'chef.deb',
25
+ platform: 'ubuntu',
26
+ platform_version: '14.04',
27
+ arch: 'x86_64',
28
+ sha1: 'SHA1',
29
+ md5: 'ABCDEF123456',
30
+ )
31
+ end
32
+
33
+ let(:packages) { [package] }
34
+ let(:client) { double('Artifactory::Client') }
35
+ let(:artifact) { double('Artifactory::Resource::Artifact', upload: nil) }
36
+
37
+ before do
38
+ subject.stub(:client).and_return(client)
39
+ subject.stub(:artifact_for).and_return(artifact)
40
+ package.stub(:metadata).and_return(metadata)
41
+ end
42
+
43
+ subject { described_class.new(path, repository: repository) }
44
+
45
+ describe '#publish' do
46
+ before { subject.stub(:packages).and_return(packages) }
47
+
48
+ it 'validates the package' do
49
+ expect(package).to receive(:validate!).once
50
+ subject.publish
51
+ end
52
+
53
+ it 'uploads the package' do
54
+ expect(artifact).to receive(:upload).with(
55
+ repository,
56
+ 'com/getchef/chef/11.0.6/chef.deb',
57
+ an_instance_of(Hash)
58
+ ).once
59
+
60
+ subject.publish
61
+ end
62
+
63
+ context 'when the metadata is from an older version of Omnibus' do
64
+ before { package.metadata.stub(:[]).with(:homepage).and_return(nil) }
65
+
66
+ it 'raises an exception' do
67
+ expect { subject.publish }.to raise_error(OldMetadata)
68
+ end
69
+ end
70
+
71
+ context 'when a block is given' do
72
+ it 'yields the package to the block' do
73
+ block = ->(package) { package.do_something! }
74
+ expect(package).to receive(:do_something!).once
75
+ subject.publish(&block)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+
3
+ module Omnibus
4
+ describe S3Publisher do
5
+ let(:path) { '/path/to/files/*.deb' }
6
+
7
+ let(:package) do
8
+ double(Package,
9
+ path: '/path/to/files/chef.deb',
10
+ name: 'chef.deb',
11
+ content: 'BINARY',
12
+ validate!: true,
13
+ )
14
+ end
15
+
16
+ let(:metadata) do
17
+ Package::Metadata.new(package,
18
+ name: 'chef',
19
+ friendly_name: 'Chef',
20
+ homepage: 'https://getchef.com',
21
+ version: '11.0.6',
22
+ basename: 'chef.deb',
23
+ platform: 'ubuntu',
24
+ platform_version: '14.04',
25
+ arch: 'x86_64',
26
+ sha1: 'SHA1',
27
+ md5: 'ABCDEF123456',
28
+ )
29
+ end
30
+
31
+ let(:packages) { [package] }
32
+
33
+ let(:client) { double('UberS3', store: nil) }
34
+
35
+ before do
36
+ package.stub(:metadata).and_return(metadata)
37
+ subject.stub(:client).and_return(client)
38
+ end
39
+
40
+ subject { described_class.new(path) }
41
+
42
+ describe '#initialize' do
43
+ it 'raises an exception when publish_s3_access_key is missing' do
44
+ expect { Config.publish_s3_access_key }
45
+ .to raise_error(MissingConfigOption)
46
+ end
47
+
48
+ it 'raises an exception when release_s3_secret_key is missing' do
49
+ expect { Config.publish_s3_secret_key }
50
+ .to raise_error(MissingConfigOption)
51
+ end
52
+ end
53
+
54
+ describe '#publish' do
55
+ before { subject.stub(:packages).and_return(packages) }
56
+
57
+ it 'validates the package' do
58
+ expect(package).to receive(:validate!).once
59
+ subject.publish
60
+ end
61
+
62
+ it 'uploads the metadata' do
63
+ expect(client).to receive(:store).with(
64
+ 'ubuntu/14.04/x86_64/chef.deb/chef.deb.metadata.json',
65
+ package.metadata.to_json,
66
+ access: :private,
67
+ ).once
68
+
69
+ subject.publish
70
+ end
71
+
72
+ it 'uploads the package' do
73
+ expect(client).to receive(:store).with(
74
+ 'ubuntu/14.04/x86_64/chef.deb/chef.deb',
75
+ package.content,
76
+ access: :private,
77
+ content_md5: package.metadata[:md5],
78
+ ).once
79
+
80
+ subject.publish
81
+ end
82
+
83
+ context 'when the upload is set to public' do
84
+ subject { described_class.new(path, acl: 'public') }
85
+
86
+ it 'sets the access control to public_read' do
87
+ expect(client).to receive(:store).with(
88
+ 'ubuntu/14.04/x86_64/chef.deb/chef.deb.metadata.json',
89
+ package.metadata.to_json,
90
+ access: :public_read,
91
+ ).once
92
+
93
+ subject.publish
94
+ end
95
+ end
96
+
97
+ context 'when the upload is set to a nonsensical value' do
98
+ subject { described_class.new(path, acl: 'baconbits') }
99
+
100
+ it 'sets the access control to private' do
101
+ expect(client).to receive(:store).with(
102
+ 'ubuntu/14.04/x86_64/chef.deb/chef.deb.metadata.json',
103
+ package.metadata.to_json,
104
+ access: :private,
105
+ ).once
106
+
107
+ subject.publish
108
+ end
109
+ end
110
+
111
+ context 'when a block is given' do
112
+ it 'yields the package to the block' do
113
+ block = ->(package) { package.do_something! }
114
+ expect(package).to receive(:do_something!).once
115
+ subject.publish(&block)
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end