hanami 1.3.0.beta1 → 1.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +44 -5
- data/FEATURES.md +17 -2
- data/LICENSE.md +1 -1
- data/README.md +5 -5
- data/bin/hanami +2 -2
- data/hanami.gemspec +14 -14
- data/lib/hanami.rb +1 -1
- data/lib/hanami/app.rb +1 -1
- data/lib/hanami/application.rb +2 -2
- data/lib/hanami/application_configuration.rb +3 -3
- data/lib/hanami/cli/commands.rb +2 -2
- data/lib/hanami/cli/commands/command.rb +4 -6
- data/lib/hanami/cli/commands/generate/action/action_spec.minitest.erb +1 -1
- data/lib/hanami/cli/commands/generate/action/view_spec.minitest.erb +1 -1
- data/lib/hanami/cli/commands/generate/app/application.erb +5 -18
- data/lib/hanami/cli/commands/generate/app/layout_spec.minitest.erb +2 -3
- data/lib/hanami/cli/commands/generate/app/layout_spec.rspec.erb +1 -2
- data/lib/hanami/cli/commands/generate/app/routes.erb +1 -1
- data/lib/hanami/cli/commands/new.rb +4 -4
- data/lib/hanami/cli/commands/new/Gemfile.erb +1 -2
- data/lib/hanami/cli/commands/new/README.md.erb +1 -1
- data/lib/hanami/cli/commands/new/config.ru.erb +1 -1
- data/lib/hanami/cli/commands/new/config/environment.erb +2 -2
- data/lib/hanami/cli/commands/new/gitignore.erb +2 -0
- data/lib/hanami/cli/commands/new/gitignore_with_sqlite.erb +2 -0
- data/lib/hanami/common_logger.rb +29 -3
- data/lib/hanami/components/app/assets.rb +1 -1
- data/lib/hanami/components/app/controller.rb +1 -1
- data/lib/hanami/components/app/routes.rb +8 -6
- data/lib/hanami/components/app/view.rb +1 -1
- data/lib/hanami/components/routes_inspector.rb +1 -1
- data/lib/hanami/configuration.rb +7 -4
- data/lib/hanami/configuration/app.rb +5 -2
- data/lib/hanami/early_hints.rb +1 -1
- data/lib/hanami/environment.rb +38 -10
- data/lib/hanami/{middleware.rb → middleware_stack.rb} +5 -5
- data/lib/hanami/rake_helper.rb +1 -1
- data/lib/hanami/rake_tasks.rb +1 -0
- data/lib/hanami/routes.rb +1 -1
- data/lib/hanami/setup.rb +1 -1
- data/lib/hanami/templates/welcome.html.erb +2 -2
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami/welcome.rb +6 -1
- metadata +45 -34
@@ -301,7 +301,7 @@ module Hanami
|
|
301
301
|
application_name: options.fetch(:application_name),
|
302
302
|
application_base_url: options.fetch(:application_base_url),
|
303
303
|
hanami_head: options.fetch(:hanami_head),
|
304
|
-
hanami_model_version: '~> 1.3
|
304
|
+
hanami_model_version: '~> 1.3',
|
305
305
|
code_reloading: code_reloading?,
|
306
306
|
hanami_version: hanami_version,
|
307
307
|
project_module: Utils::String.classify(project),
|
@@ -502,7 +502,7 @@ module Hanami
|
|
502
502
|
# @since 1.1.0
|
503
503
|
# @api private
|
504
504
|
def generate_app(context)
|
505
|
-
Hanami::CLI::Commands::New::App.new(
|
505
|
+
Hanami::CLI::Commands::New::App.new(out: @out, files: @files).call(app: context.application_name, application_base_url: context.application_base_url, **context.options)
|
506
506
|
end
|
507
507
|
|
508
508
|
# @since 1.1.0
|
@@ -565,8 +565,8 @@ module Hanami
|
|
565
565
|
|
566
566
|
# @since 1.1.0
|
567
567
|
# @api private
|
568
|
-
def initialize(*)
|
569
|
-
super
|
568
|
+
def initialize(*args, **kwargs)
|
569
|
+
super(*args, **kwargs)
|
570
570
|
@templates = Templates.new(self.class.superclass)
|
571
571
|
end
|
572
572
|
end
|
@@ -10,7 +10,6 @@ gem 'hanami-controller', require: false, git: 'https://github.com/hanami/contro
|
|
10
10
|
gem 'hanami-view', require: false, git: 'https://github.com/hanami/view.git', branch: 'develop'
|
11
11
|
gem 'hanami-helpers', require: false, git: 'https://github.com/hanami/helpers.git', branch: 'develop'
|
12
12
|
gem 'hanami-mailer', require: false, git: 'https://github.com/hanami/mailer.git', branch: 'develop'
|
13
|
-
gem 'hanami-cli', require: false, git: 'https://github.com/hanami/cli.git', branch: 'develop'
|
14
13
|
gem 'hanami-assets', require: false, git: 'https://github.com/hanami/assets.git', branch: 'develop'
|
15
14
|
gem 'hanami-model', require: false, git: 'https://github.com/hanami/model.git', branch: 'develop'
|
16
15
|
gem 'hanami', git: 'https://github.com/hanami/hanami.git', branch: 'develop'
|
@@ -34,7 +33,7 @@ gem 'haml'
|
|
34
33
|
<%- if code_reloading -%>
|
35
34
|
group :development do
|
36
35
|
# Code reloading
|
37
|
-
# See:
|
36
|
+
# See: https://guides.hanamirb.org/projects/code-reloading
|
38
37
|
gem 'shotgun', platforms: :ruby
|
39
38
|
gem 'hanami-webconsole'
|
40
39
|
end
|
@@ -30,4 +30,4 @@ How to prepare (create and migrate) DB for `development` and `test` environments
|
|
30
30
|
% HANAMI_ENV=test bundle exec hanami db prepare
|
31
31
|
```
|
32
32
|
|
33
|
-
Explore Hanami [guides](
|
33
|
+
Explore Hanami [guides](https://guides.hanamirb.org/), [API docs](http://docs.hanamirb.org/<%= Hanami::VERSION %>/), or jump in [chat](http://chat.hanamirb.org) for help. Enjoy! 🌸
|
@@ -30,12 +30,12 @@ Hanami.configure do
|
|
30
30
|
mailer do
|
31
31
|
root 'lib/<%= project %>/mailers'
|
32
32
|
|
33
|
-
# See
|
33
|
+
# See https://guides.hanamirb.org/mailers/delivery
|
34
34
|
delivery :test
|
35
35
|
end
|
36
36
|
|
37
37
|
environment :development do
|
38
|
-
# See:
|
38
|
+
# See: https://guides.hanamirb.org/projects/logging
|
39
39
|
logger level: :debug
|
40
40
|
end
|
41
41
|
|
data/lib/hanami/common_logger.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rack/common_logger'
|
2
|
+
require 'hanami/utils/hash'
|
2
3
|
|
3
4
|
module Hanami
|
4
5
|
# Rack logger for Hanami.app
|
@@ -44,13 +45,17 @@ module Hanami
|
|
44
45
|
# @api private
|
45
46
|
FORM_HASH = 'rack.request.form_hash'.freeze
|
46
47
|
|
48
|
+
# @since 1.3.0
|
49
|
+
# @api private
|
50
|
+
ROUTER_PARAMS = 'router.params'.freeze
|
51
|
+
|
47
52
|
# @since 1.0.0
|
48
53
|
# @api private
|
49
54
|
#
|
50
55
|
# rubocop:disable Metrics/AbcSize
|
51
56
|
# rubocop:disable Metrics/MethodLength
|
52
57
|
def log(env, status, header, began_at)
|
53
|
-
now =
|
58
|
+
now = ElapsedTime.call
|
54
59
|
length = extract_content_length(header)
|
55
60
|
|
56
61
|
msg = Hash[
|
@@ -58,7 +63,7 @@ module Hanami
|
|
58
63
|
verb: env[REQUEST_METHOD],
|
59
64
|
status: status.to_s[0..3],
|
60
65
|
ip: env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR],
|
61
|
-
path: env[SCRIPT_NAME] + env[PATH_INFO],
|
66
|
+
path: env[SCRIPT_NAME] + env[PATH_INFO].to_s,
|
62
67
|
length: length,
|
63
68
|
params: extract_params(env),
|
64
69
|
elapsed: now - began_at
|
@@ -73,11 +78,32 @@ module Hanami
|
|
73
78
|
logger.info(msg)
|
74
79
|
end
|
75
80
|
end
|
81
|
+
# rubocop:enable Metrics/MethodLength
|
82
|
+
# rubocop:enable Metrics/AbcSize
|
76
83
|
|
77
84
|
# @since 1.1.0
|
78
85
|
# @api private
|
79
86
|
def extract_params(env)
|
80
|
-
|
87
|
+
result = env.fetch(QUERY_HASH, {})
|
88
|
+
result.merge!(env.fetch(FORM_HASH, {}))
|
89
|
+
result.merge!(Utils::Hash.deep_stringify(env.fetch(ROUTER_PARAMS, {})))
|
90
|
+
result
|
91
|
+
end
|
92
|
+
|
93
|
+
# Wrapper which uses Rack's monotonic clock_time (used for began_at since Rack 2.1.0)
|
94
|
+
#
|
95
|
+
# @since 1.3.4
|
96
|
+
# @api private
|
97
|
+
class ElapsedTime
|
98
|
+
@clock = if Gem::Version.new(Rack::RELEASE) >= Gem::Version.new('2.1.0')
|
99
|
+
-> { Rack::Utils.clock_time }
|
100
|
+
else
|
101
|
+
-> { Time.now }
|
102
|
+
end.freeze
|
103
|
+
|
104
|
+
def self.call
|
105
|
+
@clock.call
|
106
|
+
end
|
81
107
|
end
|
82
108
|
end
|
83
109
|
end
|
@@ -8,7 +8,7 @@ module Hanami
|
|
8
8
|
# @since 0.9.0
|
9
9
|
# @api private
|
10
10
|
module App
|
11
|
-
# hanami-controller configuration for a
|
11
|
+
# hanami-controller configuration for a single Hanami application in the project.
|
12
12
|
#
|
13
13
|
# @since 0.9.0
|
14
14
|
# @api private
|
@@ -8,7 +8,7 @@ module Hanami
|
|
8
8
|
# @since 0.9.0
|
9
9
|
# @api private
|
10
10
|
module App
|
11
|
-
# hanami-router configuration for a
|
11
|
+
# hanami-router configuration for a single Hanami application in the project.
|
12
12
|
#
|
13
13
|
# @since 0.9.0
|
14
14
|
# @api private
|
@@ -39,17 +39,19 @@ module Hanami
|
|
39
39
|
resolver = Hanami::Routing::EndpointResolver.new(pattern: config.controller_pattern, namespace: namespace)
|
40
40
|
default_app = Hanami::Routing::Default.new
|
41
41
|
|
42
|
-
|
42
|
+
options = {
|
43
43
|
resolver: resolver,
|
44
44
|
default_app: default_app,
|
45
|
-
parsers: config.body_parsers,
|
46
45
|
scheme: config.scheme,
|
47
46
|
host: config.host,
|
48
47
|
port: config.port,
|
49
48
|
prefix: config.path_prefix,
|
50
|
-
force_ssl: config.force_ssl
|
51
|
-
|
52
|
-
|
49
|
+
force_ssl: config.force_ssl
|
50
|
+
}
|
51
|
+
|
52
|
+
options[:parsers] = config.body_parsers if config.body_parsers.any?
|
53
|
+
|
54
|
+
Hanami::Router.new(options, &config.routes)
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
data/lib/hanami/configuration.rb
CHANGED
@@ -20,6 +20,7 @@ module Hanami
|
|
20
20
|
# @param app [#call] an application compatible with Rack SPEC
|
21
21
|
# @param options [Hash] a set of options
|
22
22
|
# @option :at [String] options the mount point
|
23
|
+
# @option :host [String] options the mount point
|
23
24
|
#
|
24
25
|
# @since 0.9.0
|
25
26
|
#
|
@@ -27,12 +28,14 @@ module Hanami
|
|
27
28
|
# # config/environment.rb
|
28
29
|
# # ...
|
29
30
|
# Hanami.configure do
|
31
|
+
# mount Beta::Application, at: '/', host: 'beta.bookshelf.com'
|
32
|
+
# mount Admin::Application, at: '/api'
|
30
33
|
# mount Web::Application, at: '/'
|
31
34
|
#
|
32
35
|
# # ...
|
33
36
|
# end
|
34
37
|
def mount(app, options)
|
35
|
-
mounted[app] = App.new(app, options
|
38
|
+
mounted[app] = App.new(app, options)
|
36
39
|
end
|
37
40
|
|
38
41
|
# Configure database
|
@@ -75,7 +78,7 @@ module Hanami
|
|
75
78
|
# mailer do
|
76
79
|
# root 'lib/bookshelf/mailers'
|
77
80
|
#
|
78
|
-
# # See
|
81
|
+
# # See https://guides.hanamirb.org/mailers/delivery
|
79
82
|
# delivery :test
|
80
83
|
# end
|
81
84
|
#
|
@@ -138,7 +141,7 @@ module Hanami
|
|
138
141
|
# @api private
|
139
142
|
def apps
|
140
143
|
mounted.each_pair do |klass, app|
|
141
|
-
yield(app) if klass
|
144
|
+
yield(app) if klass <= Hanami::Application
|
142
145
|
end
|
143
146
|
end
|
144
147
|
|
@@ -151,7 +154,7 @@ module Hanami
|
|
151
154
|
# @see Hanami.logger
|
152
155
|
# @see Hanami::Logger
|
153
156
|
#
|
154
|
-
# @see
|
157
|
+
# @see https://guides.hanamirb.org/projects/logging
|
155
158
|
#
|
156
159
|
# @example Basic Usage
|
157
160
|
# # config/environment.rb
|
@@ -7,11 +7,14 @@ module Hanami
|
|
7
7
|
class App < SimpleDelegator
|
8
8
|
# @api private
|
9
9
|
attr_reader :path_prefix
|
10
|
+
# @api private
|
11
|
+
attr_reader :host
|
10
12
|
|
11
13
|
# @api private
|
12
|
-
def initialize(app,
|
14
|
+
def initialize(app, options = {})
|
13
15
|
super(app)
|
14
|
-
@path_prefix =
|
16
|
+
@path_prefix = options[:at]
|
17
|
+
@host = options[:host]
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
data/lib/hanami/early_hints.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Hanami
|
4
4
|
# HTTP/2 Early Hints Rack middleware
|
5
5
|
#
|
6
|
-
# It sends extra responses **before** the main
|
6
|
+
# It sends extra responses **before** the main response is sent.
|
7
7
|
# These extra responses are HTTP/2 Early Hints (103).
|
8
8
|
# They specify the web assets (javascripts, stylesheets, etc..) to be "pushed",
|
9
9
|
# so modern browsers pre-fetch them in parallel with the main HTTP response.
|
data/lib/hanami/environment.rb
CHANGED
@@ -36,6 +36,12 @@ module Hanami
|
|
36
36
|
# @api private
|
37
37
|
DEFAULT_ENV = 'development'.freeze
|
38
38
|
|
39
|
+
# Test environment
|
40
|
+
#
|
41
|
+
# @since 1.3.3
|
42
|
+
# @api private
|
43
|
+
TEST_ENV = 'test'.freeze
|
44
|
+
|
39
45
|
# Production environment
|
40
46
|
#
|
41
47
|
# @since 0.6.0
|
@@ -48,11 +54,21 @@ module Hanami
|
|
48
54
|
# @api private
|
49
55
|
RACK_ENV_DEPLOYMENT = 'deployment'.freeze
|
50
56
|
|
51
|
-
#
|
57
|
+
# @since 1.3.3
|
58
|
+
# @api private
|
59
|
+
DOTENV_LOCAL_FILE = '.env.local'.freeze
|
60
|
+
|
61
|
+
# Default `.env` files that are loaded. The entries are ordered from highest
|
62
|
+
# to lowest priority.
|
52
63
|
#
|
53
|
-
# @since
|
64
|
+
# @since 1.3.3
|
54
65
|
# @api private
|
55
|
-
|
66
|
+
DOTENV_FILES = [
|
67
|
+
'.env.%{environment}.local'.freeze,
|
68
|
+
DOTENV_LOCAL_FILE,
|
69
|
+
'.env.%{environment}'.freeze,
|
70
|
+
'.env'.freeze
|
71
|
+
].freeze
|
56
72
|
|
57
73
|
# Default configuration directory under application root
|
58
74
|
#
|
@@ -132,9 +148,8 @@ module Hanami
|
|
132
148
|
# located under the config directory. All the settings in those files will
|
133
149
|
# be exported as `ENV` variables.
|
134
150
|
#
|
135
|
-
#
|
136
|
-
#
|
137
|
-
# control.
|
151
|
+
# This table: https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
|
152
|
+
# has more info on the priority of the .env files.
|
138
153
|
#
|
139
154
|
# The format of those `.env.<environment>` files follows UNIX and UNIX-like
|
140
155
|
# operating system environment variable declaration format and compatible
|
@@ -391,7 +406,7 @@ module Hanami
|
|
391
406
|
# @since 0.4.0
|
392
407
|
# @api private
|
393
408
|
def require_application_environment
|
394
|
-
Bundler.setup(*bundler_groups)
|
409
|
+
::Bundler.setup(*bundler_groups)
|
395
410
|
require project_environment_configuration.to_s # if project_environment_configuration.exist?
|
396
411
|
end
|
397
412
|
|
@@ -487,10 +502,13 @@ module Hanami
|
|
487
502
|
# @since 0.2.0
|
488
503
|
# @api private
|
489
504
|
def set_application_env_vars!
|
490
|
-
|
491
|
-
|
505
|
+
DOTENV_FILES.each do |filename_format|
|
506
|
+
file = filename_format % { environment: environment }
|
507
|
+
next unless dotenv_applicable?(file)
|
492
508
|
|
493
|
-
|
509
|
+
path = root.join(file)
|
510
|
+
env.load!(path) if path.exist?
|
511
|
+
end
|
494
512
|
end
|
495
513
|
|
496
514
|
# @since 0.1.0
|
@@ -509,5 +527,15 @@ module Hanami
|
|
509
527
|
env[RACK_ENV]
|
510
528
|
end
|
511
529
|
end
|
530
|
+
|
531
|
+
# @api private
|
532
|
+
# @since 1.3.3
|
533
|
+
#
|
534
|
+
# @see https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
|
535
|
+
def dotenv_applicable?(file)
|
536
|
+
return false if file == DOTENV_LOCAL_FILE && environment == TEST_ENV
|
537
|
+
|
538
|
+
true
|
539
|
+
end
|
512
540
|
end
|
513
541
|
end
|
@@ -6,12 +6,12 @@ module Hanami
|
|
6
6
|
#
|
7
7
|
# @since 0.1.0
|
8
8
|
# @api private
|
9
|
-
class
|
9
|
+
class MiddlewareStack
|
10
10
|
# Instantiate a middleware stack
|
11
11
|
#
|
12
12
|
# @param configuration [Hanami::ApplicationConfiguration] the application's configuration
|
13
13
|
#
|
14
|
-
# @return [Hanami::
|
14
|
+
# @return [Hanami::MiddlewareStack] the new stack
|
15
15
|
#
|
16
16
|
# @since 0.1.0
|
17
17
|
# @api private
|
@@ -25,7 +25,7 @@ module Hanami
|
|
25
25
|
|
26
26
|
# Load the middleware stack
|
27
27
|
#
|
28
|
-
# @return [Hanami::
|
28
|
+
# @return [Hanami::MiddlewareStack] the loaded middleware stack
|
29
29
|
#
|
30
30
|
# @since 0.2.0
|
31
31
|
# @api private
|
@@ -62,7 +62,7 @@ module Hanami
|
|
62
62
|
#
|
63
63
|
# @since 0.2.0
|
64
64
|
#
|
65
|
-
# @see Hanami::
|
65
|
+
# @see Hanami::MiddlewareStack#prepend
|
66
66
|
#
|
67
67
|
# @example
|
68
68
|
# # apps/web/application.rb
|
@@ -89,7 +89,7 @@ module Hanami
|
|
89
89
|
#
|
90
90
|
# @since 0.6.0
|
91
91
|
#
|
92
|
-
# @see Hanami::
|
92
|
+
# @see Hanami::MiddlewareStack#use
|
93
93
|
#
|
94
94
|
# @example
|
95
95
|
# # apps/web/application.rb
|