class Build::Environment

This is the basic environment data structure which is essentially a linked list of hashes. It is primarily used for organising build configurations across a wide range of different sub-systems, e.g. platform configuration, target configuration, local project configuration, etc.

Constants

Default
Replace
VERSION

Attributes

name[R]
parent[R]
update[R]
values[R]

Public Class Methods

combine(*environments) click to toggle source

Flatten the list of environments.

# File lib/build/environment/constructor.rb, line 129
def self.combine(*environments)
        ordered = []
        
        environments.each do |environment|
                environment.flatten_to_array(ordered)
        end
        
        ordered.inject(nil) do |parent, environment|
                environment.dup(parent: parent)
        end
end
new(parent = nil, values = nil, name: nil, &block) click to toggle source
# File lib/build/environment/base.rb, line 24
def initialize(parent = nil, values = nil, name: nil, &block)
        @parent = parent
        @values = (values || {}).to_h
        @update = block
        
        @name = name
end
system_environment(env = ENV, **options) click to toggle source

Construct an environment from a given system environment:

# File lib/build/environment/system.rb, line 64
def self.system_environment(env = ENV, **options)
        self.new(nil, Hash[env.map{|key, value| [key.downcase.to_sym, value]}], **options)
end

Public Instance Methods

==(other) click to toggle source
# File lib/build/environment/base.rb, line 32
def == other
        self.equal?(other) or
                self.class == other.class and
                @parent == other.parent and
                @values == other.values and
                @update == other.update and
                @name == other.name
end
[](key) click to toggle source
# File lib/build/environment/base.rb, line 100
def [](key)
        environment = lookup(key)
        
        environment ? environment.values[key] : nil
end
[]=(key, value) click to toggle source
# File lib/build/environment/base.rb, line 106
def []=(key, value)
        @values[key] = value
end
checksum(digester: Digest::SHA1.new) click to toggle source
# File lib/build/environment/flatten.rb, line 60
def checksum(digester: Digest::SHA1.new)
        checksum_recursively(digester)
        
        return digester.hexdigest
end
construct!(proxy, *arguments, &block) click to toggle source
# File lib/build/environment/constructor.rb, line 38
def construct!(proxy, *arguments, &block)
        constructor = Constructor.new(self, proxy)
        
        if block_given?
                constructor.instance_exec(*arguments, &block)
        end
        
        return self
end
defined() click to toggle source
# File lib/build/environment/flatten.rb, line 56
def defined
        @values.select{|name,value| Define === value}
end
dup(parent: @parent, values: @values, update: @update, name: @name) click to toggle source
# File lib/build/environment/base.rb, line 54
def dup(parent: @parent, values: @values, update: @update, name: @name)
        self.class.new(parent, values.dup, name: name, &update)
end
eql?(other) click to toggle source
# File lib/build/environment/base.rb, line 41
def eql?(other)
        self == other
end
evaluate(**options) click to toggle source
# File lib/build/environment/flatten.rb, line 42
def evaluate(**options)
        self.class.new(nil, self.to_h, **options)
end
evaluator() click to toggle source
# File lib/build/environment/flatten.rb, line 38
def evaluator
        Evaluator.new(self)
end
export() click to toggle source

Make a hash appropriate for a process environment

# File lib/build/environment/system.rb, line 69
def export
        System.convert_to_shell(self)
end
fetch(key, *default) { |key, *default| ... } click to toggle source
# File lib/build/environment/base.rb, line 88
def fetch(key, *default, &block)
        if environment = lookup(key)
                return environment.values[key]
        elsif block_given?
                yield(key, *default)
        elsif !default.empty?
                return default.first
        else
                raise KeyError.new("Environment missing #{key}")
        end
end
flatten(**options) click to toggle source
# File lib/build/environment/flatten.rb, line 46
def flatten(**options)
        hash = {}
        
        flatten_to_hash(hash)
        
        options[:name] ||= self.name
        
        return self.class.new(nil, hash, **options)
end
flatten_to_array(array) click to toggle source
# File lib/build/environment/constructor.rb, line 154
def flatten_to_array(array)
        if @parent
                @parent.flatten_to_array(array)
        end
        
        array << self
end
freeze() click to toggle source
Calls superclass method
# File lib/build/environment/base.rb, line 58
def freeze
        return self if frozen?
        
        @parent.freeze
        @values.freeze
        @update.freeze
        
        super
end
hash() click to toggle source
# File lib/build/environment/base.rb, line 45
def hash
        @parent.hash ^ @values.hash ^ @update.hash ^ @name.hash
end
include?(key) click to toggle source
# File lib/build/environment/base.rb, line 76
def include?(key)
        if @values.include?(key)
                true
        elsif @parent
                @parent.include?(key)
        end
end
lookup(name) click to toggle source
# File lib/build/environment/base.rb, line 68
def lookup(name)
        if @values.include? name
                self
        elsif @parent
                @parent.lookup(name)
        end
end
merge(**options, &block) click to toggle source
# File lib/build/environment/constructor.rb, line 141
def merge(**options, &block)
        self.class.new(self, **options, &block)
end
size() click to toggle source
# File lib/build/environment/base.rb, line 84
def size
        @values.size + (@parent ? @parent.size : 0)
end
to_a() click to toggle source

Convert the hierarchy of environments to an array where the parent comes before the child.

# File lib/build/environment/constructor.rb, line 146
def to_a
        flat = []
        
        flatten_to_array(flat)
        
        return flat
end
to_h() click to toggle source
# File lib/build/environment/flatten.rb, line 25
def to_h
        hash = {}
        
        # Flatten this chain of environments:
        flatten_to_hash(hash)
        
        # Evaluate all items to their respective object value:
        evaluator = Evaluator.new(hash)
        
        # Evaluate all the individual environment values so that they are flat:
        Hash[hash.map{|key, value| [key, evaluator.object_value(value)]}]
end
to_s() click to toggle source
# File lib/build/environment/base.rb, line 110
def to_s
        buffer = String.new("\#<#{self.class} ")
        
        if @name
                buffer << @name.inspect << ' '
        end
        
        if @update
                buffer << @update.source_location.join(':') << ' '
        end
        
        buffer << @values.to_s << '>'
        
        return buffer
end

Protected Instance Methods

checksum_recursively(digester) click to toggle source
# File lib/build/environment/flatten.rb, line 72
def checksum_recursively(digester)
        sorted_keys.each do |key|
                digester.update(key.to_s)
                
                case value = @values[key]
                when Proc
                        digester.update(value.source_location.join)
                else
                        digester.update(value.to_s)
                end
        end
        
        @parent.checksum_recursively(digester) if @parent
end
flatten_to_hash(hash) click to toggle source

We fold in the ancestors one at a time from oldest to youngest.

# File lib/build/environment/flatten.rb, line 119
def flatten_to_hash(hash)
        if parent = @parent
                parent = parent.flatten_to_hash(hash)
        end
        
        if @update
                self.dup(parent: parent).update!.update_hash(hash)
        else
                self.update_hash(hash)
        end
end
sorted_keys() click to toggle source
# File lib/build/environment/flatten.rb, line 68
def sorted_keys
        @values.keys.sort_by(&:to_s)
end
update!() click to toggle source

Apply the update function to this environment.

# File lib/build/environment/flatten.rb, line 111
def update!
        construct!(self, &@update)
        @update = nil
        
        return self
end
update_hash(hash) click to toggle source
# File lib/build/environment/flatten.rb, line 87
def update_hash(hash)
        @values.each do |key, value|
                previous = hash[key]
                
                if Replace === value
                        # Replace the parent value
                        hash[key] = value
                elsif Default === value
                        # Update the parent value if not defined.
                        hash[key] = previous || value
                elsif Array === previous
                        # Merge with the parent value
                        hash[key] = previous + Array(value)
                elsif OpenStruct === value
                        hash[key] = value.to_h
                else
                        hash[key] = value
                end
        end
        
        return self
end