omnibus 6.1.9 → 7.0.12

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.
@@ -53,10 +53,7 @@ module Omnibus
53
53
  # @return [Aws::S3::Resource]
54
54
  #
55
55
  def client
56
- Aws.config.update(
57
- region: s3_configuration[:region],
58
- credentials: get_credentials
59
- )
56
+ Aws.config.update(region: s3_configuration[:region])
60
57
 
61
58
  @s3_client ||= Aws::S3::Resource.new(resource_params)
62
59
  end
@@ -70,6 +67,7 @@ module Omnibus
70
67
  params = {
71
68
  use_accelerate_endpoint: s3_configuration[:use_accelerate_endpoint],
72
69
  force_path_style: s3_configuration[:force_path_style],
70
+ credentials: get_credentials,
73
71
  }
74
72
 
75
73
  if s3_configuration[:use_accelerate_endpoint]
@@ -84,12 +82,14 @@ module Omnibus
84
82
  end
85
83
 
86
84
  #
87
- # Create credentials object based on credential profile or access key
85
+ # Create credentials object based on AWS IAM role arn, credential profile or access key
88
86
  # parameters for use by the client object.
89
87
  #
90
88
  # @return [Aws::SharedCredentials, Aws::Credentials]
91
89
  def get_credentials
92
- if s3_configuration[:profile]
90
+ if s3_configuration[:iam_role_arn]
91
+ Aws::AssumeRoleCredentials.new(role_arn: s3_configuration[:iam_role_arn], role_session_name: "omnibus-assume-role-s3-access")
92
+ elsif s3_configuration[:profile]
93
93
  Aws::SharedCredentials.new(profile_name: s3_configuration[:profile])
94
94
  elsif s3_configuration[:access_key_id] && s3_configuration[:secret_access_key]
95
95
  Aws::Credentials.new(s3_configuration[:access_key_id], s3_configuration[:secret_access_key])
@@ -205,6 +205,46 @@ module Omnibus
205
205
  end
206
206
  expose :maintainer
207
207
 
208
+ #
209
+ # Sets the bin_dirs where this software installs bins.
210
+ #
211
+ # @example
212
+ # bin_dirs ['/opt/chef-workstation/bin']
213
+ #
214
+ # @param [Array<String>] val
215
+ # the bin_dirs of the software
216
+ #
217
+ # @return [Array<String>]
218
+ #
219
+ def bin_dirs(val = NULL)
220
+ if null?(val)
221
+ @bin_dirs || [windows_safe_path("#{install_dir}/bin"), windows_safe_path("#{install_dir}/embedded/bin")]
222
+ else
223
+ @bin_dirs = val
224
+ end
225
+ end
226
+ expose :bin_dirs
227
+
228
+ #
229
+ # Sets the lib_dirs where this software installs libs.
230
+ #
231
+ # @example
232
+ # lib_dirs ['/opt/chef-workstation/bin']
233
+ #
234
+ # @param [Array<String>] val
235
+ # the lib_dirs of the software
236
+ #
237
+ # @return [Array<String>]
238
+ #
239
+ def lib_dirs(val = NULL)
240
+ if null?(val)
241
+ @lib_dirs || [windows_safe_path("#{install_dir}/embedded/lib")]
242
+ else
243
+ @lib_dirs = val
244
+ end
245
+ end
246
+ expose :lib_dirs
247
+
208
248
  #
209
249
  # Add a software dependency to this software.
210
250
  #
@@ -668,33 +708,22 @@ module Omnibus
668
708
  "ARFLAGS" => "-X64 cru",
669
709
  }
670
710
  when "solaris2"
671
- if platform_version.satisfies?("<= 5.10")
672
- solaris_flags = {
673
- # this override is due to a bug in libtool documented here:
674
- # http://lists.gnu.org/archive/html/bug-libtool/2005-10/msg00004.html
675
- "CC" => "gcc -static-libgcc",
676
- "LDFLAGS" => "-R#{install_dir}/embedded/lib -L#{install_dir}/embedded/lib -static-libgcc",
677
- "CFLAGS" => "-I#{install_dir}/embedded/include -O2",
678
- }
679
- elsif platform_version.satisfies?(">= 5.11")
680
- solaris_flags = {
681
- "CC" => "gcc -m64 -static-libgcc",
682
- "LDFLAGS" => "-Wl,-rpath,#{install_dir}/embedded/lib -L#{install_dir}/embedded/lib -static-libgcc",
683
- "CFLAGS" => "-I#{install_dir}/embedded/include -O2",
684
- }
685
- end
686
- solaris_flags
711
+ {
712
+ "CC" => "gcc -m64 -static-libgcc",
713
+ "LDFLAGS" => "-Wl,-rpath,#{install_dir}/embedded/lib -L#{install_dir}/embedded/lib -static-libgcc",
714
+ "CFLAGS" => "-I#{install_dir}/embedded/include -O2",
715
+ }
687
716
  when "freebsd"
688
717
  {
689
718
  "CC" => "clang",
690
719
  "CXX" => "clang++",
691
720
  "LDFLAGS" => "-L#{install_dir}/embedded/lib",
692
- "CFLAGS" => "-I#{install_dir}/embedded/include -O2",
721
+ "CFLAGS" => "-I#{install_dir}/embedded/include -O2 -D_FORTIFY_SOURCE=2 -fstack-protector",
693
722
  }
694
723
  when "suse"
695
724
  suse_flags = {
696
725
  "LDFLAGS" => "-Wl,-rpath,#{install_dir}/embedded/lib -L#{install_dir}/embedded/lib",
697
- "CFLAGS" => "-I#{install_dir}/embedded/include -O2",
726
+ "CFLAGS" => "-I#{install_dir}/embedded/include -O2 -D_FORTIFY_SOURCE=2 -fstack-protector",
698
727
  }
699
728
  # Enable gcc version 4.8 if it is available
700
729
  if which("gcc-4.8") && platform_version.satisfies?("< 12")
@@ -721,7 +750,7 @@ module Omnibus
721
750
  else
722
751
  {
723
752
  "LDFLAGS" => "-Wl,-rpath,#{install_dir}/embedded/lib -L#{install_dir}/embedded/lib",
724
- "CFLAGS" => "-I#{install_dir}/embedded/include -O2",
753
+ "CFLAGS" => "-I#{install_dir}/embedded/include -O2 -D_FORTIFY_SOURCE=2 -fstack-protector",
725
754
  }
726
755
  end
727
756
 
@@ -1075,8 +1104,8 @@ module Omnibus
1075
1104
  log.info(log_key) do
1076
1105
  "Forcing a build because resolved version is nil"
1077
1106
  end
1078
- execute_build
1079
- project.dirty!(self)
1107
+ execute_build(build_wrappers)
1108
+ project.dirty!(self) unless project.dirty? # omnibus can only be mildly dirty
1080
1109
  elsif project.dirty?
1081
1110
  log.info(log_key) do
1082
1111
  "Building because `#{project.culprit.name}' dirtied the cache"
@@ -15,5 +15,5 @@
15
15
  #
16
16
 
17
17
  module Omnibus
18
- VERSION = "6.1.9".freeze
18
+ VERSION = "7.0.12".freeze
19
19
  end
@@ -1,5 +1,5 @@
1
1
 
2
- # Copyright 2012-2018 Chef Software, Inc.
2
+ # Copyright 2012-2020, Chef Software Inc.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
16
16
 
17
17
  WHITELIST_LIBS = [
18
18
  /ld-linux/,
19
+ /libanl\.so/,
19
20
  /libc\.so/,
20
21
  /libcrypt\.so/,
21
22
  /libdl/,
@@ -33,6 +34,7 @@ WHITELIST_LIBS = [
33
34
  ].freeze
34
35
 
35
36
  ARCH_WHITELIST_LIBS = [
37
+ /libanl\.so/,
36
38
  /libc\.so/,
37
39
  /libcrypt\.so/,
38
40
  /libdb-5\.3\.so/,
@@ -22,13 +22,14 @@ Gem::Specification.new do |gem|
22
22
  gem.require_paths = ["lib"]
23
23
 
24
24
  gem.add_dependency "aws-sdk-s3", "~> 1"
25
- gem.add_dependency "chef-sugar-ng", ">= 3.3"
25
+ gem.add_dependency "chef-sugar", ">= 3.3"
26
26
  gem.add_dependency "chef-cleanroom", "~> 1.0"
27
+ gem.add_dependency "ffi", "< 1.13" # 1.13 does not work on Windows: https://github.com/ffi/ffi/issues/784
27
28
  gem.add_dependency "ffi-yajl", "~> 2.2"
28
29
  gem.add_dependency "mixlib-shellout", ">= 2.0", "< 4.0"
29
- gem.add_dependency "ohai", ">= 13", "< 16"
30
+ gem.add_dependency "ohai", ">= 13", "< 17"
30
31
  gem.add_dependency "ruby-progressbar", "~> 1.7"
31
- gem.add_dependency "thor", "~> 0.18"
32
+ gem.add_dependency "thor", ">= 0.18", "< 2.0"
32
33
  gem.add_dependency "license_scout", "~> 1.0"
33
34
 
34
35
  gem.add_dependency "mixlib-versioning"
@@ -36,7 +37,7 @@ Gem::Specification.new do |gem|
36
37
 
37
38
  gem.add_development_dependency "artifactory", "~> 3.0"
38
39
  gem.add_development_dependency "aruba", "~> 0.5"
39
- gem.add_development_dependency "chefstyle", "= 0.13.3"
40
+ gem.add_development_dependency "chefstyle", "= 1.1.0"
40
41
  gem.add_development_dependency "fauxhai", ">= 5.2"
41
42
  gem.add_development_dependency "rspec", "~> 3.0"
42
43
  gem.add_development_dependency "rspec-json_expectations"
@@ -11,25 +11,22 @@ require 'pty'
11
11
 
12
12
  puts rpm_cmd
13
13
  PTY.spawn(rpm_cmd) do |r, w, pid|
14
+ # Older versions of rpmsign will prompt right away for the passphrase
14
15
  prompt = r.read(19)
15
16
 
16
- # match the expected prompt exactly, since that's the only way we know if
17
- # something went wrong.
18
- unless prompt == 'Enter pass phrase: '
19
- STDERR.puts "unexpected output from `#{rpm_cmd}`: '#{prompt}'"
20
- Process.kill(:KILL, pid)
21
- exit 1
17
+ if prompt == 'Enter pass phrase: '
18
+ STDOUT.puts prompt
19
+ w.write("#{password}\n")
22
20
  end
23
21
 
24
- STDOUT.puts prompt
25
- w.write("#{password}\n")
26
-
27
22
  # Keep printing output unti the command exits
28
23
  loop do
29
24
  begin
30
25
  line = r.gets
31
26
  puts line
32
- if (line =~ /failed/) && !(line =~ /warning:/)
27
+ if line =~ /Please enter the passphrase to unlock the OpenPGP secret key:/
28
+ w.write("#{password}\n")
29
+ elsif (line =~ /failed/) && !(line =~ /warning:/)
33
30
  STDERR.puts 'RPM signing failure'
34
31
  exit 1
35
32
  end
@@ -109,6 +109,158 @@ module Omnibus
109
109
  end
110
110
  end
111
111
 
112
+ describe "#sign_software_libs_and_bins" do
113
+ context "when pkg signing is disabled" do
114
+ it "does not sign anything" do
115
+ expect(subject).not_to receive(:sign_binary)
116
+ expect(subject).not_to receive(:sign_library)
117
+ subject.sign_software_libs_and_bins
118
+ end
119
+
120
+ it "returns an empty set" do
121
+ expect(subject.sign_software_libs_and_bins).to be_nil
122
+ end
123
+ end
124
+
125
+ context "when pkg signing is enabled" do
126
+ before do
127
+ subject.signing_identity("My Special Identity")
128
+ end
129
+
130
+ context "without software" do
131
+ it "does not sign anything" do
132
+ expect(subject).not_to receive(:sign_binary)
133
+ expect(subject).not_to receive(:sign_library)
134
+ subject.sign_software_libs_and_bins
135
+ end
136
+
137
+ it "returns an empty set" do
138
+ expect(subject.sign_software_libs_and_bins).to eq(Set.new)
139
+ end
140
+ end
141
+
142
+ context "project with software" do
143
+ let(:software) do
144
+ Software.new(project).tap do |software|
145
+ software.name("software-full-name")
146
+ end
147
+ end
148
+
149
+ before do
150
+ allow(project).to receive(:softwares).and_return([software])
151
+ end
152
+
153
+ context "with empty bin_dirs and lib_dirs" do
154
+ before do
155
+ allow(software).to receive(:lib_dirs).and_return([])
156
+ allow(software).to receive(:bin_dirs).and_return([])
157
+ end
158
+
159
+ it "does not sign anything" do
160
+ expect(subject).not_to receive(:sign_binary)
161
+ expect(subject).not_to receive(:sign_library)
162
+ subject.sign_software_libs_and_bins
163
+ end
164
+
165
+ it "returns an empty set" do
166
+ expect(subject.sign_software_libs_and_bins).to eq(Set.new)
167
+ end
168
+ end
169
+
170
+ context "with default bin_dirs and lib_dirs" do
171
+ context "with binaries" do
172
+ let(:bin) { "/opt/#{project.name}/bin/test_bin" }
173
+ let(:embedded_bin) { "/opt/#{project.name}/embedded/bin/test_bin" }
174
+ before do
175
+ allow(Dir).to receive(:[]).with("/opt/#{project.name}/bin/*").and_return([bin])
176
+ allow(Dir).to receive(:[]).with("/opt/#{project.name}/embedded/bin/*").and_return([embedded_bin])
177
+ allow(Dir).to receive(:[]).with("/opt/#{project.name}/embedded/lib/*").and_return([])
178
+ allow(subject).to receive(:is_binary?).with(bin).and_return(true)
179
+ allow(subject).to receive(:is_binary?).with(embedded_bin).and_return(true)
180
+ allow(subject).to receive(:find_linked_libs).with(bin).and_return([])
181
+ allow(subject).to receive(:find_linked_libs).with(embedded_bin).and_return([])
182
+ allow(subject).to receive(:sign_binary).with(bin, true)
183
+ allow(subject).to receive(:sign_binary).with(embedded_bin, true)
184
+ end
185
+
186
+ it "signs the binaries" do
187
+ expect(subject).to receive(:sign_binary).with(bin, true)
188
+ expect(subject).to receive(:sign_binary).with(embedded_bin, true)
189
+ subject.sign_software_libs_and_bins
190
+ end
191
+
192
+ it "returns a set with the signed binaries" do
193
+ expect(subject.sign_software_libs_and_bins).to eq(Set.new [bin, embedded_bin])
194
+ end
195
+ end
196
+
197
+ context "with library" do
198
+ let(:lib) { "/opt/#{project.name}/embedded/lib/test_lib" }
199
+ before do
200
+ allow(Dir).to receive(:[]).with("/opt/#{project.name}/bin/*").and_return([])
201
+ allow(Dir).to receive(:[]).with("/opt/#{project.name}/embedded/bin/*").and_return([])
202
+ allow(Dir).to receive(:[]).with("/opt/#{project.name}/embedded/lib/*").and_return([lib])
203
+ allow(subject).to receive(:is_macho?).with(lib).and_return(true)
204
+ allow(subject).to receive(:find_linked_libs).with(lib).and_return([])
205
+ allow(subject).to receive(:sign_library).with(lib)
206
+ end
207
+
208
+ it "signs the library" do
209
+ expect(subject).to receive(:sign_library).with(lib)
210
+ subject.sign_software_libs_and_bins
211
+ end
212
+ end
213
+
214
+ context "with binaries and libraries with linked libs" do
215
+ let(:bin) { "/opt/#{project.name}/bin/test_bin" }
216
+ let(:bin2) { "/opt/#{project.name}/bin/test_bin2" }
217
+ let(:embedded_bin) { "/opt/#{project.name}/embedded/bin/test_bin" }
218
+ let(:lib) { "/opt/#{project.name}/embedded/lib/test_lib" }
219
+ let(:lib2) { "/opt/#{project.name}/embedded/lib/test_lib2" }
220
+ before do
221
+ allow(Dir).to receive(:[]).with("/opt/#{project.name}/bin/*").and_return([bin, bin2])
222
+ allow(Dir).to receive(:[]).with("/opt/#{project.name}/embedded/bin/*").and_return([embedded_bin])
223
+ allow(Dir).to receive(:[]).with("/opt/#{project.name}/embedded/lib/*").and_return([lib])
224
+ allow(subject).to receive(:is_binary?).with(bin).and_return(true)
225
+ allow(subject).to receive(:is_binary?).with(bin2).and_return(true)
226
+ allow(subject).to receive(:is_binary?).with(embedded_bin).and_return(true)
227
+ allow(subject).to receive(:is_macho?).with(lib).and_return(true)
228
+ allow(subject).to receive(:is_macho?).with(lib2).and_return(true)
229
+ allow(subject).to receive(:find_linked_libs).with(bin).and_return([lib2])
230
+ allow(subject).to receive(:find_linked_libs).with(bin2).and_return([])
231
+ allow(subject).to receive(:find_linked_libs).with(embedded_bin).and_return([])
232
+ allow(subject).to receive(:find_linked_libs).with(lib).and_return([])
233
+ allow(subject).to receive(:find_linked_libs).with(lib2).and_return([])
234
+ allow(subject).to receive(:sign_binary).with(bin, true)
235
+ allow(subject).to receive(:sign_binary).with(bin2, true)
236
+ allow(subject).to receive(:sign_binary).with(embedded_bin, true)
237
+ allow(subject).to receive(:sign_library).with(lib)
238
+ allow(subject).to receive(:sign_library).with(lib2)
239
+ allow(Digest::SHA256).to receive(:file).with(bin).and_return(Digest::SHA256.new.update(bin))
240
+ allow(Digest::SHA256).to receive(:file).with(bin2).and_return(Digest::SHA256.new.update(bin2))
241
+ allow(Digest::SHA256).to receive(:file).with(embedded_bin).and_return(Digest::SHA256.new.update(embedded_bin))
242
+ allow(Digest::SHA256).to receive(:file).with(lib).and_return(Digest::SHA256.new.update(lib))
243
+ allow(Digest::SHA256).to receive(:file).with(lib2).and_return(Digest::SHA256.new.update(lib2))
244
+ end
245
+
246
+ it "signs the binaries" do
247
+ expect(subject).to receive(:sign_binary).with(bin, true)
248
+ expect(subject).to receive(:sign_binary).with(bin2, true)
249
+ expect(subject).to receive(:sign_binary).with(embedded_bin, true)
250
+ subject.sign_software_libs_and_bins
251
+ end
252
+
253
+ it "signs the libraries" do
254
+ expect(subject).to receive(:sign_library).with(lib)
255
+ expect(subject).to receive(:sign_library).with(lib2)
256
+ subject.sign_software_libs_and_bins
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end
262
+ end
263
+
112
264
  describe "#build_component_pkg" do
113
265
  it "executes the pkgbuild command" do
114
266
  expect(subject).to receive(:shellout!).with <<-EOH.gsub(/^ {10}/, "")
@@ -118,6 +270,7 @@ module Omnibus
118
270
  --scripts "#{staging_dir}/Scripts" \\
119
271
  --root "/opt/project-full-name" \\
120
272
  --install-location "/opt/project-full-name" \\
273
+ --preserve-xattr \\
121
274
  "project-full-name-core.pkg"
122
275
  EOH
123
276
 
@@ -267,5 +420,206 @@ module Omnibus
267
420
  end
268
421
  end
269
422
  end
423
+
424
+ describe "#find_linked_libs" do
425
+ context "with linked libs" do
426
+ let(:file) { "/opt/#{project.name}/embedded/bin/test_bin" }
427
+ let(:stdout) do
428
+ <<~EOH
429
+ /opt/#{project.name}/embedded/bin/test_bin:
430
+ /opt/#{project.name}/embedded/lib/lib.dylib (compatibility version 7.0.0, current version 7.4.0)
431
+ /opt/#{project.name}/embedded/lib/lib.6.dylib (compatibility version 7.0.0, current version 7.4.0)
432
+ /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)
433
+ EOH
434
+ end
435
+ let(:shellout) { Mixlib::ShellOut.new }
436
+
437
+ before do
438
+ allow(shellout).to receive(:run_command)
439
+ allow(shellout).to receive(:stdout)
440
+ .and_return(stdout)
441
+ allow(subject).to receive(:shellout!)
442
+ .with("otool -L #{file}")
443
+ .and_return(shellout)
444
+ end
445
+
446
+ it "returns empty array" do
447
+ expect(subject.find_linked_libs(file)).to eq([
448
+ "/opt/#{project.name}/embedded/lib/lib.dylib",
449
+ "/opt/#{project.name}/embedded/lib/lib.6.dylib",
450
+ ])
451
+ end
452
+ end
453
+
454
+ context "with only system linked libs" do
455
+ let(:file) { "/opt/#{project.name}/embedded/lib/lib.dylib" }
456
+ let(:stdout) do
457
+ <<~EOH
458
+ /opt/#{project.name}/embedded/lib/lib.dylib:
459
+ /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)
460
+ EOH
461
+ end
462
+ let(:shellout) { Mixlib::ShellOut.new }
463
+ before do
464
+ allow(shellout).to receive(:run_command)
465
+ allow(shellout).to receive(:stdout)
466
+ .and_return(stdout)
467
+ allow(subject).to receive(:shellout!)
468
+ .with("otool -L #{file}")
469
+ .and_return(shellout)
470
+ end
471
+
472
+ it "returns empty array" do
473
+ expect(subject.find_linked_libs(file)).to eq([])
474
+ end
475
+ end
476
+
477
+ context "file is just a file" do
478
+ let(:file) { "/opt/#{project.name}/embedded/lib/file.rb" }
479
+ let(:shellout) { Mixlib::ShellOut.new }
480
+ before do
481
+ allow(shellout).to receive(:run_command)
482
+ allow(shellout).to receive(:stdout)
483
+ .and_return("#{file}: is not an object file")
484
+ allow(subject).to receive(:shellout!)
485
+ .with("otool -L #{file}")
486
+ .and_return(shellout)
487
+ end
488
+
489
+ it "returns empty array" do
490
+ expect(subject.find_linked_libs(file)).to eq([])
491
+ end
492
+ end
493
+ end
494
+
495
+ describe "#is_binary?" do
496
+ context "when is a file, executable, and not a symlink" do
497
+ before do
498
+ allow(File).to receive(:file?).with("file").and_return(true)
499
+ allow(File).to receive(:executable?).with("file").and_return(true)
500
+ allow(File).to receive(:symlink?).with("file").and_return(false)
501
+ end
502
+
503
+ it "returns true" do
504
+ expect(subject.is_binary?("file")).to be true
505
+ end
506
+ end
507
+
508
+ context "when not a file" do
509
+ before do
510
+ allow(File).to receive(:file?).with("file").and_return(false)
511
+ allow(File).to receive(:executable?).with("file").and_return(true)
512
+ allow(File).to receive(:symlink?).with("file").and_return(false)
513
+ end
514
+
515
+ it "returns false" do
516
+ expect(subject.is_binary?("file")).to be false
517
+ end
518
+ end
519
+
520
+ context "when not an executable" do
521
+ it "returns false" do
522
+ allow(File).to receive(:file?).with("file").and_return(true)
523
+ allow(File).to receive(:executable?).with("file").and_return(false)
524
+ allow(File).to receive(:symlink?).with("file").and_return(false)
525
+ expect(subject.is_binary?("file")).to be false
526
+ end
527
+ end
528
+
529
+ context "when is symlink" do
530
+ it "returns false" do
531
+ allow(File).to receive(:file?).with("file").and_return(true)
532
+ allow(File).to receive(:executable?).with("file").and_return(true)
533
+ allow(File).to receive(:symlink?).with("file").and_return(true)
534
+ expect(subject.is_binary?("file")).to be false
535
+ end
536
+ end
537
+ end
538
+
539
+ describe "#is_macho?" do
540
+ let(:shellout) { Mixlib::ShellOut.new }
541
+
542
+ context "when is a Mach-O library" do
543
+ before do
544
+ allow(subject).to receive(:is_binary?).with("file").and_return(true)
545
+ expect(subject).to receive(:shellout!).with("file file").and_return(shellout)
546
+ allow(shellout).to receive(:stdout)
547
+ .and_return("file: Mach-O 64-bit dynamically linked shared library x86_64")
548
+ end
549
+
550
+ it "returns true" do
551
+ expect(subject.is_macho?("file")).to be true
552
+ end
553
+ end
554
+
555
+ context "when is a Mach-O Bundle" do
556
+ before do
557
+ allow(subject).to receive(:is_binary?).with("file").and_return(true)
558
+ expect(subject).to receive(:shellout!).with("file file").and_return(shellout)
559
+ allow(shellout).to receive(:stdout)
560
+ .and_return("file: Mach-O 64-bit bundle x86_64")
561
+ end
562
+
563
+ it "returns true" do
564
+ expect(subject.is_macho?("file")).to be true
565
+ end
566
+ end
567
+
568
+ context "when is not a Mach-O Bundle or Mach-O library" do
569
+ before do
570
+ allow(subject).to receive(:is_binary?).with("file").and_return(true)
571
+ expect(subject).to receive(:shellout!).with("file file").and_return(shellout)
572
+ allow(shellout).to receive(:stdout)
573
+ .and_return("file: ASCII text")
574
+ end
575
+
576
+ it "returns true" do
577
+ expect(subject.is_macho?("file")).to be false
578
+ end
579
+ end
580
+ end
581
+
582
+ describe "#sign_library" do
583
+ before do
584
+ subject.signing_identity("My Special Identity")
585
+ end
586
+
587
+ it "calls sign_binary without hardened runtime" do
588
+ expect(subject).to receive(:sign_binary).with("file")
589
+ subject.sign_library("file")
590
+ end
591
+ end
592
+
593
+ describe "#sign_binary" do
594
+ before do
595
+ subject.signing_identity("My Special Identity")
596
+ end
597
+
598
+ it "it signs the binary without hardened runtime" do
599
+ expect(subject).to receive(:shellout!)
600
+ .with("codesign -s '#{subject.signing_identity}' 'file' --force\n")
601
+ subject.sign_binary("file")
602
+ end
603
+
604
+ context "with hardened runtime" do
605
+ it "it signs the binary with hardened runtime" do
606
+ expect(subject).to receive(:shellout!)
607
+ .with("codesign -s '#{subject.signing_identity}' 'file' --options=runtime --force\n")
608
+ subject.sign_binary("file", true)
609
+ end
610
+
611
+ context "with entitlements" do
612
+ let(:entitlements_file) { File.join(tmp_path, "project-full-name/resources/project-full-name/pkg/entitlements.plist") }
613
+
614
+ it "it signs the binary with the entitlements" do
615
+ allow(subject).to receive(:resource_path).with("entitlements.plist").and_return(entitlements_file)
616
+ allow(File).to receive(:exist?).with(entitlements_file).and_return(true)
617
+ expect(subject).to receive(:shellout!)
618
+ .with("codesign -s '#{subject.signing_identity}' 'file' --options=runtime --entitlements #{entitlements_file} --force\n")
619
+ subject.sign_binary("file", true)
620
+ end
621
+ end
622
+ end
623
+ end
270
624
  end
271
625
  end