Class: Plover::Builder

Inherits:
Object
  • Object
show all
Extended by:
Log
Includes:
Log
Defined in:
lib/plover.rb

Defined Under Namespace

Modules: Common Classes: ArtifactError, BuildError, FlagError

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Log

log, log_config, log_level, log_severity, logger

Constructor Details

#initialize(flags = {}, use_env_flags: true) ⇒ Builder

Returns a new instance of Builder.



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/plover.rb', line 195

def initialize(flags = {}, use_env_flags: true)
  @configuration = self.class.configuration

  @configuration[:options][:log][:level] = ENV["PLOVER_LOG_LEVEL"]&.to_sym || flags[:log_level] || @configuration[:options][:log][:level] || :info
  @configuration[:options][:log][:sink] = ENV["PLOVER_LOG_SINK"] || flags[:log_sink] || @configuration[:options][:log][:sink] || :stdout

  @configuration[:options][:flags] = @configuration[:options][:flags].merge(flags).merge(use_env_flags ? self.class.env_flags : {})

  self.class.auto_include_common

  if @configuration[:options][:expected_flags].any?
    missing_flags = @configuration[:options][:expected_flags].reject { |sym| @configuration[:options][:flags].key?(sym) }
    fail_build("Missing required flags: #{missing_flags.join(", ")}") if missing_flags.any?
  end

  log :debug, "Initialized, options=#{@configuration[:options]}"
end

Class Attribute Details

.configurationObject (readonly)

Returns the value of attribute configuration.



115
116
117
# File 'lib/plover.rb', line 115

def configuration
  @configuration
end

Instance Attribute Details

#configurationObject (readonly)

Returns the value of attribute configuration.



84
85
86
# File 'lib/plover.rb', line 84

def configuration
  @configuration
end

Class Method Details

.auto_include_commonObject



168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/plover.rb', line 168

def auto_include_common
  return if @configuration[:options][:common_include] == :none

  ObjectSpace.each_object(Module).select { |m| m&.name&.start_with?("Plover::Builder::Common::") }.each do |mod|
    next if mod.name.to_s.end_with?("::ClassMethods")

    next if @configuration[:options][:common_include].is_a?(Array) && !@configuration[:options][:common_include].any? { |m| m == mod.name.split("::").last }

    if mod.respond_to?(:apply_concern) && !included_modules.include?(mod)
      log(:debug, "Loading Common #{mod.name}")
      mod.apply_concern(self)
    end
  end
end

.common_include(*modules) ⇒ Object



147
148
149
150
151
152
# File 'lib/plover.rb', line 147

def common_include(*modules)
  configuration[:options][:common_include] = [] unless configuration[:options][:common_include].is_a?(Array)

  configuration[:options][:common_include].concat(modules)
  auto_include_common
end

.common_include_allObject



130
131
132
133
# File 'lib/plover.rb', line 130

def common_include_all
  configuration[:options][:common_include] = :all
  auto_include_common
end

.common_include_noneObject



135
136
137
# File 'lib/plover.rb', line 135

def common_include_none
  configuration[:options][:common_include] = :none
end

.deep_copy(obj) ⇒ Object



183
184
185
186
187
188
189
190
191
192
# File 'lib/plover.rb', line 183

def deep_copy(obj)
  case obj
  when Hash
    obj.each_with_object({}) { |(k, v), h| h[k] = deep_copy(v) }
  when Array
    obj.map { |e| deep_copy(e) }
  else
    obj
  end
end

.env_flagsObject



154
155
156
157
158
# File 'lib/plover.rb', line 154

def env_flags
  ENV.select { |key, _| key.start_with?("PLOVER_FLAG_") }
    .map { |key, value| [key.sub(/^PLOVER_FLAG_/, "").downcase.to_sym, value] }
    .to_h
end

.expect_flags(*flags) ⇒ Object



126
127
128
# File 'lib/plover.rb', line 126

def expect_flags(*flags)
  configuration[:options][:expected_flags] = flags.map(&:to_sym)
end

.inherited(subclass) ⇒ Object



117
118
119
120
# File 'lib/plover.rb', line 117

def inherited(subclass)
  subclass.extend(Log)
  subclass.instance_variable_set(:@configuration, deep_copy(configuration))
end

.log_level(severity) ⇒ Object



139
140
141
# File 'lib/plover.rb', line 139

def log_level(severity)
  configuration[:options][:log][:level] = severity.to_sym
end

.log_sink(sink) ⇒ Object



143
144
145
# File 'lib/plover.rb', line 143

def log_sink(sink)
  configuration[:options][:log][:sink] = sink
end

.phase(phase, &block) ⇒ Object



160
161
162
# File 'lib/plover.rb', line 160

def phase(phase, &block)
  configuration[:steps][phase] << block
end

.prepend_phase(phase, &block) ⇒ Object



164
165
166
# File 'lib/plover.rb', line 164

def prepend_phase(phase, &block)
  configuration[:steps][phase].unshift(block)
end

.set_flag(name, value) ⇒ Object



122
123
124
# File 'lib/plover.rb', line 122

def set_flag(name, value)
  configuration[:options][:flags][name.to_sym] = value
end

Instance Method Details

#append_phase(phase, &block) ⇒ Object



217
218
219
# File 'lib/plover.rb', line 217

def append_phase(phase, &block)
  @configuration[:steps][phase] << block
end

#artifact(phase, name) ⇒ Object



255
256
257
# File 'lib/plover.rb', line 255

def artifact(phase, name)
  @configuration[:artifacts][phase][name]
end

#artifacts(phase = nil) ⇒ Object



259
260
261
# File 'lib/plover.rb', line 259

def artifacts(phase = nil)
  phase ? @configuration[:artifacts][phase] : @configuration[:artifacts]
end

#esc(str) ⇒ Object



221
222
223
# File 'lib/plover.rb', line 221

def esc(str)
  Shellwords.escape(str)
end

#esc_artifact(phase, name) ⇒ Object



250
251
252
253
# File 'lib/plover.rb', line 250

def esc_artifact(phase, name)
  artifact = self.artifact(phase, name)
  artifact ? esc(artifact) : nil
end

#esc_flag(name) ⇒ Object



229
230
231
# File 'lib/plover.rb', line 229

def esc_flag(name)
  flag(name) ? esc(flag(name)) : nil
end

#fail_build(message) ⇒ Object

Raises:



270
271
272
273
# File 'lib/plover.rb', line 270

def fail_build(message)
  log :fatal, "Build failure: #{message}"
  raise BuildError.new(message)
end

#flag(name) ⇒ Object



225
226
227
# File 'lib/plover.rb', line 225

def flag(name)
  @configuration[:options][:flags][name.to_sym]
end

#prepend_phase(phase, &block) ⇒ Object



213
214
215
# File 'lib/plover.rb', line 213

def prepend_phase(phase, &block)
  @configuration[:steps][phase].unshift(block)
end

#push_artifact(name, value) ⇒ Object



244
245
246
247
248
# File 'lib/plover.rb', line 244

def push_artifact(name, value)
  return unless @current_phase
  log :debug, "Pushed artifact name='#{name}' value='#{value}'"
  @configuration[:artifacts][@current_phase][name] = value
end

#raise_unless_artifact(phase, name, message) ⇒ Object



263
264
265
266
267
268
# File 'lib/plover.rb', line 263

def raise_unless_artifact(phase, name, message)
  unless artifact(phase, name)
    log :fatal, "Missing artifact '#{name}': #{message}"
    raise ArtifactError.new(message)
  end
end

#raise_unless_flag(name, message) ⇒ Object



237
238
239
240
241
242
# File 'lib/plover.rb', line 237

def raise_unless_flag(name, message)
  unless flag(name)
    log :fatal, "Missing flag '#{name}': #{message}"
    raise FlagError.new(message)
  end
end

#runObject



283
284
285
286
287
288
289
290
291
292
# File 'lib/plover.rb', line 283

def run
  run_phase(:setup)
  Dir.chdir(ENV["PLOVER_BUILD_ROOT"] || flag(:build_root) || ".") do
    run_phase(:before_build)
    run_phase(:build)
    run_phase(:after_build)
  end
  run_phase(:teardown)
  logger.close unless @configuration[:options][:log][:sink] == :stdout
end

#run_phase(phase) ⇒ Object



275
276
277
278
279
280
281
# File 'lib/plover.rb', line 275

def run_phase(phase)
  log :debug, "\\/ #{phase.to_s.capitalize} Phase Starting \\/"
  @current_phase = phase
  @configuration[:steps][phase].each { |block| instance_exec(&block) }
  @current_phase = nil
  log :debug, "/\\ #{phase.to_s.capitalize} Phase Finished /\\"
end

#set_flag(name, value) ⇒ Object



233
234
235
# File 'lib/plover.rb', line 233

def set_flag(name, value)
  @configuration[:options][:flags][name.to_sym] = value
end