hanami 1.3.1 → 2.0.0.alpha2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +110 -6
- data/FEATURES.md +9 -1
- data/LICENSE.md +1 -1
- data/README.md +4 -5
- data/hanami.gemspec +26 -30
- data/lib/hanami.rb +40 -243
- data/lib/hanami/application.rb +338 -174
- data/lib/hanami/application/autoloader/inflector_adapter.rb +22 -0
- data/lib/hanami/application/container/boot/inflector.rb +7 -0
- data/lib/hanami/application/container/boot/logger.rb +8 -0
- data/lib/hanami/application/container/boot/rack_logger.rb +19 -0
- data/lib/hanami/application/container/boot/rack_monitor.rb +12 -0
- data/lib/hanami/application/container/boot/settings.rb +7 -0
- data/lib/hanami/application/router.rb +59 -0
- data/lib/hanami/application/routing/middleware/stack.rb +89 -0
- data/lib/hanami/application/routing/resolver.rb +82 -0
- data/lib/hanami/application/routing/resolver/node.rb +50 -0
- data/lib/hanami/application/routing/resolver/trie.rb +59 -0
- data/lib/hanami/application/settings.rb +23 -0
- data/lib/hanami/application/settings/definition.rb +26 -0
- data/lib/hanami/application/settings/loader.rb +97 -0
- data/lib/hanami/application/settings/struct.rb +65 -0
- data/lib/hanami/boot.rb +5 -0
- data/lib/hanami/cli/application/cli.rb +40 -0
- data/lib/hanami/cli/application/command.rb +47 -0
- data/lib/hanami/cli/application/commands.rb +16 -0
- data/lib/hanami/cli/application/commands/console.rb +81 -0
- data/lib/hanami/cli/base_command.rb +48 -0
- data/lib/hanami/cli/commands.rb +6 -42
- data/lib/hanami/cli/commands/command.rb +20 -30
- data/lib/hanami/cli/commands/server.rb +63 -14
- data/lib/hanami/configuration.rb +248 -190
- data/lib/hanami/configuration/middleware.rb +8 -28
- data/lib/hanami/configuration/router.rb +50 -0
- data/lib/hanami/configuration/sessions.rb +50 -0
- data/lib/hanami/init.rb +5 -0
- data/lib/hanami/server.rb +5 -69
- data/lib/hanami/setup.rb +8 -2
- data/lib/hanami/slice.rb +138 -0
- data/lib/hanami/version.rb +3 -1
- data/lib/hanami/web/rack_logger.rb +96 -0
- metadata +84 -228
- data/bin/hanami +0 -6
- data/lib/hanami/action/csrf_protection.rb +0 -211
- data/lib/hanami/action/routing_helpers.rb +0 -40
- data/lib/hanami/app.rb +0 -96
- data/lib/hanami/application_configuration.rb +0 -1495
- data/lib/hanami/application_name.rb +0 -108
- data/lib/hanami/application_namespace.rb +0 -14
- data/lib/hanami/assets/asset.rb +0 -72
- data/lib/hanami/assets/static.rb +0 -102
- data/lib/hanami/cli/commands/assets.rb +0 -16
- data/lib/hanami/cli/commands/assets/precompile.rb +0 -42
- data/lib/hanami/cli/commands/console.rb +0 -95
- data/lib/hanami/cli/commands/db.rb +0 -32
- data/lib/hanami/cli/commands/db/apply.rb +0 -32
- data/lib/hanami/cli/commands/db/console.rb +0 -44
- data/lib/hanami/cli/commands/db/create.rb +0 -32
- data/lib/hanami/cli/commands/db/drop.rb +0 -32
- data/lib/hanami/cli/commands/db/migrate.rb +0 -39
- data/lib/hanami/cli/commands/db/prepare.rb +0 -32
- data/lib/hanami/cli/commands/db/rollback.rb +0 -59
- data/lib/hanami/cli/commands/db/version.rb +0 -32
- data/lib/hanami/cli/commands/destroy.rb +0 -26
- data/lib/hanami/cli/commands/destroy/action.rb +0 -137
- data/lib/hanami/cli/commands/destroy/app.rb +0 -159
- data/lib/hanami/cli/commands/destroy/mailer.rb +0 -74
- data/lib/hanami/cli/commands/destroy/migration.rb +0 -51
- data/lib/hanami/cli/commands/destroy/model.rb +0 -84
- data/lib/hanami/cli/commands/generate.rb +0 -28
- data/lib/hanami/cli/commands/generate/action.rb +0 -321
- data/lib/hanami/cli/commands/generate/action/action.erb +0 -7
- data/lib/hanami/cli/commands/generate/action/action_spec.minitest.erb +0 -11
- data/lib/hanami/cli/commands/generate/action/action_spec.rspec.erb +0 -9
- data/lib/hanami/cli/commands/generate/action/action_without_view.erb +0 -7
- data/lib/hanami/cli/commands/generate/action/view.erb +0 -7
- data/lib/hanami/cli/commands/generate/action/view_spec.minitest.erb +0 -12
- data/lib/hanami/cli/commands/generate/action/view_spec.rspec.erb +0 -10
- data/lib/hanami/cli/commands/generate/app.rb +0 -243
- data/lib/hanami/cli/commands/generate/app/application.erb +0 -313
- data/lib/hanami/cli/commands/generate/app/favicon.ico +0 -0
- data/lib/hanami/cli/commands/generate/app/gitkeep.erb +0 -0
- data/lib/hanami/cli/commands/generate/app/layout.erb +0 -7
- data/lib/hanami/cli/commands/generate/app/layout_spec.minitest.erb +0 -10
- data/lib/hanami/cli/commands/generate/app/layout_spec.rspec.erb +0 -10
- data/lib/hanami/cli/commands/generate/app/routes.erb +0 -5
- data/lib/hanami/cli/commands/generate/app/template.erb.erb +0 -10
- data/lib/hanami/cli/commands/generate/app/template.haml.erb +0 -7
- data/lib/hanami/cli/commands/generate/app/template.slim.erb +0 -8
- data/lib/hanami/cli/commands/generate/mailer.rb +0 -104
- data/lib/hanami/cli/commands/generate/mailer/mailer.erb +0 -9
- data/lib/hanami/cli/commands/generate/mailer/mailer_spec.minitest.erb +0 -7
- data/lib/hanami/cli/commands/generate/mailer/mailer_spec.rspec.erb +0 -5
- data/lib/hanami/cli/commands/generate/migration.rb +0 -41
- data/lib/hanami/cli/commands/generate/migration/migration.erb +0 -4
- data/lib/hanami/cli/commands/generate/model.rb +0 -125
- data/lib/hanami/cli/commands/generate/model/entity.erb +0 -2
- data/lib/hanami/cli/commands/generate/model/entity_spec.minitest.erb +0 -5
- data/lib/hanami/cli/commands/generate/model/entity_spec.rspec.erb +0 -3
- data/lib/hanami/cli/commands/generate/model/migration.erb +0 -10
- data/lib/hanami/cli/commands/generate/model/repository.erb +0 -5
- data/lib/hanami/cli/commands/generate/model/repository_spec.minitest.erb +0 -5
- data/lib/hanami/cli/commands/generate/model/repository_spec.rspec.erb +0 -3
- data/lib/hanami/cli/commands/generate/secret.rb +0 -48
- data/lib/hanami/cli/commands/new.rb +0 -578
- data/lib/hanami/cli/commands/new/.env.development.erb +0 -3
- data/lib/hanami/cli/commands/new/.env.test.erb +0 -3
- data/lib/hanami/cli/commands/new/.gitkeep.erb +0 -0
- data/lib/hanami/cli/commands/new/Gemfile.erb +0 -58
- data/lib/hanami/cli/commands/new/README.md.erb +0 -33
- data/lib/hanami/cli/commands/new/config.ru.erb +0 -3
- data/lib/hanami/cli/commands/new/config/boot.erb +0 -2
- data/lib/hanami/cli/commands/new/config/environment.erb +0 -49
- data/lib/hanami/cli/commands/new/gitignore.erb +0 -2
- data/lib/hanami/cli/commands/new/gitignore_with_sqlite.erb +0 -3
- data/lib/hanami/cli/commands/new/hanamirc.erb +0 -3
- data/lib/hanami/cli/commands/new/lib/project.erb +0 -2
- data/lib/hanami/cli/commands/new/minitest/Rakefile.erb +0 -12
- data/lib/hanami/cli/commands/new/minitest/features_helper.erb +0 -11
- data/lib/hanami/cli/commands/new/minitest/spec_helper.erb +0 -7
- data/lib/hanami/cli/commands/new/rspec/Rakefile.erb +0 -9
- data/lib/hanami/cli/commands/new/rspec/capybara.erb +0 -8
- data/lib/hanami/cli/commands/new/rspec/features_helper.erb +0 -12
- data/lib/hanami/cli/commands/new/rspec/rspec.erb +0 -2
- data/lib/hanami/cli/commands/new/rspec/spec_helper.erb +0 -103
- data/lib/hanami/cli/commands/new/schema.sql.erb +0 -0
- data/lib/hanami/cli/commands/project.rb +0 -421
- data/lib/hanami/cli/commands/routes.rb +0 -21
- data/lib/hanami/cli/commands/templates.rb +0 -31
- data/lib/hanami/cli/commands/version.rb +0 -19
- data/lib/hanami/common_logger.rb +0 -93
- data/lib/hanami/components.rb +0 -156
- data/lib/hanami/components/app/assets.rb +0 -59
- data/lib/hanami/components/app/controller.rb +0 -74
- data/lib/hanami/components/app/routes.rb +0 -59
- data/lib/hanami/components/app/view.rb +0 -44
- data/lib/hanami/components/component.rb +0 -182
- data/lib/hanami/components/components.rb +0 -479
- data/lib/hanami/components/routes_inspector.rb +0 -72
- data/lib/hanami/config/cookies.rb +0 -69
- data/lib/hanami/config/framework_configuration.rb +0 -43
- data/lib/hanami/config/load_paths.rb +0 -46
- data/lib/hanami/config/mapper.rb +0 -47
- data/lib/hanami/config/routes.rb +0 -20
- data/lib/hanami/config/security.rb +0 -110
- data/lib/hanami/config/sessions.rb +0 -103
- data/lib/hanami/configuration/app.rb +0 -18
- data/lib/hanami/early_hints.rb +0 -129
- data/lib/hanami/env.rb +0 -69
- data/lib/hanami/environment.rb +0 -513
- data/lib/hanami/environment_application_configurations.rb +0 -37
- data/lib/hanami/frameworks.rb +0 -22
- data/lib/hanami/hanamirc.rb +0 -169
- data/lib/hanami/mailer/glue.rb +0 -27
- data/lib/hanami/middleware_stack.rb +0 -172
- data/lib/hanami/rake_helper.rb +0 -78
- data/lib/hanami/rake_tasks.rb +0 -2
- data/lib/hanami/rendering_policy.rb +0 -95
- data/lib/hanami/routes.rb +0 -219
- data/lib/hanami/routing/default.rb +0 -32
- data/lib/hanami/static.rb +0 -63
- data/lib/hanami/templates/default.html.erb +0 -30
- data/lib/hanami/templates/welcome.html.erb +0 -52
- data/lib/hanami/views/default.rb +0 -37
- data/lib/hanami/views/default_template_finder.rb +0 -22
- data/lib/hanami/views/null_view.rb +0 -15
- data/lib/hanami/welcome.rb +0 -36
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
require "delegate"
|
|
2
|
-
|
|
3
|
-
module Hanami
|
|
4
|
-
# @api private
|
|
5
|
-
class Configuration
|
|
6
|
-
# @api private
|
|
7
|
-
class App < SimpleDelegator
|
|
8
|
-
# @api private
|
|
9
|
-
attr_reader :path_prefix
|
|
10
|
-
|
|
11
|
-
# @api private
|
|
12
|
-
def initialize(app, path_prefix)
|
|
13
|
-
super(app)
|
|
14
|
-
@path_prefix = path_prefix
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
data/lib/hanami/early_hints.rb
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Hanami
|
|
4
|
-
# HTTP/2 Early Hints Rack middleware
|
|
5
|
-
#
|
|
6
|
-
# It sends extra responses **before** the main reponse is sent.
|
|
7
|
-
# These extra responses are HTTP/2 Early Hints (103).
|
|
8
|
-
# They specify the web assets (javascripts, stylesheets, etc..) to be "pushed",
|
|
9
|
-
# so modern browsers pre-fetch them in parallel with the main HTTP response.
|
|
10
|
-
#
|
|
11
|
-
# @see https://tools.ietf.org/html/draft-ietf-httpbis-early-hints-05
|
|
12
|
-
#
|
|
13
|
-
# @since 1.2.0
|
|
14
|
-
# @api private
|
|
15
|
-
class EarlyHints
|
|
16
|
-
# @since 1.2.0
|
|
17
|
-
# @api private
|
|
18
|
-
class NotSupportedByServerError < ::StandardError
|
|
19
|
-
# @since 1.2.0
|
|
20
|
-
# @api private
|
|
21
|
-
def initialize
|
|
22
|
-
super("Current Ruby server doesn't support Early Hints.\nPlease make sure to use a web server with Early Hints enabled (only Puma for now).")
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# @since 1.2.0
|
|
27
|
-
# @api private
|
|
28
|
-
def initialize(app)
|
|
29
|
-
@app = app
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# @param env [Hash] Rack env
|
|
33
|
-
#
|
|
34
|
-
# @return [Array,Rack::Response] a Rack response
|
|
35
|
-
#
|
|
36
|
-
# @raise [Hanami::EarlyHints::NotSupportedByServerError] if the current Ruby
|
|
37
|
-
# server doesn't support Early Hints
|
|
38
|
-
#
|
|
39
|
-
# @since 1.2.0
|
|
40
|
-
# @api private
|
|
41
|
-
def call(env)
|
|
42
|
-
@app.call(env).tap do
|
|
43
|
-
send_early_hints(env)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
private
|
|
48
|
-
|
|
49
|
-
# Pushing a lot of assets may exceed the limit of HTTP headers of a single
|
|
50
|
-
# Early Hints (103) response.
|
|
51
|
-
#
|
|
52
|
-
# For this reason we send multiple Early Hints (103) responses for each `n`
|
|
53
|
-
# assets. We call this `n` number `BATCH_SIZE`.
|
|
54
|
-
#
|
|
55
|
-
# If the current page needs to push 23 assets, it will send 3 Early Hints
|
|
56
|
-
# (103) responses:
|
|
57
|
-
#
|
|
58
|
-
# 1. Response #1: 10 assets
|
|
59
|
-
# 2. Response #2: 10 assets
|
|
60
|
-
# 3. Response #3: 3 assets
|
|
61
|
-
#
|
|
62
|
-
# @since 1.2.0
|
|
63
|
-
# @api private
|
|
64
|
-
BATCH_SIZE = 10
|
|
65
|
-
|
|
66
|
-
# Rack servers that support Early Hints (only Puma for now),
|
|
67
|
-
# inject an object into the Rack env to send multiple Early Hints (103)
|
|
68
|
-
# responses.
|
|
69
|
-
#
|
|
70
|
-
# @since 1.2.0
|
|
71
|
-
# @api private
|
|
72
|
-
#
|
|
73
|
-
# @see https://github.com/puma/puma/pull/1403
|
|
74
|
-
RACK_EARLY_HINTS_ENV_KEY = "rack.early_hints"
|
|
75
|
-
|
|
76
|
-
# This cache key is used by `hanami-assets` to collect the assets that are
|
|
77
|
-
# eligible to be pushed.
|
|
78
|
-
#
|
|
79
|
-
# It stores these values in a thread-local variable.
|
|
80
|
-
#
|
|
81
|
-
# NOTE: if changing this key here, it MUST be changed into `hanami-assets` as well
|
|
82
|
-
#
|
|
83
|
-
# @since 1.2.0
|
|
84
|
-
# @api private
|
|
85
|
-
CACHE_KEY = :__hanami_assets
|
|
86
|
-
|
|
87
|
-
# Tries to send multiple Early Hints (103) HTTP responses, if there are
|
|
88
|
-
# assets eligible.
|
|
89
|
-
#
|
|
90
|
-
# @param env [Hash] Rack env
|
|
91
|
-
#
|
|
92
|
-
# @raise [Hanami::EarlyHints::NotSupportedByServerError] if the current Ruby
|
|
93
|
-
# server doesn't support Early Hints
|
|
94
|
-
#
|
|
95
|
-
# @since 1.2.0
|
|
96
|
-
# @api private
|
|
97
|
-
def send_early_hints(env)
|
|
98
|
-
return if Thread.current[CACHE_KEY].nil?
|
|
99
|
-
|
|
100
|
-
Thread.current[CACHE_KEY].each_slice(BATCH_SIZE) do |slice|
|
|
101
|
-
link = slice.map do |asset, options|
|
|
102
|
-
ret = %(<#{asset}>; rel=preload)
|
|
103
|
-
ret += "; as=#{options[:as]}" unless options[:as].nil?
|
|
104
|
-
ret += "; crossorigin" if options[:crossorigin]
|
|
105
|
-
ret
|
|
106
|
-
end.join("\n")
|
|
107
|
-
|
|
108
|
-
send_early_hints_response(env, link)
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
# Tries to send an Early Hints (103) HTTP response for a batch of assets
|
|
113
|
-
#
|
|
114
|
-
# @param env [Hash] Rack env
|
|
115
|
-
# @param link [String] the serialized HTTP `Link` headers
|
|
116
|
-
#
|
|
117
|
-
# @raise [Hanami::EarlyHints::NotSupportedByServerError] if the current Ruby
|
|
118
|
-
# server doesn't support Early Hints
|
|
119
|
-
#
|
|
120
|
-
# @since 1.2.0
|
|
121
|
-
# @api private
|
|
122
|
-
def send_early_hints_response(env, link)
|
|
123
|
-
env[RACK_EARLY_HINTS_ENV_KEY].call("Link" => link)
|
|
124
|
-
rescue NoMethodError => exception
|
|
125
|
-
raise exception if env.key?(RACK_EARLY_HINTS_ENV_KEY)
|
|
126
|
-
raise NotSupportedByServerError
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
end
|
data/lib/hanami/env.rb
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
begin
|
|
2
|
-
require 'dotenv/parser'
|
|
3
|
-
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
module Hanami
|
|
7
|
-
# Encapsulate access to ENV
|
|
8
|
-
#
|
|
9
|
-
# @since 0.9.0
|
|
10
|
-
# @api private
|
|
11
|
-
class Env
|
|
12
|
-
# Create a new instance
|
|
13
|
-
#
|
|
14
|
-
# @param env [#[],#[]=] a Hash like object. It defaults to ENV
|
|
15
|
-
#
|
|
16
|
-
# @return [Hanami::Env]
|
|
17
|
-
#
|
|
18
|
-
# @since 0.9.0
|
|
19
|
-
# @api private
|
|
20
|
-
def initialize(env: ENV)
|
|
21
|
-
@env = env
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# Return a value, if found
|
|
25
|
-
#
|
|
26
|
-
# @param key [String] the key
|
|
27
|
-
#
|
|
28
|
-
# @return [String,NilClass] the value, if found
|
|
29
|
-
#
|
|
30
|
-
# @since 0.9.0
|
|
31
|
-
# @api private
|
|
32
|
-
def [](key)
|
|
33
|
-
@env[key]
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Sets a value
|
|
37
|
-
#
|
|
38
|
-
# @param key [String] the key
|
|
39
|
-
# @param value [String] the value
|
|
40
|
-
#
|
|
41
|
-
# @since 0.9.0
|
|
42
|
-
# @api private
|
|
43
|
-
def []=(key, value)
|
|
44
|
-
@env[key] = value
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Loads a dotenv file and updates self
|
|
48
|
-
#
|
|
49
|
-
# @param path [String, Pathname] the path to the dotenv file
|
|
50
|
-
#
|
|
51
|
-
# @return void
|
|
52
|
-
#
|
|
53
|
-
# @since 0.9.0
|
|
54
|
-
# @api private
|
|
55
|
-
def load!(path)
|
|
56
|
-
return unless defined?(Dotenv::Parser)
|
|
57
|
-
|
|
58
|
-
contents = ::File.open(path, "rb:bom|utf-8", &:read)
|
|
59
|
-
parsed = Dotenv::Parser.call(contents)
|
|
60
|
-
|
|
61
|
-
parsed.each do |k, v|
|
|
62
|
-
next if @env.has_key?(k)
|
|
63
|
-
|
|
64
|
-
@env[k] = v
|
|
65
|
-
end
|
|
66
|
-
nil
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
data/lib/hanami/environment.rb
DELETED
|
@@ -1,513 +0,0 @@
|
|
|
1
|
-
require 'thread'
|
|
2
|
-
require 'pathname'
|
|
3
|
-
require 'hanami/utils'
|
|
4
|
-
require 'hanami/utils/hash'
|
|
5
|
-
require 'hanami/env'
|
|
6
|
-
require 'hanami/hanamirc'
|
|
7
|
-
require 'hanami/components'
|
|
8
|
-
|
|
9
|
-
module Hanami
|
|
10
|
-
# Define and expose information about the Hanami environment.
|
|
11
|
-
#
|
|
12
|
-
# @since 0.1.0
|
|
13
|
-
# @api private
|
|
14
|
-
class Environment
|
|
15
|
-
# Global lock (used to serialize process of environment configuration)
|
|
16
|
-
#
|
|
17
|
-
# @since 0.8.0
|
|
18
|
-
# @api private
|
|
19
|
-
LOCK = Mutex.new
|
|
20
|
-
|
|
21
|
-
# Standard Rack ENV key
|
|
22
|
-
#
|
|
23
|
-
# @since 0.1.0
|
|
24
|
-
# @api private
|
|
25
|
-
RACK_ENV = 'RACK_ENV'.freeze
|
|
26
|
-
|
|
27
|
-
# Standard Hanami ENV key
|
|
28
|
-
#
|
|
29
|
-
# @since 0.1.0
|
|
30
|
-
# @api private
|
|
31
|
-
HANAMI_ENV = 'HANAMI_ENV'.freeze
|
|
32
|
-
|
|
33
|
-
# Default Hanami environment
|
|
34
|
-
#
|
|
35
|
-
# @since 0.1.0
|
|
36
|
-
# @api private
|
|
37
|
-
DEFAULT_ENV = 'development'.freeze
|
|
38
|
-
|
|
39
|
-
# Production environment
|
|
40
|
-
#
|
|
41
|
-
# @since 0.6.0
|
|
42
|
-
# @api private
|
|
43
|
-
PRODUCTION_ENV = 'production'.freeze
|
|
44
|
-
|
|
45
|
-
# Rack production environment (aka deployment)
|
|
46
|
-
#
|
|
47
|
-
# @since 0.6.0
|
|
48
|
-
# @api private
|
|
49
|
-
RACK_ENV_DEPLOYMENT = 'deployment'.freeze
|
|
50
|
-
|
|
51
|
-
# Default `.env` per environment file name
|
|
52
|
-
#
|
|
53
|
-
# @since 0.2.0
|
|
54
|
-
# @api private
|
|
55
|
-
DEFAULT_DOTENV_ENV = '.env.%s'.freeze
|
|
56
|
-
|
|
57
|
-
# Default configuration directory under application root
|
|
58
|
-
#
|
|
59
|
-
# @since 0.2.0
|
|
60
|
-
# @api private
|
|
61
|
-
DEFAULT_CONFIG = 'config'.freeze
|
|
62
|
-
|
|
63
|
-
# Standard Hanami host ENV key
|
|
64
|
-
#
|
|
65
|
-
# @since 0.1.0
|
|
66
|
-
# @api private
|
|
67
|
-
HANAMI_HOST = 'HANAMI_HOST'.freeze
|
|
68
|
-
|
|
69
|
-
# Default HTTP host
|
|
70
|
-
#
|
|
71
|
-
# @since 0.1.0
|
|
72
|
-
# @api private
|
|
73
|
-
DEFAULT_HOST = 'localhost'.freeze
|
|
74
|
-
|
|
75
|
-
# Default IP address listen
|
|
76
|
-
#
|
|
77
|
-
# @since 0.1.0
|
|
78
|
-
# @api private
|
|
79
|
-
LISTEN_ALL_HOST = '0.0.0.0'.freeze
|
|
80
|
-
|
|
81
|
-
# Standard Hanami port ENV key
|
|
82
|
-
#
|
|
83
|
-
# @since 0.1.0
|
|
84
|
-
# @api private
|
|
85
|
-
HANAMI_PORT = 'HANAMI_PORT'.freeze
|
|
86
|
-
|
|
87
|
-
# Default Hanami HTTP port
|
|
88
|
-
#
|
|
89
|
-
# @since 0.1.0
|
|
90
|
-
# @api private
|
|
91
|
-
DEFAULT_PORT = 2300
|
|
92
|
-
|
|
93
|
-
# Default Rack configuration file
|
|
94
|
-
#
|
|
95
|
-
# @since 0.2.0
|
|
96
|
-
# @api private
|
|
97
|
-
DEFAULT_RACKUP = 'config.ru'.freeze
|
|
98
|
-
|
|
99
|
-
# Default environment configuration file
|
|
100
|
-
#
|
|
101
|
-
# @since 0.2.0
|
|
102
|
-
# @api private
|
|
103
|
-
DEFAULT_ENVIRONMENT_CONFIG = 'environment'.freeze
|
|
104
|
-
|
|
105
|
-
# Code reloading per environment
|
|
106
|
-
#
|
|
107
|
-
# @since 0.2.0
|
|
108
|
-
# @api private
|
|
109
|
-
CODE_RELOADING = { 'development' => true }.freeze
|
|
110
|
-
|
|
111
|
-
# @since 0.4.0
|
|
112
|
-
# @api private
|
|
113
|
-
APPS_PATH = 'apps'.freeze
|
|
114
|
-
|
|
115
|
-
# @since 0.4.0
|
|
116
|
-
# @api private
|
|
117
|
-
SERVE_STATIC_ASSETS = 'SERVE_STATIC_ASSETS'.freeze
|
|
118
|
-
|
|
119
|
-
# @since 0.4.0
|
|
120
|
-
# @api private
|
|
121
|
-
SERVE_STATIC_ASSETS_ENABLED = 'true'.freeze
|
|
122
|
-
|
|
123
|
-
# Initialize a Hanami environment
|
|
124
|
-
#
|
|
125
|
-
# It accepts an optional set of configurations from the CLI commands.
|
|
126
|
-
# Those settings override the defaults defined by this object.
|
|
127
|
-
#
|
|
128
|
-
# When initialized, it sets standard `ENV` variables for Rack and Hanami,
|
|
129
|
-
# such as `RACK_ENV` and `HANAMI_ENV`.
|
|
130
|
-
#
|
|
131
|
-
# It evaluates configuration ONLY from `.env.<environment>` file
|
|
132
|
-
# located under the config directory. All the settings in those files will
|
|
133
|
-
# be exported as `ENV` variables.
|
|
134
|
-
#
|
|
135
|
-
# Master .env file is ignored to suggest clear separation of environment
|
|
136
|
-
# configurations and discourage putting sensitive information into source
|
|
137
|
-
# control.
|
|
138
|
-
#
|
|
139
|
-
# The format of those `.env.<environment>` files follows UNIX and UNIX-like
|
|
140
|
-
# operating system environment variable declaration format and compatible
|
|
141
|
-
# with `dotenv` and `foreman` gems.
|
|
142
|
-
#
|
|
143
|
-
# @param options [Hash] override default options for various environment
|
|
144
|
-
# attributes
|
|
145
|
-
#
|
|
146
|
-
# @return [Hanami::Environment] the environment
|
|
147
|
-
#
|
|
148
|
-
# @see Hanami::Commands::Console
|
|
149
|
-
# @see Hanami::Commands::Routes
|
|
150
|
-
# @see Hanami::Commands::Server
|
|
151
|
-
# @see Hanami::Environment#config
|
|
152
|
-
#
|
|
153
|
-
# @api private
|
|
154
|
-
#
|
|
155
|
-
# @example Define ENV variables from .env
|
|
156
|
-
#
|
|
157
|
-
# # % tree .
|
|
158
|
-
# # .
|
|
159
|
-
# # # ...
|
|
160
|
-
# # ├── .env.test
|
|
161
|
-
# # └── .env.development
|
|
162
|
-
#
|
|
163
|
-
# # % cat .env.test
|
|
164
|
-
# # FOO="bar"
|
|
165
|
-
# # XYZ="yes"
|
|
166
|
-
#
|
|
167
|
-
# # % cat .env.development
|
|
168
|
-
# # FOO="ok"
|
|
169
|
-
#
|
|
170
|
-
# require 'hanami/environment'
|
|
171
|
-
#
|
|
172
|
-
# env = Hanami::Environment.new
|
|
173
|
-
# env.environment # => "development"
|
|
174
|
-
#
|
|
175
|
-
# # Framework defined ENV vars
|
|
176
|
-
# ENV['HANAMI_ENV'] # => "development"
|
|
177
|
-
# ENV['RACK_ENV'] # => "development"
|
|
178
|
-
#
|
|
179
|
-
# ENV['HANAMI_HOST'] # => "localhost"
|
|
180
|
-
# ENV['HANAMI_PORT'] # => "2300"
|
|
181
|
-
#
|
|
182
|
-
# # User defined ENV vars
|
|
183
|
-
# ENV['FOO'] # => "ok"
|
|
184
|
-
# ENV['XYZ'] # => nil
|
|
185
|
-
#
|
|
186
|
-
# # Hanami::Environment evaluates `.env.development` because the current
|
|
187
|
-
# # environment is "development".
|
|
188
|
-
# # Variables declared on `.env.development` will not override
|
|
189
|
-
# # any variable declared on the shell when calling a `hanami` command.
|
|
190
|
-
# # Eg. In `FOO="not ok" bundle exec hanami c` `FOO` will not be overwritten
|
|
191
|
-
# # to `"ok"`.
|
|
192
|
-
def initialize(options = {})
|
|
193
|
-
opts = options.to_h.dup
|
|
194
|
-
@env = Hanami::Env.new(env: opts.delete(:env) || ENV)
|
|
195
|
-
@options = Hanami::Hanamirc.new(root).options
|
|
196
|
-
@options.merge! Utils::Hash.symbolize(opts.clone)
|
|
197
|
-
LOCK.synchronize { set_env_vars! }
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
# The current environment
|
|
201
|
-
#
|
|
202
|
-
# In order to decide the value, it looks up to the following `ENV` vars:
|
|
203
|
-
#
|
|
204
|
-
# * HANAMI_ENV
|
|
205
|
-
# * RACK_ENV
|
|
206
|
-
#
|
|
207
|
-
# If those are missing it falls back to the default one: `"development"`.
|
|
208
|
-
#
|
|
209
|
-
# Rack environment `"deployment"` is translated to Hanami `"production"`.
|
|
210
|
-
#
|
|
211
|
-
# @return [String] the current environment
|
|
212
|
-
#
|
|
213
|
-
# @since 0.1.0
|
|
214
|
-
# @api private
|
|
215
|
-
#
|
|
216
|
-
# @see Hanami::Environment::DEFAULT_ENV
|
|
217
|
-
def environment
|
|
218
|
-
@environment ||= env[HANAMI_ENV] || rack_env || DEFAULT_ENV
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
# @since 0.3.1
|
|
222
|
-
# @api private
|
|
223
|
-
#
|
|
224
|
-
# @see Hanami.env?(name)
|
|
225
|
-
def environment?(*names)
|
|
226
|
-
names.map(&:to_s).include?(environment)
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
# A set of Bundler groups
|
|
230
|
-
#
|
|
231
|
-
# @return [Array] A set of groups
|
|
232
|
-
#
|
|
233
|
-
# @since 0.2.0
|
|
234
|
-
# @api private
|
|
235
|
-
#
|
|
236
|
-
# @see http://bundler.io/v1.7/groups.html
|
|
237
|
-
def bundler_groups
|
|
238
|
-
[:default, environment]
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
# Project name
|
|
242
|
-
#
|
|
243
|
-
# @return [String] Project name
|
|
244
|
-
#
|
|
245
|
-
# @since 0.8.0
|
|
246
|
-
# @api private
|
|
247
|
-
def project_name
|
|
248
|
-
@options.fetch(:project)
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
# Application's root
|
|
252
|
-
#
|
|
253
|
-
# It defaults to the current working directory.
|
|
254
|
-
# Hanami assumes that all the commands are executed from there.
|
|
255
|
-
#
|
|
256
|
-
# @return [Pathname] application's root
|
|
257
|
-
#
|
|
258
|
-
# @since 0.2.0
|
|
259
|
-
# @api private
|
|
260
|
-
def root
|
|
261
|
-
@root ||= Pathname.new(Dir.pwd)
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
# Application's config directory
|
|
265
|
-
#
|
|
266
|
-
# It's the application where all the configurations are stored.
|
|
267
|
-
#
|
|
268
|
-
# In order to decide the value, it looks up the following sources:
|
|
269
|
-
#
|
|
270
|
-
# * CLI option `config`
|
|
271
|
-
#
|
|
272
|
-
# If those are missing it falls back to the default one: `"config/"`.
|
|
273
|
-
#
|
|
274
|
-
# When a relative path is given via CLI option, it assumes to be located
|
|
275
|
-
# under application's root. If absolute path, it will be used as it is.
|
|
276
|
-
#
|
|
277
|
-
# @return [Pathname] the config directory
|
|
278
|
-
#
|
|
279
|
-
# @since 0.2.0
|
|
280
|
-
# @api private
|
|
281
|
-
#
|
|
282
|
-
# @see Hanami::Environment::DEFAULT_CONFIG
|
|
283
|
-
# @see Hanami::Environment#root
|
|
284
|
-
def config
|
|
285
|
-
@config ||= root.join(@options.fetch(:config) { DEFAULT_CONFIG })
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
# The HTTP host name
|
|
289
|
-
#
|
|
290
|
-
# In order to decide the value, it looks up the following sources:
|
|
291
|
-
#
|
|
292
|
-
# * CLI option `host`
|
|
293
|
-
# * HANAMI_HOST ENV var
|
|
294
|
-
#
|
|
295
|
-
# If those are missing it falls back to the following defaults:
|
|
296
|
-
#
|
|
297
|
-
# * `"localhost"` for development
|
|
298
|
-
# * `"0.0.0.0"` for all the other environments
|
|
299
|
-
#
|
|
300
|
-
# @return [String] the HTTP host name
|
|
301
|
-
#
|
|
302
|
-
# @since 0.1.0
|
|
303
|
-
# @api private
|
|
304
|
-
#
|
|
305
|
-
# @see Hanami::Environment::DEFAULT_HOST
|
|
306
|
-
# @see Hanami::Environment::LISTEN_ALL_HOST
|
|
307
|
-
def host
|
|
308
|
-
@host ||= @options.fetch(:host) do
|
|
309
|
-
env[HANAMI_HOST] || default_host
|
|
310
|
-
end
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
# The HTTP port
|
|
314
|
-
#
|
|
315
|
-
# In order to decide the value, it looks up the following sources:
|
|
316
|
-
#
|
|
317
|
-
# * CLI option `port`
|
|
318
|
-
# * HANAMI_PORT ENV var
|
|
319
|
-
#
|
|
320
|
-
# If those are missing it falls back to the default one: `2300`.
|
|
321
|
-
#
|
|
322
|
-
# @return [Integer] the default port
|
|
323
|
-
#
|
|
324
|
-
# @since 0.1.0
|
|
325
|
-
# @api private
|
|
326
|
-
#
|
|
327
|
-
# @see Hanami::Environment::DEFAULT_PORT
|
|
328
|
-
def port
|
|
329
|
-
@port ||= @options.fetch(:port) do
|
|
330
|
-
env[HANAMI_PORT] || DEFAULT_PORT
|
|
331
|
-
end.to_i
|
|
332
|
-
end
|
|
333
|
-
|
|
334
|
-
# Check if the current port is the default one
|
|
335
|
-
#
|
|
336
|
-
# @since 1.0.0
|
|
337
|
-
# @api private
|
|
338
|
-
#
|
|
339
|
-
# @see Hanami::ApplicationConfiguration#port
|
|
340
|
-
def default_port?
|
|
341
|
-
port == DEFAULT_PORT
|
|
342
|
-
end
|
|
343
|
-
|
|
344
|
-
# Path to the Rack configuration file
|
|
345
|
-
#
|
|
346
|
-
# In order to decide the value, it looks up the following sources:
|
|
347
|
-
#
|
|
348
|
-
# * CLI option `rackup`
|
|
349
|
-
#
|
|
350
|
-
# If those are missing it falls back to the default one: `"config.ru"`.
|
|
351
|
-
#
|
|
352
|
-
# When a relative path is given via CLI option, it assumes to be located
|
|
353
|
-
# under application's root. If absolute path, it will be used as it is.
|
|
354
|
-
#
|
|
355
|
-
# @return [Pathname] path to the Rack configuration file
|
|
356
|
-
#
|
|
357
|
-
# @since 0.2.0
|
|
358
|
-
# @api private
|
|
359
|
-
def rackup
|
|
360
|
-
root.join(@options.fetch(:rackup) { DEFAULT_RACKUP })
|
|
361
|
-
end
|
|
362
|
-
|
|
363
|
-
# Path to environment configuration file.
|
|
364
|
-
#
|
|
365
|
-
# In order to decide the value, it looks up the following sources:
|
|
366
|
-
#
|
|
367
|
-
# * CLI option `environment`
|
|
368
|
-
#
|
|
369
|
-
# If those are missing it falls back to the default one:
|
|
370
|
-
# `"config/environment.rb"`.
|
|
371
|
-
#
|
|
372
|
-
# When a relative path is given via CLI option, it assumes to be located
|
|
373
|
-
# under application's root. If absolute path, it will be used as it is.
|
|
374
|
-
#
|
|
375
|
-
# @return [Pathname] path to applications
|
|
376
|
-
#
|
|
377
|
-
# @since 0.1.0
|
|
378
|
-
# @api private
|
|
379
|
-
#
|
|
380
|
-
# @see Hanami::Environment::DEFAULT_ENVIRONMENT_CONFIG
|
|
381
|
-
def env_config
|
|
382
|
-
root.join("config", "environment.rb")
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
alias project_environment_configuration env_config
|
|
386
|
-
|
|
387
|
-
# Require application environment
|
|
388
|
-
#
|
|
389
|
-
# Eg <tt>require "config/environment"</tt>.
|
|
390
|
-
#
|
|
391
|
-
# @since 0.4.0
|
|
392
|
-
# @api private
|
|
393
|
-
def require_application_environment
|
|
394
|
-
Bundler.setup(*bundler_groups)
|
|
395
|
-
require project_environment_configuration.to_s # if project_environment_configuration.exist?
|
|
396
|
-
end
|
|
397
|
-
|
|
398
|
-
# @api private
|
|
399
|
-
alias require_project_environment require_application_environment
|
|
400
|
-
|
|
401
|
-
# Determine if activate code reloading for the current environment while
|
|
402
|
-
# running the server.
|
|
403
|
-
#
|
|
404
|
-
# In order to decide the value, it looks up the following sources:
|
|
405
|
-
#
|
|
406
|
-
# * CLI option `code_reloading`
|
|
407
|
-
#
|
|
408
|
-
# If those are missing it falls back to the following defaults:
|
|
409
|
-
#
|
|
410
|
-
# * true for development
|
|
411
|
-
# * false for all the other environments
|
|
412
|
-
#
|
|
413
|
-
# @return [TrueClass,FalseClass] the result of the check
|
|
414
|
-
#
|
|
415
|
-
# @since 0.2.0
|
|
416
|
-
# @api private
|
|
417
|
-
#
|
|
418
|
-
# @see Hanami::Commands::Server
|
|
419
|
-
# @see Hanami::Environment::CODE_RELOADING
|
|
420
|
-
def code_reloading?
|
|
421
|
-
@options.fetch(:code_reloading) { !!CODE_RELOADING[environment] }
|
|
422
|
-
end
|
|
423
|
-
|
|
424
|
-
# @since 0.6.0
|
|
425
|
-
# @api private
|
|
426
|
-
def serve_static_assets?
|
|
427
|
-
SERVE_STATIC_ASSETS_ENABLED == env[SERVE_STATIC_ASSETS]
|
|
428
|
-
end
|
|
429
|
-
|
|
430
|
-
# @since 0.6.0
|
|
431
|
-
# @api private
|
|
432
|
-
def static_assets_middleware
|
|
433
|
-
return unless serve_static_assets?
|
|
434
|
-
|
|
435
|
-
if environment?(:development, :test)
|
|
436
|
-
require 'hanami/assets/static'
|
|
437
|
-
Hanami::Assets::Static
|
|
438
|
-
else
|
|
439
|
-
require 'hanami/static'
|
|
440
|
-
Hanami::Static
|
|
441
|
-
end
|
|
442
|
-
end
|
|
443
|
-
|
|
444
|
-
# @since 0.4.0
|
|
445
|
-
# @api private
|
|
446
|
-
def apps_path
|
|
447
|
-
@options.fetch(:path, APPS_PATH)
|
|
448
|
-
end
|
|
449
|
-
|
|
450
|
-
# Serialize the most relevant settings into a Hash
|
|
451
|
-
#
|
|
452
|
-
# @return [::Hash]
|
|
453
|
-
#
|
|
454
|
-
# @since 0.1.0
|
|
455
|
-
# @api private
|
|
456
|
-
def to_options
|
|
457
|
-
@options.merge(
|
|
458
|
-
environment: environment,
|
|
459
|
-
env_config: env_config,
|
|
460
|
-
apps_path: apps_path,
|
|
461
|
-
rackup: rackup,
|
|
462
|
-
host: host,
|
|
463
|
-
port: port
|
|
464
|
-
)
|
|
465
|
-
end
|
|
466
|
-
|
|
467
|
-
private
|
|
468
|
-
|
|
469
|
-
# @api private
|
|
470
|
-
attr_reader :env
|
|
471
|
-
|
|
472
|
-
# @since 0.1.0
|
|
473
|
-
# @api private
|
|
474
|
-
def set_env_vars!
|
|
475
|
-
set_application_env_vars!
|
|
476
|
-
set_hanami_env_vars!
|
|
477
|
-
end
|
|
478
|
-
|
|
479
|
-
# @since 0.2.0
|
|
480
|
-
# @api private
|
|
481
|
-
def set_hanami_env_vars!
|
|
482
|
-
env[HANAMI_ENV] = env[RACK_ENV] = environment
|
|
483
|
-
env[HANAMI_HOST] = host
|
|
484
|
-
env[HANAMI_PORT] = port.to_s
|
|
485
|
-
end
|
|
486
|
-
|
|
487
|
-
# @since 0.2.0
|
|
488
|
-
# @api private
|
|
489
|
-
def set_application_env_vars!
|
|
490
|
-
dotenv = root.join(DEFAULT_DOTENV_ENV % environment)
|
|
491
|
-
return unless dotenv.exist?
|
|
492
|
-
|
|
493
|
-
env.load!(dotenv)
|
|
494
|
-
end
|
|
495
|
-
|
|
496
|
-
# @since 0.1.0
|
|
497
|
-
# @api private
|
|
498
|
-
def default_host
|
|
499
|
-
environment == DEFAULT_ENV ? DEFAULT_HOST : LISTEN_ALL_HOST
|
|
500
|
-
end
|
|
501
|
-
|
|
502
|
-
# @since 0.6.0
|
|
503
|
-
# @api private
|
|
504
|
-
def rack_env
|
|
505
|
-
case env[RACK_ENV]
|
|
506
|
-
when RACK_ENV_DEPLOYMENT
|
|
507
|
-
PRODUCTION_ENV
|
|
508
|
-
else
|
|
509
|
-
env[RACK_ENV]
|
|
510
|
-
end
|
|
511
|
-
end
|
|
512
|
-
end
|
|
513
|
-
end
|