lib/hanami.rb in hanami-2.0.0.beta4 vs lib/hanami.rb in hanami-2.0.0.rc1

- old
+ new

@@ -1,21 +1,34 @@ # frozen_string_literal: true +require "zeitwerk" +require_relative "hanami/constants" + # A complete web framework for Ruby # # @since 0.1.0 # # @see http://hanamirb.org module Hanami @_mutex = Mutex.new @_bundled = {} + # @api private + # @since 2.0.0 + def self.loader + @loader ||= Zeitwerk::Loader.for_gem.tap do |loader| + loader.ignore( + "#{loader.dirs.first}/hanami/{constants,boot,errors,prepare,rake_tasks,setup}.rb" + ) + end + end + # Finds and loads the Hanami app file (`config/app.rb`). # # Raises an exception if the app file cannot be found. # - # @return [Hanami::App] the loaded app class + # @return [app] the loaded app class # # @api public # @since 2.0.0 def self.setup(raise_exception: true) return app if app? @@ -32,36 +45,22 @@ "Your app file should be at `config/app.rb` in your project's root directory." ) end end - # Finds and returns the absolute path for the Hanami app file (`config/app.rb`). + # Returns the Hamami app class. # - # Searches within the given directory, then searches upwards through parent directories until the - # app file can be found. + # To ensure your Hanami app is loaded, run {.setup} (or `require "hanami/setup"`) first. # - # @param dir [String] The directory from which to start searching. Defaults to the current - # directory. + # @return [Hanami::App] the app class # - # @return [String, nil] the app file path, or nil if not found. + # @raise [AppLoadError] if the app has not been loaded # + # @see .setup + # # @api public # @since 2.0.0 - def self.app_path(dir = Dir.pwd) - dir = Pathname(dir).expand_path - path = dir.join(APP_PATH) - - if path.file? - path.to_s - elsif !dir.root? - app_path(dir.parent) - end - end - - APP_PATH = "config/app.rb" - private_constant :APP_PATH - def self.app @_mutex.synchronize do unless defined?(@_app) raise AppLoadError, "Hanami.app is not yet configured. " \ @@ -70,62 +69,162 @@ @_app end end + # Returns true if the Hanami app class has been loaded. + # + # @return [Boolean] + # + # @api public + # @since 2.0.0 def self.app? instance_variable_defined?(:@_app) end + # @api private + # @since 2.0.0 def self.app=(klass) @_mutex.synchronize do if instance_variable_defined?(:@_app) raise AppLoadError, "Hanami.app is already configured." end @_app = klass unless klass.name.nil? end end + # Finds and returns the absolute path for the Hanami app file (`config/app.rb`). + # + # 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. + # + # @return [String, nil] the app file path, or nil if not found. + # + # @api public + # @since 2.0.0 + def self.app_path(dir = Dir.pwd) + dir = Pathname(dir).expand_path + path = dir.join(APP_PATH) + + if path.file? + path.to_s + elsif !dir.root? + app_path(dir.parent) + end + end + + # Returns the Hanami app environment as loaded from the `HANAMI_ENV` environment variable. + # + # @example + # Hanami.env # => :development + # + # @return [Symbol] the environment name + # + # @api public + # @since 2.0.0 def self.env ENV.fetch("HANAMI_ENV") { ENV.fetch("RACK_ENV", "development") }.to_sym end + # Returns true if {.env} matches any of the given names + # + # @example + # Hanami.env # => :development + # Hanami.env?(:development, :test) # => true + # + # @param names [Array<Symbol>] the environment names to check + # + # @return [Boolean] + # + # @api public + # @since 2.0.0 def self.env?(*names) names.map(&:to_sym).include?(env) end + # Returns the app's logger. + # + # Direct global access to the logger via this method is not recommended. Instead, consider + # accessing the logger via the app or slice container, in most cases as an dependency using the + # `Deps` mixin. + # + # @example + # # app/my_component.rb + # + # module MyApp + # class MyComponent + # include Deps["logger"] + # + # def some_method + # logger.info("hello") + # end + # end + # end + # + # @return [Dry::Logger::Dispatcher] + # + # @api public + # @since 1.0.0 def self.logger app[:logger] end + # Prepares the Hanami app. + # + # @see App::ClassMethods#prepare + # + # @api public + # @since 2.0.0 def self.prepare app.prepare end + # Boots the Hanami app. + # + # @see App::ClassMethods#boot + # + # @api public + # @since 2.0.0 def self.boot app.boot end + # Shuts down the Hanami app. + # + # @see App::ClassMethods#shutdown + # + # @api public + # @since 2.0.0 def self.shutdown app.shutdown end + # @api private + # @since 2.0.0 def self.bundled?(gem_name) @_mutex.synchronize do @_bundled[gem_name] ||= begin gem(gem_name) rescue Gem::LoadError false end end end + # Returns an array of bundler group names to be eagerly loaded by hanami-cli and other CLI + # extensions. + # + # @api private + # @since 2.0.0 def self.bundler_groups [:plugins] end - require_relative "hanami/version" + loader.setup + require_relative "hanami/errors" require_relative "hanami/extensions" - require_relative "hanami/app" end