hanami 0.9.2 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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