hanami 0.8.0 → 0.9.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 +23 -0
- data/FEATURES.md +13 -0
- data/README.md +28 -1
- data/hanami.gemspec +20 -17
- data/lib/hanami.rb +106 -7
- data/lib/hanami/action/routing_helpers.rb +2 -2
- data/lib/hanami/app.rb +72 -0
- data/lib/hanami/application.rb +144 -183
- data/lib/hanami/application_configuration.rb +1541 -0
- data/lib/hanami/application_name.rb +2 -2
- data/lib/hanami/application_namespace.rb +12 -0
- data/lib/hanami/assets/asset.rb +3 -1
- data/lib/hanami/assets/static.rb +3 -9
- data/lib/hanami/cli.rb +10 -7
- data/lib/hanami/cli_sub_commands/assets.rb +1 -9
- data/lib/hanami/cli_sub_commands/generate.rb +16 -0
- data/lib/hanami/commands/apps.rb +4 -0
- data/lib/hanami/commands/assets/precompile.rb +6 -19
- data/lib/hanami/commands/command.rb +64 -0
- data/lib/hanami/commands/console.rb +37 -26
- data/lib/hanami/commands/db/apply.rb +4 -2
- data/lib/hanami/commands/db/console.rb +11 -27
- data/lib/hanami/commands/db/create.rb +4 -2
- data/lib/hanami/commands/db/drop.rb +4 -2
- data/lib/hanami/commands/db/migrate.rb +11 -5
- data/lib/hanami/commands/db/prepare.rb +4 -2
- data/lib/hanami/commands/db/version.rb +4 -2
- data/lib/hanami/commands/generate/abstract.rb +5 -7
- data/lib/hanami/commands/generate/action.rb +18 -6
- data/lib/hanami/commands/generate/app.rb +15 -2
- data/lib/hanami/commands/generate/migration.rb +3 -2
- data/lib/hanami/commands/generate/model.rb +4 -3
- data/lib/hanami/commands/generate/secret_token.rb +31 -0
- data/lib/hanami/commands/new/abstract.rb +14 -5
- data/lib/hanami/commands/new/container.rb +1 -0
- data/lib/hanami/commands/routes.rb +5 -22
- data/lib/hanami/commands/server.rb +14 -142
- data/lib/hanami/components.rb +107 -0
- data/lib/hanami/components/app/assets.rb +55 -0
- data/lib/hanami/components/app/controller.rb +69 -0
- data/lib/hanami/components/app/logger.rb +30 -0
- data/lib/hanami/components/app/routes.rb +51 -0
- data/lib/hanami/components/app/view.rb +40 -0
- data/lib/hanami/components/component.rb +166 -0
- data/lib/hanami/components/components.rb +366 -0
- data/lib/hanami/components/routes_inspector.rb +70 -0
- data/lib/hanami/config/load_paths.rb +7 -6
- data/lib/hanami/config/mapper.rb +1 -1
- data/lib/hanami/config/security.rb +0 -8
- data/lib/hanami/configuration.rb +27 -1697
- data/lib/hanami/env.rb +67 -0
- data/lib/hanami/environment.rb +31 -21
- data/lib/hanami/environment_application_configurations.rb +30 -0
- data/lib/hanami/frameworks.rb +1 -0
- data/lib/hanami/generators/app/application.rb.tt +2 -2
- data/lib/hanami/generators/application/app/Gemfile.tt +3 -1
- data/lib/hanami/generators/application/app/config/application.rb.tt +2 -2
- data/lib/hanami/generators/application/app/gitignore_with_sqlite.tt +3 -0
- data/lib/hanami/generators/application/app/lib/app_name.rb.tt +4 -25
- data/lib/hanami/generators/application/app/spec_helper.rb.minitest.tt +1 -1
- data/lib/hanami/generators/application/app/spec_helper.rb.rspec.tt +1 -1
- data/lib/hanami/generators/application/container/Gemfile.tt +3 -1
- data/lib/hanami/generators/application/container/capybara.rb.rspec.tt +1 -1
- data/lib/hanami/generators/application/container/config.ru.tt +1 -1
- data/lib/hanami/generators/application/container/config/environment.rb.tt +35 -1
- data/lib/hanami/generators/application/container/features_helper.rb.minitest.tt +1 -1
- data/lib/hanami/generators/application/container/gitignore_with_sqlite.tt +3 -0
- data/lib/hanami/generators/application/container/lib/project.rb.tt +1 -57
- data/lib/hanami/generators/application/container/spec_helper.rb.minitest.tt +1 -1
- data/lib/hanami/generators/application/container/spec_helper.rb.rspec.tt +2 -3
- data/lib/hanami/generators/database_config.rb +8 -11
- data/lib/hanami/generators/model/entity.rb.tt +1 -2
- data/lib/hanami/generators/model/repository.rb.tt +1 -2
- data/lib/hanami/generators/template_engine.rb +8 -3
- data/lib/hanami/generators/test_framework.rb +4 -3
- data/lib/hanami/middleware.rb +41 -21
- data/lib/hanami/rake_helper.rb +6 -8
- data/lib/hanami/server.rb +43 -33
- data/lib/hanami/static.rb +2 -2
- data/lib/hanami/version.rb +35 -1
- data/lib/hanami/welcome.rb +4 -5
- metadata +68 -42
- data/lib/hanami/commands/db/abstract.rb +0 -19
- data/lib/hanami/config/configure.rb +0 -17
- data/lib/hanami/config/mapping.rb +0 -12
- data/lib/hanami/container.rb +0 -71
- data/lib/hanami/generators/application/container/gitignore_with_db.tt +0 -4
- data/lib/hanami/loader.rb +0 -257
- data/lib/hanami/repositories/car_repository.rb +0 -3
- data/lib/hanami/repositories/name_repository.rb +0 -3
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
require 'hanami/commands/
|
|
1
|
+
require 'hanami/commands/command'
|
|
2
2
|
|
|
3
3
|
module Hanami
|
|
4
4
|
module Commands
|
|
5
5
|
class DB
|
|
6
|
-
class Create <
|
|
6
|
+
class Create < Command
|
|
7
|
+
requires 'model.configuration'
|
|
8
|
+
|
|
7
9
|
def start
|
|
8
10
|
require 'hanami/model/migrator'
|
|
9
11
|
Hanami::Model::Migrator.create
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
require 'hanami/commands/
|
|
1
|
+
require 'hanami/commands/command'
|
|
2
2
|
|
|
3
3
|
module Hanami
|
|
4
4
|
module Commands
|
|
5
5
|
class DB
|
|
6
|
-
class Drop <
|
|
6
|
+
class Drop < Command
|
|
7
|
+
requires 'model.configuration'
|
|
8
|
+
|
|
7
9
|
def start
|
|
8
10
|
require 'hanami/model/migrator'
|
|
9
11
|
Hanami::Model::Migrator.drop
|
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
require 'hanami/commands/
|
|
1
|
+
require 'hanami/commands/command'
|
|
2
2
|
|
|
3
3
|
module Hanami
|
|
4
4
|
module Commands
|
|
5
5
|
class DB
|
|
6
|
-
class Migrate <
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
class Migrate < Command
|
|
7
|
+
requires 'model.sql'
|
|
8
|
+
|
|
9
|
+
def initialize(options, version)
|
|
10
|
+
super(options)
|
|
9
11
|
@version = version
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def start
|
|
13
15
|
require 'hanami/model/migrator'
|
|
14
|
-
Hanami::Model::Migrator.migrate(version:
|
|
16
|
+
Hanami::Model::Migrator.migrate(version: version)
|
|
15
17
|
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
attr_reader :version
|
|
16
22
|
end
|
|
17
23
|
end
|
|
18
24
|
end
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
require 'hanami/commands/
|
|
1
|
+
require 'hanami/commands/command'
|
|
2
2
|
|
|
3
3
|
module Hanami
|
|
4
4
|
module Commands
|
|
5
5
|
class DB
|
|
6
|
-
class Prepare <
|
|
6
|
+
class Prepare < Command
|
|
7
|
+
requires 'model.sql'
|
|
8
|
+
|
|
7
9
|
def start
|
|
8
10
|
require 'hanami/model/migrator'
|
|
9
11
|
Hanami::Model::Migrator.prepare
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
require 'hanami/commands/
|
|
1
|
+
require 'hanami/commands/command'
|
|
2
2
|
|
|
3
3
|
module Hanami
|
|
4
4
|
module Commands
|
|
5
5
|
class DB
|
|
6
|
-
class Version <
|
|
6
|
+
class Version < Command
|
|
7
|
+
requires 'model.configuration'
|
|
8
|
+
|
|
7
9
|
def start
|
|
8
10
|
require 'hanami/model/migrator'
|
|
9
11
|
puts Hanami::Model::Migrator.version
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'hanami/environment'
|
|
2
|
+
require 'hanami/commands/command'
|
|
2
3
|
require 'hanami/generators/generatable'
|
|
3
4
|
require 'hanami/generators/test_framework'
|
|
4
5
|
require 'hanami/generators/template_engine'
|
|
@@ -8,17 +9,19 @@ require 'hanami/utils/string'
|
|
|
8
9
|
module Hanami
|
|
9
10
|
module Commands
|
|
10
11
|
class Generate
|
|
11
|
-
class Abstract
|
|
12
|
+
class Abstract < Commands::Command
|
|
12
13
|
|
|
13
14
|
include Hanami::Generators::Generatable
|
|
14
15
|
|
|
15
16
|
attr_reader :options, :target_path
|
|
16
17
|
|
|
17
18
|
def initialize(options)
|
|
19
|
+
super
|
|
20
|
+
|
|
18
21
|
@options = Hanami::Utils::Hash.new(options).symbolize!
|
|
19
22
|
assert_options!
|
|
20
23
|
|
|
21
|
-
@target_path =
|
|
24
|
+
@target_path = Hanami.root
|
|
22
25
|
end
|
|
23
26
|
|
|
24
27
|
def template_source_path
|
|
@@ -40,11 +43,6 @@ module Hanami
|
|
|
40
43
|
@hanamirc ||= Hanamirc.new(target_path)
|
|
41
44
|
end
|
|
42
45
|
|
|
43
|
-
def environment
|
|
44
|
-
@environment ||= Hanami::Environment.new(options)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
|
|
48
46
|
def template_engine
|
|
49
47
|
@template_engine ||= Hanami::Generators::TemplateEngine.new(hanamirc, options[:template])
|
|
50
48
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'hanami/commands/generate/abstract'
|
|
2
2
|
require 'hanami/routing/route'
|
|
3
|
+
require 'hanami/utils/blank'
|
|
3
4
|
|
|
4
5
|
module Hanami
|
|
5
6
|
module Commands
|
|
@@ -81,6 +82,7 @@ module Hanami
|
|
|
81
82
|
assert_application_name!
|
|
82
83
|
assert_controller_class_name!
|
|
83
84
|
assert_action_name!
|
|
85
|
+
assert_url!
|
|
84
86
|
assert_http_method!
|
|
85
87
|
end
|
|
86
88
|
|
|
@@ -167,8 +169,8 @@ module Hanami
|
|
|
167
169
|
# @since 0.5.0
|
|
168
170
|
# @api private
|
|
169
171
|
def known_application_names
|
|
170
|
-
|
|
171
|
-
File.basename(
|
|
172
|
+
applications_path.children.map do |app|
|
|
173
|
+
::File.basename(app)
|
|
172
174
|
end
|
|
173
175
|
end
|
|
174
176
|
|
|
@@ -193,8 +195,18 @@ module Hanami
|
|
|
193
195
|
def assert_application_name!
|
|
194
196
|
return unless environment.container?
|
|
195
197
|
if argument_blank?(@application_name) || !application_path.exist?
|
|
196
|
-
existing_apps = known_application_names.join('
|
|
197
|
-
|
|
198
|
+
existing_apps = known_application_names.map { |name| "`#{name}'" }.join(' ')
|
|
199
|
+
warn "`#{@application_name.downcase}' is not a valid APPLICATION_NAME. Please specify one of: #{existing_apps}"
|
|
200
|
+
exit(1)
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# @since 0.9.0
|
|
205
|
+
# @api private
|
|
206
|
+
def assert_url!
|
|
207
|
+
if options.key?(:url) && Hanami::Utils::Blank.blank?(options[:url])
|
|
208
|
+
warn "`#{options[:url]}' is not a valid URL"
|
|
209
|
+
exit(1)
|
|
198
210
|
end
|
|
199
211
|
end
|
|
200
212
|
|
|
@@ -202,8 +214,8 @@ module Hanami
|
|
|
202
214
|
# @api private
|
|
203
215
|
def assert_http_method!
|
|
204
216
|
if !Hanami::Routing::Route::VALID_HTTP_VERBS.include?(http_method.upcase)
|
|
205
|
-
|
|
206
|
-
|
|
217
|
+
warn "`#{http_method.upcase}' is not a valid HTTP method. Please use one of: #{Hanami::Routing::Route::VALID_HTTP_VERBS.map { |verb| "`#{verb}'" }.join(" ")}"
|
|
218
|
+
exit(1)
|
|
207
219
|
end
|
|
208
220
|
end
|
|
209
221
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'hanami/commands/generate/abstract'
|
|
2
2
|
require 'hanami/application_name'
|
|
3
|
+
require 'hanami/utils/blank'
|
|
3
4
|
require 'securerandom'
|
|
4
5
|
|
|
5
6
|
module Hanami
|
|
@@ -10,9 +11,14 @@ module Hanami
|
|
|
10
11
|
attr_reader :base_path
|
|
11
12
|
|
|
12
13
|
def initialize(options, application_name)
|
|
13
|
-
|
|
14
|
+
@environment = Hanami::Environment.new(options)
|
|
15
|
+
@options = Hanami::Utils::Hash.new(options).symbolize!
|
|
16
|
+
assert_options!
|
|
17
|
+
|
|
18
|
+
@target_path = Hanami.root
|
|
14
19
|
assert_application_name!(application_name)
|
|
15
20
|
assert_architecture!
|
|
21
|
+
assert_application_base_url!
|
|
16
22
|
|
|
17
23
|
@application_name = ApplicationName.new(application_name)
|
|
18
24
|
@base_path = Pathname.pwd
|
|
@@ -65,7 +71,7 @@ module Hanami
|
|
|
65
71
|
end
|
|
66
72
|
|
|
67
73
|
def add_mount_app
|
|
68
|
-
generator.inject_into_file base_path.join('config/environment.rb'), after: /Hanami
|
|
74
|
+
generator.inject_into_file base_path.join('config/environment.rb'), after: /Hanami.configure do/ do |match|
|
|
69
75
|
"\n mount #{ classified_app_name }::Application, at: '#{ application_base_url }'"
|
|
70
76
|
end
|
|
71
77
|
end
|
|
@@ -114,6 +120,13 @@ module Hanami
|
|
|
114
120
|
raise ArgumentError.new('App generator is only available for container architecture.')
|
|
115
121
|
end
|
|
116
122
|
end
|
|
123
|
+
|
|
124
|
+
def assert_application_base_url!
|
|
125
|
+
if options.key?(:application_base_url) && Utils::Blank.blank?(options[:application_base_url])
|
|
126
|
+
warn "`' is not a valid URL"
|
|
127
|
+
exit(1)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
117
130
|
end
|
|
118
131
|
end
|
|
119
132
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'hanami/commands/generate/abstract'
|
|
2
|
+
require 'hanami/utils/file_list'
|
|
2
3
|
|
|
3
4
|
module Hanami
|
|
4
5
|
module Commands
|
|
@@ -27,7 +28,7 @@ module Hanami
|
|
|
27
28
|
@name = name
|
|
28
29
|
@underscored_name = Utils::String.new(@name).underscore
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
Components.resolve('model.configuration')
|
|
31
32
|
assert_migration_name!
|
|
32
33
|
end
|
|
33
34
|
|
|
@@ -42,7 +43,7 @@ module Hanami
|
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
def existing_migration_path
|
|
45
|
-
|
|
46
|
+
Utils::FileList["#{Hanami::Model.configuration.migrations}/[0-9]*_#{underscored_name}.rb"].first
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def new_migration_path
|
|
@@ -5,11 +5,12 @@ module Hanami
|
|
|
5
5
|
class Generate
|
|
6
6
|
class Model < Abstract
|
|
7
7
|
|
|
8
|
-
attr_reader :model_name
|
|
8
|
+
attr_reader :input, :model_name
|
|
9
9
|
|
|
10
10
|
def initialize(options, model_name)
|
|
11
11
|
super(options)
|
|
12
|
-
@
|
|
12
|
+
@input = Utils::String.new(model_name).underscore
|
|
13
|
+
@model_name = Utils::String.new(@input).classify
|
|
13
14
|
|
|
14
15
|
assert_model_name!
|
|
15
16
|
end
|
|
@@ -88,7 +89,7 @@ module Hanami
|
|
|
88
89
|
# @since 0.5.0
|
|
89
90
|
# @api private
|
|
90
91
|
def model_name_underscored
|
|
91
|
-
|
|
92
|
+
input
|
|
92
93
|
end
|
|
93
94
|
|
|
94
95
|
# @since 0.8.0
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'hanami/commands/generate/abstract'
|
|
2
|
+
require 'hanami/application_name'
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
module Commands
|
|
7
|
+
class Generate
|
|
8
|
+
class SecretToken
|
|
9
|
+
|
|
10
|
+
def initialize(application_name)
|
|
11
|
+
@application_name = application_name
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def start
|
|
15
|
+
if Hanami::Utils::Blank.blank?(@application_name)
|
|
16
|
+
puts SecureRandom.hex(32)
|
|
17
|
+
else
|
|
18
|
+
puts "Set the following environment variable to provide the secret token:"
|
|
19
|
+
puts %(#{ upcase_app_name }_SESSIONS_SECRET="#{ SecureRandom.hex(32) }")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
def upcase_app_name
|
|
25
|
+
@application_name.upcase
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -4,6 +4,7 @@ require 'hanami/generators/database_config'
|
|
|
4
4
|
require 'hanami/generators/generatable'
|
|
5
5
|
require 'hanami/generators/test_framework'
|
|
6
6
|
require 'hanami/generators/template_engine'
|
|
7
|
+
require 'hanami/utils'
|
|
7
8
|
require 'hanami/utils/hash'
|
|
8
9
|
|
|
9
10
|
module Hanami
|
|
@@ -28,15 +29,15 @@ module Hanami
|
|
|
28
29
|
assert_name!
|
|
29
30
|
assert_architecture!
|
|
30
31
|
|
|
31
|
-
@hanami_model_version = '~> 0.
|
|
32
|
+
@hanami_model_version = '~> 0.7'
|
|
32
33
|
@database_config = Hanami::Generators::DatabaseConfig.new(options[:database], project_name)
|
|
33
34
|
@test_framework = Hanami::Generators::TestFramework.new(hanamirc, @options[:test])
|
|
34
35
|
@template_engine = Hanami::Generators::TemplateEngine.new(hanamirc, @options[:template])
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def start
|
|
38
|
-
FileUtils.mkdir_p(
|
|
39
|
-
Dir.chdir(
|
|
39
|
+
FileUtils.mkdir_p(project_directory)
|
|
40
|
+
Dir.chdir(project_directory) do
|
|
40
41
|
@target_path = Pathname.pwd
|
|
41
42
|
|
|
42
43
|
super
|
|
@@ -62,7 +63,7 @@ module Hanami
|
|
|
62
63
|
def add_git_templates
|
|
63
64
|
return if git_dir_present?
|
|
64
65
|
|
|
65
|
-
source = database_config.
|
|
66
|
+
source = database_config.sqlite? ? 'gitignore_with_sqlite.tt' : 'gitignore.tt'
|
|
66
67
|
target = '.gitignore'
|
|
67
68
|
add_mapping(source, target)
|
|
68
69
|
end
|
|
@@ -75,6 +76,10 @@ module Hanami
|
|
|
75
76
|
ApplicationName.new(real_project_name)
|
|
76
77
|
end
|
|
77
78
|
|
|
79
|
+
def project_directory
|
|
80
|
+
@name == '.' ? '.' : project_name
|
|
81
|
+
end
|
|
82
|
+
|
|
78
83
|
def target
|
|
79
84
|
Pathname.new('.')
|
|
80
85
|
end
|
|
@@ -90,13 +95,17 @@ module Hanami
|
|
|
90
95
|
end
|
|
91
96
|
|
|
92
97
|
def hanami_version
|
|
93
|
-
|
|
98
|
+
Hanami::Version.gem_requirement
|
|
94
99
|
end
|
|
95
100
|
|
|
96
101
|
def hanami_head?
|
|
97
102
|
options.fetch(:hanami_head, false)
|
|
98
103
|
end
|
|
99
104
|
|
|
105
|
+
def code_reloading?
|
|
106
|
+
!Hanami::Utils.jruby?
|
|
107
|
+
end
|
|
108
|
+
|
|
100
109
|
def architecture
|
|
101
110
|
options.fetch(:architecture, DEFAULT_ARCHITECTURE)
|
|
102
111
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'hanami/commands/command'
|
|
2
|
+
|
|
1
3
|
module Hanami
|
|
2
4
|
module Commands
|
|
3
5
|
# Display application/container routes.
|
|
@@ -8,33 +10,14 @@ module Hanami
|
|
|
8
10
|
#
|
|
9
11
|
# @since 0.1.0
|
|
10
12
|
# @api private
|
|
11
|
-
class Routes
|
|
12
|
-
|
|
13
|
-
#
|
|
14
|
-
# @since 0.1.0
|
|
15
|
-
# @see Hanami::Environment#initialize
|
|
16
|
-
def initialize(options)
|
|
17
|
-
@environment = Hanami::Environment.new(options)
|
|
18
|
-
@environment.require_application_environment
|
|
19
|
-
end
|
|
13
|
+
class Routes < Command
|
|
14
|
+
requires 'routes.inspector'
|
|
20
15
|
|
|
21
16
|
# Display to STDOUT application routes
|
|
22
17
|
#
|
|
23
18
|
# @since 0.1.0
|
|
24
19
|
def start
|
|
25
|
-
puts
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
private
|
|
29
|
-
|
|
30
|
-
# @since 0.1.0
|
|
31
|
-
# @api private
|
|
32
|
-
def app
|
|
33
|
-
if @environment.container?
|
|
34
|
-
Hanami::Container.new
|
|
35
|
-
else
|
|
36
|
-
Hanami::Application.applications.first.new
|
|
37
|
-
end
|
|
20
|
+
puts requirements['routes.inspector'].inspect
|
|
38
21
|
end
|
|
39
22
|
end
|
|
40
23
|
end
|
|
@@ -1,156 +1,28 @@
|
|
|
1
|
-
require '
|
|
2
|
-
require 'hanami/server'
|
|
1
|
+
require 'hanami/commands/command'
|
|
3
2
|
|
|
4
3
|
module Hanami
|
|
5
4
|
module Commands
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
WARNING_MESSAGE = 'Your platform doesn\'t support code reloading.'.freeze
|
|
13
|
-
|
|
14
|
-
ENTR_EXECUTE_COMMAND = "find %{paths} -type f | entr -r bundle exec hanami rackserver %{args}".freeze
|
|
15
|
-
|
|
16
|
-
attr_reader :server
|
|
5
|
+
# Server command (`hanami server`)
|
|
6
|
+
#
|
|
7
|
+
# @since 0.1.0
|
|
8
|
+
# @api private
|
|
9
|
+
class Server < Command
|
|
10
|
+
requires 'code_reloading'
|
|
17
11
|
|
|
18
12
|
def initialize(options)
|
|
19
|
-
|
|
20
|
-
detect_strategy!
|
|
21
|
-
prepare_server!
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def start
|
|
25
|
-
preload_applications!
|
|
26
|
-
|
|
27
|
-
case @strategy
|
|
28
|
-
when :entr
|
|
29
|
-
exec ENTR_EXECUTE_COMMAND % {paths: project_paths, args: server_options}
|
|
30
|
-
when :shotgun
|
|
31
|
-
Shotgun.enable_copy_on_write
|
|
32
|
-
Shotgun.preload
|
|
33
|
-
@server.start
|
|
34
|
-
when :rackup
|
|
35
|
-
@server.start
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
|
|
41
|
-
def server_options
|
|
42
|
-
_options = @options.dup
|
|
43
|
-
_options.delete(:code_reloading)
|
|
44
|
-
_options.inject([]) {|res, (k, v)| res << "--#{k}=#{v}" ; res}.join(" ")
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def project_paths
|
|
48
|
-
applications = Hanami::Environment.new.container? ? 'apps' : 'app'
|
|
49
|
-
"#{ applications } config db lib"
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def prepare_server!
|
|
53
|
-
case @strategy
|
|
54
|
-
when :rackup
|
|
55
|
-
@server = Hanami::Server.new(@options)
|
|
56
|
-
when :shotgun
|
|
57
|
-
@server = Hanami::Server.new(@options)
|
|
58
|
-
@server.app = Shotgun::Loader.new(@server.rackup_config)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Determine server strategy
|
|
63
|
-
#
|
|
64
|
-
# In order to decide the value, it looks up the following sources:
|
|
65
|
-
#
|
|
66
|
-
# * CLI option `code_reloading`
|
|
67
|
-
#
|
|
68
|
-
# If those are missing it falls back to the following defaults:
|
|
69
|
-
#
|
|
70
|
-
# * :shotgun for development and if Shotgun enabled and `fork supported
|
|
71
|
-
# * :entr for development and Shotgun disabled but `entr` installed
|
|
72
|
-
# * :rackup for all other cases
|
|
73
|
-
#
|
|
74
|
-
# @return [:shotgun,:entr, :rackup] the result of the check
|
|
75
|
-
#
|
|
76
|
-
# @since 0.8.0
|
|
77
|
-
#
|
|
78
|
-
# @see Hanami::Environment::CODE_RELOADING
|
|
79
|
-
def detect_strategy!
|
|
80
|
-
@strategy = :rackup
|
|
81
|
-
if Hanami::Environment.new(@options).code_reloading?
|
|
82
|
-
if shotgun_enabled?
|
|
83
|
-
if fork_supported?
|
|
84
|
-
@strategy = :shotgun
|
|
85
|
-
else
|
|
86
|
-
puts WARNING_MESSAGE
|
|
87
|
-
end
|
|
88
|
-
elsif entr_enabled?
|
|
89
|
-
@strategy = :entr
|
|
90
|
-
end
|
|
91
|
-
end
|
|
13
|
+
super(options)
|
|
92
14
|
|
|
93
|
-
|
|
15
|
+
require 'hanami/server'
|
|
16
|
+
@server = Hanami::Server.new
|
|
94
17
|
end
|
|
95
18
|
|
|
96
|
-
def
|
|
97
|
-
|
|
98
|
-
Hanami::Application.preload!
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# Check if entr(1) is installed
|
|
102
|
-
#
|
|
103
|
-
# @return [Boolean]
|
|
104
|
-
#
|
|
105
|
-
# @since 0.8.0
|
|
106
|
-
# @api private
|
|
107
|
-
def entr_enabled?
|
|
108
|
-
!!which('entr')
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
# Check if Shotgun is enabled
|
|
113
|
-
#
|
|
114
|
-
# @return [Boolean]
|
|
115
|
-
#
|
|
116
|
-
# @since 0.8.0
|
|
117
|
-
# @api private
|
|
118
|
-
def shotgun_enabled?
|
|
119
|
-
begin
|
|
120
|
-
require 'shotgun'
|
|
121
|
-
true
|
|
122
|
-
rescue LoadError
|
|
123
|
-
false
|
|
124
|
-
end
|
|
19
|
+
def start
|
|
20
|
+
server.start
|
|
125
21
|
end
|
|
126
22
|
|
|
127
|
-
|
|
128
|
-
#
|
|
129
|
-
# @return [Boolean]
|
|
130
|
-
#
|
|
131
|
-
# @since 0.8.0
|
|
132
|
-
# @api private
|
|
133
|
-
def fork_supported?
|
|
134
|
-
Kernel.respond_to?(:fork)
|
|
135
|
-
end
|
|
23
|
+
protected
|
|
136
24
|
|
|
137
|
-
|
|
138
|
-
#
|
|
139
|
-
# Usage:
|
|
140
|
-
# which('ruby') #=> /usr/bin/ruby
|
|
141
|
-
#
|
|
142
|
-
# @since 0.8.0
|
|
143
|
-
# @api private
|
|
144
|
-
def which(cmd)
|
|
145
|
-
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
|
146
|
-
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
|
147
|
-
exts.each { |ext|
|
|
148
|
-
exe = File.join(path, "#{cmd}#{ext}")
|
|
149
|
-
return exe if File.executable?(exe) && !File.directory?(exe)
|
|
150
|
-
}
|
|
151
|
-
end
|
|
152
|
-
return nil
|
|
153
|
-
end
|
|
25
|
+
attr_reader :server
|
|
154
26
|
end
|
|
155
27
|
end
|
|
156
28
|
end
|