rspec-puppet-facts 2.0.5 → 3.0.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.
@@ -2,6 +2,6 @@ module RspecPuppetFacts
2
2
  # This module contains the current version constant
3
3
  module Version
4
4
  # The current version of this gem
5
- STRING = '2.0.5'
5
+ STRING = '3.0.0'
6
6
  end
7
7
  end
@@ -2,6 +2,7 @@ require 'puppet'
2
2
  require 'facter'
3
3
  require 'facterdb'
4
4
  require 'json'
5
+ require 'deep_merge'
5
6
 
6
7
  # The purpose of this module is to simplify the Puppet
7
8
  # module's RSpec tests by looping through all supported
@@ -56,7 +57,7 @@ module RspecPuppetFacts
56
57
  #
57
58
  # @api private
58
59
  def on_supported_os_implementation(opts = {})
59
- unless (facterversion = opts[:facterversion]) =~ /\A\d+\.\d+(?:\.\d+)*\z/
60
+ unless /\A\d+\.\d+(?:\.\d+)*\z/.match?((facterversion = opts[:facterversion]))
60
61
  raise ArgumentError, ":facterversion must be in the format 'n.n' or " \
61
62
  "'n.n.n' (n is numeric), not '#{facterversion}'"
62
63
  end
@@ -68,19 +69,20 @@ module RspecPuppetFacts
68
69
  opts[:hardwaremodels].each do |hardwaremodel|
69
70
 
70
71
  os_release_filter = "/^#{Regexp.escape(operatingsystemmajrelease.split(' ')[0])}/"
71
- if os_sup['operatingsystem'] =~ /BSD/i
72
+ case os_sup['operatingsystem']
73
+ when /BSD/i
72
74
  hardwaremodel = 'amd64'
73
- elsif os_sup['operatingsystem'] =~ /Solaris/i
75
+ when /Solaris/i
74
76
  hardwaremodel = 'i86pc'
75
- elsif os_sup['operatingsystem'] =~ /AIX/i
77
+ when /AIX/i
76
78
  hardwaremodel = '/^IBM,.*/'
77
79
  os_release_filter = if operatingsystemmajrelease =~ /\A(\d+)\.(\d+)\Z/
78
80
  "/^#{$~[1]}#{$~[2]}00-/"
79
81
  else
80
82
  "/^#{operatingsystemmajrelease}-/"
81
83
  end
82
- elsif os_sup['operatingsystem'] =~ /Windows/i
83
- hardwaremodel = facterversion =~ /^[12]\./ ? 'x64' : 'x86_64'
84
+ when /Windows/i
85
+ hardwaremodel = /^[12]\./.match?(facterversion) ? 'x64' : 'x86_64'
84
86
  os_sup['operatingsystem'] = os_sup['operatingsystem'].downcase
85
87
  operatingsystemmajrelease = operatingsystemmajrelease[/\A(?:Server )?(.+)/i, 1]
86
88
 
@@ -90,7 +92,7 @@ module RspecPuppetFacts
90
92
  if operatingsystemmajrelease == '2016' && Puppet::Util::Package.versioncmp(facterversion, '3.4') < 0
91
93
  os_release_filter = '/^10\\.0\\./'
92
94
  end
93
- elsif os_sup['operatingsystem'] =~ /Amazon/i
95
+ when /Amazon/i
94
96
  # Tighten the regex for Amazon Linux 2 so that we don't pick up Amazon Linux 2016 or 2017 facts
95
97
  os_release_filter = "/^2$/" if operatingsystemmajrelease == '2'
96
98
  end
@@ -112,35 +114,33 @@ module RspecPuppetFacts
112
114
  end
113
115
  end
114
116
 
115
- facterversion_obj = Gem::Version.new(facterversion)
117
+ strict_requirement = RspecPuppetFacts::facter_version_to_strict_requirement(facterversion)
118
+
119
+ loose_requirement = RspecPuppetFacts::facter_version_to_loose_requirement(facterversion)
120
+ received_facts = []
116
121
 
117
122
  # FacterDB may have newer versions of facter data for which it contains a subset of all possible
118
123
  # facter data (see FacterDB 0.5.2 for Facter releases 3.8 and 3.9). In this situation we need to
119
124
  # cycle through and downgrade Facter versions per platform type until we find matching Facter data.
120
125
  filter.each do |filter_spec|
121
- facter_version_filter = RspecPuppetFacts.facter_version_to_filter(facterversion)
122
- db = FacterDB.get_facts(filter_spec.merge({ :facterversion => facter_version_filter }))
123
-
124
- if db.empty?
125
- if RspecPuppetFacts.spec_facts_strict?
126
- raise ArgumentError, "No facts were found in the FacterDB for Facter v#{facterversion} on #{filter_spec}, aborting"
127
- end
126
+ versions = FacterDB.get_facts(filter_spec).to_h { |facts| [Gem::Version.new(facts[:facterversion]), facts] }
128
127
 
129
- version = FacterDB.get_facts(filter_spec).map { |facts| Gem::Version.new(facts[:facterversion]) }.sort.reverse.detect { |v| v <= facterversion_obj }
128
+ version, facts = versions.select { |v, _f| strict_requirement =~ v }.max_by { |v, _f| v }
130
129
 
130
+ unless version
131
+ version, facts = versions.select { |v, _f| loose_requirement =~ v }.max_by { |v, _f| v } if loose_requirement
131
132
  next unless version
132
- version = version.to_s
133
- facter_version_filter = "/\\A#{Regexp.escape(version)}/"
134
133
 
135
- unless version == facterversion
136
- RspecPuppetFacts.warning "No facts were found in the FacterDB for Facter v#{facterversion} on #{filter_spec}, using v#{version} instead"
134
+ if RspecPuppetFacts.spec_facts_strict?
135
+ raise ArgumentError, "No facts were found in the FacterDB for Facter v#{facterversion} on #{filter_spec}, aborting"
137
136
  end
137
+
138
+ RspecPuppetFacts.warning "No facts were found in the FacterDB for Facter v#{facterversion} on #{filter_spec}, using v#{version} instead"
138
139
  end
139
140
 
140
- filter_spec[:facterversion] = facter_version_filter
141
+ received_facts << facts
141
142
  end
142
143
 
143
- received_facts = FacterDB::get_facts(filter)
144
144
  unless received_facts.any?
145
145
  RspecPuppetFacts.warning "No facts were found in the FacterDB for: #{filter.inspect}"
146
146
  return {}
@@ -178,8 +178,9 @@ module RspecPuppetFacts
178
178
  os_facts_hash
179
179
  end
180
180
 
181
+ # @api private
181
182
  def stringify_keys(hash)
182
- Hash[hash.collect { |k,v| [k.to_s, v.is_a?(Hash) ? stringify_keys(v) : v] }]
183
+ hash.to_h { |k, v| [k.to_s, v.is_a?(Hash) ? stringify_keys(v) : v] }
183
184
  end
184
185
 
185
186
  # Register a custom fact that will be included in the facts hash.
@@ -210,7 +211,8 @@ module RspecPuppetFacts
210
211
  # @api private
211
212
  def self.register_custom_fact(name, value, options)
212
213
  @custom_facts ||= {}
213
- @custom_facts[name.to_s] = {:options => options, :value => value}
214
+ name = RSpec.configuration.facterdb_string_keys ? name.to_s : name.to_sym
215
+ @custom_facts[name] = {:options => options, :value => value}
214
216
  end
215
217
 
216
218
  # Adds any custom facts according to the rules defined for the operating
@@ -226,7 +228,13 @@ module RspecPuppetFacts
226
228
  next if fact[:options][:confine] && !fact[:options][:confine].include?(os)
227
229
  next if fact[:options][:exclude] && fact[:options][:exclude].include?(os)
228
230
 
229
- facts[name] = fact[:value].respond_to?(:call) ? fact[:value].call(os, facts) : fact[:value]
231
+ value = fact[:value].respond_to?(:call) ? fact[:value].call(os, facts) : fact[:value]
232
+ # if merge_facts passed, merge supplied facts into facts hash
233
+ if fact[:options][:merge_facts]
234
+ facts.deep_merge!({name => value})
235
+ else
236
+ facts[name] = value
237
+ end
230
238
  end
231
239
 
232
240
  facts
@@ -352,13 +360,47 @@ module RspecPuppetFacts
352
360
  @metadata = nil
353
361
  end
354
362
 
355
- # Generates a JGrep statement expression for a specific facter version
356
- # @return [String] JGrep statement expression
357
- # @param version [String] the Facter version
363
+ # Construct the strict facter version requirement
364
+ # @return [Gem::Requirement] The version requirement to match
358
365
  # @api private
359
- def self.facter_version_to_filter(version)
360
- major, minor = version.split('.')
361
- "/\\A#{major}\\.#{minor}\\./"
366
+ def self.facter_version_to_strict_requirement(version)
367
+ Gem::Requirement.new(facter_version_to_strict_requirement_string(version))
368
+ end
369
+
370
+ # Construct the strict facter version requirement string
371
+ # @return [String] The version requirement to match
372
+ # @api private
373
+ def self.facter_version_to_strict_requirement_string(version)
374
+ if /\A[0-9]+(\.[0-9]+)*\Z/.match?(version)
375
+ # Interpret 3 as ~> 3.0
376
+ "~> #{version}.0"
377
+ else
378
+ version
379
+ end
380
+ end
381
+
382
+ # Construct the loose facter version requirement
383
+ # @return [Optional[Gem::Requirement]] The version requirement to match
384
+ # @api private
385
+ def self.facter_version_to_loose_requirement(version)
386
+ string = facter_version_to_loose_requirement_string(version)
387
+ Gem::Requirement.new(string) if string
388
+ end
389
+
390
+ # Construct the facter version requirement string
391
+ # @return [String] The version requirement to match
392
+ # @api private
393
+ def self.facter_version_to_loose_requirement_string(version)
394
+ if (m = /\A(?<major>[0-9]+)\.(?<minor>[0-9]+)(?:\.(?<patch>[0-9]+))?\Z/.match(version))
395
+ # Interpret 3.1 as < 3.2 and 3.2.1 as < 3.3
396
+ "< #{m[:major]}.#{m[:minor].to_i + 1}"
397
+ elsif /\A[0-9]+\Z/.match?(version)
398
+ # Interpret 3 as < 4
399
+ "< #{version.to_i + 1}"
400
+ else
401
+ # This would be the same as the strict requirement
402
+ nil
403
+ end
362
404
  end
363
405
 
364
406
  def self.facter_version_for_puppet_version(puppet_version)
@@ -13,18 +13,20 @@ Gem::Specification.new do |s|
13
13
  s.description = 'Contains facts from many Facter version on many Operating Systems'
14
14
  s.licenses = 'Apache-2.0'
15
15
 
16
- # see .travis.yml for the supported ruby versions
17
- s.required_ruby_version = '>= 2.4.0'
16
+ s.required_ruby_version = '>= 2.7.0'
18
17
 
19
18
  s.files = `git ls-files`.split("\n")
20
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
19
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
22
20
 
23
- s.add_development_dependency 'mime-types'
24
- s.add_development_dependency 'rake'
25
- s.add_development_dependency 'rspec'
26
- s.add_development_dependency 'yard'
27
- s.add_runtime_dependency 'puppet'
28
- s.add_runtime_dependency 'facter'
29
- s.add_runtime_dependency 'facterdb', '>= 0.5.0'
21
+ s.add_development_dependency 'mime-types', '~> 3.5', '>= 3.5.2'
22
+ s.add_development_dependency 'rake', '~> 13.1'
23
+ s.add_development_dependency 'rspec', '~> 3.12'
24
+ s.add_development_dependency 'yard', '~> 0.9.34'
25
+
26
+ s.add_development_dependency 'voxpupuli-rubocop', '~> 2.6.0'
27
+
28
+ s.add_runtime_dependency 'deep_merge', '~> 1.2'
29
+ s.add_runtime_dependency 'facter', '< 5'
30
+ s.add_runtime_dependency 'facterdb', '>= 0.5.0', '< 2'
31
+ s.add_runtime_dependency 'puppet', '>= 7', '< 9'
30
32
  end