lotusrb 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/FEATURES.md +17 -0
  4. data/README.md +16 -355
  5. data/lib/lotus.rb +0 -1
  6. data/lib/lotus/action/csrf_protection.rb +167 -0
  7. data/lib/lotus/application.rb +3 -1
  8. data/lib/lotus/cli.rb +14 -13
  9. data/lib/lotus/commands/console.rb +1 -1
  10. data/lib/lotus/commands/db.rb +102 -0
  11. data/lib/lotus/commands/db/abstract.rb +15 -0
  12. data/lib/lotus/commands/db/apply.rb +14 -0
  13. data/lib/lotus/commands/db/console.rb +1 -5
  14. data/lib/lotus/commands/db/create.rb +14 -0
  15. data/lib/lotus/commands/db/drop.rb +14 -0
  16. data/lib/lotus/commands/db/migrate.rb +19 -0
  17. data/lib/lotus/commands/db/prepare.rb +14 -0
  18. data/lib/lotus/commands/db/version.rb +14 -0
  19. data/lib/lotus/commands/generate.rb +20 -20
  20. data/lib/lotus/commands/new.rb +1 -0
  21. data/lib/lotus/commands/routes.rb +1 -2
  22. data/lib/lotus/configuration.rb +29 -0
  23. data/lib/lotus/container.rb +19 -3
  24. data/lib/lotus/environment.rb +62 -9
  25. data/lib/lotus/frameworks.rb +1 -0
  26. data/lib/lotus/generators/action.rb +46 -10
  27. data/lib/lotus/generators/action/action_spec.minitest.tt +1 -1
  28. data/lib/lotus/generators/action/action_spec.rspec.tt +1 -1
  29. data/lib/lotus/generators/action/view_spec.minitest.tt +2 -1
  30. data/lib/lotus/generators/action/view_spec.rspec.tt +2 -1
  31. data/lib/lotus/generators/app.rb +39 -0
  32. data/lib/lotus/generators/app/.gitkeep +1 -0
  33. data/lib/lotus/generators/application/app.rb +184 -0
  34. data/lib/lotus/generators/application/app/.env.development.tt +3 -0
  35. data/lib/lotus/generators/application/app/.env.test.tt +3 -0
  36. data/lib/lotus/generators/application/{container/config → app}/.env.tt +0 -0
  37. data/lib/lotus/generators/application/app/.gitkeep +1 -0
  38. data/lib/lotus/generators/application/app/Gemfile.tt +35 -0
  39. data/lib/lotus/generators/application/app/Rakefile.minitest.tt +10 -0
  40. data/lib/lotus/generators/application/app/Rakefile.rspec.tt +5 -0
  41. data/lib/lotus/generators/application/app/apps/.gitkeep.tt +1 -0
  42. data/lib/lotus/generators/application/app/capybara.rb.rspec.tt +8 -0
  43. data/lib/lotus/generators/application/app/config.ru.tt +3 -0
  44. data/lib/lotus/generators/application/app/config/application.rb.tt +227 -0
  45. data/lib/lotus/generators/application/app/config/environment.rb.tt +5 -0
  46. data/lib/lotus/generators/application/app/config/routes.rb.tt +2 -0
  47. data/lib/lotus/generators/application/app/db/.gitkeep +1 -0
  48. data/lib/lotus/generators/application/app/features_helper.rb.minitest.tt +11 -0
  49. data/lib/lotus/generators/application/app/features_helper.rb.rspec.tt +12 -0
  50. data/lib/lotus/generators/application/app/gitignore.tt +2 -0
  51. data/lib/lotus/generators/application/app/lib/app_name.rb.tt +47 -0
  52. data/lib/lotus/generators/application/app/lib/chirp/entities/.gitkeep +1 -0
  53. data/lib/lotus/generators/application/app/lib/chirp/repositories/.gitkeep +1 -0
  54. data/lib/lotus/generators/application/app/lib/config/mapping.rb.tt +7 -0
  55. data/lib/lotus/generators/application/app/lotusrc.tt +3 -0
  56. data/lib/lotus/generators/application/app/rspec.rspec.tt +2 -0
  57. data/lib/lotus/generators/application/app/schema.sql.tt +0 -0
  58. data/lib/lotus/generators/application/app/spec_helper.rb.minitest.tt +7 -0
  59. data/lib/lotus/generators/application/app/spec_helper.rb.rspec.tt +100 -0
  60. data/lib/lotus/generators/application/app/templates/application.html.erb.tt +9 -0
  61. data/lib/lotus/generators/application/app/views/application_layout.rb.tt +7 -0
  62. data/lib/lotus/generators/application/container.rb +37 -13
  63. data/lib/lotus/generators/application/container/{config/.env.development.tt → .env.development.tt} +0 -0
  64. data/lib/lotus/generators/application/container/{config/.env.test.tt → .env.test.tt} +0 -0
  65. data/lib/lotus/generators/application/container/.env.tt +1 -0
  66. data/lib/lotus/generators/application/container/lib/app_name.rb.tt +9 -0
  67. data/lib/lotus/generators/application/container/schema.sql.tt +0 -0
  68. data/lib/lotus/generators/migration.rb +58 -0
  69. data/lib/lotus/generators/migration/migration.rb.tt +4 -0
  70. data/lib/lotus/generators/model.rb +10 -7
  71. data/lib/lotus/generators/slice.rb +4 -12
  72. data/lib/lotus/generators/slice/application.rb.tt +3 -19
  73. data/lib/lotus/generators/slice/config/routes.rb.tt +1 -7
  74. data/lib/lotus/loader.rb +15 -1
  75. data/lib/lotus/lotusrc.rb +8 -3
  76. data/lib/lotus/templates/{welcome.html → welcome.html.erb} +4 -3
  77. data/lib/lotus/version.rb +1 -1
  78. data/lib/lotus/welcome.rb +20 -1
  79. data/lotusrb.gemspec +5 -5
  80. metadata +67 -18
  81. data/lib/lotus/generators/slice/action.rb.tt +0 -8
  82. data/lib/lotus/generators/slice/config/mapping.rb.tt +0 -13
  83. data/lib/lotus/generators/slice/templates/template.html.erb.tt +0 -2
  84. data/lib/lotus/generators/slice/view.rb.tt +0 -5
  85. data/lib/lotus/logger.rb +0 -141
@@ -0,0 +1,14 @@
1
+ require 'lotus/commands/db/abstract'
2
+
3
+ module Lotus
4
+ module Commands
5
+ class DB
6
+ class Prepare < Abstract
7
+ def start
8
+ require 'lotus/model/migrator'
9
+ Lotus::Model::Migrator.prepare
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'lotus/commands/db/abstract'
2
+
3
+ module Lotus
4
+ module Commands
5
+ class DB
6
+ class Version < Abstract
7
+ def start
8
+ require 'lotus/model/migrator'
9
+ puts Lotus::Model::Migrator.version
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -10,8 +10,7 @@ module Lotus
10
10
  # @since 0.3.0
11
11
  # @api private
12
12
  GENERATORS_NAMESPACE = "Lotus::Generators::%s".freeze
13
- APP = 'app'.freeze
14
- SLICE_TYPE = 'slice'.freeze
13
+ APP_ARCHITECTURE = 'app'.freeze
15
14
 
16
15
  # @since 0.3.0
17
16
  # @api private
@@ -20,21 +19,23 @@ module Lotus
20
19
 
21
20
  # @since 0.3.0
22
21
  # @api private
23
- attr_reader :cli, :source, :target, :app, :app_name, :name, :options
22
+ attr_reader :cli, :source, :target, :app, :app_name, :name, :options, :env
24
23
 
25
24
  # @since 0.3.0
26
25
  # @api private
27
26
  def initialize(type, app_name, name, env, cli)
28
27
  @cli = cli
28
+ @env = env
29
29
  @name = name
30
+ @options = env.to_options.merge(cli.options)
31
+
32
+ sanitize_input(app_name, name)
33
+ @type = type
30
34
 
31
- @type = sanitize_type(type)
32
- @app_name = app_name
33
35
  @source = Pathname.new(::File.dirname(__FILE__) + "/../generators/#{ @type }/").realpath
34
36
  @target = Pathname.pwd.realpath
35
37
 
36
38
  @app = Utils::String.new(@app_name).classify
37
- @options = sanitize_app_name_options(app_name).merge(env.to_options.merge(cli.options))
38
39
  end
39
40
 
40
41
  # @since 0.3.0
@@ -49,7 +50,11 @@ module Lotus
49
50
  # @since 0.3.0
50
51
  # @api private
51
52
  def app_root
52
- @app_root ||= Pathname.new([@options[:path], @app_name].join(::File::SEPARATOR))
53
+ @app_root ||= begin
54
+ result = Pathname.new(@options[:apps_path])
55
+ result = result.join(@app_name) if @env.container?
56
+ result
57
+ end
53
58
  end
54
59
 
55
60
  # @since 0.3.0
@@ -74,19 +79,14 @@ module Lotus
74
79
  Utils::Class.load!(GENERATORS_NAMESPACE % class_name).new(self)
75
80
  end
76
81
 
77
- # @since 0.3.1
78
- # @api private
79
- def sanitize_app_name_options(app_name)
80
- {
81
- application: app_name,
82
- application_base_url: "/#{app_name}"
83
- }
84
- end
85
-
86
- # @since 0.3.1
87
- # @api private
88
- def sanitize_type(type)
89
- type == APP ? SLICE_TYPE : type
82
+ def sanitize_input(app_name, name)
83
+ if options[:architecture] == APP_ARCHITECTURE
84
+ @app_name = nil
85
+ @name = app_name
86
+ else
87
+ @app_name = app_name
88
+ @name = name
89
+ end
90
90
  end
91
91
  end
92
92
  end
@@ -1,4 +1,5 @@
1
1
  require 'pathname'
2
+ require 'securerandom'
2
3
  require 'lotus/application_name'
3
4
  require 'lotus/utils/string'
4
5
  require 'lotus/utils/class'
@@ -2,11 +2,10 @@ module Lotus
2
2
  module Commands
3
3
  class Routes
4
4
  def initialize(environment)
5
- @environment = environment
5
+ environment.require_application_environment
6
6
  end
7
7
 
8
8
  def start
9
- require @environment.env_config
10
9
  puts Lotus::Container.new.routes.inspector.to_s
11
10
  end
12
11
  end
@@ -108,6 +108,21 @@ module Lotus
108
108
  @security ||= Config::Security.new
109
109
  end
110
110
 
111
+ # Force ssl redirection if http scheme is set
112
+ #
113
+ # @return [Boolean]
114
+ #
115
+ # @since 0.4.0
116
+ #
117
+ # @see Lotus::Routing::ForceSsl
118
+ def force_ssl(value = nil)
119
+ if value
120
+ @force_ssl = value
121
+ else
122
+ @force_ssl || false
123
+ end
124
+ end
125
+
111
126
  # The root of the application
112
127
  #
113
128
  # By default it returns the current directory, for this reason, **all the
@@ -1627,6 +1642,20 @@ module Lotus
1627
1642
  @view ||= Config::FrameworkConfiguration.new
1628
1643
  end
1629
1644
 
1645
+ # This options is used as a bridge between container and router application.
1646
+ #
1647
+ # @return [String, NilClass] path prefix for routes
1648
+ #
1649
+ # @since 0.4.0
1650
+ # @api private
1651
+ def path_prefix(value = nil)
1652
+ if value.nil?
1653
+ @path_prefix
1654
+ else
1655
+ @path_prefix = value
1656
+ end
1657
+ end
1658
+
1630
1659
  private
1631
1660
  # @since 0.2.0
1632
1661
  # @api private
@@ -3,16 +3,32 @@ require 'lotus/router'
3
3
 
4
4
  module Lotus
5
5
  class Container
6
+ class Router < ::Lotus::Router
7
+ def mount(app, options)
8
+ app = app.new(path_prefix: options.fetch(:at)) if lotus_app?(app)
9
+ super(app, options)
10
+ end
11
+
12
+ private
13
+
14
+ def lotus_app?(app)
15
+ app.ancestors.include? Lotus::Application
16
+ end
17
+ end
18
+
6
19
  attr_reader :routes
7
20
 
8
- def self.configure(&blk)
9
- Mutex.new.synchronize { @@configuration = blk }
21
+ def self.configure(options = {}, &blk)
22
+ Mutex.new.synchronize do
23
+ @@options = options
24
+ @@configuration = blk
25
+ end
10
26
  end
11
27
 
12
28
  def initialize
13
29
  Mutex.new.synchronize do
14
30
  assert_configuration_presence!
15
- @routes = Lotus::Router.new(&@@configuration)
31
+ @routes = Router.new(&@@configuration)
16
32
  end
17
33
  end
18
34
 
@@ -94,6 +94,22 @@ module Lotus
94
94
  # @api private
95
95
  CODE_RELOADING = { 'development' => true }.freeze
96
96
 
97
+ # @since 0.4.0
98
+ # @api private
99
+ CONTAINER = 'container'.freeze
100
+
101
+ # @since 0.4.0
102
+ # @api private
103
+ CONTAINER_PATH = 'apps'.freeze
104
+
105
+ # @since 0.4.0
106
+ # @api private
107
+ APPLICATION = 'app'.freeze
108
+
109
+ # @since 0.4.0
110
+ # @api private
111
+ APPLICATION_PATH = 'app'.freeze
112
+
97
113
  # Initialize a Lotus environment
98
114
  #
99
115
  # It accepts an optional set of configurations from the CLI commands.
@@ -121,17 +137,17 @@ module Lotus
121
137
  #
122
138
  # @example Define ENV variables from .env
123
139
  #
124
- # # % tree config/
125
- # # config
140
+ # # % tree .
141
+ # # .
142
+ # # # ...
126
143
  # # ├── .env
127
- # # ├── .env.development
128
- # # └── environment.rb
144
+ # # └── .env.development
129
145
  #
130
- # # % cat config/.env
146
+ # # % cat .env
131
147
  # # FOO="bar"
132
148
  # # XYZ="yes"
133
149
  #
134
- # # % cat config/.env.development
150
+ # # % cat .env.development
135
151
  # # FOO="ok"
136
152
  #
137
153
  # require 'lotus/environment'
@@ -156,7 +172,7 @@ module Lotus
156
172
  # # the one defined in the parent (eg `FOO` is overwritten). All the
157
173
  # # other settings (eg `XYZ`) will be left untouched.
158
174
  def initialize(options = {})
159
- @options = Lotus::Lotusrc.new(root).read
175
+ @options = Lotus::Lotusrc.new(root, options).read
160
176
  @options.merge! Utils::Hash.new(options).symbolize!
161
177
  @mutex = Mutex.new
162
178
  @mutex.synchronize { set_env_vars! }
@@ -315,6 +331,16 @@ module Lotus
315
331
  root.join(@options.fetch(:environment) { config.join(DEFAULT_ENVIRONMENT_CONFIG) })
316
332
  end
317
333
 
334
+ # Require application environment
335
+ #
336
+ # Eg <tt>require "config/environment"</tt>.
337
+ #
338
+ # @since 0.4.0
339
+ # @api private
340
+ def require_application_environment
341
+ require env_config.to_s
342
+ end
343
+
318
344
  # Determine if activate code reloading for the current environment while
319
345
  # running the server.
320
346
  #
@@ -337,6 +363,32 @@ module Lotus
337
363
  @options.fetch(:code_reloading) { !!CODE_RELOADING[environment] }
338
364
  end
339
365
 
366
+ # @since 0.4.0
367
+ # @api private
368
+ def architecture
369
+ @options.fetch(:architecture) {
370
+ puts "Cannot recognize Lotus architecture, please check `.lotusrc'"
371
+ exit 1
372
+ }
373
+ end
374
+
375
+ # @since 0.4.0
376
+ # @api private
377
+ def container?
378
+ architecture == CONTAINER
379
+ end
380
+
381
+ # @since 0.4.0
382
+ # @api private
383
+ def apps_path
384
+ @options.fetch(:path) {
385
+ case architecture
386
+ when CONTAINER then CONTAINER_PATH
387
+ when APPLICATION then APPLICATION_PATH
388
+ end
389
+ }
390
+ end
391
+
340
392
  # Serialize the most relevant settings into a Hash
341
393
  #
342
394
  # @return [Lotus::Utils::Hash]
@@ -347,6 +399,7 @@ module Lotus
347
399
  @options.merge(
348
400
  environment: environment,
349
401
  env_config: env_config,
402
+ apps_path: apps_path,
350
403
  rackup: rackup,
351
404
  host: host,
352
405
  port: port
@@ -373,8 +426,8 @@ module Lotus
373
426
  # @since 0.2.0
374
427
  # @api private
375
428
  def set_application_env_vars!
376
- Dotenv.load config.join(DEFAULT_DOTENV)
377
- Dotenv.overload config.join(DEFAULT_DOTENV_ENV % environment)
429
+ Dotenv.load root.join(DEFAULT_DOTENV)
430
+ Dotenv.overload root.join(DEFAULT_DOTENV_ENV % environment)
378
431
  end
379
432
 
380
433
  # @since 0.1.0
@@ -2,6 +2,7 @@ require 'lotus/router'
2
2
  require 'lotus/view'
3
3
  require 'lotus/controller'
4
4
  require 'lotus/action/glue'
5
+ require 'lotus/action/csrf_protection'
5
6
 
6
7
  Lotus::Controller.configure do
7
8
  prepare do
@@ -42,12 +42,14 @@ module Lotus
42
42
  assert_action!
43
43
 
44
44
  opts = {
45
- app: app,
46
- controller: @controller_name,
47
- action: @action_name,
48
- action_path: _action_path_without_suffix,
49
- view_path: _view_path_without_suffix,
50
- template_path: _template_path,
45
+ app: app,
46
+ controller: @controller_name,
47
+ action: @action_name,
48
+ action_path: _action_path_without_suffix,
49
+ relative_action_path: _relative_action_path,
50
+ relative_view_path: _relative_view_path,
51
+ view_path: _view_path_without_suffix,
52
+ template_path: _template_path,
51
53
  }
52
54
 
53
55
  test_type = case options[:test]
@@ -98,6 +100,15 @@ module Lotus
98
100
  end
99
101
  end
100
102
 
103
+ def app
104
+ if env.container?
105
+ super
106
+ else
107
+ env.require_application_environment
108
+ Utils::String.new(Lotus::Application.applications.first).namespace
109
+ end
110
+ end
111
+
101
112
  # @since 0.3.0
102
113
  # @api private
103
114
  def generate_route
@@ -108,14 +119,21 @@ module Lotus
108
119
 
109
120
  # Insert at the top of the file
110
121
  cli.insert_into_file _routes_path, before: /\A(.*)/ do
111
- "get '/#{ @controller }', to: '#{ @name }'\n"
122
+ "get '#{ _route_url }', to: '#{ @name }'\n"
112
123
  end
113
124
  end
114
125
 
126
+ # @since 0.4.0
127
+ # @api private
128
+ def _route_url
129
+ options.fetch(:url, "/#{ @controller }")
130
+ end
131
+
115
132
  # @since 0.3.0
116
133
  # @api private
117
134
  def _routes_path
118
- app_root.join("config", "routes#{ SUFFIX }")
135
+ routes_root = env.container? ? app_root : env.root
136
+ routes_root.join("config", "routes#{ SUFFIX }")
119
137
  end
120
138
 
121
139
  # @since 0.3.0
@@ -151,13 +169,31 @@ module Lotus
151
169
  # @since 0.3.0
152
170
  # @api private
153
171
  def _action_spec_path
154
- spec_root.join(app_name, 'controllers', @controller, "#{ @action }_spec#{ SUFFIX }")
172
+ spec_root.join(app_name.to_s, 'controllers', @controller, "#{ @action }_spec#{ SUFFIX }")
155
173
  end
156
174
 
157
175
  # @since 0.3.0
158
176
  # @api private
159
177
  def _view_spec_path
160
- spec_root.join(app_name, 'views', @controller, "#{ @action }_spec#{ SUFFIX }")
178
+ spec_root.join(app_name.to_s, 'views', @controller, "#{ @action }_spec#{ SUFFIX }")
179
+ end
180
+
181
+ # @since 0.4.0
182
+ # @api private
183
+ def _relative_action_path
184
+ result = '../../../'
185
+ result << '../' if env.container?
186
+ result << _action_path_without_suffix.to_s
187
+ result
188
+ end
189
+
190
+ # @since 0.4.0
191
+ # @api private
192
+ def _relative_view_path
193
+ result = '../../../'
194
+ result << '../' if env.container?
195
+ result << _view_path_without_suffix.to_s
196
+ result
161
197
  end
162
198
  end
163
199
  end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require_relative '../../../../<%= config[:action_path] %>'
2
+ require_relative '<%= config[:relative_action_path] %>'
3
3
 
4
4
  describe <%= config[:app] %>::Controllers::<%= config[:controller] %>::<%= config[:action] %> do
5
5
  let(:action) { <%= config[:app] %>::Controllers::<%= config[:controller] %>::<%= config[:action] %>.new }
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require_relative '../../../../<%= config[:action_path] %>'
2
+ require_relative '<%= config[:relative_action_path] %>'
3
3
 
4
4
  describe <%= config[:app] %>::Controllers::<%= config[:controller] %>::<%= config[:action] %> do
5
5
  let(:action) { <%= config[:app] %>::Controllers::<%= config[:controller] %>::<%= config[:action] %>.new }