Module: Lizarb

Defined in:
lib/lizarb.rb,
lib/lizarb/version.rb

Defined Under Namespace

Classes: Error, ModeNotFound, SystemNotFound

Constant Summary collapse

CUR_DIR =
Dir.pwd
IS_APP_DIR =
File.file? "#{CUR_DIR}/app.rb"
IS_LIZ_DIR =
File.file? "#{CUR_DIR}/lib/lizarb.rb"
IS_GEM_DIR =
File.file? "#{CUR_DIR}/lizarb.gemspec"
APP_DIR =
IS_APP_DIR ? CUR_DIR : GEM_DIR
VERSION =
"1.0.5"

Class Method Summary collapse

Class Method Details

.app(&block) ⇒ Object

called from exe/lizarb



72
73
74
75
76
77
78
79
# File 'lib/lizarb.rb', line 72

def app &block
  require "app"
  if block_given?
    App.class_exec(&block)
  else
    lookup_and_require_app
  end
end

.callObject

called from exe/lizarb



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/lizarb.rb', line 82

def call
  require "bundler/setup"

  level = App.log_boot
  is_lowest = level == -3
  App::LOG_LEVELS.each do |k, v|
    puts "$log_boot_#{k} = #{v >= level}" if level == -3
    eval "$log_boot_#{k} = true" if v >= level
  end
  log "LizaRB v#{Lizarb.version}                                                                                                      https://lizarb.org" if defined? $log_boot_higher
  log "#{self}.#{__method__}" if defined? $log_boot_low

  lookup_and_set_mode
  lookup_and_load_settings
  require_liza_and_systems
  connect_systems
end

.connect_box(key, system_class) ⇒ Object



380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'lib/lizarb.rb', line 380

def connect_box key, system_class
  t = Time.now

  box_class = system_class.box
  color_box_class = Liza::Unit.stick(system_class.color, box_class.name).to_s

  log "CONNECTING BOX                        #{color_box_class}" if defined? $log_boot_low
  index = 0
  # system_class.subs.keys.each do |sub_key|
  system_class.subs.each do |sub_key|
    panel_class_name      = "#{sub_key}_panel".camelize
    controller_class_name = sub_key.to_s.camelize

    index += 1
    pad = 30-box_class.name.size-sub_key.to_s.size
    log "CONNECTED  BOX TO PANEL               #{"#{color_box_class}[:#{sub_key}]"}#{"".ljust pad} is an instance of #{panel_class_name.ljust_blanks 20} and it configures #{controller_class_name}" if defined? $log_boot_low
  end

  log "CONNECTED  BOX            #{t.diff}s" if defined? $log_boot_low
end

.connect_part(unit_class, key, part_class, system) ⇒ Object

parts



403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
# File 'lib/lizarb.rb', line 403

def connect_part unit_class, key, part_class, system
  if defined? $log_boot_lowest
    t = Time.now
    string = "      #{unit_class}.part :#{key}"
    log string
  end

  part_class ||= if system.nil?
              Liza.const "#{key}_part"
            else
              Liza.const("#{system}_system")
                  .const "#{key}_part"
            end

  if part_class.insertion
    unit_class.class_exec(&part_class.insertion)
  end

  if part_class.extension
    part_class.const_set :Extension, Class.new(Liza::PartExtension)
    part_class::Extension.class_exec(&part_class.extension)
  end

  if defined? $log_boot_lowest
    log "      ."
  end
end

.connect_system(key, system_class) ⇒ Object



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
# File 'lib/lizarb.rb', line 346

def connect_system key, system_class
  t = Time.now
  puts if defined? $log_boot_low

  system_class.color DevSystem::ColorShell.parse system_class.color unless system_class.color.is_a? Array

  color_system_class = Liza::Unit.stick(system_class.color, system_class.name).to_s

  log "CONNECTING SYSTEM                     #{color_system_class}" if defined? $log_boot_low
  
  # Ignore this for now.
  # This feature has been commented out for simplicity purposes.
  # It injects code into other classes just like Part does. System defines them

  # index = 0
  # system_class.registrar.each do |string, target_block|
  #   reg_type, _sep, reg_target = string.to_s.lpartition "_"

  #   index += 1

  #   target_klass = Liza.const reg_target

  #   if reg_type == "insertion"
  #     target_klass.class_exec(&target_block)
  #   else
  #     raise "TODO: decide and implement system extension"
  #   end
  #   log "CONNECTING SYSTEM-PART                #{color_system_class}.#{reg_type.to_s.ljust 11} to #{target_klass.to_s.ljust 30} at #{target_block.source_location * ":"}  " if defined? $log_boot_low
  # end

  # pad = 21-system_class.name.size
  # log "CONNECTED  SYSTEM         #{t.diff}s for #{color_system_class}#{"".ljust pad} to connect to #{index} system parts" if defined? $log_boot_normal
end

.connect_systemsObject



328
329
330
331
332
333
334
# File 'lib/lizarb.rb', line 328

def connect_systems
  log "  Lizarb.#{__method__} (#{App.systems.count})" if defined? $log_boot_low
  App.systems.each do |system_key, system_class|
    connect_system system_key, system_class
    connect_box system_key, system_class
  end
end

.exitObject

called from exe/lizarb



101
102
103
104
# File 'lib/lizarb.rb', line 101

def exit
  exit_messages if defined? $log_boot_normal
  super 0
end

.exit_messagesObject



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/lizarb.rb', line 106

def exit_messages
  info = {
    ruby: RUBY_VERSION,
    bundler: Bundler::VERSION,
    zeitwerk: Zeitwerk::VERSION,
    lizarb: VERSION,
    app: $APP,
    mode: App.mode,
    log_boot: App.log_boot,
    log_level: App.get(:log_level),
  }
  github = "https://github.com/lizarb/lizarb"
  puts info.to_s
  puts "Report bugs at #{github}/issues"
  puts "Fork us on Github at #{github}/fork"
end

.loadersObject



436
437
438
# File 'lib/lizarb.rb', line 436

def loaders
  @loaders
end

.log(s) ⇒ Object



46
47
48
49
# File 'lib/lizarb.rb', line 46

def log s
  print "#{$boot_time.diff}s " if defined? $log_boot_low
  puts s
end

.lookup_and_load_core_extObject

setup phase



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/lizarb.rb', line 125

def lookup_and_load_core_ext
  files =
    if IS_GEM_DIR
      Dir["#{CUR_DIR}/lib/lizarb/ruby/*.rb"]
    else
      Dir["#{GEM_DIR}/lib/lizarb/ruby/*.rb"] + Dir["#{CUR_DIR}/lib/lizarb/ruby/*.rb"]
    end

  files.each do |file_name|
    log "#{self} loading #{file_name}" if $VERBOSE
    load file_name
  end
end

.lookup_and_load_settingsObject



192
193
194
195
196
197
# File 'lib/lizarb.rb', line 192

def lookup_and_load_settings
  log "  Lizarb.#{__method__}" if defined? $log_boot_low
  files = ["#{$APP}.#{$mode}.env", "#{$APP}.env"]
  require "dotenv"
  Dotenv.load(*files)
end

.lookup_and_require_appObject

app phase

Raises:



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/lizarb.rb', line 163

def lookup_and_require_app
  finder = \
    proc do |lib_name, file_name|
      log "#{self} checking if #{file_name} exists" if $VERBOSE
      if File.file? "#{file_name}"
        require lib_name
        true
      else
        false
      end
    end

  return if finder.call "#{CUR_DIR}/#{$APP}", "#{CUR_DIR}/#{$APP}.rb"
  return if finder.call "#{GEM_DIR}/#{$APP}", "#{GEM_DIR}/#{$APP}.rb"

  raise Error, "Could not find #{$APP}.rb in #{CUR_DIR} or #{GEM_DIR}"
end

.lookup_and_set_gemfileObject



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/lizarb.rb', line 139

def lookup_and_set_gemfile
  gemfile = nil

  finder = \
    proc do |file_name|
      log "#{self}.#{__method__} #{file_name}" if $VERBOSE
      if File.file? file_name
        file_name
      else
        false
      end
    end

  gemfile ||= finder.call "#{CUR_DIR}/#{$APP}.gemfile.rb"
  gemfile ||= finder.call "#{GEM_DIR}/#{$APP}.gemfile.rb" unless IS_GEM_DIR
  gemfile ||= finder.call "#{CUR_DIR}/Gemfile"
  gemfile ||= finder.call "#{GEM_DIR}/app_global.gemfile.rb"

  log "#{self} setting BUNDLE_GEMFILE to #{gemfile}" if $VERBOSE
  ENV["BUNDLE_GEMFILE"] = gemfile
end

.lookup_and_set_modeObject

call phase



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

def lookup_and_set_mode
  log "  Lizarb.#{__method__}" if defined? $log_boot_low

  $mode = App.mode
  log "    $mode = #{$mode.inspect}" if defined? $log_boot_lower
  $coding = App.coding?
  log "    $coding enabled because $mode == :code | A bit slower for debugging purposes" if $coding && defined? $log_boot_lower
end

.reload(&block) ⇒ Object



440
441
442
443
444
445
446
447
# File 'lib/lizarb.rb', line 440

def reload &block
  @mutex.synchronize do
    loaders.map &:reload
    yield if block_given?
  end

  true
end

.require_liza_and_systemsObject



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/lizarb.rb', line 199

def require_liza_and_systems
  log "  Lizarb.#{__method__}" if defined? $log_boot_low

  log "    require Zeitwerk and Liza" if defined? $log_boot_lower

  require "zeitwerk"
  require "liza"

  # loaders[0] first loads Liza, then each System class

  log "    Zeitwerk loaders [0] first loads Liza, then each System class" if defined? $log_boot_lower

  loaders << loader = Zeitwerk::Loader.new
  loader.tag = Liza.to_s

  # collapse Liza paths

  # ORDER MATTERS: IGNORE, COLLAPSE, PUSH
  loader.collapse "#{Liza.source_location_radical}/**/*"
  loader.push_dir "#{Liza.source_location_radical}", namespace: Liza

  # loader setup

  loader.enable_reloading
  loader.setup

  # bundle each System gem

  Bundler.require :systems

  # load each System class

  log "      App.systems is Hash containing all system classes" if defined? $log_boot_lowest
  App.systems.keys.each do |k|
    key = "#{k}_system"

    require_system key
    klass = Object.const_get key.camelize

    App.systems[k] = klass
  end

  App.systems.freeze

  # loaders[1] first loads each System, then the App
  log "    Zeitwerk loaders [1] first loads each System, then the App" if defined? $log_boot_lower
  loaders << loader = Zeitwerk::Loader.new

  # collapse each System paths

  App.systems.each do |k, klass|
    # ORDER MATTERS: IGNORE, COLLAPSE, PUSH
    loader.collapse "#{klass.source_location_radical}/**/*"
    loader.push_dir "#{klass.source_location_radical}", namespace: klass
  end

  # cherrypick App paths

  app_dir = App.path
  if app_dir
    log "      Application Directory: #{app_dir}" if defined? $log_boot_lowest
    list = Dir["#{app_dir}/*"].to_set
  end

  if app_dir.nil? || list.empty?
    log "      Application Directory is empty" if defined? $log_boot_lowest
  else
    log "      Application Directory found #{list.count} items to collapse" if defined? $log_boot_lowest

    to_collapse = []

    App.systems.each do |k, klass|
      next if klass.subs.empty?
      box_dir  = "#{app_dir}/#{k}"
      box_file = "#{box_dir}_box.rb"

      if !list.include? box_file
        log "        Missd box file    #{box_file}! Generating it"

        File.write box_file, <<-RUBY
class #{k.to_s.camelize}Box < #{k.to_s.camelize}System::#{k.to_s.camelize}Box

end
        RUBY
      end

      log "        Found box file    #{box_file}" if defined? $log_boot_lowest
      to_collapse << box_file

      if !list.include? box_dir
        log "        Missd controllers #{box_dir}" if defined? $log_boot_lowest
      else
        log "        Found controllers #{box_dir}" if defined? $log_boot_lowest
        to_collapse << box_dir
      end

    end

    # ORDER MATTERS: IGNORE, COLLAPSE, PUSH
    to_ignore = list - to_collapse
    to_ignore.each do |file|
      log "      Ignoring   #{file}" if $log_boot_lowest
      loader.ignore file
    end

    to_collapse.each do |path|
      log "      Collapsing #{path}" if $log_boot_lowest
      if path.end_with? ".rb"
        loader.collapse path
      else
        loader.collapse "#{path}/**/*"
      end
    end
    loader.collapse "#{app_dir}/*"

    loader.push_dir app_dir, namespace: Object
  end

  # loader setup

  loader.enable_reloading
  loader.setup

  # App connects to systems

  log "    Zeitwerk loaders eager load" if defined? $log_boot_lowest
  loaders.map &:eager_load
end

.require_system(key) ⇒ Object

systems



338
339
340
341
342
343
344
# File 'lib/lizarb.rb', line 338

def require_system key
  log "        require '#{key}'" if defined? $log_boot_lowest
  require key
rescue LoadError => e
  def e.backtrace; []; end
  raise SystemNotFound, "FILE #{key}.rb not found on $LOAD_PATH", []
end

.ruby_supports_raise_cause?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/lizarb.rb', line 61

def ruby_supports_raise_cause?
  RUBY_ENGINE != "jruby"
end

.ruby_versionObject

Returns RUBY_VERSION as a Gem::Version



57
58
59
# File 'lib/lizarb.rb', line 57

def ruby_version
  @ruby_version ||= Gem::Version.new RUBY_VERSION
end

.setupObject

called from exe/lizarb



66
67
68
69
# File 'lib/lizarb.rb', line 66

def setup
  lookup_and_load_core_ext
  lookup_and_set_gemfile
end

.thread_idObject



458
459
460
461
462
463
# File 'lib/lizarb.rb', line 458

def thread_id
  @thread_ids[thread_object_id] ||=
    @thread_ids_mutex.synchronize do
      @thread_ids.count
    end
end

.thread_object_idObject

thread management



451
452
453
# File 'lib/lizarb.rb', line 451

def thread_object_id
  Thread.current.object_id
end

.versionObject

Returns Lizarb::VERSION as a Gem::Version



52
53
54
# File 'lib/lizarb.rb', line 52

def version
  @version ||= Gem::Version.new VERSION
end