hanami 1.0.0.beta2 → 1.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/FEATURES.md +2 -0
  4. data/LICENSE.md +1 -1
  5. data/README.md +1 -1
  6. data/hanami.gemspec +8 -8
  7. data/lib/hanami.rb +0 -5
  8. data/lib/hanami/action/csrf_protection.rb +35 -0
  9. data/lib/hanami/app.rb +1 -1
  10. data/lib/hanami/application.rb +2 -0
  11. data/lib/hanami/application_configuration.rb +1 -12
  12. data/lib/hanami/application_name.rb +8 -2
  13. data/lib/hanami/application_namespace.rb +2 -0
  14. data/lib/hanami/assets/asset.rb +1 -0
  15. data/lib/hanami/cli.rb +7 -0
  16. data/lib/hanami/cli_base.rb +3 -0
  17. data/lib/hanami/cli_sub_commands/assets.rb +2 -0
  18. data/lib/hanami/cli_sub_commands/db.rb +15 -2
  19. data/lib/hanami/cli_sub_commands/destroy.rb +6 -0
  20. data/lib/hanami/cli_sub_commands/generate.rb +7 -2
  21. data/lib/hanami/commands/assets/precompile.rb +4 -0
  22. data/lib/hanami/commands/command.rb +13 -0
  23. data/lib/hanami/commands/console.rb +6 -0
  24. data/lib/hanami/commands/db/apply.rb +3 -0
  25. data/lib/hanami/commands/db/console.rb +7 -0
  26. data/lib/hanami/commands/db/create.rb +3 -0
  27. data/lib/hanami/commands/db/drop.rb +3 -0
  28. data/lib/hanami/commands/db/migrate.rb +5 -0
  29. data/lib/hanami/commands/db/prepare.rb +3 -0
  30. data/lib/hanami/commands/db/version.rb +3 -0
  31. data/lib/hanami/commands/generate/abstract.rb +13 -1
  32. data/lib/hanami/commands/generate/action.rb +21 -0
  33. data/lib/hanami/commands/generate/app.rb +21 -0
  34. data/lib/hanami/commands/generate/mailer.rb +16 -3
  35. data/lib/hanami/commands/generate/migration.rb +13 -2
  36. data/lib/hanami/commands/generate/model.rb +14 -1
  37. data/lib/hanami/commands/generate/secret_token.rb +6 -0
  38. data/lib/hanami/commands/new/abstract.rb +39 -4
  39. data/lib/hanami/commands/new/app.rb +15 -0
  40. data/lib/hanami/commands/new/container.rb +14 -0
  41. data/lib/hanami/commands/routes.rb +2 -0
  42. data/lib/hanami/commands/server.rb +4 -0
  43. data/lib/hanami/components/app/assets.rb +4 -0
  44. data/lib/hanami/components/app/controller.rb +4 -0
  45. data/lib/hanami/components/app/routes.rb +6 -0
  46. data/lib/hanami/components/app/view.rb +4 -0
  47. data/lib/hanami/components/component.rb +2 -0
  48. data/lib/hanami/components/components.rb +12 -5
  49. data/lib/hanami/components/routes_inspector.rb +2 -0
  50. data/lib/hanami/config/cookies.rb +1 -0
  51. data/lib/hanami/config/framework_configuration.rb +1 -0
  52. data/lib/hanami/config/load_paths.rb +4 -0
  53. data/lib/hanami/config/mapper.rb +11 -0
  54. data/lib/hanami/config/routes.rb +4 -0
  55. data/lib/hanami/config/security.rb +2 -0
  56. data/lib/hanami/config/sessions.rb +6 -0
  57. data/lib/hanami/configuration.rb +102 -0
  58. data/lib/hanami/environment.rb +13 -0
  59. data/lib/hanami/environment_application_configurations.rb +7 -0
  60. data/lib/hanami/generators/app/application.rb.tt +31 -23
  61. data/lib/hanami/generators/app/favicon.ico +0 -0
  62. data/lib/hanami/generators/database_config.rb +19 -1
  63. data/lib/hanami/generators/generatable.rb +13 -0
  64. data/lib/hanami/generators/generator.rb +8 -0
  65. data/lib/hanami/generators/template_engine.rb +9 -0
  66. data/lib/hanami/generators/test_framework.rb +12 -0
  67. data/lib/hanami/hanamirc.rb +2 -0
  68. data/lib/hanami/mailer/glue.rb +1 -0
  69. data/lib/hanami/middleware.rb +24 -0
  70. data/lib/hanami/rendering_policy.rb +15 -0
  71. data/lib/hanami/routes.rb +14 -12
  72. data/lib/hanami/routing/default.rb +7 -0
  73. data/lib/hanami/server.rb +6 -0
  74. data/lib/hanami/version.rb +1 -1
  75. data/lib/hanami/views/default.rb +3 -0
  76. data/lib/hanami/views/default_template_finder.rb +2 -0
  77. data/lib/hanami/views/null_view.rb +2 -0
  78. data/lib/hanami/welcome.rb +7 -0
  79. metadata +18 -19
  80. data/lib/hanami/root.rb +0 -7
@@ -2,6 +2,8 @@ require 'ipaddr'
2
2
  require 'hanami/utils/string'
3
3
 
4
4
  module Hanami
5
+ # @since 0.2.0
6
+ # @api private
5
7
  module Config
6
8
  # Sessions configuration
7
9
  #
@@ -82,6 +84,8 @@ module Hanami
82
84
  end
83
85
  end
84
86
 
87
+ # @since 0.2.0
88
+ # @api private
85
89
  def domain
86
90
  domain = @configuration.host
87
91
  if !BLACKLISTED_DOMAINS.include?(domain) && !ip_address?(domain)
@@ -89,6 +93,8 @@ module Hanami
89
93
  end
90
94
  end
91
95
 
96
+ # @since 0.2.0
97
+ # @api private
92
98
  def ip_address?(string)
93
99
  !!IPAddr.new(string) rescue false
94
100
  end
@@ -5,25 +5,65 @@ require 'hanami/utils/class'
5
5
  require 'hanami/utils/string'
6
6
 
7
7
  module Hanami
8
+ # @api private
8
9
  class Configuration
10
+ # @api private
9
11
  class App < SimpleDelegator
12
+ # @api private
10
13
  attr_reader :path_prefix
11
14
 
15
+ # @api private
12
16
  def initialize(app, path_prefix)
13
17
  super(app)
14
18
  @path_prefix = path_prefix
15
19
  end
16
20
  end
17
21
 
22
+ # @api private
18
23
  def initialize(&blk)
19
24
  @settings = Concurrent::Map.new
20
25
  instance_eval(&blk)
21
26
  end
22
27
 
28
+ # Mount a Hanami::Application or a Rack app
29
+ #
30
+ # @param app [#call] an application compatible with Rack SPEC
31
+ # @param options [Hash] a set of options
32
+ # @option :at [String] options the mount point
33
+ #
34
+ # @since 0.9.0
35
+ #
36
+ # @example
37
+ # # config/environment.rb
38
+ # # ...
39
+ # Hanami.configure do
40
+ # mount Web::Application, at: '/'
41
+ #
42
+ # # ...
43
+ # end
23
44
  def mount(app, options)
24
45
  mounted[app] = App.new(app, options.fetch(:at))
25
46
  end
26
47
 
48
+ # Configure database
49
+ #
50
+ # @param blk [Proc] the database configuration
51
+ #
52
+ # @see Hanami::Model.configure
53
+ #
54
+ # @example
55
+ # # config/environment.rb
56
+ # # ...
57
+ # Hanami.configure do
58
+ # model do
59
+ # adapter :sql, ENV['DATABASE_URL']
60
+ #
61
+ # migrations 'db/migrations'
62
+ # schema 'db/schema.sql'
63
+ # end
64
+ #
65
+ # # ...
66
+ # end
27
67
  def model(&blk)
28
68
  if block_given?
29
69
  settings.put_if_absent(:model, blk)
@@ -32,20 +72,61 @@ module Hanami
32
72
  end
33
73
  end
34
74
 
75
+ # Configure mailer
76
+ #
77
+ # @param blk [Proc] the mailer configuration
78
+ #
79
+ # @see Hanami::Mailer.configure
80
+ #
81
+ # @example
82
+ # # config/environment.rb
83
+ # # ...
84
+ # Hanami.configure do
85
+ # mailer do
86
+ # root 'lib/bookshelf/mailers'
87
+ #
88
+ # # See http://hanamirb.org/guides/mailers/delivery
89
+ # delivery :test
90
+ # end
91
+ #
92
+ # # ...
93
+ # end
35
94
  def mailer(&blk)
36
95
  settings.put_if_absent(:mailer, blk)
37
96
  end
38
97
 
98
+ # @since 0.9.0
99
+ # @api private
39
100
  def mounted
40
101
  settings.fetch_or_store(:mounted, {})
41
102
  end
42
103
 
104
+ # @since 0.9.0
105
+ # @api private
43
106
  def apps
44
107
  mounted.each_pair do |klass, app|
45
108
  yield(app) if klass.ancestors.include?(Hanami::Application)
46
109
  end
47
110
  end
48
111
 
112
+ # Configure logger
113
+ #
114
+ # @since 1.0.0.beta1
115
+ #
116
+ # @param options [Hash] a set of options
117
+ #
118
+ # @see Hanami.logger
119
+ # @see Hanami::Logger
120
+ #
121
+ # @example
122
+ # # config/environment.rb
123
+ # # ...
124
+ # Hanami.configure do
125
+ # # ...
126
+ # environment :development do
127
+ # logger level: :debug
128
+ # end
129
+ # end
49
130
  def logger(options = nil)
50
131
  if options.nil?
51
132
  settings.fetch(:logger, nil)
@@ -54,12 +135,33 @@ module Hanami
54
135
  end
55
136
  end
56
137
 
138
+ # Configure settings for the current environment
139
+ # @since 1.0.0.beta1
140
+ #
141
+ # @param name [Symbol] the name of the Hanami environment
142
+ #
143
+ # @see Hanami.env
144
+ #
145
+ # @example Configure Logging for Different Environments
146
+ # # config/environment.rb
147
+ # # ...
148
+ # Hanami.configure do
149
+ # # ...
150
+ # environment :development do
151
+ # logger level: :debug
152
+ # end
153
+ #
154
+ # environment :production do
155
+ # logger level: :info, formatter: :json
156
+ # end
157
+ # end
57
158
  def environment(name)
58
159
  yield if ENV['HANAMI_ENV'] == name.to_s
59
160
  end
60
161
 
61
162
  private
62
163
 
164
+ # @api private
63
165
  attr_reader :settings
64
166
  end
65
167
  end
@@ -157,6 +157,8 @@ module Hanami
157
157
  # @see Hanami::Commands::Server
158
158
  # @see Hanami::Environment#config
159
159
  #
160
+ # @api private
161
+ #
160
162
  # @example Define ENV variables from .env
161
163
  #
162
164
  # # % tree .
@@ -219,6 +221,7 @@ module Hanami
219
221
  # @return [String] the current environment
220
222
  #
221
223
  # @since 0.1.0
224
+ # @api private
222
225
  #
223
226
  # @see Hanami::Environment::DEFAULT_ENV
224
227
  def environment
@@ -226,6 +229,7 @@ module Hanami
226
229
  end
227
230
 
228
231
  # @since 0.3.1
232
+ # @api private
229
233
  #
230
234
  # @see Hanami.env?(name)
231
235
  def environment?(*names)
@@ -262,6 +266,7 @@ module Hanami
262
266
  # @return [Pathname] application's root
263
267
  #
264
268
  # @since 0.2.0
269
+ # @api private
265
270
  def root
266
271
  @root ||= Pathname.new(Dir.pwd)
267
272
  end
@@ -282,6 +287,7 @@ module Hanami
282
287
  # @return [Pathname] the config directory
283
288
  #
284
289
  # @since 0.2.0
290
+ # @api private
285
291
  #
286
292
  # @see Hanami::Environment::DEFAULT_CONFIG
287
293
  # @see Hanami::Environment#root
@@ -304,6 +310,7 @@ module Hanami
304
310
  # @return [String] the HTTP host name
305
311
  #
306
312
  # @since 0.1.0
313
+ # @api private
307
314
  #
308
315
  # @see Hanami::Environment::DEFAULT_HOST
309
316
  # @see Hanami::Environment::LISTEN_ALL_HOST
@@ -325,6 +332,7 @@ module Hanami
325
332
  # @return [Integer] the default port
326
333
  #
327
334
  # @since 0.1.0
335
+ # @api private
328
336
  #
329
337
  # @see Hanami::Environment::DEFAULT_PORT
330
338
  def port
@@ -357,6 +365,7 @@ module Hanami
357
365
  # @return [Pathname] path to the Rack configuration file
358
366
  #
359
367
  # @since 0.2.0
368
+ # @api private
360
369
  def rackup
361
370
  root.join(@options.fetch(:rackup) { DEFAULT_RACKUP })
362
371
  end
@@ -376,6 +385,7 @@ module Hanami
376
385
  # @return [Pathname] path to applications
377
386
  #
378
387
  # @since 0.1.0
388
+ # @api private
379
389
  #
380
390
  # @see Hanami::Environment::DEFAULT_ENVIRONMENT_CONFIG
381
391
  def env_config
@@ -394,6 +404,7 @@ module Hanami
394
404
  require project_environment_configuration.to_s # if project_environment_configuration.exist?
395
405
  end
396
406
 
407
+ # @api private
397
408
  alias require_project_environment require_application_environment
398
409
 
399
410
  # Determine if activate code reloading for the current environment while
@@ -411,6 +422,7 @@ module Hanami
411
422
  # @return [TrueClass,FalseClass] the result of the check
412
423
  #
413
424
  # @since 0.2.0
425
+ # @api private
414
426
  #
415
427
  # @see Hanami::Commands::Server
416
428
  # @see Hanami::Environment::CODE_RELOADING
@@ -483,6 +495,7 @@ module Hanami
483
495
 
484
496
  private
485
497
 
498
+ # @api private
486
499
  attr_reader :env
487
500
 
488
501
  # @since 0.1.0
@@ -1,16 +1,21 @@
1
1
  module Hanami
2
+ # @api private
2
3
  class EnvironmentApplicationConfigurations
4
+ # @api private
3
5
  ALL = :all
4
6
 
7
+ # @api private
5
8
  def initialize
6
9
  @configurations = Concurrent::Hash.new { |k, v| k[v] = [] }
7
10
  end
8
11
 
12
+ # @api private
9
13
  def add(environment, &blk)
10
14
  env = (environment || ALL).to_sym
11
15
  configurations[env].push(blk)
12
16
  end
13
17
 
18
+ # @api private
14
19
  def each(environment, &blk)
15
20
  configurations.each do |env, blks|
16
21
  next unless matching_env?(environment, env)
@@ -20,8 +25,10 @@ module Hanami
20
25
 
21
26
  private
22
27
 
28
+ # @api private
23
29
  attr_reader :configurations
24
30
 
31
+ # @api private
25
32
  def matching_env?(environment, env)
26
33
  environment.to_sym == env ||
27
34
  env == ALL
@@ -13,7 +13,9 @@ module <%= config[:classified_app_name] %>
13
13
  #
14
14
  root __dir__
15
15
 
16
- # Relative load paths where this application will recursively load the code.
16
+ # Relative load paths where this application will recursively load the
17
+ # code.
18
+ #
17
19
  # When you add new directories, remember to add them here.
18
20
  #
19
21
  load_paths << [
@@ -47,8 +49,10 @@ module <%= config[:classified_app_name] %>
47
49
  # host 'example.org'
48
50
 
49
51
  # URI port used by the routing system to generate absolute URLs
50
- # Argument: An object coercible to integer, default to 80 if the scheme is http and 443 if it's https
51
- # This SHOULD be configured only in case the application listens to that non standard ports
52
+ # Argument: An object coercible to integer, defaults to 80 if the scheme
53
+ # is http and 443 if it's https
54
+ #
55
+ # This should only be configured if app listens to non-standard ports
52
56
  #
53
57
  # port 443
54
58
 
@@ -56,13 +60,16 @@ module <%= config[:classified_app_name] %>
56
60
  # Argument: boolean to toggle the feature
57
61
  # A Hash with options
58
62
  #
59
- # Options: :domain - The domain (String - nil by default, not required)
60
- # :path - Restrict cookies to a relative URI (String - nil by default)
61
- # :max_age - Cookies expiration expressed in seconds (Integer - nil by default)
62
- # :secure - Restrict cookies to secure connections
63
- # (Boolean - Automatically set on true if currently using a secure connection)
64
- # See #scheme and #ssl?
65
- # :httponly - Prevent JavaScript access (Boolean - true by default)
63
+ # Options:
64
+ # :domain - The domain (String - nil by default, not required)
65
+ # :path - Restrict cookies to a relative URI
66
+ # (String - nil by default)
67
+ # :max_age - Cookies expiration expressed in seconds
68
+ # (Integer - nil by default)
69
+ # :secure - Restrict cookies to secure connections
70
+ # (Boolean - Automatically true when using HTTPS)
71
+ # See #scheme and #ssl?
72
+ # :httponly - Prevent JavaScript access (Boolean - true by default)
66
73
  #
67
74
  # cookies true
68
75
  # or
@@ -81,24 +88,25 @@ module <%= config[:classified_app_name] %>
81
88
  # middleware.use Rack::Protection
82
89
 
83
90
  # Default format for the requests that don't specify an HTTP_ACCEPT header
84
- # Argument: A symbol representation of a mime type, default to :html
91
+ # Argument: A symbol representation of a mime type, defaults to :html
85
92
  #
86
93
  # default_request_format :html
87
94
 
88
- # Default format for responses that doesn't take into account the request format
89
- # Argument: A symbol representation of a mime type, default to :html
95
+ # Default format for responses that don't consider the request format
96
+ # Argument: A symbol representation of a mime type, defaults to :html
90
97
  #
91
98
  # default_response_format :html
92
99
 
93
100
  # HTTP Body parsers
94
101
  # Parse non GET responses body for a specific mime type
95
- # Argument: Symbol, which represent the format of the mime type (only `:json` is supported)
102
+ # Argument: Symbol, which represent the format of the mime type
103
+ # (only `:json` is supported)
96
104
  # Object, the parser
97
105
  #
98
106
  # body_parsers :json
99
107
 
100
108
  # When it's true and the router receives a non-encrypted request (http),
101
- # it redirects to the secure equivalent resource (https). Default disabled.
109
+ # it redirects to the secure equivalent (https). Disabled by default.
102
110
  #
103
111
  # force_ssl true
104
112
 
@@ -180,8 +188,8 @@ module <%= config[:classified_app_name] %>
180
188
  #
181
189
  security.x_content_type_options 'nosniff'
182
190
 
183
- # X-XSS-Protection is a HTTP header to determine the behavior of the browser
184
- # in case an XSS attack is detected.
191
+ # X-XSS-Protection is a HTTP header to determine the behavior of the
192
+ # browser in case an XSS attack is detected.
185
193
  #
186
194
  # Read more at:
187
195
  #
@@ -190,16 +198,16 @@ module <%= config[:classified_app_name] %>
190
198
  #
191
199
  security.x_xss_protection '1; mode=block'
192
200
 
193
- # Content-Security-Policy (CSP) is a HTTP header supported by modern browsers.
194
- # It determines trusted sources of execution for dynamic contents
195
- # (JavaScript) or other web related assets: stylesheets, images, fonts,
196
- # plugins, etc.
201
+ # Content-Security-Policy (CSP) is a HTTP header supported by modern
202
+ # browsers. It determines trusted sources of execution for dynamic
203
+ # contents (JavaScript) or other web related assets: stylesheets, images,
204
+ # fonts, plugins, etc.
197
205
  #
198
206
  # Web applications can send this header to mitigate Cross Site Scripting
199
207
  # (XSS) attacks.
200
208
  #
201
- # The default value allows images, scripts, AJAX, fonts and CSS from the same
202
- # origin, and does not allow any other resources to load (eg object,
209
+ # The default value allows images, scripts, AJAX, fonts and CSS from the
210
+ # same origin, and does not allow any other resources to load (eg object,
203
211
  # frame, media, etc).
204
212
  #
205
213
  # Inline JavaScript is NOT allowed. To enable it, please use:
Binary file
@@ -1,9 +1,12 @@
1
1
  require 'shellwords'
2
2
 
3
3
  module Hanami
4
+ # @api private
4
5
  module Generators
6
+ # @api private
5
7
  class DatabaseConfig
6
8
 
9
+ # @api private
7
10
  SUPPORTED_ENGINES = {
8
11
  'mysql' => { type: :sql, mri: 'mysql2', jruby: 'jdbc-mysql' },
9
12
  'mysql2' => { type: :sql, mri: 'mysql2', jruby: 'jdbc-mysql' },
@@ -13,10 +16,15 @@ module Hanami
13
16
  'sqlite3' => { type: :sql, mri: 'sqlite3', jruby: 'jdbc-sqlite3' }
14
17
  }.freeze
15
18
 
19
+ # @api private
16
20
  DEFAULT_ENGINE = 'sqlite'.freeze
17
21
 
18
- attr_reader :engine, :name
22
+ # @api private
23
+ attr_reader :engine
24
+ # @api private
25
+ attr_reader :name
19
26
 
27
+ # @api private
20
28
  def initialize(engine, name)
21
29
  @engine = engine
22
30
  @name = name
@@ -27,6 +35,7 @@ module Hanami
27
35
  end
28
36
  end
29
37
 
38
+ # @api private
30
39
  def to_hash
31
40
  {
32
41
  gem: gem,
@@ -35,28 +44,34 @@ module Hanami
35
44
  }
36
45
  end
37
46
 
47
+ # @api private
38
48
  def type
39
49
  SUPPORTED_ENGINES[engine][:type]
40
50
  end
41
51
 
52
+ # @api private
42
53
  def sql?
43
54
  type == :sql
44
55
  end
45
56
 
57
+ # @api private
46
58
  def sqlite?
47
59
  ['sqlite', 'sqlite3'].include?(engine)
48
60
  end
49
61
 
50
62
  private
51
63
 
64
+ # @api private
52
65
  def platform
53
66
  Hanami::Utils.jruby? ? :jruby : :mri
54
67
  end
55
68
 
69
+ # @api private
56
70
  def platform_prefix
57
71
  'jdbc:'.freeze if Hanami::Utils.jruby?
58
72
  end
59
73
 
74
+ # @api private
60
75
  def uri
61
76
  {
62
77
  development: environment_uri(:development),
@@ -64,10 +79,12 @@ module Hanami
64
79
  }
65
80
  end
66
81
 
82
+ # @api private
67
83
  def gem
68
84
  SUPPORTED_ENGINES[engine][platform]
69
85
  end
70
86
 
87
+ # @api private
71
88
  def base_uri
72
89
  case engine
73
90
  when 'mysql', 'mysql2'
@@ -83,6 +100,7 @@ module Hanami
83
100
  end
84
101
  end
85
102
 
103
+ # @api private
86
104
  def environment_uri(environment)
87
105
  case engine
88
106
  when 'sqlite', 'sqlite3'