class Litbuild::BlueprintLibrary

BlueprintLibrary initializes and sets configuration parameters for blueprints, and provides a common access point for blueprints and parameters. It always loads blueprints from the *current working directory* and uses config parameters from *the environment*.

Constants

REQUIRED_PARAMS

Attributes

blueprints[R]
parameters[R]

Public Class Methods

new(logfile_namer_class:) click to toggle source
# File lib/litbuild/blueprint_library.rb, line 19
def initialize(logfile_namer_class:)
  @blueprints = {}
  Blueprint.descendants.each do |blueprint_type|
    load_blueprints_of_type(blueprint_type)
  end
  @parameters = resolve_parameter_values
  log_namer = logfile_namer_class.new(@parameters['LOGFILE_DIR'])
  @blueprints.each_value do |bp|
    bp.prepare(parameters: @parameters,
               logfile_namer: log_namer,
               library: self)
  end
end

Public Instance Methods

blueprint_for(target:) click to toggle source
# File lib/litbuild/blueprint_library.rb, line 33
def blueprint_for(target:)
  name, phase = split_name_and_phase(target: target)
  bp = blueprints[name]
  unless bp
    raise(UnknownBlueprint, "Blueprint #{name} not found in library")
  end

  bp.for_phase(phase)
end
dependencies_for(blueprint) click to toggle source

Convert the dependency declarations found in a `depends-on` directive to actual blueprints. See the `Dependencies` section of doc/blueprints.txt for details on how this works.

# File lib/litbuild/blueprint_library.rb, line 46
def dependencies_for(blueprint)
  dep_names = blueprint.deduped_dependency_names
  dep_names.map do |dep|
    if dep.match?(/::/) # Explicit phase specified
      blueprint_for(target: dep)
    else
      bp = blueprint_for(target: dep)
      if bp.phases&.include?(blueprint.active_phase)
        bp.for_phase(blueprint.active_phase)
      else
        bp
      end
    end
  end
end

Private Instance Methods

load_blueprints_of_type(blueprint_type) click to toggle source

These methods are used during initialization, be cautious when modifying them.

# File lib/litbuild/blueprint_library.rb, line 77
def load_blueprints_of_type(blueprint_type)
  # Sometimes, starting in ruby 2.3, there is an extra singleton
  # descendant of Blueprint, or something. (This happens about a
  # thrid of the time, so I really mean "soemtime"s.) IDK what's
  # going on and I don't feel like fussing with it; this kludge
  # works around the issue, whatever it is.
  return unless blueprint_type.name

  Dir.glob("./#{blueprint_type.directory_name}/*.txt").each do |a_file|
    bp_text = File.read(a_file)
    begin
      # All blueprints have a name and a full-name. If a blueprint
      # has no `name:` or `full-name:` directive, they will be
      # provided at load time.
      %w[name full-name].each do |directive|
        unless bp_text.match?(/^#{directive}:/)
          bp_text = "#{directive}: #{File.basename(a_file, '.txt')}\n\n" +
                    bp_text
        end
      end
      bp = blueprint_type.new(text: bp_text)
    rescue ArgumentError => e
      raise(Litbuild::ParseError, "Could not parse #{a_file}: #{e.message}")
    end
    if @blueprints[bp.name]
      raise(DuplicateBlueprint,
            "Duplicate blueprint #{bp.name} found in #{a_file}")
    else
      @blueprints[bp.name] = bp
    end
  end
end
resolve_parameter_values() click to toggle source
# File lib/litbuild/blueprint_library.rb, line 110
def resolve_parameter_values
  values = {}
  REQUIRED_PARAMS.each { |key| values[key] = 'UNSET' }
  @blueprints.each_value do |bp|
    values.merge!(bp.parameter_defaults)
  end
  ENV.each do |k, v|
    values[k] = v if values.key?(k)
  end
  @parameters = values
end
split_name_and_phase(target:) click to toggle source

split a target name, like linux::headers, into a blueprint name (linux) and a phase name (headers).

# File lib/litbuild/blueprint_library.rb, line 66
def split_name_and_phase(target:)
  if target.match?(/::/)
    target.strip.match(/(.*)::(.*)/)[1..2]
  else
    [target.strip, nil]
  end
end