Class: Litbuild::Blueprint

Inherits:
Object
  • Object
show all
Defined in:
lib/litbuild/blueprint.rb

Direct Known Subclasses

Commands, Narrative, Package, Section

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(text:) ⇒ Blueprint

WARNING: in most cases, a freshly-created blueprint cannot be used until it has also been prepared. (See below.)



29
30
31
32
33
34
35
36
# File 'lib/litbuild/blueprint.rb', line 29

def initialize(text:)
  parser = BlueprintParser.new(text)
  @base_directives = parser.base_directives
  @phase_directives = parser.phase_directives
  @base_grafs = parser.base_grafs
  @phase_grafs = parser.phase_grafs
  @active_phase = @base_directives['default-phase']&.first
end

Instance Attribute Details

#active_phaseObject (readonly)

Returns the value of attribute active_phase.



19
20
21
# File 'lib/litbuild/blueprint.rb', line 19

def active_phase
  @active_phase
end

#base_grafsObject (readonly)

Returns the value of attribute base_grafs.



20
21
22
# File 'lib/litbuild/blueprint.rb', line 20

def base_grafs
  @base_grafs
end

#logfile_namer=(value) ⇒ Object (writeonly)

Sets the attribute logfile_namer

Parameters:

  • value

    the value to set the attribute logfile_namer to.



21
22
23
# File 'lib/litbuild/blueprint.rb', line 21

def logfile_namer=(value)
  @logfile_namer = value
end

Class Method Details

.descendantsObject



23
24
25
# File 'lib/litbuild/blueprint.rb', line 23

def self.descendants
  ObjectSpace.each_object(Class).select { |c| c < self }
end

.directory_nameObject

This should simply be the name of the directory where blueprints of each specific type are expected to be found by Driver.



14
15
16
# File 'lib/litbuild/blueprint.rb', line 14

def self.directory_name
  raise(SubclassResponsibility)
end

Instance Method Details

#[](directive) ⇒ Object



94
95
96
# File 'lib/litbuild/blueprint.rb', line 94

def [](directive)
  directives[directive]
end

#accept(visitor:) ⇒ Object

Dependencies need to be handled before their dependants; that’s handled here. Subclasses should run ‘super` before doing anything else with the Visitor, or call the send_to_dependencies method directly, so that this happens properly!



60
61
62
# File 'lib/litbuild/blueprint.rb', line 60

def accept(visitor:)
  send_to_dependencies(visitor: visitor)
end

#deduped_dependency_namesObject

If a dependency is declared both without a phase (typically in the base directives for the blueprint) and with a phase (typically in a phase of that blueprint), throw away the phaseless declaration to avoid including two versions of the dependency.



181
182
183
184
185
186
187
188
189
# File 'lib/litbuild/blueprint.rb', line 181

def deduped_dependency_names
  dep_names = self['depends-on'].clone || []
  deps_with_phase = dep_names.select { |dep| dep.match?(/::/) }
  deps_with_phase.each do |dep|
    dep_without_phase = dep.split('::')[0]
    dep_names.delete(dep_without_phase)
  end
  dep_names
end

#directivesObject



86
87
88
89
90
91
92
# File 'lib/litbuild/blueprint.rb', line 86

def directives
  if active_phase
    @phase_directives[active_phase]
  else
    @base_directives
  end
end

#failure_lineObject



173
174
175
# File 'lib/litbuild/blueprint.rb', line 173

def failure_line
  'FAILURE'
end

#file_nameObject



122
123
124
125
126
127
128
# File 'lib/litbuild/blueprint.rb', line 122

def file_name
  if active_phase
    "#{name}-#{active_phase}"
  else
    name
  end.tr(' ', '-')
end

#for_phase(new_active_phase) ⇒ Object

Return a copy of this blueprint that is initialized to operate on the specified phase.



66
67
68
69
70
71
72
# File 'lib/litbuild/blueprint.rb', line 66

def for_phase(new_active_phase)
  return self unless phases?

  phased_blueprint = clone
  phased_blueprint.phase = new_active_phase if new_active_phase
  phased_blueprint
end

#full_nameObject



118
119
120
# File 'lib/litbuild/blueprint.rb', line 118

def full_name
  value('full-name')
end

#header_textObject



130
131
132
# File 'lib/litbuild/blueprint.rb', line 130

def header_text
  value('full-name')
end

#header_text_with_phaseObject



134
135
136
# File 'lib/litbuild/blueprint.rb', line 134

def header_text_with_phase
  "#{header_text} (#{active_phase} phase)"
end

#logfile(stage_name, phase_name = nil) ⇒ Object



138
139
140
141
# File 'lib/litbuild/blueprint.rb', line 138

def logfile(stage_name, phase_name = nil)
  phase = phase_name&.tr(' ', '_')
  @logfile_namer.path_for(name, phase, stage_name)
end

#nameObject



106
107
108
# File 'lib/litbuild/blueprint.rb', line 106

def name
  value('name')
end

#name_with_phaseObject



110
111
112
113
114
115
116
# File 'lib/litbuild/blueprint.rb', line 110

def name_with_phase
  if active_phase
    "#{name}::#{active_phase}"
  else
    name
  end
end

#parameter_defaultsObject



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/litbuild/blueprint.rb', line 143

def parameter_defaults
  values = {}
  all_directive_sets = [@base_directives, @phase_directives.values].flatten
  all_directive_sets.each do |dirset|
    next unless dirset.key?('parameter')

    dirset['parameter'].each do |a_param|
      val = a_param['default'].first
      values[a_param['name'].first] = if val == '(empty)'
                                        ''
                                      else
                                        val
                                      end
    end
  end
  values
end

#phase_grafsObject



82
83
84
# File 'lib/litbuild/blueprint.rb', line 82

def phase_grafs
  @phase_grafs[active_phase]
end

#phasesObject



74
75
76
# File 'lib/litbuild/blueprint.rb', line 74

def phases
  @phase_directives.keys
end

#phases?Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/litbuild/blueprint.rb', line 78

def phases?
  !@phase_directives.empty?
end

#prepare(parameters:, logfile_namer:, library:) ⇒ Object

This prepares a blueprint for use. This is separate from initialize because parameters are not available until after all blueprints have been parsed, and the logfile namer is not available until after the LOGFILE_DIR parameter can be resolved.

Parameters is a set of configuration parameters Logfile_namer is used to generate log file names Library is the BlueprintLibrary, used (for example) to find dependencies.



47
48
49
50
51
52
53
54
# File 'lib/litbuild/blueprint.rb', line 47

def prepare(parameters:, logfile_namer:, library:)
  @logfile_namer = logfile_namer
  @bp_library = library
  [@base_directives,
   @phase_directives,
   @base_grafs,
   @phase_grafs].each { |component| resolve_all(parameters, component) }
end

#success_lineObject



169
170
171
# File 'lib/litbuild/blueprint.rb', line 169

def success_line
  'SUCCESS'
end

#target_nameObject



161
162
163
164
165
166
167
# File 'lib/litbuild/blueprint.rb', line 161

def target_name
  if active_phase
    "#{name}::#{active_phase}"
  else
    name
  end
end

#value(directive) ⇒ Object

This is just like the [] operator method except that it always returns only the first value for a directive – which is helpful for all the directives that are only ever supposed to have a single value, like ‘name` or `full-name`.



102
103
104
# File 'lib/litbuild/blueprint.rb', line 102

def value(directive)
  self[directive]&.first
end