hanami 0.9.2 → 1.0.0.beta1

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/FEATURES.md +5 -0
  4. data/hanami.gemspec +8 -8
  5. data/lib/hanami.rb +25 -1
  6. data/lib/hanami/app.rb +4 -0
  7. data/lib/hanami/application.rb +1 -14
  8. data/lib/hanami/application_configuration.rb +2 -37
  9. data/lib/hanami/cli_base.rb +15 -0
  10. data/lib/hanami/cli_sub_commands/destroy.rb +2 -2
  11. data/lib/hanami/cli_sub_commands/generate.rb +2 -1
  12. data/lib/hanami/commands/generate/abstract.rb +5 -0
  13. data/lib/hanami/commands/generate/mailer.rb +2 -2
  14. data/lib/hanami/commands/generate/model.rb +24 -8
  15. data/lib/hanami/commands/new/abstract.rb +1 -1
  16. data/lib/hanami/commands/new/container.rb +1 -0
  17. data/lib/hanami/common_logger.rb +73 -0
  18. data/lib/hanami/components.rb +11 -0
  19. data/lib/hanami/components/app/controller.rb +1 -0
  20. data/lib/hanami/components/components.rb +73 -20
  21. data/lib/hanami/configuration.rb +12 -0
  22. data/lib/hanami/env.rb +2 -0
  23. data/lib/hanami/environment.rb +5 -1
  24. data/lib/hanami/generators/app/application.rb.tt +0 -30
  25. data/lib/hanami/generators/application/container/Gemfile.tt +0 -1
  26. data/lib/hanami/generators/application/container/config/boot.rb.tt +2 -0
  27. data/lib/hanami/generators/application/container/config/environment.rb.tt +14 -5
  28. data/lib/hanami/generators/database_config.rb +1 -1
  29. data/lib/hanami/generators/mailer/{mailer_spec.rb.tt → mailer_spec.rb.minitest.tt} +0 -0
  30. data/lib/hanami/generators/mailer/mailer_spec.rb.rspec.tt +5 -0
  31. data/lib/hanami/generators/model/migration.rb.tt +10 -0
  32. data/lib/hanami/mailer/glue.rb +4 -46
  33. data/lib/hanami/server.rb +4 -12
  34. data/lib/hanami/static.rb +4 -8
  35. data/lib/hanami/version.rb +1 -1
  36. metadata +25 -62
  37. data/lib/hanami/components/app/logger.rb +0 -30
  38. data/lib/hanami/config/logger.rb +0 -200
  39. data/lib/hanami/generators/application/app/.env.development.tt +0 -4
  40. data/lib/hanami/generators/application/app/.env.test.tt +0 -4
  41. data/lib/hanami/generators/application/app/.gitignore +0 -0
  42. data/lib/hanami/generators/application/app/.gitkeep +0 -1
  43. data/lib/hanami/generators/application/app/Gemfile.tt +0 -57
  44. data/lib/hanami/generators/application/app/Rakefile.minitest.tt +0 -12
  45. data/lib/hanami/generators/application/app/Rakefile.rspec.tt +0 -9
  46. data/lib/hanami/generators/application/app/apps/.gitkeep.tt +0 -1
  47. data/lib/hanami/generators/application/app/capybara.rb.rspec.tt +0 -8
  48. data/lib/hanami/generators/application/app/config.ru.tt +0 -3
  49. data/lib/hanami/generators/application/app/config/application.rb.tt +0 -347
  50. data/lib/hanami/generators/application/app/config/environment.rb.tt +0 -4
  51. data/lib/hanami/generators/application/app/config/initializers/.gitkeep +0 -0
  52. data/lib/hanami/generators/application/app/config/routes.rb.tt +0 -5
  53. data/lib/hanami/generators/application/app/db/.gitkeep +0 -1
  54. data/lib/hanami/generators/application/app/favicon.ico +0 -0
  55. data/lib/hanami/generators/application/app/features_helper.rb.minitest.tt +0 -11
  56. data/lib/hanami/generators/application/app/features_helper.rb.rspec.tt +0 -12
  57. data/lib/hanami/generators/application/app/gitignore.tt +0 -2
  58. data/lib/hanami/generators/application/app/gitignore_with_db.tt +0 -4
  59. data/lib/hanami/generators/application/app/gitignore_with_sqlite.tt +0 -3
  60. data/lib/hanami/generators/application/app/hanamirc.tt +0 -4
  61. data/lib/hanami/generators/application/app/lib/app_name.rb.tt +0 -35
  62. data/lib/hanami/generators/application/app/lib/chirp/entities/.gitkeep +0 -1
  63. data/lib/hanami/generators/application/app/lib/chirp/repositories/.gitkeep +0 -1
  64. data/lib/hanami/generators/application/app/rspec.rspec.tt +0 -2
  65. data/lib/hanami/generators/application/app/schema.sql.tt +0 -0
  66. data/lib/hanami/generators/application/app/spec_helper.rb.minitest.tt +0 -7
  67. data/lib/hanami/generators/application/app/spec_helper.rb.rspec.tt +0 -104
  68. data/lib/hanami/generators/application/app/templates/application.html.erb.tt +0 -10
  69. data/lib/hanami/generators/application/app/templates/application.html.haml.tt +0 -7
  70. data/lib/hanami/generators/application/app/templates/application.html.slim.tt +0 -8
  71. data/lib/hanami/generators/application/app/views/application_layout.rb.tt +0 -7
@@ -101,6 +101,17 @@ module Hanami
101
101
  end
102
102
  end
103
103
 
104
+ # Release all the resolved components.
105
+ # This is used for code reloading.
106
+ #
107
+ # NOTE: this MUST NOT be used unless you know what you're doing.
108
+ #
109
+ # @since 1.0.0.beta1
110
+ # @api private
111
+ def self.release
112
+ @_resolved.clear
113
+ end
114
+
104
115
  require 'hanami/components/component'
105
116
  require 'hanami/components/components'
106
117
  end
@@ -28,6 +28,7 @@ module Hanami
28
28
  unless namespace.const_defined?('Controller', false)
29
29
  controller = Hanami::Controller.duplicate(namespace) do
30
30
  handle_exceptions config.handle_exceptions
31
+ public_directory Hanami.public_directory
31
32
  default_request_format config.default_request_format
32
33
  default_response_format config.default_response_format
33
34
  default_headers(
@@ -13,11 +13,25 @@ module Hanami
13
13
  # @since 0.9.0
14
14
  # @api private
15
15
  register 'all' do
16
- requires 'model', 'apps', 'finalizers'
16
+ requires 'logger', 'mailer', 'code', 'model', 'apps', 'finalizers'
17
17
 
18
18
  resolve { true }
19
19
  end
20
20
 
21
+ # Setup project's logger
22
+ #
23
+ # @since 1.0.0.beta1
24
+ # @api private
25
+ register 'logger' do
26
+ prepare do
27
+ require 'hanami/logger'
28
+ end
29
+
30
+ resolve do |configuration|
31
+ Hanami::Logger.new(Hanami.environment.project_name, configuration.logger) unless configuration.logger.nil?
32
+ end
33
+ end
34
+
21
35
  # Check if code reloading is enabled
22
36
  #
23
37
  # @since 0.9.0
@@ -31,9 +45,20 @@ module Hanami
31
45
  end
32
46
 
33
47
  resolve do
34
- defined?(Shotgun) &&
35
- Components['environment'].code_reloading? &&
36
- true
48
+ !!(defined?(Shotgun) && # rubocop:disable Style/DoubleNegation
49
+ Components['environment'].code_reloading?)
50
+ end
51
+ end
52
+
53
+ register 'code' do
54
+ run do
55
+ directory = Hanami.root.join('lib')
56
+
57
+ if Hanami.code_reloading?
58
+ Utils.reload!(directory)
59
+ else
60
+ Utils.require!(directory)
61
+ end
37
62
  end
38
63
  end
39
64
 
@@ -50,11 +75,12 @@ module Hanami
50
75
  # Hanami::Components.resolve('model')
51
76
  # Hanami::Components['model'] # => nil
52
77
  register 'model' do
53
- requires 'model.configuration', 'model.sql'
78
+ requires 'logger', 'model.configuration', 'model.sql'
54
79
 
55
80
  resolve do
56
81
  if Components['model.configuration']
57
82
  Hanami::Model.load!
83
+ Hanami::Model.configuration.logger = Components['logger']
58
84
  true
59
85
  end
60
86
  end
@@ -77,6 +103,7 @@ module Hanami
77
103
 
78
104
  resolve do |configuration|
79
105
  if Components['model.bundled']
106
+ Hanami::Model.instance_variable_set(:@configuration, nil) if Hanami.code_reloading?
80
107
  Hanami::Model.configure(&configuration.model)
81
108
  Hanami::Model.configuration
82
109
  end
@@ -135,6 +162,46 @@ module Hanami
135
162
  end
136
163
  end
137
164
 
165
+ # Tries to evaluate hanami-mailer configuration
166
+ #
167
+ # @since 1.0.0.beta1
168
+ # @api private
169
+ #
170
+ # @example With hanami-mailer
171
+ # Hanami::Components.resolve('mailer.configuration')
172
+ # Hanami::Components['mailer.configuration'].class # => Hanami::Mailer::Configuration
173
+ register 'mailer.configuration' do
174
+ prepare do
175
+ require 'hanami/mailer'
176
+ require 'hanami/mailer/glue'
177
+ end
178
+
179
+ resolve do |configuration|
180
+ Hanami::Mailer.configuration = Hanami::Mailer::Configuration.new if Hanami.code_reloading?
181
+ Hanami::Mailer.configure(&configuration.mailer)
182
+ Hanami::Mailer.configuration
183
+ end
184
+ end
185
+
186
+ # Tries to load hanami-mailer
187
+ #
188
+ # @since 1.0.0.beta1
189
+ # @api private
190
+ #
191
+ # @example
192
+ # Hanami::Components.resolve('mailer')
193
+ # Hanami::Components['mailer'] # => true
194
+ register 'mailer' do
195
+ requires 'mailer.configuration'
196
+
197
+ resolve do
198
+ if Components['mailer.configuration']
199
+ Hanami::Mailer.load!
200
+ true
201
+ end
202
+ end
203
+ end
204
+
138
205
  # Loads the routes for all the mounted Hanami/Rack applications
139
206
  #
140
207
  # This is used only by `hanami routes` command.
@@ -259,7 +326,7 @@ module Hanami
259
326
  # @api private
260
327
  register 'app.frameworks' do
261
328
  run do |app|
262
- ['app.controller', 'app.view', 'app.assets', 'app.logger'].each do |c|
329
+ ['app.controller', 'app.view', 'app.assets'].each do |c|
263
330
  component(c).call(app)
264
331
  end
265
332
  end
@@ -307,20 +374,6 @@ module Hanami
307
374
  end
308
375
  end
309
376
 
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
377
  # Load the code for a single Hanami application in the project
325
378
  #
326
379
  # @since 0.9.0
@@ -46,6 +46,18 @@ module Hanami
46
46
  end
47
47
  end
48
48
 
49
+ def logger(options = nil)
50
+ if options.nil?
51
+ settings.fetch(:logger, nil)
52
+ else
53
+ settings[:logger] = options
54
+ end
55
+ end
56
+
57
+ def environment(name)
58
+ yield if ENV['HANAMI_ENV'] == name.to_s
59
+ end
60
+
49
61
  private
50
62
 
51
63
  attr_reader :settings
@@ -59,6 +59,8 @@ module Hanami
59
59
  parsed = Dotenv::Parser.call(contents)
60
60
 
61
61
  parsed.each do |k, v|
62
+ next if @env.has_key?(k)
63
+
62
64
  @env[k] = v
63
65
  end
64
66
  nil
@@ -193,6 +193,10 @@ module Hanami
193
193
  # # is "development". The settings defined in this last file override
194
194
  # # the one defined in the parent (eg `FOO` is overwritten). All the
195
195
  # # other settings (eg `XYZ`) will be left untouched.
196
+ # # Variables declared on `.env` and `.env.development` will not override
197
+ # # any variable declared on the shell when calling a `hanami` command.
198
+ # # Eg. In `FOO="not ok" bundle exec hanami c` `FOO` will not be overwritten
199
+ # # to `"ok"`.
196
200
  def initialize(options = {})
197
201
  opts = options.to_h.dup
198
202
  @env = Hanami::Env.new(env: opts.delete(:env) || ENV)
@@ -331,7 +335,7 @@ module Hanami
331
335
 
332
336
  # Check if the current port is the default one
333
337
  #
334
- # @since x.x.x
338
+ # @since 1.0.0.beta1
335
339
  # @api private
336
340
  #
337
341
  # @see Hanami::ApplicationConfiguration#port
@@ -271,18 +271,6 @@ module <%= config[:classified_app_name] %>
271
271
  configure :development do
272
272
  # Don't handle exceptions, render the stack trace
273
273
  handle_exceptions false
274
-
275
- # Logger
276
- # See: http://hanamirb.org/guides/projects/logging
277
- #
278
- # Logger stream. It defaults to STDOUT.
279
- # logger.stream "log/development.log"
280
- #
281
- # Logger level. It defaults to DEBUG
282
- # logger.level :debug
283
- #
284
- # Logger format. It defaults to DEFAULT
285
- # logger.format :default
286
274
  end
287
275
 
288
276
  ##
@@ -291,12 +279,6 @@ module <%= config[:classified_app_name] %>
291
279
  configure :test do
292
280
  # Don't handle exceptions, render the stack trace
293
281
  handle_exceptions false
294
-
295
- # Logger
296
- # See: http://hanamirb.org/guides/projects/logging
297
- #
298
- # Logger level. It defaults to ERROR
299
- logger.level :error
300
282
  end
301
283
 
302
284
  ##
@@ -307,18 +289,6 @@ module <%= config[:classified_app_name] %>
307
289
  # host 'example.org'
308
290
  # port 443
309
291
 
310
- # Logger
311
- # See: http://hanamirb.org/guides/projects/logging
312
- #
313
- # Logger stream. It defaults to STDOUT.
314
- # logger.stream "log/production.log"
315
- #
316
- # Logger level. It defaults to INFO
317
- logger.level :info
318
-
319
- # Logger format.
320
- logger.format :json
321
-
322
292
  assets do
323
293
  # Don't compile static assets in production mode (eg. Sass, ES6)
324
294
  #
@@ -1,6 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'bundler'
4
3
  gem 'rake'
5
4
  <%- if config[:hanami_head] -%>
6
5
 
@@ -0,0 +1,2 @@
1
+ require_relative './environment'
2
+ Hanami.boot
@@ -13,7 +13,7 @@ Hanami.configure do
13
13
  #
14
14
  # * SQL adapter
15
15
  # adapter :sql, 'sqlite://db/<%= config[:project_name] %>_development.sqlite3'
16
- # adapter :sql, 'postgres://localhost/<%= config[:project_name] %>_development'
16
+ # adapter :sql, 'postgresql://localhost/<%= config[:project_name] %>_development'
17
17
  # adapter :sql, 'mysql://localhost/<%= config[:project_name] %>_development'
18
18
  #
19
19
  adapter :<%= config[:database_config][:type] %>, ENV['DATABASE_URL']
@@ -31,10 +31,19 @@ Hanami.configure do
31
31
  root 'lib/<%= config[:project_name] %>/mailers'
32
32
 
33
33
  # See http://hanamirb.org/guides/mailers/delivery
34
- delivery do
35
- development :test
36
- test :test
37
- # production :smtp, address: ENV['SMTP_PORT'], port: 1025
34
+ delivery :test
35
+ end
36
+
37
+ environment :development do
38
+ # See: http://hanamirb.org/guides/projects/logging
39
+ logger level: :debug
40
+ end
41
+
42
+ environment :production do
43
+ logger level: :info, formatter: :json
44
+
45
+ mailer do
46
+ delivery :smtp, address: ENV['SMTP_HOST'], port: ENV['SMTP_PORT']
38
47
  end
39
48
  end
40
49
  end
@@ -77,7 +77,7 @@ module Hanami
77
77
  "mysql2://localhost/#{ name }"
78
78
  end
79
79
  when 'postgresql', 'postgres'
80
- "postgres://localhost/#{ name }"
80
+ "postgresql://localhost/#{ name }"
81
81
  when 'sqlite', 'sqlite3'
82
82
  "sqlite://db/#{ Shellwords.escape(name) }"
83
83
  end
@@ -0,0 +1,5 @@
1
+ RSpec.describe Mailers::<%= config[:mailer] %> do
2
+ it 'delivers email' do
3
+ mail = Mailers::<%= config[:mailer] %>.deliver
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ Hanami::Model.migration do
2
+ change do
3
+ create_table :<%= config[:table_name] %> do
4
+ primary_key :id
5
+
6
+ column :created_at, DateTime, null: false
7
+ column :updated_at, DateTime, null: false
8
+ end
9
+ end
10
+ end
@@ -1,55 +1,13 @@
1
- require 'hanami/utils/basic_object'
2
-
3
1
  module Hanami::Mailer
4
- # @since 0.5.0
5
- # @api private
6
- class Delivery < ::Hanami::Utils::BasicObject
7
- # @since 0.5.0
8
- # @api private
9
- def initialize(env, &blk)
10
- @env = env
11
- instance_eval(&blk)
12
- end
13
-
14
- # @since 0.5.0
15
- # @api private
16
- def to_config
17
- @config
18
- end
19
-
20
- # @since 0.5.0
21
- # @api private
22
- def test(*args)
23
- __setup_config(:test, *args)
24
- end
25
-
26
- private
27
-
28
- # @since 0.5.0
29
- # @api private
30
- def method_missing(m, *args)
31
- __setup_config(m, *args)
32
- end
33
-
34
- # @since 0.5.0
35
- # @api private
36
- def __setup_config(env, *args)
37
- if env.to_s == @env
38
- @config = args
39
- end
40
- end
41
- end
42
-
43
-
44
2
  # @since 0.5.0
45
3
  # @api private
46
4
  module Glue
47
-
48
5
  # @since 0.5.0
49
6
  # @api private
50
- def delivery(&blk)
51
- raise ArgumentError unless block_given?
52
- delivery_method(*Hanami::Mailer::Delivery.new(Hanami.env, &blk).to_config)
7
+ def self.included(configuration)
8
+ configuration.class_eval do
9
+ alias_method :delivery, :delivery_method
10
+ end
53
11
  end
54
12
  end
55
13
 
@@ -30,8 +30,7 @@ module Hanami
30
30
  # @since 0.8.0
31
31
  def middleware
32
32
  mw = Hash.new { |e, m| e[m] = [] }
33
- mw["deployment"].concat([::Rack::ContentLength, ::Rack::CommonLogger])
34
- mw["development"].concat(mw["deployment"] + [::Rack::ShowExceptions, ::Rack::Lint])
33
+ mw["development"].concat([::Rack::ShowExceptions, ::Rack::Lint])
35
34
  require 'hanami/assets/static'
36
35
  mw["development"].push(::Hanami::Assets::Static)
37
36
  mw
@@ -45,15 +44,8 @@ module Hanami
45
44
  private
46
45
 
47
46
  def setup
48
- if code_reloading?
49
- @app = Shotgun::Loader.new(rackup, &reloadable)
50
- else
51
- reloadable.call
52
- end
53
- end
54
-
55
- def reloadable
56
- ->(*) { Hanami::Components.resolve('model', 'finalizers') }
47
+ return unless code_reloading?
48
+ @app = Shotgun::Loader.new(rackup)
57
49
  end
58
50
 
59
51
  def environment
@@ -63,7 +55,7 @@ module Hanami
63
55
  # @since 0.8.0
64
56
  # @api private
65
57
  def code_reloading?
66
- Components['code_reloading']
58
+ Hanami.code_reloading?
67
59
  end
68
60
 
69
61
  def rackup
@@ -32,10 +32,6 @@ module Hanami
32
32
  # @api private
33
33
  HEADER_RULES = [[:all, { 'Cache-Control' => "public, max-age=#{MAX_AGE}" }]].freeze
34
34
 
35
- # @since 0.8.0
36
- # @api private
37
- EXCLUDED_ENTRIES = %w(. ..).freeze
38
-
39
35
  # @since 0.8.0
40
36
  # @api private
41
37
  URL_PREFIX = '/'.freeze
@@ -53,10 +49,10 @@ module Hanami
53
49
  def _urls(root)
54
50
  return [] unless root.exist?
55
51
 
56
- Dir.entries(root).sort.map do |entry|
57
- next if EXCLUDED_ENTRIES.include?(entry)
58
- "#{URL_PREFIX}#{entry}"
59
- end.compact
52
+ asset_files = Dir.chdir(root) do
53
+ Dir['**/*'].select { |path| File.file? path }
54
+ end
55
+ Hash[asset_files.map { |entry| ["#{URL_PREFIX}#{entry}", entry] }]
60
56
  end
61
57
  end
62
58
  end