omnibus 5.2.0 → 5.3.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.
@@ -105,7 +105,7 @@ module Omnibus
105
105
  #
106
106
  def license(val = NULL)
107
107
  if null?(val)
108
- @license || 'unknown'
108
+ @license || project.license
109
109
  else
110
110
  unless val.is_a?(String)
111
111
  raise InvalidValue.new(:license, 'be a String')
@@ -397,29 +397,7 @@ module Omnibus
397
397
  # @return [String]
398
398
  #
399
399
  def safe_architecture
400
- case Ohai['kernel']['machine']
401
- when 'x86_64'
402
- 'amd64'
403
- when 'i686'
404
- 'i386'
405
- when /armv\dl/
406
- if Ohai['platform'] == 'raspbian' || Ohai['platform'] == 'ubuntu'
407
- 'armhf'
408
- else
409
- Ohai['kernel']['machine']
410
- end
411
- when 'aarch64'
412
- # Debian prefers amd64 on ARMv8/AArch64 (64bit ARM) platforms
413
- # see https://wiki.debian.org/Arm64Port
414
- 'arm64'
415
- when 'ppc64le'
416
- # Debian prefers to use ppc64el for little endian architecture name
417
- # where as others like gnutools/rhel use ppc64le( note the last 2 chars)
418
- # see http://linux.debian.ports.powerpc.narkive.com/8eeWSBtZ/switching-ppc64el-port-name-to-ppc64le
419
- 'ppc64el' #dpkg --print-architecture = ppc64el
420
- else
421
- Ohai['kernel']['machine']
422
- end
400
+ @safe_architecture ||= shellout!("dpkg --print-architecture").stdout.split("\n").first || "noarch"
423
401
  end
424
402
  end
425
403
  end
@@ -141,7 +141,7 @@ module Omnibus
141
141
  #
142
142
  def license(val = NULL)
143
143
  if null?(val)
144
- @license || 'unknown'
144
+ @license || project.license
145
145
  else
146
146
  unless val.is_a?(String)
147
147
  raise InvalidValue.new(:license, 'be a String')
@@ -49,6 +49,13 @@ module Omnibus
49
49
  end
50
50
  end
51
51
 
52
+ #
53
+ # Reset cached project information.
54
+ #
55
+ def reset!
56
+ @loaded_projects = nil
57
+ end
58
+
52
59
  private
53
60
 
54
61
  #
@@ -52,6 +52,13 @@ module Omnibus
52
52
  end
53
53
  end
54
54
 
55
+ #
56
+ # Reset cached software information.
57
+ #
58
+ def reset!
59
+ @loaded_softwares = nil
60
+ end
61
+
55
62
  private
56
63
 
57
64
  #
@@ -237,6 +244,8 @@ module Omnibus
237
244
  #
238
245
  # @option val [String] :git (nil)
239
246
  # a git URL
247
+ # @option val [String] :github (nil)
248
+ # a github ORG/REPO pair (e.g. chef/chef) that will be transformed to https://github.com/ORG/REPO.git
240
249
  # @option val [String] :url (nil)
241
250
  # general URL
242
251
  # @option val [String] :path (nil)
@@ -280,6 +289,8 @@ module Omnibus
280
289
  "be a kind of `Hash', but was `#{val.class.inspect}'")
281
290
  end
282
291
 
292
+ val = canonicalize_source(val)
293
+
283
294
  extra_keys = val.keys - [
284
295
  :git, :path, :url, # fetcher types
285
296
  :md5, :sha1, :sha256, :sha512, # hash type - common to all fetchers
@@ -302,7 +313,8 @@ module Omnibus
302
313
  @source.merge!(val)
303
314
  end
304
315
 
305
- apply_overrides(:source)
316
+ override = canonicalize_source(overrides[:source])
317
+ apply_overrides(:source, override)
306
318
  end
307
319
  expose :source
308
320
 
@@ -589,18 +601,34 @@ module Omnibus
589
601
  "CFLAGS" => "-I#{install_dir}/embedded/include -O2",
590
602
  }
591
603
  when "solaris2"
592
- {
593
- # this override is due to a bug in libtool documented here:
594
- # http://lists.gnu.org/archive/html/bug-libtool/2005-10/msg00004.html
595
- "CC" => "gcc -static-libgcc",
596
- "LDFLAGS" => "-R#{install_dir}/embedded/lib -L#{install_dir}/embedded/lib -static-libgcc",
597
- "CFLAGS" => "-I#{install_dir}/embedded/include",
598
- }
604
+ if platform_version.satisfies?('<= 5.10')
605
+ solaris_flags = {
606
+ # this override is due to a bug in libtool documented here:
607
+ # http://lists.gnu.org/archive/html/bug-libtool/2005-10/msg00004.html
608
+ "CC" => "gcc -static-libgcc",
609
+ "LDFLAGS" => "-R#{install_dir}/embedded/lib -L#{install_dir}/embedded/lib -static-libgcc",
610
+ "CFLAGS" => "-I#{install_dir}/embedded/include",
611
+ }
612
+ elsif platform_version.satisfies?('>= 5.11')
613
+ solaris_flags = {
614
+ "CC" => "gcc -m64 -static-libgcc",
615
+ "LDFLAGS" => "-Wl,-rpath,#{install_dir}/embedded/lib -L#{install_dir}/embedded/lib -static-libgcc",
616
+ "CFLAGS" => "-I#{install_dir}/embedded/include -O2",
617
+ }
618
+ end
619
+ solaris_flags
599
620
  when "freebsd"
600
621
  freebsd_flags = {
601
622
  "LDFLAGS" => "-L#{install_dir}/embedded/lib",
602
623
  "CFLAGS" => "-I#{install_dir}/embedded/include -O2",
603
624
  }
625
+ # Enable gcc version 4.9 if it is available
626
+ if (Ohai['os_version'].to_i <= 903000) && which('gcc49')
627
+ freebsd_flags.merge!(
628
+ "CC" => "gcc49",
629
+ "CXX" => "g++49",
630
+ )
631
+ end
604
632
  # Clang became the default compiler in FreeBSD 10+
605
633
  if Ohai['os_version'].to_i >= 1000024
606
634
  freebsd_flags.merge!(
@@ -614,8 +642,16 @@ module Omnibus
614
642
  opt_flag = windows_arch_i386? ? "-march=i686" : "-march=x86-64"
615
643
  {
616
644
  "LDFLAGS" => "-L#{install_dir}/embedded/lib #{arch_flag}",
617
- # If we're happy with these flags, enable SSE for other platforms running x86 too.
618
- "CFLAGS" => "-I#{install_dir}/embedded/include #{arch_flag} -O3 -mfpmath=sse -msse2 #{opt_flag}"
645
+ # We do not wish to enable SSE even though we target i686 because
646
+ # of a stack alignment issue with some libraries. We have not
647
+ # exactly ascertained the cause but some compiled library/binary
648
+ # violates gcc's assumption that the stack is going to be 16-byte
649
+ # aligned which is just fine as long as one is pushing 32-bit
650
+ # values from general purpose registers but stuff hits the fan as
651
+ # soon as gcc emits aligned SSE xmm register spills which generate
652
+ # GPEs and terminate the application very rudely with very little
653
+ # to debug with.
654
+ "CFLAGS" => "-I#{install_dir}/embedded/include #{arch_flag} -O3 #{opt_flag}"
619
655
  }
620
656
  else
621
657
  {
@@ -648,14 +684,17 @@ module Omnibus
648
684
  }
649
685
 
650
686
  if solaris2?
651
- # in order to provide compatibility for earlier versions of libc on solaris 10,
652
- # we need to specify a mapfile that restricts the version of system libraries
653
- # used. See http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter5-1.html
654
- # for more information
655
- # use the mapfile if it exists, otherwise ignore it
656
687
  ld_options = "-R#{install_dir}/embedded/lib"
657
- mapfile_path = File.expand_path(Config.solaris_linker_mapfile, Config.project_root)
658
- ld_options << " -M #{mapfile_path}" if File.exist?(mapfile_path)
688
+
689
+ if platform_version.satisfies?('<= 5.10')
690
+ # in order to provide compatibility for earlier versions of libc on solaris 10,
691
+ # we need to specify a mapfile that restricts the version of system libraries
692
+ # used. See http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter5-1.html
693
+ # for more information
694
+ # use the mapfile if it exists, otherwise ignore it
695
+ mapfile_path = File.expand_path(Config.solaris_linker_mapfile, Config.project_root)
696
+ ld_options << " -M #{mapfile_path}" if File.exist?(mapfile_path)
697
+ end
659
698
 
660
699
  # solaris linker can also use LD_OPTIONS, so we throw the kitchen sink against
661
700
  # the linker, to find every way to make it use our rpath. This is also required
@@ -1069,15 +1108,27 @@ module Omnibus
1069
1108
  # Apply overrides in the @overrides hash that mask instance variables
1070
1109
  # that are set by parsing the DSL
1071
1110
  #
1072
- def apply_overrides(attr)
1111
+ def apply_overrides(attr, override=overrides[attr])
1073
1112
  val = instance_variable_get(:"@#{attr}")
1074
- if val.is_a?(Hash) || overrides[attr].is_a?(Hash)
1113
+ if val.is_a?(Hash) || override.is_a?(Hash)
1075
1114
  val ||= {}
1076
- override = overrides[attr] || {}
1115
+ override ||= {}
1077
1116
  val.merge(override)
1078
1117
  else
1079
- overrides[attr] || val
1118
+ override || val
1119
+ end
1120
+ end
1121
+
1122
+ #
1123
+ # Transform github -> git in source
1124
+ #
1125
+ def canonicalize_source(source)
1126
+ if source.is_a?(Hash) && source[:github]
1127
+ source = source.dup
1128
+ source[:git] = "https://github.com/#{source[:github]}.git"
1129
+ source.delete(:github)
1080
1130
  end
1131
+ source
1081
1132
  end
1082
1133
 
1083
1134
  #
@@ -15,5 +15,5 @@
15
15
  #
16
16
 
17
17
  module Omnibus
18
- VERSION = '5.2.0'
18
+ VERSION = '5.3.0'
19
19
  end
@@ -36,10 +36,11 @@ Gem::Specification.new do |gem|
36
36
  gem.add_development_dependency 'bundler'
37
37
  gem.add_development_dependency 'artifactory', '~> 2.0'
38
38
  gem.add_development_dependency 'aruba', '~> 0.5'
39
- gem.add_development_dependency 'fauxhai', '~> 2.3'
39
+ gem.add_development_dependency 'fauxhai', '~> 3.2'
40
40
  gem.add_development_dependency 'rspec', '~> 3.0'
41
41
  gem.add_development_dependency 'rspec-its'
42
42
  gem.add_development_dependency 'webmock'
43
43
  gem.add_development_dependency 'rake'
44
44
  gem.add_development_dependency 'appbundler'
45
+ gem.add_development_dependency 'pry'
45
46
  end
@@ -9,11 +9,16 @@ module Omnibus
9
9
  let(:install_dir) { File.join(tmp_path, "install_dir")}
10
10
  let(:software_project_dir) { File.join(tmp_path, "software_project_dir")}
11
11
 
12
+ let(:expected_project_license_path) { "LICENSE" }
13
+ let(:expected_project_license) { "Unspecified" }
14
+ let(:expected_project_license_content) { "" }
15
+
12
16
  before do
13
17
  FileUtils.mkdir_p(install_dir)
14
18
  FileUtils.mkdir_p(software_project_dir)
19
+
15
20
  allow_any_instance_of(Software).to receive(:project_dir).and_return(software_project_dir)
16
- %w{README LICENSE NOTICE}.each do |file|
21
+ %w{LICENSE NOTICE}.each do |file|
17
22
  File.open(File.join(software_project_dir, file), "w+") do |f|
18
23
  f.puts "This file is #{file}."
19
24
  end
@@ -22,6 +27,7 @@ module Omnibus
22
27
 
23
28
  shared_examples "correctly created licenses" do
24
29
  it "creates the main license file for the project correctly" do
30
+ create_licenses
25
31
  project_license = File.join(install_dir, expected_project_license_path)
26
32
  expect(File.exist?(project_license)).to be(true)
27
33
  project_license = File.read(project_license)
@@ -31,20 +37,36 @@ module Omnibus
31
37
  expect(project_license).to match /This product bundles snoopy 1.0.0,\nwhich is available under a "GPL v2"/
32
38
  expect(project_license).to match /This product bundles zlib 1.7.2,\nwhich is available under a "Zlib"/
33
39
  expect(project_license).not_to match /preparation/
34
- expect(project_license).to match /LICENSES\/snoopy-README/
40
+ expect(project_license).to match /LICENSES\/snoopy-artistic.html/
35
41
  expect(project_license).to match /LICENSES\/snoopy-NOTICE/
36
42
  expect(project_license).to match /LICENSES\/zlib-LICENSE/
37
43
  end
38
44
 
39
45
  it "creates the license files of software components correctly" do
46
+ create_licenses
40
47
  license_dir = File.join(install_dir, "LICENSES")
41
48
  expect(Dir.glob("#{license_dir}/**/*").length).to be(3)
42
49
 
43
- %w{snoopy-NOTICE snoopy-README zlib-LICENSE}.each do |software_license|
50
+ %w{snoopy-NOTICE zlib-LICENSE}.each do |software_license|
44
51
  license_path = File.join(license_dir, software_license)
45
52
  expect(File.exist?(license_path)).to be(true)
46
53
  expect(File.read(license_path)).to match /#{software_license.split("-").last}/
47
54
  end
55
+
56
+ remote_license_file = File.join(license_dir, "snoopy-artistic.html")
57
+ remote_license_file_contents = File.read(remote_license_file)
58
+ expect(File.exist?(remote_license_file)).to be(true)
59
+ expect(remote_license_file_contents).to match /The "Artistic License" - dev.perl.org/
60
+ end
61
+
62
+ it "warns for non-standard software license info" do
63
+ output = capture_logging { create_licenses }
64
+ expect(output).to include("Software 'snoopy' uses license 'GPL v2' which is not one of the standard licenses")
65
+ end
66
+
67
+ it "warns for missing software license info" do
68
+ output = capture_logging { create_licenses }
69
+ expect(output).to include("Software 'private_code' does not contain licensing information.")
48
70
  end
49
71
  end
50
72
 
@@ -80,7 +102,7 @@ module Omnibus
80
102
  name 'snoopy'
81
103
  default_version '1.0.0'
82
104
  license "GPL v2"
83
- license_file "README"
105
+ license_file "http://dev.perl.org/licenses/artistic.html"
84
106
  license_file "NOTICE"
85
107
  end
86
108
  end
@@ -93,25 +115,25 @@ module Omnibus
93
115
  end
94
116
  end
95
117
 
118
+ let(:software_with_warnings) { nil }
119
+
96
120
  def create_licenses
97
121
  project.library.component_added(preparation)
98
122
  project.library.component_added(snoopy)
99
123
  project.library.component_added(zlib)
100
124
  project.library.component_added(private_code)
125
+ project.library.component_added(software_with_warnings) if software_with_warnings
101
126
 
102
127
  Licensing.create!(project)
103
128
  end
104
129
 
105
130
  describe "without license definitions in the project" do
106
- let(:expected_project_license_path) { "LICENSE" }
107
- let(:expected_project_license) { "Unspecified" }
108
- let(:expected_project_license_content) { "" }
131
+ it_behaves_like "correctly created licenses"
109
132
 
110
- before do
111
- create_licenses
133
+ it "warns for missing project license" do
134
+ output = capture_logging { create_licenses }
135
+ expect(output).to include("Project 'test-project' does not contain licensing information.")
112
136
  end
113
-
114
- it_behaves_like "correctly created licenses"
115
137
  end
116
138
 
117
139
  describe "with license definitions in the project" do
@@ -127,8 +149,6 @@ module Omnibus
127
149
  File.open(File.join(Config.project_root, license_file), "w+") do |f|
128
150
  f.puts "Chef Custom License is awesome."
129
151
  end
130
-
131
- create_licenses
132
152
  end
133
153
 
134
154
  after do
@@ -136,6 +156,82 @@ module Omnibus
136
156
  end
137
157
 
138
158
  it_behaves_like "correctly created licenses"
159
+
160
+ it "warns for non-standard project license" do
161
+ output = capture_logging { create_licenses }
162
+ expect(output).to include("Project 'test-project' is using 'Custom Chef' which is not one of the standard licenses")
163
+ end
164
+ end
165
+
166
+ describe "with a local license file that does not exist" do
167
+ let(:software_with_warnings) do
168
+ Software.new(project, 'problematic.rb').evaluate do
169
+ name 'problematic'
170
+ default_version '0.10.2'
171
+ license_file "NOT_EXISTS"
172
+ end
173
+ end
174
+
175
+ it_behaves_like "correctly created licenses"
176
+
177
+ it "should log a warning for the missing file" do
178
+ output = capture_logging { create_licenses }
179
+ expect(output).to match /License file (.*)NOT_EXISTS' does not exist for software 'problematic'./
180
+ end
181
+ end
182
+
183
+ describe "with a remote license file that does not exist" do
184
+ before do
185
+ Omnibus::Config.fetcher_retries(1)
186
+ end
187
+
188
+ let(:software_with_warnings) do
189
+ Software.new(project, 'problematic.rb').evaluate do
190
+ name 'problematic'
191
+ default_version '0.10.2'
192
+ license_file "https://downloads.chef.io/LICENSE"
193
+ end
194
+ end
195
+
196
+ it_behaves_like "correctly created licenses"
197
+
198
+ it "should log a warning for the missing file" do
199
+ output = capture_logging { create_licenses }
200
+ expect(output).to match(/Retrying failed download/)
201
+ expect(output).to match(/Can not download license file 'https:\/\/downloads.chef.io\/LICENSE' for software 'problematic'./)
202
+ end
203
+ end
204
+
205
+ describe "with a software with no license files" do
206
+ let(:software_with_warnings) do
207
+ Software.new(project, 'problematic.rb').evaluate do
208
+ name 'problematic'
209
+ default_version '0.10.2'
210
+ license "Zlib"
211
+ end
212
+ end
213
+
214
+ it_behaves_like "correctly created licenses"
215
+
216
+ it "should log a warning for the missing file pointers" do
217
+ output = capture_logging { create_licenses }
218
+ expect(output).to include("Software 'problematic' does not point to any license files.")
219
+ end
220
+ end
221
+
222
+ describe "with a project with no license files" do
223
+ let(:license) { "Zlib" }
224
+
225
+ let(:expected_project_license_path) { "LICENSE" }
226
+ let(:expected_project_license) { license }
227
+ let(:expected_project_license_content) { "" }
228
+
229
+ it_behaves_like "correctly created licenses"
230
+
231
+ it "warns for missing license files" do
232
+ output = capture_logging { create_licenses }
233
+ expect(output).to include("Project 'test-project' does not point to a license file.")
234
+ end
139
235
  end
140
236
  end
141
237
  end
@@ -139,9 +139,11 @@ module Omnibus
139
139
  )
140
140
  end
141
141
 
142
+ let(:regexp) {".*(\\.[ch]|\\.e*rb|\\.gemspec|\\.gitignore|\\.h*h|\\.java|\\.js|\\.json|\\.lock|\\.log|\\.lua|\\.md|\\.mkd|\\.out|\\.pl|\\.pm|\\.png|\\.py[oc]*|\\.r*html|\\.rdoc|\\.ri|\\.sh|\\.sql|\\.toml|\\.ttf|\\.txt|\\.xml|\\.yml|Gemfile|LICENSE|README|Rakefile|VERSION)$|.*\\/share\\/doc\\/.*|.*\\/share\\/postgresql\\/.*|.*\\/share\\/terminfo\\/.*|.*\\/terminfo\\/.*"}
143
+
142
144
  it 'raises an exception when there are external dependencies' do
143
145
  allow(subject).to receive(:shellout)
144
- .with("find #{project.install_dir}/ -type f | xargs ldd")
146
+ .with("find #{project.install_dir}/ -type f -regextype posix-extended ! -regex '#{regexp}' | xargs ldd")
145
147
  .and_return(bad_healthcheck)
146
148
 
147
149
  expect { subject.run! }.to raise_error(HealthCheckFailed)
@@ -149,7 +151,7 @@ module Omnibus
149
151
 
150
152
  it 'does not raise an exception when the healthcheck passes' do
151
153
  allow(subject).to receive(:shellout)
152
- .with("find #{project.install_dir}/ -type f | xargs ldd")
154
+ .with("find #{project.install_dir}/ -type f -regextype posix-extended ! -regex '#{regexp}' | xargs ldd")
153
155
  .and_return(good_healthcheck)
154
156
 
155
157
  expect { subject.run! }.to_not raise_error