hanami 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -0,0 +1,366 @@
1
+ require 'hanami/utils'
2
+
3
+ module Hanami
4
+ # Registered components
5
+ #
6
+ # @since 0.9.0
7
+ # @api private
8
+ #
9
+ # @see Hanami::Components
10
+ module Components # rubocop:disable Metrics/ModuleLength
11
+ # Require the entire project
12
+ #
13
+ # @since 0.9.0
14
+ # @api private
15
+ register 'all' do
16
+ requires 'model', 'apps', 'finalizers'
17
+
18
+ resolve { true }
19
+ end
20
+
21
+ # Check if code reloading is enabled
22
+ #
23
+ # @since 0.9.0
24
+ # @api private
25
+ register 'code_reloading' do
26
+ prepare do
27
+ begin
28
+ require 'shotgun'
29
+ rescue LoadError # rubocop:disable Lint/HandleExceptions
30
+ end
31
+ end
32
+
33
+ resolve do
34
+ defined?(Shotgun) &&
35
+ Components['environment'].code_reloading? &&
36
+ true
37
+ end
38
+ end
39
+
40
+ # Tries to load hanami-model, if available for the project
41
+ #
42
+ # @since 0.9.0
43
+ # @api private
44
+ #
45
+ # @example With hanami-model
46
+ # Hanami::Components.resolve('model')
47
+ # Hanami::Components['model'] # => true
48
+ #
49
+ # @example Without hanami-model
50
+ # Hanami::Components.resolve('model')
51
+ # Hanami::Components['model'] # => nil
52
+ register 'model' do
53
+ requires 'model.configuration', 'model.sql'
54
+
55
+ resolve do
56
+ if Components['model.configuration']
57
+ Hanami::Model.load!
58
+ true
59
+ end
60
+ end
61
+ end
62
+
63
+ # Tries to evaluate hanami-model configuration, if available for the project
64
+ #
65
+ # @since 0.9.0
66
+ # @api private
67
+ #
68
+ # @example With hanami-model
69
+ # Hanami::Components.resolve('model.configuration')
70
+ # Hanami::Components['model.configuration'].class # => Hanami::Model::Configuration
71
+ #
72
+ # @example Without hanami-model
73
+ # Hanami::Components.resolve('model.configuration')
74
+ # Hanami::Components['model.configuration'].class # => NilClass
75
+ register 'model.configuration' do
76
+ requires 'model.bundled'
77
+
78
+ resolve do |configuration|
79
+ if Components['model.bundled']
80
+ Hanami::Model.configure(&configuration.model)
81
+ Hanami::Model.configuration
82
+ end
83
+ end
84
+ end
85
+
86
+ # Tries to load SQL support for hanami, if available for the project
87
+ #
88
+ # @since 0.9.0
89
+ # @api private
90
+ #
91
+ # @example With hanami-model
92
+ # Hanami::Components.resolve('model.sql')
93
+ # Hanami::Components['model.sql'] # => true
94
+ #
95
+ # @example Without hanami-model
96
+ # Hanami::Components.resolve('model.sql')
97
+ # Hanami::Components['model.sql'] # => nil
98
+ register 'model.sql' do
99
+ requires 'model.configuration'
100
+
101
+ prepare do
102
+ begin
103
+ require 'hanami/model/sql'
104
+ rescue LoadError # rubocop:disable Lint/HandleExceptions
105
+ end
106
+ end
107
+
108
+ resolve do
109
+ true if defined?(Hanami::Model::Sql)
110
+ end
111
+ end
112
+
113
+ # Check if hanami-model is bundled
114
+ #
115
+ # @since 0.9.0
116
+ # @api private
117
+ #
118
+ # @example With hanami-model
119
+ # Hanami::Components.resolve('model.bundled')
120
+ # Hanami::Components['model.bundled'] # => true
121
+ #
122
+ # @example Without hanami-model
123
+ # Hanami::Components.resolve('model.bundled')
124
+ # Hanami::Components['model.bundled'] # => nil
125
+ register 'model.bundled' do
126
+ prepare do
127
+ begin
128
+ require 'hanami/model'
129
+ rescue LoadError # rubocop:disable Lint/HandleExceptions
130
+ end
131
+ end
132
+
133
+ resolve do
134
+ true if defined?(Hanami::Model)
135
+ end
136
+ end
137
+
138
+ # Loads the routes for all the mounted Hanami/Rack applications
139
+ #
140
+ # This is used only by `hanami routes` command.
141
+ #
142
+ # @since 0.9.0
143
+ # @api private
144
+ register 'routes.inspector' do
145
+ requires 'apps.configurations'
146
+
147
+ prepare do
148
+ require 'hanami/components/routes_inspector'
149
+ end
150
+
151
+ resolve do |configuration|
152
+ RoutesInspector.new(configuration)
153
+ end
154
+ end
155
+
156
+ # Loads all the Hanami applications in the project
157
+ #
158
+ # @since 0.9.0
159
+ # @api private
160
+ register 'apps' do
161
+ resolve do |configuration|
162
+ configuration.apps do |app|
163
+ component('app').call(app)
164
+ end
165
+
166
+ true
167
+ end
168
+ end
169
+
170
+ # Evaluates all the Hanami applications' configurations in the project
171
+ #
172
+ # @since 0.9.0
173
+ # @api private
174
+ register 'apps.configurations' do
175
+ resolve do |configuration|
176
+ configuration.apps do |app|
177
+ component('app.configuration').call(app)
178
+ end
179
+
180
+ true
181
+ end
182
+ end
183
+
184
+ # Evaluates all the Hanami assets configurations for each application in the project
185
+ #
186
+ # This is used only by `hanami assets precompile` command.
187
+ #
188
+ # @since 0.9.0
189
+ # @api private
190
+ register 'apps.assets.configurations' do
191
+ requires 'apps.configurations'
192
+
193
+ prepare do
194
+ require 'hanami/components/app/assets'
195
+ end
196
+
197
+ resolve do |configuration|
198
+ [].tap do |result|
199
+ configuration.apps do |app|
200
+ result << Components::App::Assets.resolve(app)
201
+ end
202
+ end
203
+ end
204
+ end
205
+
206
+ # Finalizers for the project
207
+ #
208
+ # @since 0.9.0
209
+ # @api private
210
+ register 'finalizers' do
211
+ requires 'finalizers.initializers'
212
+
213
+ resolve { true }
214
+ end
215
+
216
+ # Load project initializers
217
+ #
218
+ # @since 0.9.0
219
+ # @api private
220
+ register 'finalizers.initializers' do
221
+ run do
222
+ Hanami::Utils.require!(
223
+ Hanami.root.join('config', 'initializers')
224
+ )
225
+ end
226
+ end
227
+
228
+ # Configure, load and finalize a Hanami application in the project
229
+ #
230
+ # @since 0.9.0
231
+ # @api private
232
+ register 'app' do
233
+ run do |app|
234
+ ['app.configuration', 'app.frameworks', 'app.code', 'app.routes', 'app.finalizer'].each do |c|
235
+ component(c).call(app)
236
+ end
237
+
238
+ resolved(app.app_name, true)
239
+ end
240
+ end
241
+
242
+ # Evaluate the configuration of a single Hanami application in the project
243
+ #
244
+ # @since 0.9.0
245
+ # @api private
246
+ register 'app.configuration' do
247
+ run do |app|
248
+ resolved("#{app.app_name}.configuration") do
249
+ ApplicationConfiguration.new(app.namespace, app.configurations, app.path_prefix).tap do |config|
250
+ app.configuration = config
251
+ end
252
+ end
253
+ end
254
+ end
255
+
256
+ # Evaluate Hanami frameworks configurations of a single Hanami application in the project
257
+ #
258
+ # @since 0.9.0
259
+ # @api private
260
+ register 'app.frameworks' do
261
+ run do |app|
262
+ ['app.controller', 'app.view', 'app.assets', 'app.logger'].each do |c|
263
+ component(c).call(app)
264
+ end
265
+ end
266
+ end
267
+
268
+ # Evaluate hanami-controller configuration of a single Hanami application in the project
269
+ #
270
+ # @since 0.9.0
271
+ # @api private
272
+ register 'app.controller' do
273
+ prepare do
274
+ require 'hanami/components/app/controller'
275
+ end
276
+
277
+ run do |app|
278
+ Components::App::Controller.resolve(app)
279
+ end
280
+ end
281
+
282
+ # Evaluate hanami-view configuration of a single Hanami application in the project
283
+ #
284
+ # @since 0.9.0
285
+ # @api private
286
+ register 'app.view' do
287
+ prepare do
288
+ require 'hanami/components/app/view'
289
+ end
290
+
291
+ run do |app|
292
+ Components::App::View.resolve(app)
293
+ end
294
+ end
295
+
296
+ # Evaluate hanami-assets configuration of a single Hanami application in the project
297
+ #
298
+ # @since 0.9.0
299
+ # @api private
300
+ register 'app.assets' do
301
+ prepare do
302
+ require 'hanami/components/app/assets'
303
+ end
304
+
305
+ run do |app|
306
+ Components::App::Assets.resolve(app)
307
+ end
308
+ end
309
+
310
+ # Evaluate hanami/logger configuration of a single Hanami application in the project
311
+ #
312
+ # @since 0.9.0
313
+ # @api private
314
+ register 'app.logger' do
315
+ prepare do
316
+ require 'hanami/components/app/logger'
317
+ end
318
+
319
+ run do |app|
320
+ Components::App::Logger.resolve(app)
321
+ end
322
+ end
323
+
324
+ # Load the code for a single Hanami application in the project
325
+ #
326
+ # @since 0.9.0
327
+ # @api private
328
+ register 'app.code' do
329
+ run do |app|
330
+ config = app.configuration
331
+ config.load_paths.load!
332
+ end
333
+ end
334
+
335
+ # Load the routes for a single Hanami application in the project
336
+ #
337
+ # @since 0.9.0
338
+ # @api private
339
+ register 'app.routes' do
340
+ prepare do
341
+ require 'hanami/components/app/routes'
342
+ end
343
+
344
+ run do |app|
345
+ Components::App::Routes.resolve(app)
346
+ end
347
+ end
348
+
349
+ # Finalize a single Hanami application in the project
350
+ #
351
+ # @since 0.9.0
352
+ # @api private
353
+ register 'app.finalizer' do
354
+ run do |app|
355
+ config = app.configuration
356
+ namespace = app.namespace
357
+
358
+ config.middleware.load!
359
+
360
+ namespace.module_eval %(#{namespace}::Controller.load!)
361
+ namespace.module_eval %(#{namespace}::View.load!)
362
+ namespace.module_eval %(#{namespace}::Assets.load!)
363
+ end
364
+ end
365
+ end
366
+ end
@@ -0,0 +1,70 @@
1
+ require 'hanami/routing/default'
2
+ require_relative './app/routes'
3
+
4
+ module Hanami
5
+ module Components
6
+ # Project's routes inspector
7
+ #
8
+ # @since 0.9.0
9
+ # @api private
10
+ class RoutesInspector
11
+ # @param configuration [Hanami::Configuration]
12
+ #
13
+ # @since 0.9.0
14
+ # @api private
15
+ def initialize(configuration)
16
+ @configuration = configuration
17
+ end
18
+
19
+ # Returns a printable version of the project routes
20
+ #
21
+ # @return [String] printable routes
22
+ #
23
+ # @since 0.9.0
24
+ # @api private
25
+ def inspect
26
+ routes.map do |r|
27
+ r.inspector.to_s
28
+ end.join("\n")
29
+ end
30
+
31
+ private
32
+
33
+ # @since 0.9.0
34
+ # @api private
35
+ attr_reader :configuration
36
+
37
+ # @since 0.9.0
38
+ # @api private
39
+ def routes
40
+ configuration.mounted.each_with_object([]) do |(klass, app), result|
41
+ result << if hanami_app?(klass)
42
+ resolve_hanami_app_router(app)
43
+ else
44
+ resolve_rack_app_router(app)
45
+ end
46
+ end
47
+ end
48
+
49
+ # @since 0.9.0
50
+ # @api private
51
+ def hanami_app?(klass)
52
+ klass.ancestors.include?(Hanami::Application)
53
+ end
54
+
55
+ # @since 0.9.0
56
+ # @api private
57
+ def resolve_hanami_app_router(app)
58
+ App::Routes.application_routes(app)
59
+ end
60
+
61
+ # @since 0.9.0
62
+ # @api private
63
+ def resolve_rack_app_router(app)
64
+ Hanami::Router.new do
65
+ mount app.name, at: app.path_prefix
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,4 +1,4 @@
1
- require 'hanami/utils/load_paths'
1
+ require 'hanami/utils'
2
2
 
3
3
  module Hanami
4
4
  module Config
@@ -7,21 +7,22 @@ module Hanami
7
7
  # @since 0.1.0
8
8
  # @api private
9
9
  class LoadPaths < Utils::LoadPaths
10
- PATTERN = '**/*.rb'.freeze
11
-
12
- def load!(root)
10
+ def initialize(root)
11
+ super()
13
12
  @root = root
13
+ end
14
14
 
15
+ def load!
15
16
  each do |path|
16
- Dir.glob(path.join(PATTERN)).each { |file| require file }
17
+ Utils.require!(path)
17
18
  end
18
19
  end
19
20
 
20
21
  protected
22
+
21
23
  def realpath(path)
22
24
  @root.join(path).realpath
23
25
  end
24
26
  end
25
27
  end
26
28
  end
27
-