hanami 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/FEATURES.md +13 -0
  4. data/README.md +28 -1
  5. data/hanami.gemspec +20 -17
  6. data/lib/hanami.rb +106 -7
  7. data/lib/hanami/action/routing_helpers.rb +2 -2
  8. data/lib/hanami/app.rb +72 -0
  9. data/lib/hanami/application.rb +144 -183
  10. data/lib/hanami/application_configuration.rb +1541 -0
  11. data/lib/hanami/application_name.rb +2 -2
  12. data/lib/hanami/application_namespace.rb +12 -0
  13. data/lib/hanami/assets/asset.rb +3 -1
  14. data/lib/hanami/assets/static.rb +3 -9
  15. data/lib/hanami/cli.rb +10 -7
  16. data/lib/hanami/cli_sub_commands/assets.rb +1 -9
  17. data/lib/hanami/cli_sub_commands/generate.rb +16 -0
  18. data/lib/hanami/commands/apps.rb +4 -0
  19. data/lib/hanami/commands/assets/precompile.rb +6 -19
  20. data/lib/hanami/commands/command.rb +64 -0
  21. data/lib/hanami/commands/console.rb +37 -26
  22. data/lib/hanami/commands/db/apply.rb +4 -2
  23. data/lib/hanami/commands/db/console.rb +11 -27
  24. data/lib/hanami/commands/db/create.rb +4 -2
  25. data/lib/hanami/commands/db/drop.rb +4 -2
  26. data/lib/hanami/commands/db/migrate.rb +11 -5
  27. data/lib/hanami/commands/db/prepare.rb +4 -2
  28. data/lib/hanami/commands/db/version.rb +4 -2
  29. data/lib/hanami/commands/generate/abstract.rb +5 -7
  30. data/lib/hanami/commands/generate/action.rb +18 -6
  31. data/lib/hanami/commands/generate/app.rb +15 -2
  32. data/lib/hanami/commands/generate/migration.rb +3 -2
  33. data/lib/hanami/commands/generate/model.rb +4 -3
  34. data/lib/hanami/commands/generate/secret_token.rb +31 -0
  35. data/lib/hanami/commands/new/abstract.rb +14 -5
  36. data/lib/hanami/commands/new/container.rb +1 -0
  37. data/lib/hanami/commands/routes.rb +5 -22
  38. data/lib/hanami/commands/server.rb +14 -142
  39. data/lib/hanami/components.rb +107 -0
  40. data/lib/hanami/components/app/assets.rb +55 -0
  41. data/lib/hanami/components/app/controller.rb +69 -0
  42. data/lib/hanami/components/app/logger.rb +30 -0
  43. data/lib/hanami/components/app/routes.rb +51 -0
  44. data/lib/hanami/components/app/view.rb +40 -0
  45. data/lib/hanami/components/component.rb +166 -0
  46. data/lib/hanami/components/components.rb +366 -0
  47. data/lib/hanami/components/routes_inspector.rb +70 -0
  48. data/lib/hanami/config/load_paths.rb +7 -6
  49. data/lib/hanami/config/mapper.rb +1 -1
  50. data/lib/hanami/config/security.rb +0 -8
  51. data/lib/hanami/configuration.rb +27 -1697
  52. data/lib/hanami/env.rb +67 -0
  53. data/lib/hanami/environment.rb +31 -21
  54. data/lib/hanami/environment_application_configurations.rb +30 -0
  55. data/lib/hanami/frameworks.rb +1 -0
  56. data/lib/hanami/generators/app/application.rb.tt +2 -2
  57. data/lib/hanami/generators/application/app/Gemfile.tt +3 -1
  58. data/lib/hanami/generators/application/app/config/application.rb.tt +2 -2
  59. data/lib/hanami/generators/application/app/gitignore_with_sqlite.tt +3 -0
  60. data/lib/hanami/generators/application/app/lib/app_name.rb.tt +4 -25
  61. data/lib/hanami/generators/application/app/spec_helper.rb.minitest.tt +1 -1
  62. data/lib/hanami/generators/application/app/spec_helper.rb.rspec.tt +1 -1
  63. data/lib/hanami/generators/application/container/Gemfile.tt +3 -1
  64. data/lib/hanami/generators/application/container/capybara.rb.rspec.tt +1 -1
  65. data/lib/hanami/generators/application/container/config.ru.tt +1 -1
  66. data/lib/hanami/generators/application/container/config/environment.rb.tt +35 -1
  67. data/lib/hanami/generators/application/container/features_helper.rb.minitest.tt +1 -1
  68. data/lib/hanami/generators/application/container/gitignore_with_sqlite.tt +3 -0
  69. data/lib/hanami/generators/application/container/lib/project.rb.tt +1 -57
  70. data/lib/hanami/generators/application/container/spec_helper.rb.minitest.tt +1 -1
  71. data/lib/hanami/generators/application/container/spec_helper.rb.rspec.tt +2 -3
  72. data/lib/hanami/generators/database_config.rb +8 -11
  73. data/lib/hanami/generators/model/entity.rb.tt +1 -2
  74. data/lib/hanami/generators/model/repository.rb.tt +1 -2
  75. data/lib/hanami/generators/template_engine.rb +8 -3
  76. data/lib/hanami/generators/test_framework.rb +4 -3
  77. data/lib/hanami/middleware.rb +41 -21
  78. data/lib/hanami/rake_helper.rb +6 -8
  79. data/lib/hanami/server.rb +43 -33
  80. data/lib/hanami/static.rb +2 -2
  81. data/lib/hanami/version.rb +35 -1
  82. data/lib/hanami/welcome.rb +4 -5
  83. metadata +68 -42
  84. data/lib/hanami/commands/db/abstract.rb +0 -19
  85. data/lib/hanami/config/configure.rb +0 -17
  86. data/lib/hanami/config/mapping.rb +0 -12
  87. data/lib/hanami/container.rb +0 -71
  88. data/lib/hanami/generators/application/container/gitignore_with_db.tt +0 -4
  89. data/lib/hanami/loader.rb +0 -257
  90. data/lib/hanami/repositories/car_repository.rb +0 -3
  91. data/lib/hanami/repositories/name_repository.rb +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e5372a7522c384925f3944349192e57986d50d80
4
- data.tar.gz: 04e0cce2379b2c6a715a4651bcb20fc95283f193
3
+ metadata.gz: 231fd3e7e51ec7e9c6ccd1e9d8f91ba32b76e075
4
+ data.tar.gz: c7b8808423c4e968156bee4592a1595f511767d7
5
5
  SHA512:
6
- metadata.gz: 873a49c091e733de1f09092484baacc97c618c3ffc6666d68890b4bed9df50d3245db8f4c9af505b14883355b3c30c19e33fdb3271bb505d1d7a0bccca4b9899
7
- data.tar.gz: 760ba2f3f321c42cecaf25ffd2c9b25c60ccbbf79d1a9a65063eeb19f2df40902eac3f99cd5d028fffc91959976e874c740e1027e421cab2a9cb1b2d1f24787f
6
+ metadata.gz: 05b89fb3ac8d80064d0fa272ccea7a6344692d316f165d5cec0b58d8761442e7ec83b2231620a8b863d4a868dc47eea69861b8eaccc2ecb8af5f0ffb3c068aeb
7
+ data.tar.gz: 0d25225c8892dfcbb1c16e3031099ee33bf1dba14710b74ca2709cc0888586d6cf3b319d30468c824ae84fdbd6cd07e808fb2c0732565c43f18ba87a1a773901
data/CHANGELOG.md CHANGED
@@ -1,6 +1,29 @@
1
1
  # Hanami
2
2
  The web, with simplicity.
3
3
 
4
+ ## v0.9.0 - 2016-11-15
5
+ ### Added
6
+ - [Christophe Philemotte] Introduced `hanami secret` to generate and print a new sessions secret
7
+
8
+ ### Fixed
9
+ - [Bruz Marzolf] Skip project code preloading when code reloading is enabled
10
+ - [Bruz Marzolf] Ensure to generate project in current directory when running `hanami new .`
11
+ - [Pascal Betz] Fix constant lookup within the project namespace
12
+ - [Sean Collins] Ensure consistent order of code loading across operating systems
13
+ - [Luca Guidi] Ensure to load the project configurations only once
14
+ - [Luca Guidi] Fix duplicated Rack middleware in single Hanami application stacks
15
+
16
+ ### Changed
17
+ - [Luca Guidi] Official support for Ruby MRI 2.3+
18
+ - [Luca Guidi] Removed support for "application" architecture
19
+ - [Luca Guidi] Removed `Hanami::Container.new` in favor of `Hanami.app`
20
+ - [Luca Guidi] Removed `Hanami::Container.configure` in favor of `Hanami.configure`
21
+ - [Luca Guidi] Configure model and mailer within `Hanami.configure` block in `config/environment.rb`
22
+ - [Luca Guidi] Removed `mapping` from model configuration
23
+ - [Luca Guidi] Removed `Hanami::Application.preload!` in favor of `Hanami.boot`
24
+ - [Luca Guidi] Removed experimental code support for `entr(1)`
25
+ - [Luca Guidi & Sean Collins] Renamed assets configuration `digest` into `fingerprint`
26
+
4
27
  ## v0.8.0 - 2016-07-22
5
28
  ### Added
6
29
  - [Luca Guidi] Generate new projects with Subresurce Integrity enabled in production (security).
data/FEATURES.md CHANGED
@@ -3,6 +3,19 @@
3
3
 
4
4
  ## Features
5
5
 
6
+ ## v0.9.0 - (unreleased)
7
+
8
+ - Experimental repositories associations (only "has many")
9
+ - Database automapping for SQL databases
10
+ - Entities schema
11
+ - Immutable entities
12
+ - Removed dirty tracking for entities
13
+ - Repositories CRUD operations can accept both entities and/or data
14
+ - Removed Memory and File System adapters
15
+ - SQLite is the default adapter for new projects
16
+ - Native support for PostgreSQL types
17
+ - CLI: `hanami secret` to generate and print a new session secret for a single Hanami app
18
+
6
19
  ## v0.8.0 - 2016-07-22
7
20
 
8
21
  - New validation syntax based on predicates
data/README.md CHANGED
@@ -50,7 +50,7 @@ You can give back to Open Source, by supporting Hanami development via a [donati
50
50
 
51
51
  ## Rubies
52
52
 
53
- __Hanami__ supports Ruby (MRI) 2+
53
+ __Hanami__ supports Ruby (MRI) 2.3+
54
54
 
55
55
  ## Installation
56
56
 
@@ -112,6 +112,33 @@ vim Gemfile # edit with: gem 'hanami', path: '..'
112
112
  bundle
113
113
  ```
114
114
 
115
+ ### Development Requirements
116
+
117
+ * Ruby 2.3+ / JRuby 9.1.5.0+
118
+ * Bundler
119
+ * Qt (MacOS)
120
+ * Node.js (MacOS)
121
+
122
+ ### Testing
123
+
124
+ In order to simulate installed gems on developers' computers, the build installs
125
+ all the gems locally in `vendor/cache`, including `hanami` code from `lib/`.
126
+
127
+ **Before to run a test please make sure to have a fresh version of the code:**
128
+
129
+ ```shell
130
+ % ./script/setup
131
+ % bundle exec rspec spec/path/to/file_spec.rb
132
+ ```
133
+
134
+ ### Build / CI
135
+
136
+ To run all the tests, please use:
137
+
138
+ ```shell
139
+ % ./script/ci
140
+ ```
141
+
115
142
  ## Versioning
116
143
 
117
144
  __Hanami__ uses [Semantic Versioning 2.0.0](http://semver.org)
data/hanami.gemspec CHANGED
@@ -8,30 +8,33 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Hanami::VERSION
9
9
  spec.authors = ['Luca Guidi', 'Trung Lê', 'Alfonso Uceda Pompa']
10
10
  spec.email = ['me@lucaguidi.com', 'trung.le@ruby-journal.com', 'uceda73@gmail.com']
11
- spec.summary = %q{The web, with simplicity.}
12
- spec.description = %q{Hanami is a web framework for Ruby}
11
+ spec.summary = 'The web, with simplicity'
12
+ spec.description = 'Hanami is a web framework for Ruby'
13
13
  spec.homepage = 'http://hanamirb.org'
14
14
  spec.license = 'MIT'
15
15
 
16
- spec.files = `git ls-files -z -- lib/* bin/* LICENSE.md README.md CHANGELOG.md FEATURES.md hanami.gemspec`.split("\x0")
16
+ spec.files = `git ls-files -c -o --exclude-standard -z -- lib/* bin/* LICENSE.md README.md CHANGELOG.md FEATURES.md hanami.gemspec`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test)/})
19
19
  spec.require_paths = ['lib']
20
- spec.required_ruby_version = '>= 2.2.0'
20
+ spec.required_ruby_version = '>= 2.3.0'
21
21
 
22
- spec.add_dependency 'hanami-utils', '~> 0.8'
23
- spec.add_dependency 'hanami-validations', '~> 0.6'
24
- spec.add_dependency 'hanami-router', '~> 0.7'
25
- spec.add_dependency 'hanami-controller', '~> 0.7'
26
- spec.add_dependency 'hanami-view', '~> 0.7'
27
- spec.add_dependency 'hanami-helpers', '~> 0.4'
28
- spec.add_dependency 'hanami-mailer', '~> 0.3'
29
- spec.add_dependency 'hanami-assets', '~> 0.3'
22
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
23
+
24
+ spec.add_dependency 'hanami-utils', '~> 0.9'
25
+ spec.add_dependency 'hanami-validations', '~> 0.7'
26
+ spec.add_dependency 'hanami-router', '~> 0.8'
27
+ spec.add_dependency 'hanami-controller', '~> 0.8'
28
+ spec.add_dependency 'hanami-view', '~> 0.8'
29
+ spec.add_dependency 'hanami-helpers', '~> 0.5'
30
+ spec.add_dependency 'hanami-mailer', '~> 0.4'
31
+ spec.add_dependency 'hanami-assets', '~> 0.4'
32
+ spec.add_dependency 'concurrent-ruby', '~> 1.0'
30
33
  spec.add_dependency 'thor', '~> 0.19'
31
- spec.add_dependency 'bundler', '~> 1.6'
34
+ spec.add_dependency 'bundler', '~> 1.13'
32
35
 
33
- spec.add_development_dependency 'minispec-metadata', '~> 3.2.1'
34
- spec.add_development_dependency 'minitest', '~> 5'
35
- spec.add_development_dependency 'rack-test', '~> 0.6'
36
- spec.add_development_dependency 'rake', '~> 10'
36
+ spec.add_development_dependency 'rspec', '~> 3.5'
37
+ spec.add_development_dependency 'rack-test', '~> 0.6'
38
+ spec.add_development_dependency 'aruba', '~> 0.14'
39
+ spec.add_development_dependency 'rake', '~> 11.3'
37
40
  end
data/lib/hanami.rb CHANGED
@@ -1,8 +1,4 @@
1
- require 'hanami/version'
2
- require 'hanami/application'
3
- require 'hanami/container'
4
- require 'hanami/environment'
5
- require 'hanami/server'
1
+ require 'thread'
6
2
 
7
3
  # A complete web framework for Ruby
8
4
  #
@@ -10,8 +6,100 @@ require 'hanami/server'
10
6
  #
11
7
  # @see http://hanamirb.org
12
8
  module Hanami
9
+ require 'hanami/version'
10
+ require 'hanami/frameworks'
11
+ require 'hanami/environment'
12
+ require 'hanami/app'
13
+ require 'hanami/application'
14
+ require 'hanami/components'
15
+ require 'hanami/configuration'
16
+
17
+ # @api private
18
+ # @since 0.6.0
13
19
  DEFAULT_PUBLIC_DIRECTORY = 'public'.freeze
14
20
 
21
+ # @api private
22
+ # @since 0.9.0
23
+ @_mutex = Mutex.new
24
+
25
+ # Configure Hanami project
26
+ #
27
+ # Please note that the code for this method is generated by `hanami new`.
28
+ #
29
+ # @param blk [Proc] the configuration block
30
+ #
31
+ # @since 0.9.0
32
+ #
33
+ # @example
34
+ # # config/environment.rb
35
+ #
36
+ # # ...
37
+ #
38
+ # Hanami.configure do
39
+ # mount Admin::Application, at: "/admin"
40
+ # mount Web::Application, at: "/"
41
+ #
42
+ # model do
43
+ # adapter :sql, ENV['DATABASE_URL']
44
+ #
45
+ # migrations "db/migrations"
46
+ # schema "db/schema.sql"
47
+ # end
48
+ #
49
+ # mailer do
50
+ # root "lib/bookshelf/mailers"
51
+ #
52
+ # delivery do
53
+ # development :test
54
+ # test :test
55
+ # # production :smtp, address: ENV['SMTP_HOST'], port: 1025
56
+ # end
57
+ # end
58
+ # end
59
+ def self.configure(&blk)
60
+ @_mutex.synchronize do
61
+ @_configuration = Hanami::Configuration.new(&blk)
62
+ end
63
+ end
64
+
65
+ # Hanami configuration
66
+ #
67
+ # @return [Hanami::Configuration] the configuration
68
+ #
69
+ # @see Hanami.configure
70
+ #
71
+ # @since 0.9.0
72
+ # @api private
73
+ def self.configuration
74
+ @_mutex.synchronize do
75
+ raise "Hanami not configured" unless defined?(@_configuration)
76
+ @_configuration
77
+ end
78
+ end
79
+
80
+ # Boot Hanami project
81
+ #
82
+ # @since 0.9.0
83
+ # @api private
84
+ def self.boot
85
+ Components.resolve('all')
86
+ end
87
+
88
+ # Main application that mounts many Rack and/or Hanami applications.
89
+ #
90
+ # This is used as integration point for:
91
+ #
92
+ # * `config.ru` (`run Hanami.app`)
93
+ # * Feature tests (`Capybara.app = Hanami.app`)
94
+ #
95
+ # @return [Hanami::App] the app
96
+ #
97
+ # @since 0.9.0
98
+ # @api private
99
+ def self.app
100
+ App.new(configuration, environment)
101
+ end
102
+
15
103
  # Return root of the project (top level directory).
16
104
  #
17
105
  # @return [Pathname] root path
@@ -24,6 +112,15 @@ module Hanami
24
112
  environment.root
25
113
  end
26
114
 
115
+ # Project public directory
116
+ #
117
+ # @return [Pathname] public directory
118
+ #
119
+ # @since 0.6.0
120
+ # @api private
121
+ #
122
+ # @example
123
+ # Hanami.public_directory # => #<Pathname:/Users/luca/Code/bookshelf/public>
27
124
  def self.public_directory
28
125
  root.join(DEFAULT_PUBLIC_DIRECTORY)
29
126
  end
@@ -70,13 +167,15 @@ module Hanami
70
167
  environment.environment?(*names)
71
168
  end
72
169
 
73
- # Return environment
170
+ # Current environment
74
171
  #
75
172
  # @return [Hanami::Environment] environment
76
173
  #
77
174
  # @api private
78
175
  # @since 0.3.2
79
176
  def self.environment
80
- Environment.new
177
+ Components.resolved('environment') do
178
+ Environment.new
179
+ end
81
180
  end
82
181
  end
@@ -25,13 +25,13 @@ module Hanami
25
25
  # end
26
26
  module RoutingHelpers
27
27
  def self.included(base)
28
- factory = "#{ Utils::String.new(base).namespace }::Routes"
28
+ factory = "#{Utils::String.new(base).namespace}.routes"
29
29
 
30
30
  base.class_eval <<-END_EVAL, __FILE__, __LINE__
31
31
  private
32
32
 
33
33
  def routes
34
- #{ factory }
34
+ #{factory}
35
35
  end
36
36
  END_EVAL
37
37
  end
data/lib/hanami/app.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'rack'
2
+ require 'rack/builder'
3
+ require 'hanami/router'
4
+ require 'hanami/components'
5
+
6
+ module Hanami
7
+ # Main application that mounts many Rack and/or Hanami applications.
8
+ #
9
+ # @see Hanami.app
10
+ #
11
+ # @since 0.9.0
12
+ # @api private
13
+ class App
14
+ # Initialize a new instance
15
+ #
16
+ # @param configuration [Hanami::Configuration] general configuration
17
+ # @param environment [Hanami::Environment] current environment
18
+ #
19
+ # @since 0.9.0
20
+ # @api private
21
+ def initialize(configuration, environment)
22
+ Components.resolve('apps')
23
+
24
+ @builder = Rack::Builder.new
25
+ @routes = Hanami::Router.new
26
+
27
+ mount(configuration)
28
+ middleware(environment)
29
+ builder.run(routes)
30
+ end
31
+
32
+ # Implements Rack SPEC
33
+ #
34
+ # @param env [Hash] a Rack env
35
+ #
36
+ # @return [Array] a serialized Rack response
37
+ #
38
+ # @since 0.9.0
39
+ # @api private
40
+ def call(env)
41
+ builder.call(env)
42
+ end
43
+
44
+ private
45
+
46
+ # @since 0.9.0
47
+ # @api private
48
+ attr_reader :builder
49
+
50
+ # @since 0.9.0
51
+ # @api private
52
+ attr_reader :routes
53
+
54
+ # @since 0.9.0
55
+ # @api private
56
+ def mount(configuration)
57
+ configuration.mounted.each do |klass, app|
58
+ routes.mount(klass, at: app.path_prefix)
59
+ end
60
+ end
61
+
62
+ # @since 0.9.0
63
+ # @api private
64
+ def middleware(environment)
65
+ if middleware = environment.static_assets_middleware # rubocop:disable Lint/AssignmentInCondition
66
+ builder.use middleware
67
+ end
68
+
69
+ builder.use Rack::MethodOverride
70
+ end
71
+ end
72
+ end
@@ -1,10 +1,10 @@
1
- require 'hanami/utils/class_attribute'
2
- require 'hanami/frameworks'
3
- require 'hanami/configuration'
4
- require 'hanami/loader'
5
- require 'hanami/logger'
1
+ require 'thread'
2
+ require 'concurrent'
3
+ require 'hanami/application_name'
4
+ require 'hanami/application_namespace'
5
+ require 'hanami/application_configuration'
6
+ require 'hanami/environment_application_configurations'
6
7
  require 'hanami/rendering_policy'
7
- require 'hanami/middleware'
8
8
 
9
9
  module Hanami
10
10
  # A full stack Hanami application
@@ -28,116 +28,105 @@ module Hanami
28
28
  def self.inherited(base)
29
29
  super
30
30
 
31
- base.class_eval do
32
- include Hanami::Utils::ClassAttribute
33
-
34
- class_attribute :configuration
35
- self.configuration = Configuration.new
36
- end
37
-
38
- synchronize do
39
- applications.add(base)
31
+ base.extend(ClassMethods)
32
+ base.namespace.module_eval do
33
+ class << self
34
+ # Logger for this application
35
+ #
36
+ # @return [Hanami::Logger] the logger for this Hanami application
37
+ #
38
+ # @since 0.9.0
39
+ # @api public
40
+ #
41
+ # @example
42
+ #
43
+ # Web.logger
44
+ # Admin.logger
45
+ attr_accessor :logger
46
+
47
+ # Routes for this application
48
+ #
49
+ # @return [Hanami::Routes] the routes for this Hanami application
50
+ #
51
+ # @since 0.9.0
52
+ # @api public
53
+ #
54
+ # @example
55
+ #
56
+ # Web.routes
57
+ # Admin.routes
58
+ attr_accessor :routes
59
+ end
40
60
  end
41
61
  end
42
62
 
43
- # @since 0.8.0
44
- # @api private
45
- LOCK = Mutex.new
46
-
47
- # Return the routes for this application
63
+ # Class interface for Hanami applications
48
64
  #
49
- # @return [Hanami::Router] a route set
50
- #
51
- # @since 0.1.0
52
- #
53
- # @see Hanami::Configuration#routes
54
- attr_reader :routes
65
+ # @since 0.9.0
66
+ module ClassMethods
67
+ # Override Ruby's Class#extended
68
+ #
69
+ # @since 0.9.0
70
+ # @api private
71
+ #
72
+ # @see http://www.ruby-doc.org/core/Class.html#method-i-extended
73
+ def self.extended(base) # rubocop:disable Metrics/MethodLength
74
+ super
55
75
 
56
- # Set the routes for this application
57
- #
58
- @param [Hanami::Router]
59
- #
60
- # @since 0.1.0
61
- # @api private
62
- attr_writer :routes
76
+ base.class_eval do
77
+ @namespace = ApplicationNamespace.resolve(name)
78
+ @configurations = EnvironmentApplicationConfigurations.new
79
+ @_lock = Mutex.new
63
80
 
64
- # Rendering policy
65
- #
66
- # @param [Hanami::RenderingPolicy]
67
- #
68
- # @since 0.2.0
69
- # @api private
70
- attr_accessor :renderer
81
+ class << self
82
+ # @since 0.9.0
83
+ # @api private
84
+ attr_reader :namespace
71
85
 
72
- # Initialize and load a new instance of the application
73
- #
74
- # @return [Hanami::Application] a new instance of the application
75
- #
76
- # @since 0.1.0
77
- def initialize(options = {})
78
- self.class.configuration.path_prefix options[:path_prefix]
79
- self.class.load!(self)
80
- end
81
-
82
- # Return the configuration for this application
83
- #
84
- # @since 0.1.0
85
- # @api private
86
- #
87
- # @see Hanami::Application.configuration
88
- def configuration
89
- self.class.configuration
90
- end
86
+ # @since 0.9.0
87
+ # @api private
88
+ attr_reader :configurations
91
89
 
92
- # Return the application name
93
- #
94
- # @since 0.2.0
95
- # @api private
96
- def name
97
- self.class.name
98
- end
99
-
100
- # Process a request.
101
- # This method makes Hanami applications compatible with the Rack protocol.
102
- #
103
- # @param env [Hash] a Rack env
104
- #
105
- # @return [Array] a serialized Rack response
106
- #
107
- # @since 0.1.0
108
- #
109
- # @see http://rack.github.io
110
- # @see Hanami::RenderingPolicy#render
111
- # @see Hanami::Application#middleware
112
- def call(env)
113
- renderer.render(env, middleware.call(env))
114
- end
115
-
116
- # Rack middleware stack
117
- #
118
- # @return [Hanami::Middleware] the middleware stack
119
- #
120
- # @since 0.1.0
121
- # @api private
122
- #
123
- # @see Hanami::Middleware
124
- def middleware
125
- @middleware ||= configuration.middleware
126
- end
90
+ # @since 0.9.0
91
+ # @api private
92
+ attr_reader :configuration
93
+ end
94
+ end
95
+ end
127
96
 
128
- class << self
129
- # @since 0.2.0
97
+ # Hanami application name
98
+ #
99
+ # @return [String] the Hanami application name
100
+ #
101
+ # @since 0.9.0
130
102
  # @api private
131
- @@applications = Set.new
103
+ #
104
+ # @example
105
+ # require 'hanami'
106
+ #
107
+ # module Web
108
+ # class Application < Hanami::Application
109
+ # end
110
+ # end
111
+ #
112
+ # Web::Application.app_name # => "web"
113
+ def app_name
114
+ ApplicationName.new(name).to_s
115
+ end
132
116
 
133
- # Registry of Hanami applications in the current Ruby process
117
+ # Set configuration
118
+ #
119
+ # @param configuration [Hanami::ApplicationConfiguration] the application configuration
134
120
  #
135
- # @return [Set] a set of all the registered applications
121
+ # @raise [RuntimeError] if the configuration is assigned more than once
136
122
  #
137
- # @since 0.2.0
123
+ # @since 0.1.0
138
124
  # @api private
139
- def applications
140
- @@applications
125
+ def configuration=(configuration)
126
+ @_lock.synchronize do
127
+ raise "Can't assign configuration more than once (#{app_name})" unless @configuration.nil?
128
+ @configuration = configuration
129
+ end
141
130
  end
142
131
 
143
132
  # Configure the application.
@@ -148,7 +137,7 @@ module Hanami
148
137
  #
149
138
  # @since 0.1.0
150
139
  #
151
- # @see Hanami::Configuration
140
+ # @see Hanami::ApplicationConfiguration
152
141
  #
153
142
  # @example
154
143
  # require 'hanami'
@@ -161,92 +150,64 @@ module Hanami
161
150
  # end
162
151
  # end
163
152
  def configure(environment = nil, &blk)
164
- configuration.configure(environment, &blk)
165
- end
166
-
167
- # Eager load the application configuration, by activating the framework
168
- # duplication mechanisms.
169
- #
170
- # @param application [Hanami::Application, Class<Hanami::Application>]
171
- # @return void
172
- #
173
- # @since 0.1.1
174
- #
175
- # @example
176
- # require 'hanami'
177
- #
178
- # module OneFile
179
- # class Application < Hanami::Application
180
- # configure do
181
- # routes do
182
- # get '/', to: 'dashboard#index'
183
- # end
184
- # end
185
- #
186
- # load!
187
- # end
188
- #
189
- # module Controllers::Dashboard
190
- # class Index
191
- # include OneFile::Action
192
- #
193
- # def call(params)
194
- # self.body = 'Hello!'
195
- # end
196
- # end
197
- # end
198
- # end
199
- def load!(application = self)
200
- Hanami::Loader.new(application).load!
153
+ configurations.add(environment, &blk)
201
154
  end
155
+ end
202
156
 
203
- # Preload all the registered applications, by yielding their configurations
204
- # and preparing the frameworks.
205
- #
206
- # This is useful for testing suites, where we want to make Hanami frameworks
207
- # ready, but not preload applications code.
208
- #
209
- # This allows to test components such as views or actions in isolation and
210
- # to have faster boot times.
211
- #
212
- # @return [void]
213
- #
214
- # @since 0.2.0
215
- def preload!
216
- synchronize do
217
- applications.each(&:load!)
218
- end
157
+ # Initialize and load a new instance of the application
158
+ #
159
+ # @return [Hanami::Application] a new instance of the application
160
+ #
161
+ # @since 0.1.0
162
+ def initialize
163
+ @renderer = RenderingPolicy.new(configuration)
164
+ @middleware = configuration.middleware
165
+ end
219
166
 
220
- nil
221
- end
167
+ # Process a request.
168
+ # This method makes Hanami applications compatible with the Rack protocol.
169
+ #
170
+ # @param env [Hash] a Rack env
171
+ #
172
+ # @return [Array] a serialized Rack response
173
+ #
174
+ # @since 0.1.0
175
+ #
176
+ # @see http://rack.github.io
177
+ # @see Hanami::RenderingPolicy#render
178
+ # @see Hanami::Application#middleware
179
+ def call(env)
180
+ renderer.render(env, middleware.call(env))
181
+ end
222
182
 
223
- # Full preload for all the registered applications.
224
- #
225
- # This is useful in console where we want all the application code available.
226
- #
227
- # @return [void]
228
- #
229
- # @since 0.2.1
230
- # @api private
231
- def preload_applications!
232
- synchronize do
233
- applications.each { |app| app.new }
234
- end
183
+ private
235
184
 
236
- nil
237
- end
185
+ # Return the configuration for this application
186
+ #
187
+ # @since 0.1.0
188
+ # @api private
189
+ #
190
+ # @see Hanami::Application.configuration
191
+ def configuration
192
+ self.class.configuration
193
+ end
238
194
 
239
- private
195
+ # Rendering policy
196
+ #
197
+ # @since 0.2.0
198
+ # @api private
199
+ #
200
+ # @see Hanami::RenderingPolicy
201
+ attr_reader :renderer
240
202
 
241
- # Yields the given block in a critical section
242
- #
243
- # @since 0.2.0
244
- # @api private
245
- def synchronize
246
- LOCK.synchronize do
247
- yield
248
- end
249
- end
250
- end
203
+ # Rack middleware stack
204
+ #
205
+ # @return [Hanami::Middleware] the middleware stack
206
+ #
207
+ # @since 0.1.0
208
+ # @api private
209
+ #
210
+ # @see Hanami::Middleware
211
+ attr_reader :middleware
251
212
  end
252
213
  end