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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/FEATURES.md +13 -0
  4. data/README.md +28 -1
  5. data/hanami.gemspec +20 -17
  6. data/lib/hanami.rb +106 -7
  7. data/lib/hanami/action/routing_helpers.rb +2 -2
  8. data/lib/hanami/app.rb +72 -0
  9. data/lib/hanami/application.rb +144 -183
  10. data/lib/hanami/application_configuration.rb +1541 -0
  11. data/lib/hanami/application_name.rb +2 -2
  12. data/lib/hanami/application_namespace.rb +12 -0
  13. data/lib/hanami/assets/asset.rb +3 -1
  14. data/lib/hanami/assets/static.rb +3 -9
  15. data/lib/hanami/cli.rb +10 -7
  16. data/lib/hanami/cli_sub_commands/assets.rb +1 -9
  17. data/lib/hanami/cli_sub_commands/generate.rb +16 -0
  18. data/lib/hanami/commands/apps.rb +4 -0
  19. data/lib/hanami/commands/assets/precompile.rb +6 -19
  20. data/lib/hanami/commands/command.rb +64 -0
  21. data/lib/hanami/commands/console.rb +37 -26
  22. data/lib/hanami/commands/db/apply.rb +4 -2
  23. data/lib/hanami/commands/db/console.rb +11 -27
  24. data/lib/hanami/commands/db/create.rb +4 -2
  25. data/lib/hanami/commands/db/drop.rb +4 -2
  26. data/lib/hanami/commands/db/migrate.rb +11 -5
  27. data/lib/hanami/commands/db/prepare.rb +4 -2
  28. data/lib/hanami/commands/db/version.rb +4 -2
  29. data/lib/hanami/commands/generate/abstract.rb +5 -7
  30. data/lib/hanami/commands/generate/action.rb +18 -6
  31. data/lib/hanami/commands/generate/app.rb +15 -2
  32. data/lib/hanami/commands/generate/migration.rb +3 -2
  33. data/lib/hanami/commands/generate/model.rb +4 -3
  34. data/lib/hanami/commands/generate/secret_token.rb +31 -0
  35. data/lib/hanami/commands/new/abstract.rb +14 -5
  36. data/lib/hanami/commands/new/container.rb +1 -0
  37. data/lib/hanami/commands/routes.rb +5 -22
  38. data/lib/hanami/commands/server.rb +14 -142
  39. data/lib/hanami/components.rb +107 -0
  40. data/lib/hanami/components/app/assets.rb +55 -0
  41. data/lib/hanami/components/app/controller.rb +69 -0
  42. data/lib/hanami/components/app/logger.rb +30 -0
  43. data/lib/hanami/components/app/routes.rb +51 -0
  44. data/lib/hanami/components/app/view.rb +40 -0
  45. data/lib/hanami/components/component.rb +166 -0
  46. data/lib/hanami/components/components.rb +366 -0
  47. data/lib/hanami/components/routes_inspector.rb +70 -0
  48. data/lib/hanami/config/load_paths.rb +7 -6
  49. data/lib/hanami/config/mapper.rb +1 -1
  50. data/lib/hanami/config/security.rb +0 -8
  51. data/lib/hanami/configuration.rb +27 -1697
  52. data/lib/hanami/env.rb +67 -0
  53. data/lib/hanami/environment.rb +31 -21
  54. data/lib/hanami/environment_application_configurations.rb +30 -0
  55. data/lib/hanami/frameworks.rb +1 -0
  56. data/lib/hanami/generators/app/application.rb.tt +2 -2
  57. data/lib/hanami/generators/application/app/Gemfile.tt +3 -1
  58. data/lib/hanami/generators/application/app/config/application.rb.tt +2 -2
  59. data/lib/hanami/generators/application/app/gitignore_with_sqlite.tt +3 -0
  60. data/lib/hanami/generators/application/app/lib/app_name.rb.tt +4 -25
  61. data/lib/hanami/generators/application/app/spec_helper.rb.minitest.tt +1 -1
  62. data/lib/hanami/generators/application/app/spec_helper.rb.rspec.tt +1 -1
  63. data/lib/hanami/generators/application/container/Gemfile.tt +3 -1
  64. data/lib/hanami/generators/application/container/capybara.rb.rspec.tt +1 -1
  65. data/lib/hanami/generators/application/container/config.ru.tt +1 -1
  66. data/lib/hanami/generators/application/container/config/environment.rb.tt +35 -1
  67. data/lib/hanami/generators/application/container/features_helper.rb.minitest.tt +1 -1
  68. data/lib/hanami/generators/application/container/gitignore_with_sqlite.tt +3 -0
  69. data/lib/hanami/generators/application/container/lib/project.rb.tt +1 -57
  70. data/lib/hanami/generators/application/container/spec_helper.rb.minitest.tt +1 -1
  71. data/lib/hanami/generators/application/container/spec_helper.rb.rspec.tt +2 -3
  72. data/lib/hanami/generators/database_config.rb +8 -11
  73. data/lib/hanami/generators/model/entity.rb.tt +1 -2
  74. data/lib/hanami/generators/model/repository.rb.tt +1 -2
  75. data/lib/hanami/generators/template_engine.rb +8 -3
  76. data/lib/hanami/generators/test_framework.rb +4 -3
  77. data/lib/hanami/middleware.rb +41 -21
  78. data/lib/hanami/rake_helper.rb +6 -8
  79. data/lib/hanami/server.rb +43 -33
  80. data/lib/hanami/static.rb +2 -2
  81. data/lib/hanami/version.rb +35 -1
  82. data/lib/hanami/welcome.rb +4 -5
  83. metadata +68 -42
  84. data/lib/hanami/commands/db/abstract.rb +0 -19
  85. data/lib/hanami/config/configure.rb +0 -17
  86. data/lib/hanami/config/mapping.rb +0 -12
  87. data/lib/hanami/container.rb +0 -71
  88. data/lib/hanami/generators/application/container/gitignore_with_db.tt +0 -4
  89. data/lib/hanami/loader.rb +0 -257
  90. data/lib/hanami/repositories/car_repository.rb +0 -3
  91. data/lib/hanami/repositories/name_repository.rb +0 -3
@@ -1,9 +1,11 @@
1
- require 'hanami/commands/db/abstract'
1
+ require 'hanami/commands/command'
2
2
 
3
3
  module Hanami
4
4
  module Commands
5
5
  class DB
6
- class Create < Abstract
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/db/abstract'
1
+ require 'hanami/commands/command'
2
2
 
3
3
  module Hanami
4
4
  module Commands
5
5
  class DB
6
- class Drop < Abstract
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/db/abstract'
1
+ require 'hanami/commands/command'
2
2
 
3
3
  module Hanami
4
4
  module Commands
5
5
  class DB
6
- class Migrate < Abstract
7
- def initialize(environment, version)
8
- super(environment)
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: @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/db/abstract'
1
+ require 'hanami/commands/command'
2
2
 
3
3
  module Hanami
4
4
  module Commands
5
5
  class DB
6
- class Prepare < Abstract
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/db/abstract'
1
+ require 'hanami/commands/command'
2
2
 
3
3
  module Hanami
4
4
  module Commands
5
5
  class DB
6
- class Version < Abstract
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 = Pathname.pwd
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
- Dir.glob(applications_path.join('/*')).map do |name|
171
- File.basename(name)
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
- raise ArgumentError.new("Unknown app: `#{ @application_name.downcase }'. Please specify one of (#{ existing_apps }) as application name")
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
- existing_http_methods = Hanami::Routing::Route::VALID_HTTP_VERBS
206
- raise ArgumentError.new("Unknown HTTP method '#{http_method}', please use one of #{ existing_http_methods.join('/') }.")
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
- super(options)
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::Container.configure do/ do |match|
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
- environment.require_application_environment
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
- Dir.glob("#{Hanami::Model.configuration.migrations}/[0-9]*_#{underscored_name}.rb").first
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
- @model_name = Utils::String.new(model_name).classify
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
- Utils::String.new(model_name).underscore
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.6'
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(project_name)
39
- Dir.chdir(project_name) do
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.filesystem? ? 'gitignore_with_db.tt' : 'gitignore.tt'
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
- "~> #{Hanami::VERSION.scan(/\A\d{1,2}\.\d{1,2}/).first}"
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
@@ -20,6 +20,7 @@ module Hanami
20
20
  {
21
21
  project_name: project_name,
22
22
  hanami_head: hanami_head?,
23
+ code_reloading: code_reloading?,
23
24
  test: test_framework.framework,
24
25
  database: database_config.type,
25
26
  database_config: database_config.to_hash,
@@ -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
- # @param options [Hash] Environment's options
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 app.routes.inspector.to_s
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 'rack'
2
- require 'hanami/server'
1
+ require 'hanami/commands/command'
3
2
 
4
3
  module Hanami
5
4
  module Commands
6
- class Server
7
-
8
- # Message text when Shotgun enabled but interpreter does not support `fork`
9
- #
10
- # @since 0.8.0
11
- # @api private
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
- @options = options
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
- @strategy
15
+ require 'hanami/server'
16
+ @server = Hanami::Server.new
94
17
  end
95
18
 
96
- def preload_applications!
97
- Hanami::Environment.new(@options).require_application_environment
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
- # Check if ruby interpreter supports `fork`
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
- # Cross-platform way of finding an executable in the $PATH.
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