lib/facter/framework/core/options/options_validator.rb
# frozen_string_literal: true
module Facter
module OptionsValidator
INVALID_PAIRS_RULES = { '--color' => '--no-color',
'--json' => ['--no-json', '-y', '--yaml', '--hocon'],
'--yaml' => ['--no-yaml', '-j', '--hocon'],
'--hocon' => '--no-hocon',
'-j' => ['--no-json', '--hocon'],
'-y' => ['--no-yaml', '-j', '--hocon'],
'--puppet' => ['--no-puppet', '--no-ruby', '--no-custom-facts'],
'-p' => ['--no-puppet', '--no-ruby', '--no-custom-facts'],
'--no-external-facts' => '--external-dir',
'--custom-dir' => ['--no-custom-facts', '--no-ruby'] }.freeze
DUPLICATED_OPTIONS_RULES = { '-j' => '--json', '-y' => '--yaml', '-p' => '--puppet', '-h' => '--help',
'-v' => '--version', '-l' => '--log-level', '-d' => '--debug',
'-c' => '--config' }.freeze
LOG_LEVEL = %i[none trace debug info warn error fatal].freeze
def self.validate(options)
DUPLICATED_OPTIONS_RULES.each do |key, value|
if options.include?(key) && options.include?(value)
write_error_and_exit("option #{value} cannot be specified more than once.")
end
end
INVALID_PAIRS_RULES.each do |key, value|
common_values = [value].flatten & options
if options.include?(key) && common_values.any?
write_error_and_exit("#{key} and #{common_values.first} options conflict: please specify only one.")
end
end
end
def self.write_error_and_exit(message)
log = Facter::Log.new(self)
log.error(message, true)
Facter::Cli.start(['--help'])
exit 1
end
def self.validate_configs(options)
conflicting_configs(options).each do |op|
next unless op.values[0] && op.values[1]
message = "#{op.keys[0]} and #{op.keys[1]} options conflict: please specify only one"
write_error_and_exit(message)
end
validate_log_options(options)
end
def self.conflicting_configs(options)
no_ruby = !options[:ruby]
no_custom_facts = !options[:custom_facts]
puppet = options[:puppet]
custom_dir = options[:custom_dir].nil? ? false : options[:custom_dir].any?
default_external_dir = Facter::OptionStore.default_external_dir
# --puppet/-p option adds an external directory and is not an explicitly
# set external_dir from cli or config file
default_external_dir += [Puppet[:pluginfactdest]] if puppet && const_defined?('Puppet')
external_dir = if options[:external_dir].nil? || options[:external_dir].none?
false
else
options[:external_dir] != default_external_dir
end
[
{ 'no-ruby' => no_ruby, 'custom-dir' => custom_dir },
{ 'no-external-facts' => !options[:external_facts], 'external-dir' => external_dir },
{ 'no-custom-facts' => no_custom_facts, 'custom-dir' => custom_dir },
{ 'no-ruby' => no_ruby, 'puppet' => puppet },
{ 'no-custom-facts' => no_custom_facts, 'puppet' => puppet }
]
end
def self.validate_log_options(options)
# TODO: find a better way to do this
return if options[:debug] == true && options[:log_level] == :debug
return if options[:verbose] == true && options[:log_level] == :info
return unless [options[:debug],
options[:verbose],
options[:log_level] != Facter::DEFAULT_LOG_LEVEL]
.count(true) > 1
message = 'debug, verbose, and log-level options conflict: please specify only one.'
write_error_and_exit(message)
end
end
end