lib/hanami.rb in hanami-1.3.5 vs lib/hanami.rb in hanami-2.0.0.alpha1

- old
+ new

@@ -1,282 +1,78 @@ -require 'thread' +# frozen_string_literal: true # A complete web framework for Ruby # # @since 0.1.0 # # @see http://hanamirb.org module Hanami - require 'hanami/version' - require 'hanami/frameworks' - require 'hanami/environment' - require 'hanami/app' - require 'hanami/application' - require 'hanami/components' - require 'hanami/configuration' + require "hanami/version" + require "hanami/frameworks" + require "hanami/container" + require "hanami/application" - # @api private - # @since 0.6.0 - DEFAULT_PUBLIC_DIRECTORY = 'public'.freeze - - # @api private - # @since 0.9.0 @_mutex = Mutex.new - @_plugins = Concurrent::Array.new - # Configure Hanami project - # - # Please note that the code for this method is generated by `hanami new`. - # - # @param blk [Proc] the configuration block - # - # @since 0.9.0 - # - # @example - # # config/environment.rb - # - # # ... - # - # Hanami.configure do - # mount Admin::Application, at: "/admin" - # mount Web::Application, at: "/" - # - # model do - # adapter :sql, ENV['DATABASE_URL'] - # - # migrations "db/migrations" - # schema "db/schema.sql" - # end - # - # mailer do - # root "lib/bookshelf/mailers" - # - # delivery do - # development :test - # test :test - # # production :smtp, address: ENV['SMTP_HOST'], port: ENV['SMTP_PORT'] - # end - # end - # end - def self.configure(&blk) + def self.application @_mutex.synchronize do - @_configuration = Hanami::Configuration.new(&blk) + raise "Hanami application not configured" unless defined?(@_application) + + @_application end end - # Hanami configuration - # - # @return [Hanami::Configuration] the configuration - # - # @see Hanami.configure - # - # @since 0.9.0 - # @api private - def self.configuration + def self.application=(app) @_mutex.synchronize do - raise "Hanami not configured" unless defined?(@_configuration) - @_configuration + raise "Hanami application already configured" if defined?(@_application) + + @_application = app unless app.name.nil? end end - # Configure a plugin - # - # @see Hanami.configure - # - # @since 1.2.0 - def self.plugin(&blk) - @_plugins << blk - end + def self.app + @_mutex.synchronize do + raise "Hanami.app not configured" unless defined?(@_app) - # Plugins registry - # - # NOTE: We can't use `Components` registry. - # - # Plugins are loaded when Bundler requires `Gemfile` gems. - # During this phase the `Components` that we can resolve are erased by the - # first incoming request in development. - # They are erased by a workaround that we had to put in place in `Hanami.boot`. - # This workaround is `Components.release` and it was introduced because - # `shotgun` failed to reload components, so we have to release for each - # incoming request. - # After the `Components` registry is cleared up, Hanami is able to resolve all - # the components from scratch. - # - # When we'll switch to `hanami-reloader` for development, we can remove - # `Components.release` and we'll be able to store plugins in `Components` and - # remove `Hanami.plugins` as well. - # - # @since 1.2.0 - # @api private - def self.plugins - @_plugins + @_app + end end - # Boot your Hanami project - # - # NOTE: In case this is invoked many times, it guarantees that the boot - # process happens only once. - # - # NOTE: This MUST NOT be wrapped by a Mutex, because it would cause a deadlock. - # - # @return [NilClass] - # - # @since 0.9.0 - def self.boot - Components.release if code_reloading? - Components.resolve('all') - Hanami::Model.disconnect if defined?(Hanami::Model) - nil - end + def self.app=(app) + @_mutex.synchronize do + raise "Hanami.app already configured" if defined?(@_app) - # Main application that mounts many Rack and/or Hanami applications. - # - # This is used as integration point for: - # - # * `config.ru` (`run Hanami.app`) - # * Feature tests (`Capybara.app = Hanami.app`) - # - # - # - # It lazily loads your Hanami project, in case it wasn't booted on before. - # This is the case when `hanami server` isn't invoked, but we use different - # ways to run the project (eg. `rackup`). - # - # @return [Hanami::App] the app - # - # @since 0.9.0 - # @api private - # - # @see Hanami.boot - def self.app - boot - App.new(configuration, environment) + @_app = app + end end - # Check if an application is allowed to load. - # - # The list of applications to be loaded can be set via the `HANAMI_APPS` - # env variable. If the HANAMI_APPS env variable is not set, it defaults - # to loading all applications. - # - # @return [TrueClass,FalseClass] the result of the check - # - # @since 1.1.0 - # - # @example - # - # # Mount hanami app for specific app - # Hanami.configure do - # if Hanami.app?(:web) - # require_relative '../apps/web/application' - # mount Web::Application, at: '/' - # end - # end - # - def self.app?(app) - return true unless ENV.key?('HANAMI_APPS') - - allowed_apps = ENV['HANAMI_APPS'].to_s.split(',') - allowed_apps.include?(app.to_s.downcase) - end - - # Return root of the project (top level directory). - # - # @return [Pathname] root path - # - # @since 0.3.2 - # - # @example - # Hanami.root # => #<Pathname:/Users/luca/Code/bookshelf> def self.root - environment.root + Container.root end - # Project public directory - # - # @return [Pathname] public directory - # - # @since 0.6.0 - # - # @example - # Hanami.public_directory # => #<Pathname:/Users/luca/Code/bookshelf/public> - def self.public_directory - root.join(DEFAULT_PUBLIC_DIRECTORY) - end - - # Return the current environment - # - # @return [String] the current environment - # - # @since 0.3.1 - # - # @see Hanami::Environment#environment - # - # @example - # Hanami.env => "development" def self.env - environment.environment + (ENV["HANAMI_ENV"] || "development").to_sym end - # Check to see if specified environment(s) matches the current environment. - # - # If multiple names are given, it returns true, if at least one of them - # matches the current environment. - # - # @return [TrueClass,FalseClass] the result of the check - # - # @since 0.3.1 - # - # @see Hanami.env - # - # @example Single name - # puts ENV['HANAMI_ENV'] # => "development" - # - # Hanami.env?(:development) # => true - # Hanami.env?('development') # => true - # - # Hanami.env?(:production) # => false - # - # @example Multiple names - # puts ENV['HANAMI_ENV'] # => "development" - # - # Hanami.env?(:development, :test) # => true - # Hanami.env?(:production, :staging) # => false def self.env?(*names) - environment.environment?(*names) + names.map(&:to_sym).include?(env) end - # Current environment - # - # @return [Hanami::Environment] environment - # - # @api private - # @since 0.3.2 - def self.environment - Components.resolved('environment') do - Environment.new - end + def self.logger + Container[:logger] end - # Check if code reloading is enabled. - # - # @return [TrueClass,FalseClass] the result of the check - # - # @since 1.0.0 - # @api private - # - # @see https://guides.hanamirb.org/projects/code-reloading - def self.code_reloading? - environment - Components.resolve('code_reloading') - Components['code_reloading'] + def self.boot + @_mutex.synchronize do + raise "Hanami application already booted" if defined?(@_booted) + + @_booted = true + end + + Container.finalize! + self.app = application.new end - # Project logger - # - # @return [Hanami::Logger] the logger - # - # @since 1.0.0 - def self.logger - Components['logger'] + def self.bundler_groups + [:plugins] end end