class Facter::Core::Aggregate
Attributes
@!attribute [r] confines
@return [Array<LegacyFacter::Core::Confine>] An array of confines restricting
this to a specific platform
@api private
@!attribute [r] deps
@return [LegacyFacter::Core::DirectedGraph]
@api private
@!attribute [r] fact
@return [Facter::Util::Fact]
@api private
@!attribute [r] name
@return [Symbol] The name of the aggregate resolution
@api public
Public Class Methods
# File lib/facter/custom_facts/core/aggregate.rb, line 56 def initialize(name, fact) @name = name @fact = fact @confines = [] @chunks = {} @aggregate = nil @deps = LegacyFacter::Core::DirectedGraph.new end
Public Instance Methods
Compares the weight of two aggregate facts
@return [bool] Weight comparison result
@api private
# File lib/facter/custom_facts/core/aggregate.rb, line 72 def <=>(other) weight <=> other.weight end
Define how all chunks should be combined
@example Merge all chunks
aggregate.aggregate do |chunks| final_result = {} chunks.each_value do |chunk| final_result.deep_merge(chunk) end final_result end
@example Sum all chunks
aggregate.aggregate do |chunks| total = 0 chunks.each_value do |chunk| total += chunk end total end
@yield [Hash<Symbol, Object>] A hash containing chunk names and
chunk values
@return [Facter::Core::Aggregate] The aggregate fact
@api public
# File lib/facter/custom_facts/core/aggregate.rb, line 158 def aggregate(&block) raise ArgumentError, "#{self.class.name}#aggregate requires a block" unless block_given? @aggregate = block self end
Define a new chunk for the given aggregate
@example Defining a chunk with no dependencies
aggregate.chunk(:mountpoints) do # generate mountpoint information end
@example Defining an chunk to add mount options
aggregate.chunk(:mount_options, :require => [:mountpoints]) do |mountpoints| # `mountpoints` is the result of the previous chunk # generate mount option information based on the mountpoints end
@param name [Symbol] A name unique to this aggregate describing the chunk
@param opts [Hash] Hash with options for the aggregate fact
@return [Facter::Core::Aggregate] The aggregate object
@api public
# File lib/facter/custom_facts/core/aggregate.rb, line 118 def chunk(name, opts = {}, &block) evaluate_params(name, &block) deps = Array(opts.delete(:require)) unless opts.empty? raise ArgumentError, "Unexpected options passed to #{self.class.name}#chunk: #{opts.keys.inspect}" end @deps[name] = deps @chunks[name] = block self end
Evaluates the given block
@return [String] Result of the block's evaluation
@api private
# File lib/facter/custom_facts/core/aggregate.rb, line 94 def evaluate(&block) instance_eval(&block) end
Sets options for the aggregate fact
@return [nil]
@api private
# File lib/facter/custom_facts/core/aggregate.rb, line 81 def options(options) accepted_options = %i[name timeout weight fact_type] accepted_options.each do |option_name| instance_variable_set("@#{option_name}", options.delete(option_name)) if options.key?(option_name) end raise ArgumentError, "Invalid aggregate options #{options.keys.inspect}" unless options.keys.empty? end
Returns the fact's resolution type
@return [Symbol] The fact's type
@api private
# File lib/facter/custom_facts/core/aggregate.rb, line 170 def resolution_type :aggregate end
Private Instance Methods
Process the results of all chunks with the aggregate block and return the results. If no aggregate block has been specified, fall back to deep merging the given data structure
@param results [Hash<Symbol, Object>] A hash of chunk names and the output
of that chunk.
@return [Object]
# File lib/facter/custom_facts/core/aggregate.rb, line 214 def aggregate_results(results) if @aggregate @aggregate.call(results) else default_aggregate(results) end end
# File lib/facter/custom_facts/core/aggregate.rb, line 222 def default_aggregate(results) results.values.inject do |result, current| LegacyFacter::Util::Values.deep_merge(result, current) end rescue LegacyFacter::Util::Values::DeepMergeError => e raise ArgumentError, 'Could not deep merge all chunks (Original error: ' \ "#{e.message}), ensure that chunks return either an Array or Hash or " \ 'override the aggregate block', e.backtrace end
# File lib/facter/custom_facts/core/aggregate.rb, line 176 def evaluate_params(name) raise ArgumentError, "#{self.class.name}#chunk requires a block" unless block_given? raise ArgumentError, "#{self.class.name}#expected chunk name to be a Symbol" unless name.is_a? Symbol end
Order chunks based on their dependencies
@return [Array<Symbol, Proc>] A list of chunk names and blocks in evaluation order.
# File lib/facter/custom_facts/core/aggregate.rb, line 235 def order_chunks unless @deps.acyclic? raise DependencyError, "Could not order chunks; found the following dependency cycles: #{@deps.cycles.inspect}" end sorted_names = @deps.tsort sorted_names.map do |name| [name, @chunks[name]] end end
Evaluate the results of this aggregate.
@see Facter::Core::Resolvable#value @return [Object]
# File lib/facter/custom_facts/core/aggregate.rb, line 185 def resolve_value chunk_results = run_chunks aggregate_results(chunk_results) end
Order all chunks based on their dependencies and evaluate each one, passing dependent chunks as needed.
@return [Hash<Symbol, Object>] A hash containing the chunk that
generated value and the related value.
# File lib/facter/custom_facts/core/aggregate.rb, line 195 def run_chunks results = {} order_chunks.each do |(name, block)| input = @deps[name].map { |dep_name| results[dep_name] } output = block.call(*input) results[name] = LegacyFacter::Util::Values.deep_freeze(output) end results end