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

- old
+ new

@@ -1,202 +1,70 @@ -require 'thread' -require 'concurrent' -require 'hanami/application_name' -require 'hanami/application_namespace' -require 'hanami/application_configuration' -require 'hanami/environment_application_configurations' -require 'hanami/rendering_policy' +# frozen_string_literal: true +require "hanami/configuration" +require "hanami/routes" +require "hanami/router" + module Hanami - # A full stack Hanami application + # Hanami application # - # @since 0.1.0 - # - # @example - # require 'hanami' - # - # module Bookshelf - # class Application < Hanami::Application - # end - # end + # @since 2.0.0 class Application - # Override Ruby's Class#inherited - # - # @since 0.2.0 - # @api private - # - # @see http://www.ruby-doc.org/core/Class.html#method-i-inherited - def self.inherited(base) - super + @_mutex = Mutex.new - base.extend(ClassMethods) - base.namespace.module_eval do - class << self - # Routes for this application - # - # @return [Hanami::Routes] the routes for this Hanami application - # - # @since 0.9.0 - # @api public - # - # @example - # - # Web.routes - # Admin.routes - attr_accessor :routes + def self.inherited(app) + @_mutex.synchronize do + app.class_eval do + @_mutex = Mutex.new + @_configuration = Hanami::Configuration.new(env: Hanami.env) + + extend ClassMethods + include InstanceMethods end + + Hanami.application = app end end - # Class interface for Hanami applications + # Class method interface # - # @since 0.9.0 - # @api private + # @since 2.0.0 module ClassMethods - # Override Ruby's Class#extended - # - # @since 0.9.0 - # @api private - # - # @see http://www.ruby-doc.org/core/Class.html#method-i-extended - def self.extended(base) # rubocop:disable Metrics/MethodLength - super + def configuration + @_configuration + end - base.class_eval do - @namespace = ApplicationNamespace.resolve(name) - @configurations = EnvironmentApplicationConfigurations.new - @_lock = Mutex.new + alias config configuration - class << self - # @since 0.9.0 - # @api private - attr_reader :namespace + def routes(&blk) + @_mutex.synchronize do + if blk.nil? + raise "Hanami.application.routes not configured" unless defined?(@_routes) - # @since 0.9.0 - # @api private - attr_reader :configurations - - # @since 0.9.0 - # @api private - attr_reader :configuration + @_routes + else + @_routes = Routes.new(&blk) end end end + end - # Hanami application name - # - # @return [String] the Hanami application name - # - # @since 0.9.0 - # @api private - # - # @example - # require 'hanami' - # - # module Web - # class Application < Hanami::Application - # end - # end - # - # Web::Application.app_name # => "web" - def app_name - ApplicationName.new(name).to_s - end + # Instance method interface + # + # @since 2.0.0 + module InstanceMethods + def initialize(configuration: self.class.configuration, routes: self.class.routes) + @app = Rack::Builder.new do + configuration.for_each_middleware do |m, *args| + use m, *args + end - # Set configuration - # - # @param configuration [Hanami::ApplicationConfiguration] the application configuration - # - # @raise [RuntimeError] if the configuration is assigned more than once - # - # @since 0.1.0 - # @api private - def configuration=(configuration) - @_lock.synchronize do - # raise "Can't assign configuration more than once (#{app_name})" unless @configuration.nil? - @configuration = configuration + run Hanami::Router.new(**configuration.router_settings, &routes) end end - # Configure the application. - # It yields the given block in the context of the configuration - # - # @param environment [Symbol,nil] the configuration environment name - # @param blk [Proc] the configuration block - # - # @since 0.1.0 - # - # @see Hanami::ApplicationConfiguration - # - # @example - # require 'hanami' - # - # module Bookshelf - # Application < Hanami::Application - # configure do - # # ... - # end - # end - # end - def configure(environment = nil, &blk) - configurations.add(environment, &blk) + def call(env) + @app.call(env) end end - - # Initialize and load a new instance of the application - # - # @return [Hanami::Application] a new instance of the application - # - # @since 0.1.0 - # @api private - def initialize - @renderer = RenderingPolicy.new(configuration) - @middleware = configuration.middleware - end - - # Process a request. - # This method makes Hanami applications compatible with the Rack protocol. - # - # @param env [Hash] a Rack env - # - # @return [Array] a serialized Rack response - # - # @since 0.1.0 - # - # @see http://rack.github.io - # @see Hanami::RenderingPolicy#render - # @see Hanami::Application#middleware - def call(env) - renderer.render(env, middleware.call(env)) - end - - private - - # Return the configuration for this application - # - # @since 0.1.0 - # @api private - # - # @see Hanami::Application.configuration - def configuration - self.class.configuration - end - - # Rendering policy - # - # @since 0.2.0 - # @api private - # - # @see Hanami::RenderingPolicy - attr_reader :renderer - - # Rack middleware stack - # - # @return [Hanami::MiddlewareStack] the middleware stack - # - # @since 0.1.0 - # @api private - # - # @see Hanami::MiddlewareStack - attr_reader :middleware end end