hanami 0.0.0 → 0.7.0
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 +214 -0
- data/FEATURES.md +156 -0
- data/LICENSE.md +22 -0
- data/README.md +80 -15
- data/bin/hanami +5 -0
- data/hanami.gemspec +27 -12
- data/lib/hanami.rb +78 -2
- data/lib/hanami/action/csrf_protection.rb +167 -0
- data/lib/hanami/action/routing_helpers.rb +40 -0
- data/lib/hanami/application.rb +244 -0
- data/lib/hanami/application_name.rb +101 -0
- data/lib/hanami/cli.rb +119 -0
- data/lib/hanami/cli_sub_commands/assets.rb +29 -0
- data/lib/hanami/cli_sub_commands/db.rb +124 -0
- data/lib/hanami/cli_sub_commands/destroy.rb +102 -0
- data/lib/hanami/cli_sub_commands/generate.rb +127 -0
- data/lib/hanami/commands/assets/precompile.rb +35 -0
- data/lib/hanami/commands/console.rb +90 -0
- data/lib/hanami/commands/db/abstract.rb +19 -0
- data/lib/hanami/commands/db/apply.rb +14 -0
- data/lib/hanami/commands/db/console.rb +50 -0
- data/lib/hanami/commands/db/create.rb +14 -0
- data/lib/hanami/commands/db/drop.rb +14 -0
- data/lib/hanami/commands/db/migrate.rb +19 -0
- data/lib/hanami/commands/db/prepare.rb +14 -0
- data/lib/hanami/commands/db/version.rb +14 -0
- data/lib/hanami/commands/generate/abstract.rb +63 -0
- data/lib/hanami/commands/generate/action.rb +262 -0
- data/lib/hanami/commands/generate/app.rb +116 -0
- data/lib/hanami/commands/generate/mailer.rb +118 -0
- data/lib/hanami/commands/generate/migration.rb +63 -0
- data/lib/hanami/commands/generate/model.rb +96 -0
- data/lib/hanami/commands/new/abstract.rb +128 -0
- data/lib/hanami/commands/new/app.rb +116 -0
- data/lib/hanami/commands/new/container.rb +102 -0
- data/lib/hanami/commands/routes.rb +41 -0
- data/lib/hanami/commands/server.rb +79 -0
- data/lib/hanami/config/configure.rb +17 -0
- data/lib/hanami/config/cookies.rb +68 -0
- data/lib/hanami/config/framework_configuration.rb +42 -0
- data/lib/hanami/config/load_paths.rb +27 -0
- data/lib/hanami/config/mapper.rb +36 -0
- data/lib/hanami/config/mapping.rb +12 -0
- data/lib/hanami/config/routes.rb +16 -0
- data/lib/hanami/config/security.rb +58 -0
- data/lib/hanami/config/sessions.rb +97 -0
- data/lib/hanami/configuration.rb +1728 -0
- data/lib/hanami/container.rb +59 -0
- data/lib/hanami/environment.rb +485 -0
- data/lib/hanami/frameworks.rb +14 -0
- data/lib/hanami/generators/action/action.rb.tt +8 -0
- data/lib/hanami/generators/action/action_spec.minitest.tt +12 -0
- data/lib/hanami/generators/action/action_spec.rspec.tt +11 -0
- data/lib/hanami/generators/action/action_without_view.rb.tt +9 -0
- data/lib/hanami/generators/action/template.tt +0 -0
- data/lib/hanami/generators/action/view.rb.tt +5 -0
- data/lib/hanami/generators/action/view_spec.minitest.tt +13 -0
- data/lib/hanami/generators/action/view_spec.rspec.tt +12 -0
- data/lib/hanami/generators/app/.gitkeep.tt +1 -0
- data/lib/hanami/generators/app/application.rb.tt +273 -0
- data/lib/hanami/generators/app/config/initializers/.gitkeep +0 -0
- data/lib/hanami/generators/app/config/routes.rb.tt +2 -0
- data/lib/hanami/generators/app/favicon.ico +0 -0
- data/lib/hanami/generators/app/templates/application.html.erb.tt +10 -0
- data/lib/hanami/generators/app/views/application_layout.rb.tt +7 -0
- data/lib/hanami/generators/application/app/.env.development.tt +4 -0
- data/lib/hanami/generators/application/app/.env.test.tt +4 -0
- data/lib/hanami/generators/application/app/.env.tt +1 -0
- data/lib/hanami/generators/application/app/.gitignore +0 -0
- data/lib/hanami/generators/application/app/.gitkeep +1 -0
- data/lib/hanami/generators/application/app/Gemfile.tt +37 -0
- data/lib/hanami/generators/application/app/Rakefile.minitest.tt +11 -0
- data/lib/hanami/generators/application/app/Rakefile.rspec.tt +6 -0
- data/lib/hanami/generators/application/app/apps/.gitkeep.tt +1 -0
- data/lib/hanami/generators/application/app/capybara.rb.rspec.tt +8 -0
- data/lib/hanami/generators/application/app/config.ru.tt +3 -0
- data/lib/hanami/generators/application/app/config/application.rb.tt +270 -0
- data/lib/hanami/generators/application/app/config/environment.rb.tt +5 -0
- data/lib/hanami/generators/application/app/config/initializers/.gitkeep +0 -0
- data/lib/hanami/generators/application/app/config/routes.rb.tt +2 -0
- data/lib/hanami/generators/application/app/db/.gitkeep +1 -0
- data/lib/hanami/generators/application/app/favicon.ico +0 -0
- data/lib/hanami/generators/application/app/features_helper.rb.minitest.tt +11 -0
- data/lib/hanami/generators/application/app/features_helper.rb.rspec.tt +12 -0
- data/lib/hanami/generators/application/app/gitignore.tt +2 -0
- data/lib/hanami/generators/application/app/gitignore_with_db.tt +4 -0
- data/lib/hanami/generators/application/app/hanamirc.tt +3 -0
- data/lib/hanami/generators/application/app/lib/app_name.rb.tt +59 -0
- data/lib/hanami/generators/application/app/lib/chirp/entities/.gitkeep +1 -0
- data/lib/hanami/generators/application/app/lib/chirp/repositories/.gitkeep +1 -0
- data/lib/hanami/generators/application/app/lib/config/mapping.rb.tt +7 -0
- data/lib/hanami/generators/application/app/rspec.rspec.tt +2 -0
- data/lib/hanami/generators/application/app/schema.sql.tt +0 -0
- data/lib/hanami/generators/application/app/spec_helper.rb.minitest.tt +7 -0
- data/lib/hanami/generators/application/app/spec_helper.rb.rspec.tt +104 -0
- data/lib/hanami/generators/application/app/templates/application.html.erb.tt +10 -0
- data/lib/hanami/generators/application/app/views/application_layout.rb.tt +7 -0
- data/lib/hanami/generators/application/container/.env.development.tt +3 -0
- data/lib/hanami/generators/application/container/.env.test.tt +3 -0
- data/lib/hanami/generators/application/container/.env.tt +1 -0
- data/lib/hanami/generators/application/container/.gitignore +0 -0
- data/lib/hanami/generators/application/container/.gitkeep +1 -0
- data/lib/hanami/generators/application/container/Gemfile.tt +36 -0
- data/lib/hanami/generators/application/container/Rakefile.minitest.tt +11 -0
- data/lib/hanami/generators/application/container/Rakefile.rspec.tt +6 -0
- data/lib/hanami/generators/application/container/capybara.rb.rspec.tt +8 -0
- data/lib/hanami/generators/application/container/config.ru.tt +3 -0
- data/lib/hanami/generators/application/container/config/environment.rb.tt +7 -0
- data/lib/hanami/generators/application/container/config/initializers/.gitkeep +0 -0
- data/lib/hanami/generators/application/container/db/.gitkeep +1 -0
- data/lib/hanami/generators/application/container/features_helper.rb.minitest.tt +11 -0
- data/lib/hanami/generators/application/container/features_helper.rb.rspec.tt +12 -0
- data/lib/hanami/generators/application/container/gitignore.tt +2 -0
- data/lib/hanami/generators/application/container/gitignore_with_db.tt +4 -0
- data/lib/hanami/generators/application/container/hanamirc.tt +3 -0
- data/lib/hanami/generators/application/container/lib/app_name.rb.tt +60 -0
- data/lib/hanami/generators/application/container/lib/chirp/entities/.gitkeep +1 -0
- data/lib/hanami/generators/application/container/lib/chirp/mailers/.gitkeep +0 -0
- data/lib/hanami/generators/application/container/lib/chirp/mailers/templates/.gitkeep +0 -0
- data/lib/hanami/generators/application/container/lib/chirp/repositories/.gitkeep +1 -0
- data/lib/hanami/generators/application/container/lib/config/mapping.rb.tt +7 -0
- data/lib/hanami/generators/application/container/rspec.rspec.tt +2 -0
- data/lib/hanami/generators/application/container/schema.sql.tt +0 -0
- data/lib/hanami/generators/application/container/spec_helper.rb.minitest.tt +7 -0
- data/lib/hanami/generators/application/container/spec_helper.rb.rspec.tt +104 -0
- data/lib/hanami/generators/database_config.rb +99 -0
- data/lib/hanami/generators/generatable.rb +51 -0
- data/lib/hanami/generators/generator.rb +35 -0
- data/lib/hanami/generators/mailer/mailer.rb.tt +7 -0
- data/lib/hanami/generators/mailer/mailer_spec.rb.tt +7 -0
- data/lib/hanami/generators/mailer/template.html.tt +0 -0
- data/lib/hanami/generators/mailer/template.txt.tt +0 -0
- data/lib/hanami/generators/migration/migration.rb.tt +4 -0
- data/lib/hanami/generators/model/entity.rb.tt +3 -0
- data/lib/hanami/generators/model/entity_spec.minitest.tt +5 -0
- data/lib/hanami/generators/model/entity_spec.rspec.tt +3 -0
- data/lib/hanami/generators/model/repository.rb.tt +3 -0
- data/lib/hanami/generators/model/repository_spec.minitest.tt +5 -0
- data/lib/hanami/generators/model/repository_spec.rspec.tt +3 -0
- data/lib/hanami/generators/test_framework.rb +42 -0
- data/lib/hanami/hanamirc.rb +152 -0
- data/lib/hanami/loader.rb +258 -0
- data/lib/hanami/mailer/glue.rb +68 -0
- data/lib/hanami/middleware.rb +143 -0
- data/lib/hanami/rake_helper.rb +68 -0
- data/lib/hanami/rake_tasks.rb +2 -0
- data/lib/hanami/rendering_policy.rb +77 -0
- data/lib/hanami/repositories/car_repository.rb +3 -0
- data/lib/hanami/repositories/name_repository.rb +3 -0
- data/lib/hanami/root.rb +7 -0
- data/lib/hanami/routes.rb +151 -0
- data/lib/hanami/routing/default.rb +25 -0
- data/lib/hanami/setup.rb +3 -0
- data/lib/hanami/static.rb +77 -0
- data/lib/hanami/templates/default.html.erb +9 -0
- data/lib/hanami/templates/welcome.html.erb +52 -0
- data/lib/hanami/version.rb +4 -1
- data/lib/hanami/views/default.rb +34 -0
- data/lib/hanami/views/default_template_finder.rb +20 -0
- data/lib/hanami/views/null_view.rb +17 -0
- data/lib/hanami/welcome.rb +40 -0
- metadata +357 -16
- data/.gitignore +0 -9
- data/Gemfile +0 -4
- data/Rakefile +0 -2
- data/bin/console +0 -14
- data/bin/setup +0 -8
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require 'shellwords'
|
|
2
|
+
|
|
3
|
+
module Hanami
|
|
4
|
+
module Generators
|
|
5
|
+
class DatabaseConfig
|
|
6
|
+
|
|
7
|
+
SUPPORTED_ENGINES = {
|
|
8
|
+
'mysql' => { type: :sql, mri: 'mysql2', jruby: 'jdbc-mysql' },
|
|
9
|
+
'mysql2' => { type: :sql, mri: 'mysql2', jruby: 'jdbc-mysql' },
|
|
10
|
+
'postgresql' => { type: :sql, mri: 'pg', jruby: 'jdbc-postgres' },
|
|
11
|
+
'postgres' => { type: :sql, mri: 'pg', jruby: 'jdbc-postgres' },
|
|
12
|
+
'sqlite' => { type: :sql, mri: 'sqlite3', jruby: 'jdbc-sqlite3' },
|
|
13
|
+
'sqlite3' => { type: :sql, mri: 'sqlite3', jruby: 'jdbc-sqlite3' },
|
|
14
|
+
'filesystem' => { type: :file_system, mri: nil, jruby: nil },
|
|
15
|
+
'memory' => { type: :memory, mri: nil, jruby: nil }
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
DEFAULT_ENGINE = 'filesystem'.freeze
|
|
19
|
+
|
|
20
|
+
attr_reader :engine, :name
|
|
21
|
+
|
|
22
|
+
def initialize(engine, name)
|
|
23
|
+
@engine = engine
|
|
24
|
+
@name = name
|
|
25
|
+
|
|
26
|
+
SUPPORTED_ENGINES.key?(engine.to_s) or fail "\"#{ engine }\" is not a valid database type"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_hash
|
|
30
|
+
{
|
|
31
|
+
gem: gem,
|
|
32
|
+
uri: uri,
|
|
33
|
+
type: type
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def type
|
|
38
|
+
SUPPORTED_ENGINES[engine][:type]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def sql?
|
|
42
|
+
type == :sql
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def filesystem?
|
|
46
|
+
type == :file_system
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def platform
|
|
52
|
+
Hanami::Utils.jruby? ? :jruby : :mri
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def platform_prefix
|
|
56
|
+
'jdbc:'.freeze if Hanami::Utils.jruby?
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def uri
|
|
60
|
+
{
|
|
61
|
+
development: environment_uri(:development),
|
|
62
|
+
test: environment_uri(:test)
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def gem
|
|
67
|
+
SUPPORTED_ENGINES[engine][platform]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def base_uri
|
|
71
|
+
case engine
|
|
72
|
+
when 'mysql', 'mysql2'
|
|
73
|
+
if Hanami::Utils.jruby?
|
|
74
|
+
"mysql://localhost/#{ name }"
|
|
75
|
+
else
|
|
76
|
+
"mysql2://localhost/#{ name }"
|
|
77
|
+
end
|
|
78
|
+
when 'postgresql', 'postgres'
|
|
79
|
+
"postgres://localhost/#{ name }"
|
|
80
|
+
when 'sqlite', 'sqlite3'
|
|
81
|
+
"sqlite://db/#{ Shellwords.escape(name) }"
|
|
82
|
+
when 'memory'
|
|
83
|
+
"memory://localhost/#{ name }"
|
|
84
|
+
when 'filesystem'
|
|
85
|
+
"file:///db/#{ Shellwords.escape(name) }"
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def environment_uri(environment)
|
|
90
|
+
case engine
|
|
91
|
+
when 'sqlite', 'sqlite3'
|
|
92
|
+
"#{ platform_prefix }#{ base_uri }_#{ environment }.sqlite"
|
|
93
|
+
else
|
|
94
|
+
"#{ platform_prefix if sql? }#{ base_uri }_#{ environment }"
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'hanami/generators/generator'
|
|
2
|
+
|
|
3
|
+
module Hanami
|
|
4
|
+
module Generators
|
|
5
|
+
module Generatable
|
|
6
|
+
|
|
7
|
+
def start
|
|
8
|
+
map_templates
|
|
9
|
+
process_templates
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def destroy
|
|
13
|
+
generator.behavior = :revoke
|
|
14
|
+
self
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def generator
|
|
18
|
+
@generator ||= Hanami::Generators::Generator.new(template_source_path, target_path)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def map_templates
|
|
22
|
+
raise NotImplementedError, "must implement the map_templates method"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def add_mapping(source, target)
|
|
26
|
+
generator.add_mapping(source, target)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def process_templates
|
|
30
|
+
generator.process_templates(template_options)
|
|
31
|
+
post_process_templates
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def post_process_templates
|
|
35
|
+
nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def template_options
|
|
39
|
+
{}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def template_source_path
|
|
43
|
+
raise NotImplementedError, "must implement the template_source_path method"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def target_path
|
|
47
|
+
raise NotImplementedError, "must implement the target_path method"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'forwardable'
|
|
3
|
+
|
|
4
|
+
module Hanami
|
|
5
|
+
module Generators
|
|
6
|
+
class Generator
|
|
7
|
+
|
|
8
|
+
extend Forwardable
|
|
9
|
+
|
|
10
|
+
def_delegators :@processor, :run, :behavior=, :inject_into_file, :append_to_file, :prepend_to_file
|
|
11
|
+
|
|
12
|
+
class Processor < Thor
|
|
13
|
+
include Thor::Actions
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def initialize(template_source_path, target_path)
|
|
17
|
+
@template_source_path = template_source_path
|
|
18
|
+
@target_path = target_path
|
|
19
|
+
@template_mappings = []
|
|
20
|
+
@processor = Processor.new
|
|
21
|
+
@processor.class.source_root(@template_source_path)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def add_mapping(source, target)
|
|
25
|
+
@template_mappings << [source, target]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def process_templates(options = {})
|
|
29
|
+
@template_mappings.each do |src, dst|
|
|
30
|
+
@processor.template(@template_source_path.join(src), @target_path.join(dst), options)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'hanami/hanamirc'
|
|
2
|
+
module Hanami
|
|
3
|
+
module Generators
|
|
4
|
+
class TestFramework
|
|
5
|
+
RSPEC = 'rspec'.freeze
|
|
6
|
+
MINITEST = 'minitest'.freeze
|
|
7
|
+
VALID_FRAMEWORKS = [RSPEC, MINITEST].freeze
|
|
8
|
+
|
|
9
|
+
attr_reader :framework
|
|
10
|
+
|
|
11
|
+
def initialize(hanamirc, framework)
|
|
12
|
+
@framework = (framework || hanamirc.options.fetch(:test))
|
|
13
|
+
assert_framework!
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def rspec?
|
|
17
|
+
framework == RSPEC
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def minitest?
|
|
21
|
+
framework == MINITEST
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def assert_framework!
|
|
27
|
+
if !supported_framework?
|
|
28
|
+
raise ArgumentError.new("Unknown test framework '#{ framework}'. Please use one of #{ valid_test_frameworks.join(', ')}")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def valid_test_frameworks
|
|
33
|
+
VALID_FRAMEWORKS.map { |name| "'#{ name }'"}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def supported_framework?
|
|
37
|
+
VALID_FRAMEWORKS.include?(framework)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
require 'dotenv/parser'
|
|
3
|
+
require 'hanami/utils/hash'
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
# Read the .hanamirc file in the root of the application
|
|
7
|
+
#
|
|
8
|
+
# @since 0.3.0
|
|
9
|
+
# @api private
|
|
10
|
+
class Hanamirc
|
|
11
|
+
# Hanamirc name file
|
|
12
|
+
#
|
|
13
|
+
# @since 0.3.0
|
|
14
|
+
# @api private
|
|
15
|
+
#
|
|
16
|
+
# @see Hanami::Hanamirc#path_file
|
|
17
|
+
FILE_NAME = '.hanamirc'.freeze
|
|
18
|
+
|
|
19
|
+
# Architecture default value
|
|
20
|
+
#
|
|
21
|
+
# @since 0.3.0
|
|
22
|
+
# @api private
|
|
23
|
+
#
|
|
24
|
+
# @see Hanami::Hanamirc#options
|
|
25
|
+
DEFAULT_ARCHITECTURE = 'container'.freeze
|
|
26
|
+
|
|
27
|
+
# Application architecture value
|
|
28
|
+
#
|
|
29
|
+
# @since 0.6.0
|
|
30
|
+
# @api private
|
|
31
|
+
APP_ARCHITECTURE = 'app'.freeze
|
|
32
|
+
|
|
33
|
+
# Architecture key for writing the hanamirc file
|
|
34
|
+
#
|
|
35
|
+
# @since 0.3.0
|
|
36
|
+
# @api private
|
|
37
|
+
#
|
|
38
|
+
# @see Hanami::Hanamirc::DEFAULT_OPTIONS
|
|
39
|
+
ARCHITECTURE_KEY = 'architecture'.freeze
|
|
40
|
+
|
|
41
|
+
# Test suite default value
|
|
42
|
+
#
|
|
43
|
+
# @since 0.3.0
|
|
44
|
+
# @api private
|
|
45
|
+
#
|
|
46
|
+
# @see Hanami::Hanamirc::DEFAULT_OPTIONS
|
|
47
|
+
DEFAULT_TEST_SUITE = 'minitest'.freeze
|
|
48
|
+
|
|
49
|
+
# Test suite key for writing the hanamirc file
|
|
50
|
+
#
|
|
51
|
+
# @since 0.3.0
|
|
52
|
+
# @api private
|
|
53
|
+
#
|
|
54
|
+
# @see Hanami::Hanamirc::DEFAULT_OPTIONS
|
|
55
|
+
TEST_KEY = 'test'.freeze
|
|
56
|
+
|
|
57
|
+
# Template default value
|
|
58
|
+
#
|
|
59
|
+
# @since 0.3.0
|
|
60
|
+
# @api private
|
|
61
|
+
#
|
|
62
|
+
# @see Hanami::Hanamirc::DEFAULT_OPTIONS
|
|
63
|
+
DEFAULT_TEMPLATE = 'erb'.freeze
|
|
64
|
+
|
|
65
|
+
# Template key for writing the hanamirc file
|
|
66
|
+
#
|
|
67
|
+
# @since 0.3.0
|
|
68
|
+
# @api private
|
|
69
|
+
#
|
|
70
|
+
# @see Hanami::Hanamirc::DEFAULT_OPTIONS
|
|
71
|
+
TEMPLATE_KEY = 'template'.freeze
|
|
72
|
+
|
|
73
|
+
# Default values for writing the hanamirc file
|
|
74
|
+
#
|
|
75
|
+
# @since 0.5.1
|
|
76
|
+
# @api private
|
|
77
|
+
#
|
|
78
|
+
# @see Hanami::Hanamirc#options
|
|
79
|
+
DEFAULT_OPTIONS = Utils::Hash.new({
|
|
80
|
+
ARCHITECTURE_KEY => DEFAULT_ARCHITECTURE,
|
|
81
|
+
TEST_KEY => DEFAULT_TEST_SUITE,
|
|
82
|
+
TEMPLATE_KEY => DEFAULT_TEMPLATE
|
|
83
|
+
}).symbolize!.freeze
|
|
84
|
+
|
|
85
|
+
# Initialize Hanamirc class with application's root and environment options.
|
|
86
|
+
#
|
|
87
|
+
# @param root [Pathname] Application's root
|
|
88
|
+
#
|
|
89
|
+
# @see Hanami::Environment#initialize
|
|
90
|
+
def initialize(root)
|
|
91
|
+
@root = root
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Read hanamirc file (if exists) and parse it's values or return default.
|
|
95
|
+
#
|
|
96
|
+
# @return [Hanami::Utils::Hash] parsed values
|
|
97
|
+
#
|
|
98
|
+
# @example Default values if file doesn't exist
|
|
99
|
+
# Hanami::Hanamirc.new(Pathname.new(Dir.pwd)).options
|
|
100
|
+
# # => { architecture: 'container', test: 'minitest', template: 'erb' }
|
|
101
|
+
#
|
|
102
|
+
# @example Custom values if file doesn't exist
|
|
103
|
+
# options = { architect: 'application', test: 'rspec', template: 'slim' }
|
|
104
|
+
# Hanami::Hanamirc.new(Pathname.new(Dir.pwd), options).options
|
|
105
|
+
# # => { architecture: 'application', test: 'rspec', template: 'slim' }
|
|
106
|
+
def options
|
|
107
|
+
@options ||= symbolize(DEFAULT_OPTIONS.merge(file_options))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Check if hanamirc file exists
|
|
111
|
+
#
|
|
112
|
+
# @since 0.3.0
|
|
113
|
+
# @api private
|
|
114
|
+
#
|
|
115
|
+
# @return [Boolean] hanamirc file's path existing
|
|
116
|
+
def exists?
|
|
117
|
+
path_file.exist?
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
private
|
|
121
|
+
|
|
122
|
+
def symbolize(hash)
|
|
123
|
+
Utils::Hash.new(hash).symbolize!
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def file_options
|
|
127
|
+
symbolize(exists? ? Dotenv::Parser.call(content) : {})
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Return the hanamirc file's path
|
|
131
|
+
#
|
|
132
|
+
# @since 0.3.0
|
|
133
|
+
# @api private
|
|
134
|
+
#
|
|
135
|
+
# @return [Pathname] hanamirc file's path
|
|
136
|
+
#
|
|
137
|
+
# @see Hanami::Hanamirc::FILE_NAME
|
|
138
|
+
def path_file
|
|
139
|
+
@root.join FILE_NAME
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Return the content of hanamirc file
|
|
143
|
+
#
|
|
144
|
+
# @since 0.3.0
|
|
145
|
+
# @api private
|
|
146
|
+
#
|
|
147
|
+
# @return [String] content of hanamirc file
|
|
148
|
+
def content
|
|
149
|
+
path_file.read
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
require 'hanami/utils/class'
|
|
2
|
+
require 'hanami/utils/kernel'
|
|
3
|
+
require 'hanami/utils/string'
|
|
4
|
+
require 'hanami/routes'
|
|
5
|
+
require 'hanami/routing/default'
|
|
6
|
+
require 'hanami/action/session'
|
|
7
|
+
require 'hanami/config/security'
|
|
8
|
+
require 'hanami/action/routing_helpers'
|
|
9
|
+
|
|
10
|
+
module Hanami
|
|
11
|
+
# Load an application
|
|
12
|
+
#
|
|
13
|
+
# @since 0.1.0
|
|
14
|
+
# @api private
|
|
15
|
+
class Loader
|
|
16
|
+
|
|
17
|
+
STRICT_TRANSPORT_SECURITY_HEADER = 'Strict-Transport-Security'.freeze
|
|
18
|
+
STRICT_TRANSPORT_SECURITY_DEFAULT_VALUE = 'max-age=31536000'.freeze
|
|
19
|
+
|
|
20
|
+
def initialize(application)
|
|
21
|
+
@application = application
|
|
22
|
+
@configuration = @application.configuration
|
|
23
|
+
|
|
24
|
+
@mutex = Mutex.new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def load!
|
|
28
|
+
@mutex.synchronize do
|
|
29
|
+
load_configuration!
|
|
30
|
+
configure_frameworks!
|
|
31
|
+
load_configuration_load_paths!
|
|
32
|
+
load_rack!
|
|
33
|
+
load_frameworks!
|
|
34
|
+
load_initializers!
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
attr_reader :application, :configuration
|
|
40
|
+
|
|
41
|
+
def load_configuration!
|
|
42
|
+
configuration.load!(application_module)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def configure_frameworks!
|
|
46
|
+
_configure_model_framework! if defined?(Hanami::Model)
|
|
47
|
+
_configure_controller_framework!
|
|
48
|
+
_configure_view_framework!
|
|
49
|
+
_configure_assets_framework!
|
|
50
|
+
_configure_logger!
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def _configure_controller_framework!
|
|
54
|
+
config = configuration
|
|
55
|
+
unless namespace.const_defined?('Controller')
|
|
56
|
+
controller = Hanami::Controller.duplicate(namespace) do
|
|
57
|
+
handle_exceptions config.handle_exceptions
|
|
58
|
+
default_request_format config.default_request_format
|
|
59
|
+
default_response_format config.default_response_format
|
|
60
|
+
default_headers({
|
|
61
|
+
Hanami::Config::Security::X_FRAME_OPTIONS_HEADER => config.security.x_frame_options,
|
|
62
|
+
Hanami::Config::Security::CONTENT_SECURITY_POLICY_HEADER => config.security.content_security_policy
|
|
63
|
+
})
|
|
64
|
+
default_headers.merge!(STRICT_TRANSPORT_SECURITY_HEADER => STRICT_TRANSPORT_SECURITY_DEFAULT_VALUE) if config.force_ssl
|
|
65
|
+
|
|
66
|
+
if config.cookies.enabled?
|
|
67
|
+
require 'hanami/action/cookies'
|
|
68
|
+
prepare { include Hanami::Action::Cookies }
|
|
69
|
+
cookies config.cookies.default_options
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
if config.sessions.enabled?
|
|
73
|
+
prepare do
|
|
74
|
+
include Hanami::Action::Session
|
|
75
|
+
include Hanami::Action::CSRFProtection
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
prepare { include Hanami::Action::RoutingHelpers }
|
|
80
|
+
|
|
81
|
+
config.controller.__apply(self)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
namespace.const_set('Controller', controller)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def _configure_view_framework!
|
|
89
|
+
config = configuration
|
|
90
|
+
unless namespace.const_defined?('View')
|
|
91
|
+
view = Hanami::View.duplicate(namespace) do
|
|
92
|
+
root config.templates
|
|
93
|
+
layout config.layout
|
|
94
|
+
|
|
95
|
+
config.view.__apply(self)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
namespace.const_set('View', view)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def _configure_assets_framework!
|
|
103
|
+
config = configuration
|
|
104
|
+
|
|
105
|
+
unless application_module.const_defined?('Assets')
|
|
106
|
+
assets = Hanami::Assets.duplicate(namespace) do
|
|
107
|
+
root config.root
|
|
108
|
+
|
|
109
|
+
scheme config.scheme
|
|
110
|
+
host config.host
|
|
111
|
+
port config.port
|
|
112
|
+
|
|
113
|
+
public_directory Hanami.public_directory
|
|
114
|
+
prefix Utils::PathPrefix.new('/assets').join(config.path_prefix)
|
|
115
|
+
|
|
116
|
+
manifest Hanami.public_directory.join('assets.json')
|
|
117
|
+
compile true
|
|
118
|
+
|
|
119
|
+
config.assets.__apply(self)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
assets.configure do
|
|
123
|
+
cdn host != config.host
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
application_module.const_set('Assets', assets)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def _configure_model_framework!
|
|
131
|
+
config = configuration
|
|
132
|
+
if _hanami_model_loaded? && !application_module.const_defined?('Model')
|
|
133
|
+
model = Hanami::Model.duplicate(application_module) do
|
|
134
|
+
adapter(config.adapter) if config.adapter
|
|
135
|
+
mapping(&config.mapping) if config.mapping
|
|
136
|
+
|
|
137
|
+
config.model.__apply(self)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
application_module.const_set('Model', model)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def _configure_logger!
|
|
145
|
+
unless application_module.const_defined?('Logger', false)
|
|
146
|
+
if configuration.logger.nil?
|
|
147
|
+
configuration.logger Hanami::Logger.new(application_module.to_s)
|
|
148
|
+
end
|
|
149
|
+
application_module.const_set('Logger', configuration.logger)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def load_frameworks!
|
|
154
|
+
_load_view_framework!
|
|
155
|
+
_load_assets_framework!
|
|
156
|
+
_load_model_framework!
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def _load_view_framework!
|
|
160
|
+
namespace.module_eval %{
|
|
161
|
+
#{ namespace }::View.load!
|
|
162
|
+
}
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def _load_assets_framework!
|
|
166
|
+
application_module.module_eval %{
|
|
167
|
+
#{ application_module }::Assets.load!
|
|
168
|
+
}
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def _load_model_framework!
|
|
172
|
+
return unless _load_model_framework?
|
|
173
|
+
|
|
174
|
+
application_module.module_eval %{
|
|
175
|
+
#{ application_module }::Model.load!
|
|
176
|
+
}
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def _load_model_framework?
|
|
180
|
+
if _hanami_model_loaded? && application_module.const_defined?('Model')
|
|
181
|
+
model = application_module.const_get('Model')
|
|
182
|
+
model.configuration.adapter
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def _hanami_model_loaded?
|
|
187
|
+
defined?(Hanami::Model)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def _hanami_mailer_loaded?
|
|
191
|
+
defined?(Hanami::Mailer)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def load_configuration_load_paths!
|
|
195
|
+
configuration.load_paths.load!(configuration.root)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def load_rack!
|
|
199
|
+
_assign_routes_to_application_module!
|
|
200
|
+
|
|
201
|
+
return if application.is_a?(Class)
|
|
202
|
+
_assign_rendering_policy!
|
|
203
|
+
_assign_rack_routes!
|
|
204
|
+
_load_rack_middleware!
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def _assign_rendering_policy!
|
|
208
|
+
application.renderer = RenderingPolicy.new(configuration)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def _assign_rack_routes!
|
|
212
|
+
application.routes = application_routes
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def _load_rack_middleware!
|
|
216
|
+
configuration.middleware.load!(application, namespace)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def _assign_routes_to_application_module!
|
|
220
|
+
unless application_module.const_defined?('Routes')
|
|
221
|
+
routes = Hanami::Routes.new(application_routes)
|
|
222
|
+
application_module.const_set('Routes', routes)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def application_module
|
|
227
|
+
@application_module ||= Utils::Class.load!(
|
|
228
|
+
Utils::String.new(application.name).namespace
|
|
229
|
+
)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def application_routes
|
|
233
|
+
resolver = Hanami::Routing::EndpointResolver.new(pattern: configuration.controller_pattern, namespace: namespace)
|
|
234
|
+
default_app = Hanami::Routing::Default.new
|
|
235
|
+
Hanami::Router.new(
|
|
236
|
+
parsers: configuration.body_parsers,
|
|
237
|
+
resolver: resolver,
|
|
238
|
+
default_app: default_app,
|
|
239
|
+
scheme: configuration.scheme,
|
|
240
|
+
host: configuration.host,
|
|
241
|
+
port: configuration.port,
|
|
242
|
+
prefix: configuration.path_prefix,
|
|
243
|
+
force_ssl: configuration.force_ssl,
|
|
244
|
+
&configuration.routes
|
|
245
|
+
)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def namespace
|
|
249
|
+
configuration.namespace || application_module
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def load_initializers!
|
|
253
|
+
Dir["#{configuration.root}/config/initializers/**/*.rb"].each do |file|
|
|
254
|
+
require file
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|