Add lib/ to $LOAD_PATH before loading app file (#1251)
This makes it possible to require files from lib/ at conventional spot at the top of the file, rather than inside the body of the app class.
This commit is contained in:
parent
70d86d047e
commit
c963882a3c
|
@ -1,5 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "pathname"
|
||||
require "zeitwerk"
|
||||
require_relative "hanami/constants"
|
||||
|
||||
|
@ -36,7 +37,8 @@ module Hanami
|
|||
app_path = self.app_path
|
||||
|
||||
if app_path
|
||||
require(app_path)
|
||||
prepare_load_path
|
||||
require(app_path.to_s)
|
||||
app
|
||||
elsif raise_exception
|
||||
raise(
|
||||
|
@ -47,6 +49,23 @@ module Hanami
|
|||
end
|
||||
end
|
||||
|
||||
# Prepare the load path as early as possible (based on the default root inferred from the location
|
||||
# of `config/app.rb`), so `require` can work at the top of `config/app.rb`. This may be useful
|
||||
# when external classes are needed for configuring certain aspects of the app.
|
||||
#
|
||||
# @api private
|
||||
# @since 2.0.0
|
||||
private_class_method def self.prepare_load_path
|
||||
lib_path = app_path&.join("..", "..", LIB_DIR)
|
||||
|
||||
if lib_path&.directory?
|
||||
path = lib_path.realpath.to_s
|
||||
$LOAD_PATH.prepend(path) unless $LOAD_PATH.include?(path)
|
||||
end
|
||||
|
||||
lib_path
|
||||
end
|
||||
|
||||
# Returns the Hamami app class.
|
||||
#
|
||||
# To ensure your Hanami app is loaded, run {.setup} (or `require "hanami/setup"`) first.
|
||||
|
@ -98,10 +117,10 @@ module Hanami
|
|||
# Searches within the given directory, then searches upwards through parent directories until the
|
||||
# app file can be found.
|
||||
#
|
||||
# @param dir [String] The directory from which to start searching. Defaults to the current
|
||||
# directory.
|
||||
# @param dir [String, Pathname] The directory from which to start searching. Defaults to the
|
||||
# current directory.
|
||||
#
|
||||
# @return [String, nil] the app file path, or nil if not found.
|
||||
# @return [Pathname, nil] the app file path, or nil if not found.
|
||||
#
|
||||
# @api public
|
||||
# @since 2.0.0
|
||||
|
@ -110,7 +129,7 @@ module Hanami
|
|||
path = dir.join(APP_PATH)
|
||||
|
||||
if path.file?
|
||||
path.to_s
|
||||
path
|
||||
elsif !dir.root?
|
||||
app_path(dir.parent)
|
||||
end
|
||||
|
|
|
@ -29,11 +29,6 @@ module Hanami
|
|||
subclass.class_eval do
|
||||
@config = Hanami::Config.new(app_name: slice_name, env: Hanami.env)
|
||||
|
||||
# Prepare the load path (based on the default root of `Dir.pwd`) as early as possible, so
|
||||
# you can make a `require` inside the body of an `App` subclass, which may be useful for
|
||||
# certain kinds of app configuration.
|
||||
prepare_load_path
|
||||
|
||||
load_dotenv
|
||||
end
|
||||
end
|
||||
|
|
|
@ -82,6 +82,40 @@ RSpec.describe "Code loading / Loading from lib directory", :app_integration do
|
|||
end
|
||||
end
|
||||
|
||||
describe "default root with requires at top of app file" do
|
||||
before :context do
|
||||
with_directory(@dir = make_tmp_directory.realpath) do
|
||||
write "config/app.rb", <<~'RUBY'
|
||||
require "hanami"
|
||||
require "external_class"
|
||||
|
||||
module TestApp
|
||||
class App < Hanami::App
|
||||
@class_from_lib = ExternalClass
|
||||
|
||||
def self.class_from_lib
|
||||
@class_from_lib
|
||||
end
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
write "lib/external_class.rb", <<~'RUBY'
|
||||
class ExternalClass
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
with_directory(@dir) { require "hanami/setup" }
|
||||
end
|
||||
|
||||
specify "classes in lib/ can be required directly from the top of the app file" do
|
||||
expect(Hanami.app.class_from_lib).to be ExternalClass
|
||||
end
|
||||
end
|
||||
|
||||
context "app root reconfigured" do
|
||||
before :context do
|
||||
with_directory(@dir = make_tmp_directory.realpath) do
|
||||
|
|
|
@ -126,7 +126,7 @@ RSpec.describe "Hanami setup", :app_integration do
|
|||
with_tmp_directory(Dir.mktmpdir) do
|
||||
write "config/app.rb"
|
||||
|
||||
expect(app_path).to match(%r{^/.*/config/app.rb$})
|
||||
expect(app_path.to_s).to match(%r{^/.*/config/app.rb$})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -138,7 +138,7 @@ RSpec.describe "Hanami setup", :app_integration do
|
|||
write "lib/foo/bar/.keep"
|
||||
|
||||
Dir.chdir("lib/foo/bar") do
|
||||
expect(app_path).to match(%r{^/.*/config/app.rb$})
|
||||
expect(app_path.to_s).to match(%r{^/.*/config/app.rb$})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue