From a072a763fed5f27084cdceb726dff6c120be816d Mon Sep 17 00:00:00 2001 From: jordanbreen28 Date: Wed, 19 Jul 2023 13:58:56 +0100 Subject: [PATCH 1/2] (maint) - Add deep_merge gem dependency --- lib/rspec-puppet-facts.rb | 1 + rspec-puppet-facts.gemspec | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/rspec-puppet-facts.rb b/lib/rspec-puppet-facts.rb index 9745740f..cbe4d840 100644 --- a/lib/rspec-puppet-facts.rb +++ b/lib/rspec-puppet-facts.rb @@ -2,6 +2,7 @@ require 'facter' require 'facterdb' require 'json' +require 'deep_merge' # The purpose of this module is to simplify the Puppet # module's RSpec tests by looping through all supported diff --git a/rspec-puppet-facts.gemspec b/rspec-puppet-facts.gemspec index fabd0fbb..a1f5c7ca 100644 --- a/rspec-puppet-facts.gemspec +++ b/rspec-puppet-facts.gemspec @@ -25,6 +25,7 @@ Gem::Specification.new do |s| s.add_development_dependency 'voxpupuli-rubocop', '~> 2.4.0' + s.add_runtime_dependency 'deep_merge', '~> 1.2' s.add_runtime_dependency 'facter', '< 5' s.add_runtime_dependency 'facterdb', '>= 0.5.0', '< 2' s.add_runtime_dependency 'puppet', '>= 7', '< 9' From d0c9451738a25925afefbee525622c46555c0117 Mon Sep 17 00:00:00 2001 From: jordanbreen28 Date: Wed, 24 Jan 2024 14:04:56 +0000 Subject: [PATCH 2/2] (feat) - Add merge_facts option This commit adds an option to the add_custom_fact method, which allows the user to specify whether they wish to deep_merge facts. This allows the user to determine whether they wish to completely overwrite a fact, or simply merge values into the existing fact in a given fact hash. --- README.md | 22 ++++++++++++++++++++++ lib/rspec-puppet-facts.rb | 8 +++++++- spec/rspec_puppet_facts_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f177212..fdfa1b5d 100644 --- a/README.md +++ b/README.md @@ -443,6 +443,28 @@ To do this, pass a lambda as the value for the custom fact. The lambda is passed add_custom_fact :root_home, lambda { |os,facts| "/tmp/#{facts['hostname']}" } ``` +#### Merge into existing facts + +You can also supply an optional input `:merge_facts` to the `add_custom_fact` method. + +This allows you to merge facts values into a fact, if the fact is already present in the facts hash as oppose to overwriting the fact value. + +```ruby +add_custom_fact :identity, { 'user' => 'test_user' }, merge_facts: true +``` + +Will result in a hash of the identity fact like the below: + +```ruby +{ + "gid"=>0, + "group"=>"root", + "privileged"=>true, + "uid"=>0, + "user"=>"test_user" +} +``` + ### Supplying Custom External Facts through FacterDB Rspec-puppet-facts uses a gem called facterdb that contains many fact sets of various combinations that are pre generated. Rspec-puppet-facts queries facterdb to pull out a specific fact set to use when testing. diff --git a/lib/rspec-puppet-facts.rb b/lib/rspec-puppet-facts.rb index cbe4d840..0f5f0cd7 100644 --- a/lib/rspec-puppet-facts.rb +++ b/lib/rspec-puppet-facts.rb @@ -228,7 +228,13 @@ def self.with_custom_facts(os, facts) next if fact[:options][:confine] && !fact[:options][:confine].include?(os) next if fact[:options][:exclude] && fact[:options][:exclude].include?(os) - facts[name] = fact[:value].respond_to?(:call) ? fact[:value].call(os, facts) : fact[:value] + value = fact[:value].respond_to?(:call) ? fact[:value].call(os, facts) : fact[:value] + # if merge_facts passed, merge supplied facts into facts hash + if fact[:options][:merge_facts] + facts.deep_merge!({name => value}) + else + facts[name] = value + end end facts diff --git a/spec/rspec_puppet_facts_spec.rb b/spec/rspec_puppet_facts_spec.rb index 40fd0795..45b0da00 100644 --- a/spec/rspec_puppet_facts_spec.rb +++ b/spec/rspec_puppet_facts_spec.rb @@ -902,6 +902,26 @@ expect(subject['redhat-7-x86_64'][:root_home]).to eq '/root' end + it 'merges a fact value into fact when merge_facts passed' do + add_custom_fact :identity, { 'user' => 'test_user' }, merge_facts: true + expect(subject['redhat-7-x86_64'][:identity]).to eq( + { + "gid"=>0, + "group"=>"root", + "privileged"=>true, + "uid"=>0, + "user"=>"test_user" + }) + end + + it 'overwrites fact' do + add_custom_fact :identity, { 'user' => 'other_user' } + expect(subject['redhat-7-x86_64'][:identity]).to eq( + { + "user"=>"other_user" + }) + end + it 'confines a fact to a particular operating system' do add_custom_fact 'root_home', '/root', :confine => 'redhat-7-x86_64' expect(subject['redhat-7-x86_64'][:root_home]).to eq '/root'