lotusrb 0.5.0 → 0.6.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 (103) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +57 -14
  3. data/FEATURES.md +21 -0
  4. data/LICENSE.md +1 -1
  5. data/README.md +8 -7
  6. data/bin/lotus +1 -0
  7. data/lib/lotus.rb +6 -0
  8. data/lib/lotus/action/csrf_protection.rb +1 -1
  9. data/lib/lotus/application.rb +4 -4
  10. data/lib/lotus/application_name.rb +8 -6
  11. data/lib/lotus/cli.rb +75 -66
  12. data/lib/lotus/cli_sub_commands/assets.rb +29 -0
  13. data/lib/lotus/{commands → cli_sub_commands}/db.rb +24 -29
  14. data/lib/lotus/cli_sub_commands/destroy.rb +102 -0
  15. data/lib/lotus/cli_sub_commands/generate.rb +127 -0
  16. data/lib/lotus/commands/assets/precompile.rb +35 -0
  17. data/lib/lotus/commands/console.rb +28 -8
  18. data/lib/lotus/commands/db/abstract.rb +6 -2
  19. data/lib/lotus/commands/db/console.rb +5 -5
  20. data/lib/lotus/commands/generate/abstract.rb +63 -0
  21. data/lib/lotus/commands/generate/action.rb +262 -0
  22. data/lib/lotus/commands/generate/app.rb +116 -0
  23. data/lib/lotus/commands/generate/mailer.rb +118 -0
  24. data/lib/lotus/commands/generate/migration.rb +63 -0
  25. data/lib/lotus/commands/generate/model.rb +96 -0
  26. data/lib/lotus/commands/new/abstract.rb +128 -0
  27. data/lib/lotus/commands/new/app.rb +116 -0
  28. data/lib/lotus/commands/new/container.rb +102 -0
  29. data/lib/lotus/commands/routes.rb +19 -2
  30. data/lib/lotus/commands/server.rb +16 -2
  31. data/lib/lotus/config/framework_configuration.rb +13 -1
  32. data/lib/lotus/configuration.rb +24 -76
  33. data/lib/lotus/container.rb +15 -2
  34. data/lib/lotus/environment.rb +43 -4
  35. data/lib/lotus/frameworks.rb +1 -0
  36. data/lib/lotus/generators/action/action_spec.minitest.tt +1 -1
  37. data/lib/lotus/generators/action/action_spec.rspec.tt +1 -1
  38. data/lib/lotus/generators/action/view_spec.minitest.tt +1 -1
  39. data/lib/lotus/generators/action/view_spec.rspec.tt +1 -1
  40. data/lib/lotus/generators/{slice → app}/.gitkeep.tt +0 -0
  41. data/lib/lotus/generators/{slice → app}/application.rb.tt +61 -23
  42. data/lib/lotus/generators/app/config/initializers/.gitkeep +0 -0
  43. data/lib/lotus/generators/{slice → app}/config/routes.rb.tt +0 -0
  44. data/lib/lotus/generators/app/favicon.ico +0 -0
  45. data/lib/lotus/generators/{slice → app}/templates/application.html.erb.tt +2 -1
  46. data/lib/lotus/generators/app/views/application_layout.rb.tt +7 -0
  47. data/lib/lotus/generators/application/app/.env.development.tt +1 -0
  48. data/lib/lotus/generators/application/app/.env.test.tt +1 -0
  49. data/lib/lotus/generators/application/app/Gemfile.tt +1 -0
  50. data/lib/lotus/generators/application/app/Rakefile.minitest.tt +1 -0
  51. data/lib/lotus/generators/application/app/Rakefile.rspec.tt +1 -0
  52. data/lib/lotus/generators/application/app/config/application.rb.tt +56 -18
  53. data/lib/lotus/generators/application/app/config/initializers/.gitkeep +0 -0
  54. data/lib/lotus/generators/application/app/favicon.ico +0 -0
  55. data/lib/lotus/generators/application/app/gitignore.tt +2 -0
  56. data/lib/lotus/generators/application/app/lotusrc.tt +3 -3
  57. data/lib/lotus/generators/application/app/spec_helper.rb.rspec.tt +5 -1
  58. data/lib/lotus/generators/application/app/templates/application.html.erb.tt +1 -0
  59. data/lib/lotus/generators/application/container/.env.development.tt +1 -0
  60. data/lib/lotus/generators/application/container/.env.test.tt +1 -0
  61. data/lib/lotus/generators/application/container/Gemfile.tt +1 -1
  62. data/lib/lotus/generators/application/container/Rakefile.minitest.tt +1 -0
  63. data/lib/lotus/generators/application/container/Rakefile.rspec.tt +1 -0
  64. data/lib/lotus/generators/application/container/config/initializers/.gitkeep +0 -0
  65. data/lib/lotus/generators/application/container/gitignore.tt +2 -0
  66. data/lib/lotus/generators/application/container/lib/chirp/mailers/.gitkeep +0 -0
  67. data/lib/lotus/generators/application/container/lib/chirp/mailers/templates/.gitkeep +0 -0
  68. data/lib/lotus/generators/application/container/lotusrc.tt +3 -3
  69. data/lib/lotus/generators/application/container/spec_helper.rb.rspec.tt +5 -1
  70. data/lib/lotus/generators/database_config.rb +17 -4
  71. data/lib/lotus/generators/generatable.rb +51 -0
  72. data/lib/lotus/generators/generator.rb +35 -0
  73. data/lib/lotus/generators/test_framework.rb +42 -0
  74. data/lib/lotus/loader.rb +43 -0
  75. data/lib/lotus/lotusrc.rb +50 -49
  76. data/lib/lotus/middleware.rb +28 -10
  77. data/lib/lotus/rake_helper.rb +68 -0
  78. data/lib/lotus/rake_tasks.rb +2 -0
  79. data/lib/lotus/rendering_policy.rb +2 -2
  80. data/lib/lotus/repositories/car_repository.rb +3 -0
  81. data/lib/lotus/repositories/name_repository.rb +3 -0
  82. data/lib/lotus/setup.rb +1 -3
  83. data/lib/lotus/static.rb +77 -0
  84. data/lib/lotus/templates/welcome.html.erb +7 -4
  85. data/lib/lotus/version.rb +1 -1
  86. data/lib/lotus/views/default.rb +2 -1
  87. data/lib/lotus/views/default_template_finder.rb +4 -3
  88. data/lotusrb.gemspec +11 -9
  89. metadata +79 -60
  90. data/lib/lotus/commands/generate.rb +0 -97
  91. data/lib/lotus/commands/new.rb +0 -43
  92. data/lib/lotus/config/assets.rb +0 -81
  93. data/lib/lotus/generators/abstract.rb +0 -31
  94. data/lib/lotus/generators/action.rb +0 -235
  95. data/lib/lotus/generators/app.rb +0 -39
  96. data/lib/lotus/generators/app/.gitkeep +0 -1
  97. data/lib/lotus/generators/application/app.rb +0 -129
  98. data/lib/lotus/generators/application/container.rb +0 -111
  99. data/lib/lotus/generators/mailer.rb +0 -112
  100. data/lib/lotus/generators/migration.rb +0 -58
  101. data/lib/lotus/generators/model.rb +0 -90
  102. data/lib/lotus/generators/slice.rb +0 -94
  103. data/lib/lotus/generators/slice/views/application_layout.rb.tt +0 -7
@@ -1,97 +0,0 @@
1
- require 'pathname'
2
- require 'lotus/utils/string'
3
- require 'lotus/utils/class'
4
-
5
- module Lotus
6
- module Commands
7
- # @since 0.3.0
8
- # @api private
9
- class Generate
10
- # @since 0.3.0
11
- # @api private
12
- GENERATORS_NAMESPACE = "Lotus::Generators::%s".freeze
13
- APP_ARCHITECTURE = 'app'.freeze
14
-
15
- # @since 0.3.0
16
- # @api private
17
- class Error < ::StandardError
18
- end
19
-
20
- # @since 0.3.0
21
- # @api private
22
- attr_reader :cli, :source, :target, :app, :app_name, :name, :options, :env
23
-
24
- # @since 0.3.0
25
- # @api private
26
- def initialize(type, app_name, name, env, cli)
27
- @cli = cli
28
- @env = env
29
- @name = name
30
- @options = env.to_options.merge(cli.options)
31
-
32
- sanitize_input(app_name, name)
33
- @type = type
34
-
35
- @source = Pathname.new(::File.dirname(__FILE__) + "/../generators/#{ @type }/").realpath
36
- @target = Pathname.pwd.realpath
37
-
38
- @app = Utils::String.new(@app_name).classify
39
- end
40
-
41
- # @since 0.3.0
42
- # @api private
43
- def start
44
- generator.start
45
- rescue Error => e
46
- puts e.message
47
- exit 1
48
- end
49
-
50
- # @since 0.3.0
51
- # @api private
52
- def app_root
53
- @app_root ||= begin
54
- result = Pathname.new(@options[:apps_path])
55
- result = result.join(@app_name) if @env.container?
56
- result
57
- end
58
- end
59
-
60
- # @since 0.3.0
61
- # @api private
62
- def spec_root
63
- @spec_root ||= Pathname.new('spec')
64
- end
65
-
66
- # @since 0.3.1
67
- # @api private
68
- def model_root
69
- @model_root ||= Pathname.new(['lib', ::File.basename(Dir.getwd)]
70
- .join(::File::SEPARATOR))
71
- end
72
-
73
- # @since 0.5.0
74
- # @api private
75
- alias_method :core_root, :model_root
76
-
77
- private
78
- # @since 0.3.0
79
- # @api private
80
- def generator
81
- require "lotus/generators/#{ @type }"
82
- class_name = Utils::String.new(@type).classify
83
- Utils::Class.load!(GENERATORS_NAMESPACE % class_name).new(self)
84
- end
85
-
86
- def sanitize_input(app_name, name)
87
- if options[:architecture] == APP_ARCHITECTURE
88
- @app_name = nil
89
- @name = app_name
90
- else
91
- @app_name = app_name
92
- @name = name
93
- end
94
- end
95
- end
96
- end
97
- end
@@ -1,43 +0,0 @@
1
- require 'pathname'
2
- require 'securerandom'
3
- require 'lotus/application_name'
4
- require 'lotus/utils/string'
5
- require 'lotus/utils/class'
6
-
7
- module Lotus
8
- module Commands
9
- class New
10
- GENERATORS_NAMESPACE = "Lotus::Generators::Application::%s".freeze
11
-
12
- attr_reader :app_name, :source, :target, :cli, :options
13
-
14
- def initialize(app_name_or_path, environment, cli)
15
- @app_name = ApplicationName.new(_get_real_app_name(app_name_or_path))
16
- @options = environment.to_options
17
- @arch = @options.fetch(:architecture)
18
-
19
- @target = Pathname.pwd.join(@options.fetch(:path, app_name_or_path))
20
- @source = Pathname.new(@options.fetch(:source) { ::File.dirname(__FILE__) + '/../generators/application/' }).join(@arch)
21
-
22
- @cli = cli
23
-
24
- require "lotus/generators/application/#{ @arch }"
25
- command = Utils::String.new(@arch).classify
26
- @command = Utils::Class.load!(GENERATORS_NAMESPACE % command).new(self)
27
- end
28
-
29
- def start
30
- @command.start
31
- end
32
-
33
- private
34
- def _get_real_app_name(app_name_or_path)
35
- if app_name_or_path.include?(::File::SEPARATOR)
36
- raise ArgumentError.new("Invalid application name. If you want to set application path, please use --path option")
37
- end
38
-
39
- app_name_or_path == '.' ? ::File.basename(Dir.getwd) : app_name_or_path
40
- end
41
- end
42
- end
43
- end
@@ -1,81 +0,0 @@
1
- module Lotus
2
- module Config
3
- # Assets configuration
4
- #
5
- # @since 0.1.0
6
- # @api private
7
- class Assets < Utils::LoadPaths
8
- DEFAULT_DIRECTORY = 'public'.freeze
9
-
10
- # Assets source (directory)
11
- #
12
- # @since 0.5.0
13
- # @api private
14
- class Source
15
- # @since 0.5.0
16
- # @api private
17
- BLANK = ''.freeze
18
-
19
- # @since 0.5.0
20
- # @api private
21
- URL_SEPARATOR = '/'.freeze
22
-
23
- # @since 0.5.0
24
- # @api private
25
- attr_reader :urls
26
-
27
- # @since 0.5.0
28
- # @api private
29
- attr_reader :root
30
-
31
- # @since 0.5.0
32
- # @api private
33
- def initialize(path)
34
- @path = path.to_s
35
- @root = @path.sub("#{ Lotus.root }/", BLANK)
36
- @urls = {}
37
-
38
- Dir.glob("#{ path }/**/*").each do |file|
39
- next if ::File.directory?(file)
40
-
41
- @urls.store(
42
- file.sub(@path, BLANK).sub(::File::SEPARATOR, URL_SEPARATOR),
43
- file.sub("#{ @path }/", BLANK)
44
- )
45
- end
46
-
47
- @urls.freeze
48
- end
49
- end
50
-
51
- # @since 0.1.0
52
- # @api private
53
- def initialize(root)
54
- @root = root
55
- @paths = Array(DEFAULT_DIRECTORY)
56
- end
57
-
58
- # @since 0.5.0
59
- # @api private
60
- def for_each_source
61
- each do |path|
62
- yield Source.new(path) if path.exist?
63
- end
64
- end
65
-
66
- # @since 0.2.0
67
- # @api private
68
- def any?
69
- @paths.any?
70
- end
71
-
72
- protected
73
- # @since 0.1.0
74
- # @api private
75
- def realpath(path)
76
- @root.join(path).realpath
77
- end
78
- end
79
- end
80
- end
81
-
@@ -1,31 +0,0 @@
1
- require 'delegate'
2
-
3
- module Lotus
4
- module Generators
5
- # Abstract super class for generators
6
- #
7
- # @abstract
8
- # @since 0.2.0
9
- class Abstract < SimpleDelegator
10
- # Initialize a generator
11
- #
12
- # @param command [Thor] a Thor instance that comes from Lotus::Cli
13
- #
14
- # @since 0.2.0
15
- # @api private
16
- def initialize(command)
17
- super(command)
18
- end
19
-
20
- # Start the generator
21
- #
22
- # @raise [NotImplementedError]
23
- #
24
- # @abstract
25
- # @since 0.2.0
26
- def start
27
- raise NotImplementedError
28
- end
29
- end
30
- end
31
- end
@@ -1,235 +0,0 @@
1
- require 'lotus/generators/abstract'
2
- require 'lotus/utils/string'
3
- require 'lotus/routing/route'
4
-
5
- module Lotus
6
- module Generators
7
- # @since 0.3.0
8
- # @api private
9
- class Action < Abstract
10
- # @since 0.3.0
11
- # @api private
12
- ACTION_SEPARATOR = /\/|\#/
13
-
14
- # @since 0.4.1
15
- # @api private
16
- ROUTE_ENDPOINT_SEPARATOR = '#'.freeze
17
-
18
- # @since 0.4.1
19
- # @api private
20
- QUOTED_NAME = /(\"|\'|\\)/
21
-
22
- # @since 0.3.0
23
- # @api private
24
- SUFFIX = '.rb'.freeze
25
-
26
- # @since 0.3.0
27
- # @api private
28
- TEMPLATE_SUFFIX = '.html.'.freeze
29
-
30
- # @since 0.3.0
31
- # @api private
32
- DEFAULT_TEMPLATE = 'erb'.freeze
33
-
34
- # Default HTTP method used when generating an action.
35
- # @since 0.5.0
36
- # @api private
37
- DEFAULT_HTTP_METHOD = 'GET'.freeze
38
-
39
- # @since 0.3.0
40
- # @api private
41
- def initialize(command)
42
- super
43
-
44
- @name = Utils::String.new(name).underscore.gsub(QUOTED_NAME, '')
45
- @controller, @action = @name.split(ACTION_SEPARATOR)
46
- @controller_name = Utils::String.new(@controller).classify
47
- @action_name = Utils::String.new(@action).classify
48
-
49
- cli.class.source_root(source)
50
- end
51
-
52
- # @since 0.3.0
53
- # @api private
54
- def start
55
- assert_existing_app!
56
- assert_action!
57
- assert_http_method!
58
-
59
- opts = {
60
- app: app,
61
- controller: @controller_name,
62
- action: @action_name,
63
- action_path: _action_path_without_suffix,
64
- relative_action_path: _relative_action_path,
65
- relative_view_path: _relative_view_path,
66
- view_path: _view_path_without_suffix,
67
- template_path: _template_path,
68
- }
69
-
70
- test_type = case options[:test]
71
- when 'rspec'
72
- 'rspec'
73
- else
74
- 'minitest'
75
- end
76
-
77
- templates = {
78
- "action_spec.#{test_type}.tt" => _action_spec_path,
79
- }
80
-
81
- if !options[:skip_view]
82
- templates.merge!({
83
- 'action.rb.tt' => _action_path,
84
- 'view.rb.tt' => _view_path,
85
- 'template.tt' => _template_path,
86
- "view_spec.#{test_type}.tt" => _view_spec_path,
87
- })
88
- else
89
- templates.merge!({
90
- 'action_without_view.rb.tt' => _action_path,
91
- })
92
- end
93
-
94
- generate_route
95
-
96
- templates.each do |src, dst|
97
- cli.template(source.join(src), target.join(dst), opts)
98
- end
99
- end
100
-
101
- private
102
- # @since 0.3.0
103
- # @api private
104
- def assert_existing_app!
105
- unless target.join(app_root).exist?
106
- raise Lotus::Commands::Generate::Error.new("Unknown app: `#{ app_name }'")
107
- end
108
- end
109
-
110
- # @since 0.3.2
111
- # @api private
112
- def assert_action!
113
- if @action.nil?
114
- raise Lotus::Commands::Generate::Error.new("Unknown action, please add action's name with this syntax controller_name#action_name")
115
- end
116
- end
117
-
118
- # @since 0.5.0
119
- # @api private
120
- def assert_http_method!
121
- if !Lotus::Routing::Route::VALID_HTTP_VERBS.include?(_http_method.upcase)
122
- raise Lotus::Commands::Generate::Error.new("Unknown HTTP method '#{_http_method}', please use one of #{Lotus::Routing::Route::VALID_HTTP_VERBS.join(', ')}.")
123
- end
124
- end
125
-
126
- def app
127
- if env.container?
128
- super
129
- else
130
- env.require_application_environment
131
- Utils::String.new(Lotus::Application.applications.first).namespace
132
- end
133
- end
134
-
135
- # @since 0.3.0
136
- # @api private
137
- def generate_route
138
- path = target.join(_routes_path)
139
- path.dirname.mkpath
140
-
141
- FileUtils.touch(path)
142
-
143
- # Insert at the top of the file
144
- cli.insert_into_file _routes_path, before: /\A(.*)/ do
145
- "#{ _http_method } '#{ _route_url }', to: '#{ _route_endpoint }'\n"
146
- end
147
- end
148
-
149
- # @since 0.5.0
150
- # @api private
151
- def _http_method
152
- options.fetch(:method, DEFAULT_HTTP_METHOD).downcase
153
- end
154
-
155
- # @since 0.4.0
156
- # @api private
157
- def _route_url
158
- options.fetch(:url, "/#{ @controller }")
159
- end
160
-
161
- # @since 0.4.1
162
- # @api private
163
- def _route_endpoint
164
- "#{ @controller }#{ROUTE_ENDPOINT_SEPARATOR}#{ @action }"
165
- end
166
-
167
- # @since 0.3.0
168
- # @api private
169
- def _routes_path
170
- routes_root = env.container? ? app_root : env.root
171
- routes_root.join("config", "routes#{ SUFFIX }")
172
- end
173
-
174
- # @since 0.3.0
175
- # @api private
176
- def _action_path
177
- _action_path_without_suffix.to_s + SUFFIX
178
- end
179
-
180
- # @since 0.3.0
181
- # @api private
182
- def _view_path
183
- _view_path_without_suffix.to_s + SUFFIX
184
- end
185
-
186
- # @since 0.3.0
187
- # @api private
188
- def _action_path_without_suffix
189
- app_root.join("controllers", @controller, "#{ @action }")
190
- end
191
-
192
- # @since 0.3.0
193
- # @api private
194
- def _view_path_without_suffix
195
- app_root.join("views", @controller, "#{ @action }")
196
- end
197
-
198
- # @since 0.3.0
199
- # @api private
200
- def _template_path
201
- app_root.join("templates", @controller, "#{ @action }#{ TEMPLATE_SUFFIX }#{ options.fetch(:template) { DEFAULT_TEMPLATE } }")
202
- end
203
-
204
- # @since 0.3.0
205
- # @api private
206
- def _action_spec_path
207
- spec_root.join(app_name.to_s, 'controllers', @controller, "#{ @action }_spec#{ SUFFIX }")
208
- end
209
-
210
- # @since 0.3.0
211
- # @api private
212
- def _view_spec_path
213
- spec_root.join(app_name.to_s, 'views', @controller, "#{ @action }_spec#{ SUFFIX }")
214
- end
215
-
216
- # @since 0.4.0
217
- # @api private
218
- def _relative_action_path
219
- result = '../../../'
220
- result << '../' if env.container?
221
- result << _action_path_without_suffix.to_s
222
- result
223
- end
224
-
225
- # @since 0.4.0
226
- # @api private
227
- def _relative_view_path
228
- result = '../../../'
229
- result << '../' if env.container?
230
- result << _view_path_without_suffix.to_s
231
- result
232
- end
233
- end
234
- end
235
- end