omnibus 4.1.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +22 -0
  4. data/MAINTAINERS.md +2 -1
  5. data/README.md +1 -1
  6. data/lib/omnibus/builder.rb +2 -17
  7. data/lib/omnibus/cli/publish.rb +4 -0
  8. data/lib/omnibus/exceptions.rb +12 -0
  9. data/lib/omnibus/fetchers/net_fetcher.rb +4 -0
  10. data/lib/omnibus/manifest.rb +1 -1
  11. data/lib/omnibus/metadata.rb +13 -4
  12. data/lib/omnibus/packager.rb +1 -0
  13. data/lib/omnibus/packagers/base.rb +1 -0
  14. data/lib/omnibus/packagers/bff.rb +1 -1
  15. data/lib/omnibus/packagers/deb.rb +4 -0
  16. data/lib/omnibus/packagers/msi.rb +168 -55
  17. data/lib/omnibus/packagers/rpm.rb +41 -29
  18. data/lib/omnibus/packagers/solaris.rb +76 -25
  19. data/lib/omnibus/publisher.rb +4 -0
  20. data/lib/omnibus/publishers/artifactory_publisher.rb +19 -8
  21. data/lib/omnibus/sugarable.rb +5 -0
  22. data/lib/omnibus/version.rb +1 -1
  23. data/omnibus.gemspec +1 -1
  24. data/resources/msi/CustomActionFastMsi.CA.dll +0 -0
  25. data/resources/msi/localization-en-us.wxl.erb +4 -0
  26. data/resources/msi/source.wxs.erb +46 -9
  27. data/resources/rpm/spec.erb +0 -1
  28. data/spec/functional/builder_spec.rb +109 -113
  29. data/spec/functional/fetchers/net_fetcher_spec.rb +10 -0
  30. data/spec/unit/metadata_spec.rb +39 -4
  31. data/spec/unit/packagers/bff_spec.rb +9 -0
  32. data/spec/unit/packagers/deb_spec.rb +17 -5
  33. data/spec/unit/packagers/msi_spec.rb +175 -3
  34. data/spec/unit/packagers/rpm_spec.rb +50 -3
  35. data/spec/unit/packagers/solaris_spec.rb +234 -0
  36. data/spec/unit/publisher_spec.rb +14 -0
  37. data/spec/unit/publishers/artifactory_publisher_spec.rb +72 -3
  38. data/spec/unit/sugarable_spec.rb +16 -0
  39. metadata +7 -4
@@ -137,6 +137,16 @@ module Omnibus
137
137
  end
138
138
  end
139
139
 
140
+ context 'source with no checksum' do
141
+ let(:source) do
142
+ { url: source_url }
143
+ end
144
+
145
+ it 'raises an exception' do
146
+ expect { fetch! }.to raise_error(ChecksumMissing)
147
+ end
148
+ end
149
+
140
150
  context 'source with sha1' do
141
151
  let(:source) do
142
152
  { url: source_url, sha1: source_sha1 }
@@ -22,18 +22,51 @@ module Omnibus
22
22
  subject { described_class.new(package, data) }
23
23
 
24
24
  describe '.arch' do
25
- it 'returns the architecture' do
25
+ let(:architecture) { 'x86_64' }
26
+
27
+ before do
26
28
  stub_ohai(platform: 'ubuntu', version: '12.04') do |data|
27
- data['kernel']['machine'] = 'x86_64'
29
+ data['kernel']['machine'] = architecture
28
30
  end
31
+ end
32
+
33
+ it 'returns the architecture' do
29
34
  expect(described_class.arch).to eq('x86_64')
30
35
  end
31
36
 
37
+ context 'on solaris' do
38
+ before do
39
+ stub_ohai(platform: 'solaris2', version: '5.11') do |data|
40
+ data['platform'] = 'solaris2'
41
+ data['kernel']['machine'] = architecture
42
+ end
43
+ end
44
+
45
+ context 'architecture is Intel-based' do
46
+ let(:architecture) { 'i86pc' }
47
+
48
+ it 'returns i386' do
49
+ expect(described_class.arch).to eq('i386')
50
+ end
51
+ end
52
+
53
+ context 'architecture is SPARC-based' do
54
+ let(:architecture) { 'sun4v' }
55
+
56
+ it 'returns sparc' do
57
+ expect(described_class.arch).to eq('sparc')
58
+ end
59
+ end
60
+ end
61
+
32
62
  context 'on windows' do
33
- it 'returns a 32-bit value based on Config.windows_arch being set to x86' do
63
+ before do
34
64
  stub_ohai(platform: 'windows', version: '2012R2') do |data|
35
- data['kernel']['machine'] = 'x86_64'
65
+ data['kernel']['machine'] = architecture
36
66
  end
67
+ end
68
+
69
+ it 'returns a 32-bit value based on Config.windows_arch being set to x86' do
37
70
  expect(Config).to receive(:windows_arch).and_return(:x86)
38
71
  expect(described_class.arch).to eq('i386')
39
72
  end
@@ -80,7 +113,9 @@ module Omnibus
80
113
  it_behaves_like 'a version manipulator', 'fedora', '11.5', '11'
81
114
  it_behaves_like 'a version manipulator', 'freebsd', '10.0', '10'
82
115
  it_behaves_like 'a version manipulator', 'gentoo', '2004.3', '2004.3'
116
+ it_behaves_like 'a version manipulator', 'ios_xr', '6.0.0.14I', '6'
83
117
  it_behaves_like 'a version manipulator', 'mac_os_x', '10.9.1', '10.9'
118
+ it_behaves_like 'a version manipulator', 'nexus', '5.0', '5'
84
119
  it_behaves_like 'a version manipulator', 'omnios', 'r151010', 'r151010'
85
120
  it_behaves_like 'a version manipulator', 'openbsd', '5.4.4', '5.4'
86
121
  it_behaves_like 'a version manipulator', 'opensuse', '5.9', '5.9'
@@ -163,6 +163,15 @@ module Omnibus
163
163
  allow(Dir).to receive(:chdir) { |_, &b| b.call }
164
164
  end
165
165
 
166
+ it 'chowns the directory' do
167
+ # A note - the /opt/ here is essentially project.install_dir one level up.
168
+ # There is nothing magical about 'opt' as a directory.
169
+ expect(subject).to receive(:shellout!)
170
+ .with(/chown -R 0:0 #{staging_dir}\/opt$/)
171
+ subject.create_bff_file
172
+ end
173
+
174
+
166
175
  it 'logs a message' do
167
176
  output = capture_logging { subject.create_bff_file }
168
177
  expect(output).to include('Creating .bff file')
@@ -209,9 +209,9 @@ module Omnibus
209
209
  subject.write_md5_sums
210
210
  contents = File.read("#{staging_dir}/DEBIAN/md5sums")
211
211
 
212
- expect(contents).to include("9334770d184092f998009806af702c8c .filea")
213
- expect(contents).to include("826e8142e6baabe8af779f5f490cf5f5 file1")
214
- expect(contents).to include("1c1c96fd2cf8330db0bfa936ce82f3b9 file2")
212
+ expect(contents).to include("9334770d184092f998009806af702c8c .filea")
213
+ expect(contents).to include("826e8142e6baabe8af779f5f490cf5f5 file1")
214
+ expect(contents).to include("1c1c96fd2cf8330db0bfa936ce82f3b9 file2")
215
215
  end
216
216
  end
217
217
 
@@ -243,8 +243,8 @@ module Omnibus
243
243
  before do
244
244
  project.install_dir(staging_dir)
245
245
 
246
- create_file("#{staging_dir}/file1") { "1"*10_000 }
247
- create_file("#{staging_dir}/file2") { "2"*20_000 }
246
+ create_file("#{staging_dir}/file1") { "1" * 10_000 }
247
+ create_file("#{staging_dir}/file2") { "2" * 20_000 }
248
248
  end
249
249
 
250
250
  it 'stats all the files in the install_dir' do
@@ -390,6 +390,18 @@ module Omnibus
390
390
  end
391
391
  end
392
392
  end
393
+
394
+ context '64bit ARM platform' do
395
+ before do
396
+ stub_ohai(platform: 'ubuntu', version: '14.04') do |data|
397
+ data['kernel']['machine'] = 'aarch64'
398
+ end
399
+ end
400
+
401
+ it 'returns arm64' do
402
+ expect(subject.safe_architecture).to eq('arm64')
403
+ end
404
+ end
393
405
  end
394
406
  end
395
407
  end
@@ -6,7 +6,7 @@ module Omnibus
6
6
  Project.new.tap do |project|
7
7
  project.name('project')
8
8
  project.homepage('https://example.com')
9
- project.install_dir('C:/project')
9
+ project.install_dir(install_dir)
10
10
  project.build_version('1.2.3')
11
11
  project.build_iteration('2')
12
12
  project.maintainer('Chef Software <maintainers@chef.io>')
@@ -18,6 +18,7 @@ module Omnibus
18
18
  let(:project_root) { File.join(tmp_path, 'project/root') }
19
19
  let(:package_dir) { File.join(tmp_path, 'package/dir') }
20
20
  let(:staging_dir) { File.join(tmp_path, 'staging/dir') }
21
+ let(:install_dir) { 'C:/project' }
21
22
 
22
23
  before do
23
24
  Config.project_root(project_root)
@@ -179,6 +180,26 @@ module Omnibus
179
180
  expect(contents).to include('<?include "parameters.wxi" ?>')
180
181
  expect(contents).to include('<Property Id="WIXUI_INSTALLDIR" Value="WINDOWSVOLUME" />')
181
182
  end
183
+
184
+ context 'when fastmsi is not specified' do
185
+ it 'does not include a reference to the fast msi custom action' do
186
+ subject.write_source_file
187
+ contents = File.read("#{staging_dir}/source.wxs")
188
+ expect(contents).not_to include("<Binary Id=\"CustomActionFastMsiDLL\"")
189
+ end
190
+ end
191
+
192
+ context 'when fastmsi is specified' do
193
+ before do
194
+ subject.fast_msi(true)
195
+ end
196
+
197
+ it 'includes a reference to the fast msi custom action' do
198
+ subject.write_source_file
199
+ contents = File.read("#{staging_dir}/source.wxs")
200
+ expect(contents).to include("<Binary Id=\"CustomActionFastMsiDLL\"")
201
+ end
202
+ end
182
203
  end
183
204
 
184
205
  describe '#write_bundle_file' do
@@ -298,7 +319,7 @@ module Omnibus
298
319
  end
299
320
  end
300
321
 
301
- describe "#bundle_msi" do
322
+ describe '#bundle_msi' do
302
323
  it 'is a DSL method' do
303
324
  expect(subject).to have_exposed_method(:bundle_msi)
304
325
  end
@@ -315,6 +336,157 @@ module Omnibus
315
336
  end
316
337
  end
317
338
 
339
+ describe '#fast_msi' do
340
+ it 'is a DSL method' do
341
+ expect(subject).to have_exposed_method(:fast_msi)
342
+ end
343
+
344
+ it 'requires the value to be a TrueClass or a FalseClass' do
345
+ expect {
346
+ subject.fast_msi(Object.new)
347
+ }.to raise_error(InvalidValue)
348
+ end
349
+
350
+ it 'returns the given value' do
351
+ subject.fast_msi(true)
352
+ expect(subject.fast_msi).to be_truthy
353
+ end
354
+ end
355
+
356
+ describe '#zip_command' do
357
+ it 'returns a String' do
358
+ expect(subject.zip_command).to be_a(String)
359
+ end
360
+
361
+ it 'sets zip file location to the staging directory' do
362
+ expect(subject.zip_command).to include("#{subject.windows_safe_path(staging_dir)}\\#{project.name}.zip")
363
+ end
364
+ end
365
+
366
+ describe '#candle_command' do
367
+ it 'returns a String' do
368
+ expect(subject.candle_command).to be_a(String)
369
+ end
370
+
371
+ context 'default behavior' do
372
+ it 'defines the ProjectSourceDir property' do
373
+ expect(subject.candle_command).to include("-dProjectSourceDir=")
374
+ end
375
+
376
+ it 'outputs a source.wxs file to the staging directory' do
377
+ expect(subject.candle_command).to include("#{subject.windows_safe_path(staging_dir, 'source.wxs')}")
378
+ end
379
+ end
380
+
381
+ context 'when is_bundle is true' do
382
+ it 'uses the WIX Bootstrapper/Burn extension' do
383
+ expect(subject.candle_command(is_bundle: true)).to include("-ext WixBalExtension")
384
+ end
385
+
386
+ it 'defines the OmnibusCacheDir property' do
387
+ expect(subject.candle_command(is_bundle: true)).to include("-dOmnibusCacheDir=")
388
+ end
389
+
390
+ it 'outputs a bundle.wxs file to the staging directory' do
391
+ expect(subject.candle_command(is_bundle: true)).to include("#{subject.windows_safe_path(staging_dir, 'bundle.wxs')}")
392
+ end
393
+ end
394
+ end
395
+
396
+ describe '#heat_command' do
397
+ it 'returns a String' do
398
+ expect(subject.heat_command).to be_a(String)
399
+ end
400
+
401
+ context 'when fast_msi is not set' do
402
+ it 'operates in directory mode' do
403
+ expect(subject.heat_command).to include("dir \"#{subject.windows_safe_path(project.install_dir)}\"")
404
+ end
405
+
406
+ it 'sets destination to the project location' do
407
+ expect(subject.heat_command).to include("-dr PROJECTLOCATION")
408
+ end
409
+ end
410
+
411
+ context 'when fast_msi is set' do
412
+ before do
413
+ subject.fast_msi(true)
414
+ end
415
+
416
+ it 'operates in file mode' do
417
+ expect(subject.heat_command).to include("file \"#{project.name}.zip\"")
418
+ end
419
+
420
+ it 'sets destination to the install location' do
421
+ expect(subject.heat_command).to include("-dr INSTALLLOCATION")
422
+ end
423
+ end
424
+ end
425
+
426
+ describe '#light_command' do
427
+ it 'returns a String' do
428
+ expect(subject.light_command("foo")).to be_a(String)
429
+ end
430
+
431
+ context 'default behavior' do
432
+ let (:command) { subject.light_command("foo") }
433
+
434
+ it 'uses the WIX UI extension' do
435
+ expect(command).to include("-ext WixUIExtension")
436
+ end
437
+
438
+ it 'includes the project-files and source wixobj files' do
439
+ expect(command).to include("project-files.wixobj source.wixobj")
440
+ end
441
+ end
442
+
443
+ context 'when is_bundle is true' do
444
+ let (:command) { subject.light_command("foo", is_bundle: true) }
445
+
446
+ it 'uses the WIX Bootstrapper/Burn extension' do
447
+ expect(command).to include("-ext WixBalExtension")
448
+ end
449
+
450
+ it 'includes the bundle wixobj file' do
451
+ expect(command).to include("bundle.wixobj")
452
+ end
453
+ end
454
+ end
455
+
456
+ describe '#gem_path' do
457
+ let(:install_dir) { File.join(tmp_path, 'install_dir') }
458
+
459
+ before do
460
+ create_directory(install_dir)
461
+ end
462
+
463
+ after do
464
+ remove_directory(install_dir)
465
+ end
466
+
467
+ it 'is a DSL method' do
468
+ expect(subject).to have_exposed_method(:gem_path)
469
+ end
470
+
471
+ it 'requires the value to be a String' do
472
+ expect {
473
+ subject.gem_path(Object.new)
474
+ }.to raise_error(InvalidValue)
475
+ end
476
+
477
+ it 'globs for gems under the install directory' do
478
+ expected_gem_path = 'something/gems/athing-1.0.0'
479
+ create_directory(File.join(install_dir, expected_gem_path))
480
+ expect(subject.gem_path('athing-*')).to eq(expected_gem_path)
481
+ end
482
+
483
+ it 'returns the gem directory when no argument is given' do
484
+ expected_gem_path = 'foo/bar123/gems'
485
+ create_directory(File.join(install_dir, expected_gem_path))
486
+ expect(subject.gem_path).to eq(expected_gem_path)
487
+ end
488
+ end
489
+
318
490
  context 'when signing parameters are provided' do
319
491
  let(:msi) { 'somemsi.msi' }
320
492
 
@@ -343,7 +515,7 @@ module Omnibus
343
515
  subject.sign_package(msi)
344
516
  end
345
517
 
346
- describe "#timestamp_servers" do
518
+ describe '#timestamp_servers' do
347
519
  it "defaults to using ['http://timestamp.digicert.com','http://timestamp.verisign.com/scripts/timestamp.dll']" do
348
520
  subject.signing_identity('foo')
349
521
  expect(subject).to receive(:try_timestamp).with(msi, 'http://timestamp.digicert.com').and_return(false)
@@ -19,6 +19,7 @@ module Omnibus
19
19
  let(:project_root) { File.join(tmp_path, 'project/root') }
20
20
  let(:package_dir) { File.join(tmp_path, 'package/dir') }
21
21
  let(:staging_dir) { File.join(tmp_path, 'staging/dir') }
22
+ let(:architecture) { 'x86_64' }
22
23
 
23
24
  before do
24
25
  Config.project_root(project_root)
@@ -32,7 +33,9 @@ module Omnibus
32
33
  create_directory("#{staging_dir}/SOURCES")
33
34
  create_directory("#{staging_dir}/SPECS")
34
35
 
35
- stub_ohai(platform: 'redhat', version: '6.5')
36
+ stub_ohai(platform: 'redhat', version: '6.5') do |data|
37
+ data['kernel']['machine'] = architecture
38
+ end
36
39
  end
37
40
 
38
41
  describe '#signing_passphrase' do
@@ -144,7 +147,6 @@ module Omnibus
144
147
  expect(contents).to include("Version: 1.2.3")
145
148
  expect(contents).to include("Release: 2.el6")
146
149
  expect(contents).to include("Summary: The full stack of project")
147
- expect(contents).to include("BuildArch: x86_64")
148
150
  expect(contents).to include("AutoReqProv: no")
149
151
  expect(contents).to include("BuildRoot: %buildroot")
150
152
  expect(contents).to include("Prefix: /")
@@ -237,6 +239,21 @@ module Omnibus
237
239
  expect(contents).to include("%dir %attr(0555,root,root) /usr/lib")
238
240
  end
239
241
  end
242
+
243
+ context 'when the platform_family is wrlinux' do
244
+ let(:spec_file) { "#{staging_dir}/SPECS/project-1.2.3-2.nexus5.x86_64.rpm.spec" }
245
+
246
+ before do
247
+ stub_ohai(platform: 'nexus', version: '5')
248
+ end
249
+
250
+ it 'writes out a spec file with no BuildArch' do
251
+ subject.write_rpm_spec
252
+ contents = File.read(spec_file)
253
+
254
+ expect(contents).not_to include("BuildArch")
255
+ end
256
+ end
240
257
  end
241
258
 
242
259
  describe '#create_rpm_file' do
@@ -252,7 +269,7 @@ module Omnibus
252
269
 
253
270
  it 'uses the correct command' do
254
271
  expect(subject).to receive(:shellout!)
255
- .with(/rpmbuild -bb --buildroot/)
272
+ .with(/rpmbuild --target #{architecture} -bb --buildroot/)
256
273
  subject.create_rpm_file
257
274
  end
258
275
 
@@ -366,6 +383,36 @@ module Omnibus
366
383
  expect(output).to include("The `version' component of RPM package names can only include")
367
384
  end
368
385
  end
386
+
387
+ context 'when the build is for nexus' do
388
+ before do
389
+ project.build_version('1.2-3')
390
+ stub_ohai(platform: 'nexus', version: '5')
391
+ end
392
+
393
+ it 'returns the value while logging a message' do
394
+ output = capture_logging do
395
+ expect(subject.safe_version).to eq('1.2_3')
396
+ end
397
+
398
+ expect(output).to include("rpmbuild on Wind River Linux does not support this")
399
+ end
400
+ end
401
+
402
+ context 'when the build is for ios_xr' do
403
+ before do
404
+ project.build_version('1.2-3')
405
+ stub_ohai(platform: 'ios_xr', version: '6.0.0.14I')
406
+ end
407
+
408
+ it 'returns the value while logging a message' do
409
+ output = capture_logging do
410
+ expect(subject.safe_version).to eq('1.2_3')
411
+ end
412
+
413
+ expect(output).to include("rpmbuild on Wind River Linux does not support this")
414
+ end
415
+ end
369
416
  end
370
417
 
371
418
  describe '#safe_architecture' do