Class: Jets::Booter

Inherits:
Object
  • Object
show all
Defined in:
lib/jets/booter.rb

Class Method Summary collapse

Class Method Details

.app_initializersObject



56
57
58
59
60
# File 'lib/jets/booter.rb', line 56

def app_initializers
  Dir.glob("#{Jets.root}/config/initializers/**/*").each do |path|
    load path
  end
end

.boot!(options = {}) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/jets/booter.rb', line 4

def boot!(options={})
  return if @booted

  turbo_charge
  confirm_jets_project!
  require_bundle_gems unless bypass_bundler_setup?
  Jets::Dotenv.load!

  Jets.application.setup!
  # eager_load_jets is called to ensure that internal Turbines get loaded after auto_load paths configured in setup!
  eager_load_jets
  run_turbines(:initializers)
  # Load configs after Turbine initializers so Turbines can defined some config options
  # and they are available in user's project environment configs.
  Jets.application.configs!
  app_initializers
  run_turbines(:after_initializers)
  Jets.application.finish!

  # Eager load project code. Rather have user find out early than late.
  eager_load_app

  setup_db
  # build_middleware_stack # TODO: figure out how to build middleware during Jets.boot without breaking jets new and webpacker:install

  @booted = true
end

.build_middleware_stackObject

Builds and memoize stack so it only gets built on bootup



43
44
45
# File 'lib/jets/booter.rb', line 43

def build_middleware_stack
  Jets.application.build_stack
end

.bundler_groupsObject



123
124
125
# File 'lib/jets/booter.rb', line 123

def bundler_groups
  [:default, Jets.env.to_sym]
end

.bypass_bundler_setup?Boolean

Returns:

  • (Boolean)


32
33
34
35
# File 'lib/jets/booter.rb', line 32

def bypass_bundler_setup?
  command = ARGV.first
  %w[build delete deploy url].include?(command)
end

.check_config_ru!Object



139
140
141
142
143
144
145
146
147
148
# File 'lib/jets/booter.rb', line 139

def check_config_ru!
  config_ru = File.read("#{Jets.root}/config.ru")
  unless config_ru.include?("Jets.boot")
    puts 'The config.ru file is missing Jets.boot.  Please add Jets.boot after require "jets"'.color(:red)
    puts "This was changed as made in Jets v1.1.0."
    puts "To have Jets update the config.fu file for you, you can run:\n\n"
    puts "  jets upgrade"
    exit 1
  end
end

.class_mappings(class_name) ⇒ Object



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

def class_mappings(class_name)
  map = {
    "Jets::Io" => "Jets::IO",
  }
  map[class_name] || class_name
end

.confirm_jets_project!Object

Cannot call this for the jets new



128
129
130
131
132
133
# File 'lib/jets/booter.rb', line 128

def confirm_jets_project!
  unless File.exist?("#{Jets.root}/config/application.rb")
    puts "It does not look like you are running this command within a jets project.  Please confirm that you are in a jets project and try again.".color(:red)
    exit 1
  end
end

.eager_load_appObject

Eager load user’s application



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/jets/booter.rb', line 200

def eager_load_app
  Dir.glob("#{Jets.root}/app/**/*.rb").select do |path|
    next if !File.file?(path) or path =~ %r{/javascript/} or path =~ %r{/views/}
    next if path.include?('app/functions') || path.include?('app/shared/functions') || path.include?('app/internal/functions')

    class_name = path
                  .sub(/\.rb$/,'') # remove .rb
                  .sub(%{^\./},'') # remove ./
                  .sub("#{Jets.root}/",'')
                  .sub(%r{app\/\w+/concerns/},'')
                  .sub(%r{app/shared/\w+/},'') # remove shared/resources or shared/extensions
                  .sub(%r{app/\w+/},'') # remove app/controllers or app/jobs etc
    class_name = class_name.classify

    if ENV['JETS_DEBUG_EAGER_LOAD']
      puts "path: #{path}"
      puts "class_name: #{class_name}"
    end

    class_name.constantize # use constantize instead of require so dont have to worry about order.
  end
end

.eager_load_jetsObject

Eager load jet’s lib and classes



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/jets/booter.rb', line 151

def eager_load_jets
  lib_jets = File.expand_path(".", File.dirname(__FILE__))

  # Sort by path length because systems return Dir.glob in different order
  # Sometimes it returns longer paths first which messed up eager loading.
  paths = Dir.glob("#{lib_jets}/**/*.rb")
  paths = paths.sort_by { |p| p.size }
  paths.select do |path|
    next if !File.file?(path)
    next if skip_eager_load_paths?(path)

    path = path.sub("#{lib_jets}/","jets/")
    class_name = path
                  .sub(/\.rb$/,'') # remove .rb
                  .sub(/^\.\//,'') # remove ./
                  .sub(/app\/\w+\//,'') # remove app/controllers or app/jobs etc
                  .camelize
    # special class mappings
    class_name = class_mappings(class_name)
    class_name.constantize # use constantize instead of require so dont have to worry about order.
  end
end

.messageObject



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

def message
  "Jets booting up in #{Jets.env.color(:green)} mode!"
end

.require_bundle_gemsObject

require_bundle_gems called when environment boots up via Jets.boot. It also useful for when to loading Rake tasks in Jets::Commands::RakeTasks.load!

For example, some gems like webpacker that load rake tasks are specified with a git based source:

gem "webpacker", git: "https://github.com/tongueroo/webpacker.git"

This results in the user having to specific bundle exec in front of jets for those rake tasks to show up in jets help.

Instead, when the user is within the project folder, jets automatically requires bundler for the user. So the rake tasks show up when calling jets help.

When the user calls jets help from outside the project folder, bundler is not used and the load errors get rescued gracefully. This is done in Jets::Commands::RakeTasks.load! In the case when there are in another project with another Gemfile, the load errors will still be rescued.



93
94
95
96
97
98
99
100
# File 'lib/jets/booter.rb', line 93

def require_bundle_gems
  # NOTE: Dont think ENV['BUNDLE_GEMFILE'] is quite working right.  We still need
  # to be in the project directory.  Leaving logic in here for when it gets fix.
  if ENV['BUNDLE_GEMFILE'] || File.exist?("Gemfile")
    require "bundler/setup"
    Bundler.require(*bundler_groups)
  end
end

.run_turbines(name) ⇒ Object

run_turbines(:initializers) run_turbines(:after_initializers)



64
65
66
67
68
69
70
71
# File 'lib/jets/booter.rb', line 64

def run_turbines(name)
  Jets::Turbine.subclasses.each do |subclass|
    hooks = subclass.send(name) || []
    hooks.each do |label, block|
      block.call(Jets.application)
    end
  end
end

.setup_dbObject

Only connects connect to database for ActiveRecord and when config/database.yml exists. Dynomite handles connecting to the clients lazily.



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

def setup_db
  return unless File.exist?("#{Jets.root}/config/database.yml")

  db_configs = Jets.application.config.database
  # DatabaseTasks.database_configuration for db:create db:migrate tasks
  # Documented in DatabaseTasks that this is the right way to set it when
  # using ActiveRecord rake tasks outside of Rails.
  ActiveRecord::Tasks::DatabaseTasks.database_configuration = db_configs

  current_config = db_configs[Jets.env]
  if current_config.blank?
    abort("ERROR: config/database.yml exists but no environment section configured for #{Jets.env}")
  end
  # Using ActiveRecord rake tasks outside of Rails, so we need to set up the
  # db connection ourselves
  ActiveRecord::Base.establish_connection(current_config)
end

.skip_eager_load_paths?(path) ⇒ Boolean

Skip these paths because eager loading doesnt work for them. Scope to /jets as much as possible in case it collides with a user path

Returns:

  • (Boolean)


176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/jets/booter.rb', line 176

def skip_eager_load_paths?(path)
  path =~ %r{/jets/builders/rackup_wrappers} ||
  path =~ %r{/jets/builders/reconfigure_rails} ||
  path =~ %r{/jets/cli} ||
  path =~ %r{/jets/commands/templates/webpacker} ||
  path =~ %r{/jets/controller/middleware/webpacker_setup} ||
  path =~ %r{/jets/core_ext} ||
  path =~ %r{/jets/internal/app} ||
  path =~ %r{/jets/overrides} ||
  path =~ %r{/jets/spec} ||
  path =~ %r{/jets/stack} ||
  path =~ %r{/jets/turbo/project/} ||
  path =~ %r{/jets/version} ||
  path =~ %r{/templates/}
end

.turbine_initializersObject



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

def turbine_initializers
  Jets::Turbine.subclasses.each do |subclass|
    initializers = subclass.initializers || []
    initializers.each do |label, block|
      block.call(Jets.application)
    end
  end
end

.turbo_chargeObject



37
38
39
40
# File 'lib/jets/booter.rb', line 37

def turbo_charge
  turbo = Jets::Turbo.new
  turbo.charge
end