lib/framework/formatters/yaml_fact_formatter.rb
# frozen_string_literal: true
module Facter
class YamlFactFormatter
def initialize
@log = Log.new(self)
end
def format(resolved_facts)
user_queries = resolved_facts.uniq(&:user_query).map(&:user_query)
facts_to_display = if user_queries.count == 1 && user_queries.first.empty?
FormatterHelper.retrieve_fact_collection(resolved_facts)
else
FormatterHelper.retrieve_facts_to_display_for_user_query(user_queries, resolved_facts)
end
facts_to_display = Psych.parse_stream(facts_to_display.to_yaml)
facts_to_display.children[0].tag_directives = []
yaml_pretty = quote_special_strings(facts_to_display)
@log.debug('Replace --- from yaml beginning, to keep it compatible with C facter')
yaml_pretty.gsub(/^---[\r\n]+/, '')
end
private
def quote_special_strings(fact_hash)
require 'psych'
fact_hash.grep(Psych::Nodes::Scalar).each do |node|
next unless needs_quote?(node.value)
node.plain = false
node.quoted = true
node.style = Psych::Nodes::Scalar::DOUBLE_QUOTED
end
fact_hash = unquote_keys(fact_hash)
fact_hash.yaml
end
def unquote_keys(fact_hash)
fact_hash.grep(Psych::Nodes::Mapping).each do |node|
node.children.each_slice(2) do |k, _|
k.plain = true
k.quoted = false
k.style = Psych::Nodes::Scalar::ANY
end
end
fact_hash
end
def needs_quote?(value)
return false if value =~ /true|false/
return false if value[/^[0-9]+$/]
return true if value =~ /y|Y|yes|Yes|YES|n|N|no|No|NO|True|TRUE|False|FALSE|on|On|ON|off|Off|OFF|:/
return false if value[/[a-zA-Z]/]
return false if value[/[0-9]+\.[0-9]+\./]
true
end
end
end