omnibus 5.2.0 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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