hanami 2.0.0.alpha1 → 2.0.0.alpha5
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 +306 -5
- data/FEATURES.md +9 -1
- data/LICENSE.md +1 -1
- data/README.md +9 -6
- data/hanami.gemspec +12 -11
- 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 +7 -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/routes_helper.rb +9 -0
- data/lib/hanami/application/container/boot/settings.rb +7 -0
- data/lib/hanami/application/router.rb +59 -0
- data/lib/hanami/application/routes.rb +55 -0
- data/lib/hanami/application/routes_helper.rb +34 -0
- data/lib/hanami/application/routing/middleware/stack.rb +89 -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/routing/resolver.rb +87 -0
- data/lib/hanami/application/routing/router.rb +36 -0
- data/lib/hanami/application/settings/dotenv_store.rb +60 -0
- data/lib/hanami/application/settings.rb +93 -0
- data/lib/hanami/application.rb +330 -34
- data/lib/hanami/assets/application_configuration.rb +63 -0
- data/lib/hanami/assets/configuration.rb +54 -0
- data/lib/hanami/boot/source_dirs.rb +44 -0
- data/lib/hanami/boot.rb +1 -2
- data/lib/hanami/cli/application/cli.rb +40 -0
- data/lib/hanami/cli/application/command.rb +47 -0
- data/lib/hanami/cli/application/commands/console.rb +81 -0
- data/lib/hanami/cli/application/commands.rb +16 -0
- data/lib/hanami/cli/base_command.rb +48 -0
- data/lib/hanami/cli/commands/command.rb +4 -4
- data/lib/hanami/cli/commands.rb +3 -2
- data/lib/hanami/configuration/logger.rb +84 -0
- data/lib/hanami/configuration/middleware.rb +4 -4
- data/lib/hanami/configuration/null_configuration.rb +14 -0
- data/lib/hanami/configuration/router.rb +52 -0
- data/lib/hanami/configuration/sessions.rb +5 -5
- data/lib/hanami/configuration/source_dirs.rb +42 -0
- data/lib/hanami/configuration.rb +122 -131
- data/lib/hanami/init.rb +5 -0
- data/lib/hanami/setup.rb +9 -0
- data/lib/hanami/slice.rb +189 -0
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami/web/rack_logger.rb +96 -0
- data/lib/hanami.rb +17 -30
- metadata +116 -50
- data/bin/hanami +0 -8
- data/lib/hanami/configuration/cookies.rb +0 -24
- data/lib/hanami/configuration/security.rb +0 -141
- data/lib/hanami/container.rb +0 -107
- data/lib/hanami/frameworks.rb +0 -28
- data/lib/hanami/routes.rb +0 -31
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "hanami/cli"
|
4
|
+
require "hanami/cli/application/command"
|
5
|
+
require "hanami/console/context"
|
6
|
+
|
7
|
+
module Hanami
|
8
|
+
class CLI
|
9
|
+
module Application
|
10
|
+
module Commands # rubocop:disable Style/Documentation
|
11
|
+
# Hanami application `console` CLI command
|
12
|
+
class Console < Command
|
13
|
+
REPL =
|
14
|
+
begin
|
15
|
+
require "pry"
|
16
|
+
Pry
|
17
|
+
rescue LoadError
|
18
|
+
require "irb"
|
19
|
+
IRB
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Open interactive console"
|
23
|
+
|
24
|
+
def call(**)
|
25
|
+
measure "#{prompt_prefix} booted in" do
|
26
|
+
out.puts "=> starting #{prompt_prefix} console"
|
27
|
+
application.init
|
28
|
+
end
|
29
|
+
|
30
|
+
start_repl
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def start_repl
|
36
|
+
context = Hanami::Console::Context.new(application)
|
37
|
+
|
38
|
+
case REPL.name.to_sym
|
39
|
+
when :Pry
|
40
|
+
start_pry(context)
|
41
|
+
when :IRB
|
42
|
+
start_irb(context)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def start_pry(context)
|
47
|
+
# https://github.com/pry/pry/pull/1877
|
48
|
+
if Gem.loaded_specs["pry"].version >= Gem::Version.new("0.13.0")
|
49
|
+
Pry.prompt = Pry::Prompt.new(:hanami, "Hanami Console prompt.", prompt_procs)
|
50
|
+
Pry.start(context)
|
51
|
+
else
|
52
|
+
Pry.start(context, prompt_procs)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def start_irb(context)
|
57
|
+
IRB.start(context, prompt_procs)
|
58
|
+
end
|
59
|
+
|
60
|
+
def prompt_procs
|
61
|
+
[proc { default_prompt }, proc { indented_prompt }]
|
62
|
+
end
|
63
|
+
|
64
|
+
def default_prompt
|
65
|
+
"#{prompt_prefix}> "
|
66
|
+
end
|
67
|
+
|
68
|
+
def indented_prompt
|
69
|
+
"#{prompt_prefix}* "
|
70
|
+
end
|
71
|
+
|
72
|
+
def prompt_prefix
|
73
|
+
"#{inflector.underscore(application.application_name)}[#{application.config.env}]"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
register "console", Console
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "hanami/cli/registry"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
class CLI
|
7
|
+
module Application
|
8
|
+
# Hanami application CLI commands registry
|
9
|
+
module Commands
|
10
|
+
extend Hanami::CLI::Registry
|
11
|
+
|
12
|
+
require_relative "commands/console"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/inflector"
|
4
|
+
require "hanami/cli/command"
|
5
|
+
require "hanami/utils/files"
|
6
|
+
|
7
|
+
module Hanami
|
8
|
+
class CLI
|
9
|
+
# Base class for Hanami application CLI commands
|
10
|
+
class BaseCommand < Hanami::CLI::Command
|
11
|
+
attr_reader :out
|
12
|
+
attr_reader :inflector
|
13
|
+
attr_reader :files
|
14
|
+
|
15
|
+
def initialize(
|
16
|
+
command_name:,
|
17
|
+
out: $stdout,
|
18
|
+
inflector: Dry::Inflector.new,
|
19
|
+
files: Hanami::Utils::Files
|
20
|
+
)
|
21
|
+
super(command_name: command_name)
|
22
|
+
|
23
|
+
@out = out
|
24
|
+
@inflector = inflector
|
25
|
+
@files = files
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def run_command(klass, *args)
|
31
|
+
klass.new(
|
32
|
+
command_name: klass.name,
|
33
|
+
application: application,
|
34
|
+
out: out,
|
35
|
+
files: files,
|
36
|
+
).call(*args)
|
37
|
+
end
|
38
|
+
|
39
|
+
def measure(desc)
|
40
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
41
|
+
yield
|
42
|
+
stop = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
43
|
+
|
44
|
+
out.puts "=> #{desc} in #{(stop - start).round(1)}s"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -15,7 +15,7 @@ module Hanami
|
|
15
15
|
# Abstract command
|
16
16
|
#
|
17
17
|
# @since 1.1.0
|
18
|
-
class Command <
|
18
|
+
class Command < Dry::CLI::Command
|
19
19
|
# @since 1.1.0
|
20
20
|
# @api private
|
21
21
|
def self.inherited(component)
|
@@ -72,9 +72,9 @@ module Hanami
|
|
72
72
|
def call(**options)
|
73
73
|
# FIXME: merge ENV vars (like HANAMI_ENV) into **options
|
74
74
|
super(options)
|
75
|
-
rescue StandardError =>
|
76
|
-
warn
|
77
|
-
warn
|
75
|
+
rescue StandardError => exception
|
76
|
+
warn exception.message
|
77
|
+
warn exception.backtrace.join("\n\t")
|
78
78
|
exit(1)
|
79
79
|
end
|
80
80
|
end
|
data/lib/hanami/cli/commands.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "dry/cli"
|
4
|
+
require "ostruct"
|
4
5
|
|
5
6
|
module Hanami
|
6
7
|
# Hanami CLI
|
@@ -55,7 +56,7 @@ module Hanami
|
|
55
56
|
# @since 1.1.0
|
56
57
|
# @api private
|
57
58
|
module Commands
|
58
|
-
extend
|
59
|
+
extend Dry::CLI::Registry
|
59
60
|
|
60
61
|
require "hanami/cli/commands/command"
|
61
62
|
require "hanami/cli/commands/server"
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
require "hanami/logger"
|
5
|
+
|
6
|
+
module Hanami
|
7
|
+
class Configuration
|
8
|
+
# Hanami logger configuration
|
9
|
+
#
|
10
|
+
# @since 2.0.0
|
11
|
+
class Logger
|
12
|
+
include Dry::Configurable
|
13
|
+
|
14
|
+
protected :config
|
15
|
+
|
16
|
+
setting :application_name
|
17
|
+
|
18
|
+
setting :level
|
19
|
+
|
20
|
+
setting :stream
|
21
|
+
|
22
|
+
setting :formatter
|
23
|
+
|
24
|
+
setting :colors
|
25
|
+
|
26
|
+
setting :filters, default: %w[_csrf password password_confirmation].freeze
|
27
|
+
|
28
|
+
setting :options, default: [], constructor: ->(value) { Array(value).flatten }, cloneable: true
|
29
|
+
|
30
|
+
setting :logger_class, default: Hanami::Logger
|
31
|
+
|
32
|
+
def initialize(env:, application_name:)
|
33
|
+
@env = env
|
34
|
+
@application_name = application_name
|
35
|
+
|
36
|
+
config.level = case env
|
37
|
+
when :production
|
38
|
+
:info
|
39
|
+
else
|
40
|
+
:debug
|
41
|
+
end
|
42
|
+
|
43
|
+
config.stream = case env
|
44
|
+
when :test
|
45
|
+
File.join("log", "#{env}.log")
|
46
|
+
else
|
47
|
+
$stdout
|
48
|
+
end
|
49
|
+
|
50
|
+
config.formatter = case env
|
51
|
+
when :production
|
52
|
+
:json
|
53
|
+
end
|
54
|
+
|
55
|
+
config.colors = case env
|
56
|
+
when :production, :test
|
57
|
+
false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def finalize!
|
62
|
+
config.application_name = @application_name.call
|
63
|
+
end
|
64
|
+
|
65
|
+
def instance
|
66
|
+
logger_class.new(application_name, *options, stream: stream, level: level, formatter: formatter, filter: filters, colorizer: colors)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def method_missing(name, *args, &block)
|
72
|
+
if config.respond_to?(name)
|
73
|
+
config.public_send(name, *args, &block)
|
74
|
+
else
|
75
|
+
super
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def respond_to_missing?(name, _incude_all = false)
|
80
|
+
config.respond_to?(name) || super
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -6,15 +6,15 @@ module Hanami
|
|
6
6
|
#
|
7
7
|
# @since 2.0.0
|
8
8
|
class Middleware
|
9
|
+
attr_reader :stack
|
10
|
+
|
9
11
|
def initialize
|
10
12
|
@stack = []
|
11
13
|
end
|
12
14
|
|
13
|
-
def use(middleware, *args)
|
14
|
-
stack.push([middleware, *args])
|
15
|
+
def use(middleware, *args, &block)
|
16
|
+
stack.push([middleware, *args, block].compact)
|
15
17
|
end
|
16
|
-
|
17
|
-
attr_reader :stack
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
class Configuration
|
7
|
+
# NullConfiguration can serve as a fallback configuration object when out-of-gem
|
8
|
+
# configuration objects are not available (specifically, when the hanami-controller or
|
9
|
+
# hanami-view gems are not loaded)
|
10
|
+
class NullConfiguration
|
11
|
+
include Dry::Configurable
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
require_relative "../application/routing/resolver"
|
5
|
+
|
6
|
+
module Hanami
|
7
|
+
class Configuration
|
8
|
+
# Hanami router configuration
|
9
|
+
#
|
10
|
+
# @since 2.0.0
|
11
|
+
# @api private
|
12
|
+
class Router
|
13
|
+
include Dry::Configurable
|
14
|
+
|
15
|
+
# Base configuration is provided so router config can include the `base_url`
|
16
|
+
attr_reader :base_configuration
|
17
|
+
private :base_configuration
|
18
|
+
|
19
|
+
# @api private
|
20
|
+
# @since 2.0.0
|
21
|
+
def initialize(base_configuration)
|
22
|
+
@base_configuration = base_configuration
|
23
|
+
end
|
24
|
+
|
25
|
+
setting :routes_path, default: File.join("config", "routes")
|
26
|
+
|
27
|
+
setting :routes_class_name, default: "Routes"
|
28
|
+
|
29
|
+
setting :resolver, default: Application::Routing::Resolver
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
# @since 2.0.0
|
33
|
+
def options
|
34
|
+
{base_url: base_configuration.base_url}
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def method_missing(name, *args, &block)
|
40
|
+
if config.respond_to?(name)
|
41
|
+
config.public_send(name, *args, &block)
|
42
|
+
else
|
43
|
+
super
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def respond_to_missing?(name, _include_all = false)
|
48
|
+
config.respond_to?(name) || super
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -9,8 +9,11 @@ module Hanami
|
|
9
9
|
#
|
10
10
|
# @since 2.0.0
|
11
11
|
class Sessions
|
12
|
+
NULL_SESSION_OPTION = :null
|
13
|
+
private_constant :NULL_SESSION_OPTION
|
14
|
+
|
12
15
|
def self.null
|
13
|
-
|
16
|
+
self.class.new(NULL_SESSION_OPTION)
|
14
17
|
end
|
15
18
|
|
16
19
|
attr_reader :storage, :options
|
@@ -23,7 +26,7 @@ module Hanami
|
|
23
26
|
end
|
24
27
|
|
25
28
|
def enabled?
|
26
|
-
storage !=
|
29
|
+
storage != NULL_SESSION_OPTION
|
27
30
|
end
|
28
31
|
|
29
32
|
def middleware
|
@@ -32,9 +35,6 @@ module Hanami
|
|
32
35
|
|
33
36
|
private
|
34
37
|
|
35
|
-
NULL_STORAGE = :null
|
36
|
-
private_constant :NULL_STORAGE
|
37
|
-
|
38
38
|
def storage_middleware
|
39
39
|
require_storage
|
40
40
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
require "dry/system/config/component_dirs"
|
5
|
+
|
6
|
+
module Hanami
|
7
|
+
class Configuration
|
8
|
+
# Configuration for slice source dirs
|
9
|
+
#
|
10
|
+
# @since 2.0.0
|
11
|
+
class SourceDirs
|
12
|
+
DEFAULT_COMPONENT_DIR_PATHS = %w[lib actions repositories views].freeze
|
13
|
+
private_constant :DEFAULT_COMPONENT_DIR_PATHS
|
14
|
+
|
15
|
+
include Dry::Configurable
|
16
|
+
|
17
|
+
setting :component_dirs,
|
18
|
+
default: Dry::System::Config::ComponentDirs.new.tap { |dirs|
|
19
|
+
DEFAULT_COMPONENT_DIR_PATHS.each do |path|
|
20
|
+
dirs.add path
|
21
|
+
end
|
22
|
+
},
|
23
|
+
cloneable: true
|
24
|
+
|
25
|
+
setting :autoload_paths, default: %w[entities]
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def method_missing(name, *args, &block)
|
30
|
+
if config.respond_to?(name)
|
31
|
+
config.public_send(name, *args, &block)
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def respond_to_missing?(name, _include_all = false)
|
38
|
+
config.respond_to?(name) || super
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|