hanami 0.0.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +214 -0
- data/FEATURES.md +156 -0
- data/LICENSE.md +22 -0
- data/README.md +80 -15
- data/bin/hanami +5 -0
- data/hanami.gemspec +27 -12
- data/lib/hanami.rb +78 -2
- data/lib/hanami/action/csrf_protection.rb +167 -0
- data/lib/hanami/action/routing_helpers.rb +40 -0
- data/lib/hanami/application.rb +244 -0
- data/lib/hanami/application_name.rb +101 -0
- data/lib/hanami/cli.rb +119 -0
- data/lib/hanami/cli_sub_commands/assets.rb +29 -0
- data/lib/hanami/cli_sub_commands/db.rb +124 -0
- data/lib/hanami/cli_sub_commands/destroy.rb +102 -0
- data/lib/hanami/cli_sub_commands/generate.rb +127 -0
- data/lib/hanami/commands/assets/precompile.rb +35 -0
- data/lib/hanami/commands/console.rb +90 -0
- data/lib/hanami/commands/db/abstract.rb +19 -0
- data/lib/hanami/commands/db/apply.rb +14 -0
- data/lib/hanami/commands/db/console.rb +50 -0
- data/lib/hanami/commands/db/create.rb +14 -0
- data/lib/hanami/commands/db/drop.rb +14 -0
- data/lib/hanami/commands/db/migrate.rb +19 -0
- data/lib/hanami/commands/db/prepare.rb +14 -0
- data/lib/hanami/commands/db/version.rb +14 -0
- data/lib/hanami/commands/generate/abstract.rb +63 -0
- data/lib/hanami/commands/generate/action.rb +262 -0
- data/lib/hanami/commands/generate/app.rb +116 -0
- data/lib/hanami/commands/generate/mailer.rb +118 -0
- data/lib/hanami/commands/generate/migration.rb +63 -0
- data/lib/hanami/commands/generate/model.rb +96 -0
- data/lib/hanami/commands/new/abstract.rb +128 -0
- data/lib/hanami/commands/new/app.rb +116 -0
- data/lib/hanami/commands/new/container.rb +102 -0
- data/lib/hanami/commands/routes.rb +41 -0
- data/lib/hanami/commands/server.rb +79 -0
- data/lib/hanami/config/configure.rb +17 -0
- data/lib/hanami/config/cookies.rb +68 -0
- data/lib/hanami/config/framework_configuration.rb +42 -0
- data/lib/hanami/config/load_paths.rb +27 -0
- data/lib/hanami/config/mapper.rb +36 -0
- data/lib/hanami/config/mapping.rb +12 -0
- data/lib/hanami/config/routes.rb +16 -0
- data/lib/hanami/config/security.rb +58 -0
- data/lib/hanami/config/sessions.rb +97 -0
- data/lib/hanami/configuration.rb +1728 -0
- data/lib/hanami/container.rb +59 -0
- data/lib/hanami/environment.rb +485 -0
- data/lib/hanami/frameworks.rb +14 -0
- data/lib/hanami/generators/action/action.rb.tt +8 -0
- data/lib/hanami/generators/action/action_spec.minitest.tt +12 -0
- data/lib/hanami/generators/action/action_spec.rspec.tt +11 -0
- data/lib/hanami/generators/action/action_without_view.rb.tt +9 -0
- data/lib/hanami/generators/action/template.tt +0 -0
- data/lib/hanami/generators/action/view.rb.tt +5 -0
- data/lib/hanami/generators/action/view_spec.minitest.tt +13 -0
- data/lib/hanami/generators/action/view_spec.rspec.tt +12 -0
- data/lib/hanami/generators/app/.gitkeep.tt +1 -0
- data/lib/hanami/generators/app/application.rb.tt +273 -0
- data/lib/hanami/generators/app/config/initializers/.gitkeep +0 -0
- data/lib/hanami/generators/app/config/routes.rb.tt +2 -0
- data/lib/hanami/generators/app/favicon.ico +0 -0
- data/lib/hanami/generators/app/templates/application.html.erb.tt +10 -0
- data/lib/hanami/generators/app/views/application_layout.rb.tt +7 -0
- data/lib/hanami/generators/application/app/.env.development.tt +4 -0
- data/lib/hanami/generators/application/app/.env.test.tt +4 -0
- data/lib/hanami/generators/application/app/.env.tt +1 -0
- data/lib/hanami/generators/application/app/.gitignore +0 -0
- data/lib/hanami/generators/application/app/.gitkeep +1 -0
- data/lib/hanami/generators/application/app/Gemfile.tt +37 -0
- data/lib/hanami/generators/application/app/Rakefile.minitest.tt +11 -0
- data/lib/hanami/generators/application/app/Rakefile.rspec.tt +6 -0
- data/lib/hanami/generators/application/app/apps/.gitkeep.tt +1 -0
- data/lib/hanami/generators/application/app/capybara.rb.rspec.tt +8 -0
- data/lib/hanami/generators/application/app/config.ru.tt +3 -0
- data/lib/hanami/generators/application/app/config/application.rb.tt +270 -0
- data/lib/hanami/generators/application/app/config/environment.rb.tt +5 -0
- data/lib/hanami/generators/application/app/config/initializers/.gitkeep +0 -0
- data/lib/hanami/generators/application/app/config/routes.rb.tt +2 -0
- data/lib/hanami/generators/application/app/db/.gitkeep +1 -0
- data/lib/hanami/generators/application/app/favicon.ico +0 -0
- data/lib/hanami/generators/application/app/features_helper.rb.minitest.tt +11 -0
- data/lib/hanami/generators/application/app/features_helper.rb.rspec.tt +12 -0
- data/lib/hanami/generators/application/app/gitignore.tt +2 -0
- data/lib/hanami/generators/application/app/gitignore_with_db.tt +4 -0
- data/lib/hanami/generators/application/app/hanamirc.tt +3 -0
- data/lib/hanami/generators/application/app/lib/app_name.rb.tt +59 -0
- data/lib/hanami/generators/application/app/lib/chirp/entities/.gitkeep +1 -0
- data/lib/hanami/generators/application/app/lib/chirp/repositories/.gitkeep +1 -0
- data/lib/hanami/generators/application/app/lib/config/mapping.rb.tt +7 -0
- data/lib/hanami/generators/application/app/rspec.rspec.tt +2 -0
- data/lib/hanami/generators/application/app/schema.sql.tt +0 -0
- data/lib/hanami/generators/application/app/spec_helper.rb.minitest.tt +7 -0
- data/lib/hanami/generators/application/app/spec_helper.rb.rspec.tt +104 -0
- data/lib/hanami/generators/application/app/templates/application.html.erb.tt +10 -0
- data/lib/hanami/generators/application/app/views/application_layout.rb.tt +7 -0
- data/lib/hanami/generators/application/container/.env.development.tt +3 -0
- data/lib/hanami/generators/application/container/.env.test.tt +3 -0
- data/lib/hanami/generators/application/container/.env.tt +1 -0
- data/lib/hanami/generators/application/container/.gitignore +0 -0
- data/lib/hanami/generators/application/container/.gitkeep +1 -0
- data/lib/hanami/generators/application/container/Gemfile.tt +36 -0
- data/lib/hanami/generators/application/container/Rakefile.minitest.tt +11 -0
- data/lib/hanami/generators/application/container/Rakefile.rspec.tt +6 -0
- data/lib/hanami/generators/application/container/capybara.rb.rspec.tt +8 -0
- data/lib/hanami/generators/application/container/config.ru.tt +3 -0
- data/lib/hanami/generators/application/container/config/environment.rb.tt +7 -0
- data/lib/hanami/generators/application/container/config/initializers/.gitkeep +0 -0
- data/lib/hanami/generators/application/container/db/.gitkeep +1 -0
- data/lib/hanami/generators/application/container/features_helper.rb.minitest.tt +11 -0
- data/lib/hanami/generators/application/container/features_helper.rb.rspec.tt +12 -0
- data/lib/hanami/generators/application/container/gitignore.tt +2 -0
- data/lib/hanami/generators/application/container/gitignore_with_db.tt +4 -0
- data/lib/hanami/generators/application/container/hanamirc.tt +3 -0
- data/lib/hanami/generators/application/container/lib/app_name.rb.tt +60 -0
- data/lib/hanami/generators/application/container/lib/chirp/entities/.gitkeep +1 -0
- data/lib/hanami/generators/application/container/lib/chirp/mailers/.gitkeep +0 -0
- data/lib/hanami/generators/application/container/lib/chirp/mailers/templates/.gitkeep +0 -0
- data/lib/hanami/generators/application/container/lib/chirp/repositories/.gitkeep +1 -0
- data/lib/hanami/generators/application/container/lib/config/mapping.rb.tt +7 -0
- data/lib/hanami/generators/application/container/rspec.rspec.tt +2 -0
- data/lib/hanami/generators/application/container/schema.sql.tt +0 -0
- data/lib/hanami/generators/application/container/spec_helper.rb.minitest.tt +7 -0
- data/lib/hanami/generators/application/container/spec_helper.rb.rspec.tt +104 -0
- data/lib/hanami/generators/database_config.rb +99 -0
- data/lib/hanami/generators/generatable.rb +51 -0
- data/lib/hanami/generators/generator.rb +35 -0
- data/lib/hanami/generators/mailer/mailer.rb.tt +7 -0
- data/lib/hanami/generators/mailer/mailer_spec.rb.tt +7 -0
- data/lib/hanami/generators/mailer/template.html.tt +0 -0
- data/lib/hanami/generators/mailer/template.txt.tt +0 -0
- data/lib/hanami/generators/migration/migration.rb.tt +4 -0
- data/lib/hanami/generators/model/entity.rb.tt +3 -0
- data/lib/hanami/generators/model/entity_spec.minitest.tt +5 -0
- data/lib/hanami/generators/model/entity_spec.rspec.tt +3 -0
- data/lib/hanami/generators/model/repository.rb.tt +3 -0
- data/lib/hanami/generators/model/repository_spec.minitest.tt +5 -0
- data/lib/hanami/generators/model/repository_spec.rspec.tt +3 -0
- data/lib/hanami/generators/test_framework.rb +42 -0
- data/lib/hanami/hanamirc.rb +152 -0
- data/lib/hanami/loader.rb +258 -0
- data/lib/hanami/mailer/glue.rb +68 -0
- data/lib/hanami/middleware.rb +143 -0
- data/lib/hanami/rake_helper.rb +68 -0
- data/lib/hanami/rake_tasks.rb +2 -0
- data/lib/hanami/rendering_policy.rb +77 -0
- data/lib/hanami/repositories/car_repository.rb +3 -0
- data/lib/hanami/repositories/name_repository.rb +3 -0
- data/lib/hanami/root.rb +7 -0
- data/lib/hanami/routes.rb +151 -0
- data/lib/hanami/routing/default.rb +25 -0
- data/lib/hanami/setup.rb +3 -0
- data/lib/hanami/static.rb +77 -0
- data/lib/hanami/templates/default.html.erb +9 -0
- data/lib/hanami/templates/welcome.html.erb +52 -0
- data/lib/hanami/version.rb +4 -1
- data/lib/hanami/views/default.rb +34 -0
- data/lib/hanami/views/default_template_finder.rb +20 -0
- data/lib/hanami/views/null_view.rb +17 -0
- data/lib/hanami/welcome.rb +40 -0
- metadata +357 -16
- data/.gitignore +0 -9
- data/Gemfile +0 -4
- data/Rakefile +0 -2
- data/bin/console +0 -14
- data/bin/setup +0 -8
@@ -0,0 +1,262 @@
|
|
1
|
+
require 'hanami/commands/generate/abstract'
|
2
|
+
require 'hanami/routing/route'
|
3
|
+
|
4
|
+
module Hanami
|
5
|
+
module Commands
|
6
|
+
class Generate
|
7
|
+
class Action < Abstract
|
8
|
+
|
9
|
+
# @since 0.5.0
|
10
|
+
# @api private
|
11
|
+
ACTION_SEPARATOR = /[\/,#]/
|
12
|
+
|
13
|
+
# @since 0.5.0
|
14
|
+
# @api private
|
15
|
+
ROUTE_ENDPOINT_SEPARATOR = '#'.freeze
|
16
|
+
|
17
|
+
# @since 0.5.0
|
18
|
+
# @api private
|
19
|
+
QUOTED_NAME = /(\"|\'|\\)/
|
20
|
+
|
21
|
+
# Default HTTP method used when generating an action.
|
22
|
+
#
|
23
|
+
# @since 0.5.0
|
24
|
+
# @api private
|
25
|
+
DEFAULT_HTTP_METHOD = 'GET'.freeze
|
26
|
+
|
27
|
+
# HTTP methods used when generating resourceful actions.
|
28
|
+
#
|
29
|
+
# @since 0.6.0
|
30
|
+
# @api private
|
31
|
+
RESOURCEFUL_HTTP_METHODS = {
|
32
|
+
'Create' => 'POST',
|
33
|
+
'Update' => 'PATCH',
|
34
|
+
'Destroy' => 'DELETE'
|
35
|
+
}.freeze
|
36
|
+
|
37
|
+
# For resourceful actions, what to add to the end of the base URL
|
38
|
+
#
|
39
|
+
# @since 0.6.0
|
40
|
+
# @api private
|
41
|
+
RESOURCEFUL_ROUTE_URL_SUFFIXES = {
|
42
|
+
'Show' => '/:id',
|
43
|
+
'Update' => '/:id',
|
44
|
+
'Destroy' => '/:id',
|
45
|
+
'New' => '/new',
|
46
|
+
'Edit' => '/:id/edit',
|
47
|
+
}.freeze
|
48
|
+
|
49
|
+
def initialize(options, application_name, controller_and_action_name)
|
50
|
+
super(options)
|
51
|
+
if !environment.container?
|
52
|
+
application_name = File.basename(Dir.pwd)
|
53
|
+
end
|
54
|
+
|
55
|
+
controller_and_action_name = Utils::String.new(controller_and_action_name).underscore.gsub(QUOTED_NAME, '')
|
56
|
+
|
57
|
+
*controller_name, action_name = controller_and_action_name.split(ACTION_SEPARATOR)
|
58
|
+
|
59
|
+
@application_name = Utils::String.new(application_name).classify
|
60
|
+
@controller_name = Utils::String.new(controller_name.join("/")).classify
|
61
|
+
@action_name = Utils::String.new(action_name).classify
|
62
|
+
@controller_pathname = Utils::String.new(@controller_name).underscore
|
63
|
+
|
64
|
+
assert_application_name!
|
65
|
+
assert_controller_name!
|
66
|
+
assert_action_name!
|
67
|
+
assert_http_method!
|
68
|
+
end
|
69
|
+
|
70
|
+
def map_templates
|
71
|
+
add_mapping("action_spec.#{test_framework.framework}.tt", action_spec_path)
|
72
|
+
|
73
|
+
if skip_view?
|
74
|
+
add_mapping('action_without_view.rb.tt', action_path)
|
75
|
+
else
|
76
|
+
add_mapping('action.rb.tt', action_path)
|
77
|
+
add_mapping('view.rb.tt', view_path)
|
78
|
+
add_mapping('template.tt', template_path)
|
79
|
+
add_mapping("view_spec.#{test_framework.framework}.tt", view_spec_path)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def post_process_templates
|
84
|
+
generate_route
|
85
|
+
end
|
86
|
+
|
87
|
+
# @since 0.5.0
|
88
|
+
# @api private
|
89
|
+
def template_options
|
90
|
+
{
|
91
|
+
app: @application_name,
|
92
|
+
controller: @controller_name,
|
93
|
+
action: @action_name,
|
94
|
+
relative_action_path: relative_action_path,
|
95
|
+
relative_view_path: relative_view_path,
|
96
|
+
template_path: template_path,
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
# @since 0.5.0
|
103
|
+
# @api private
|
104
|
+
def generate_route
|
105
|
+
routes_path.dirname.mkpath
|
106
|
+
FileUtils.touch(routes_path)
|
107
|
+
|
108
|
+
generator.prepend_to_file(routes_path, "#{ http_method } '#{ route_url }', to: '#{ route_endpoint }'\n")
|
109
|
+
end
|
110
|
+
|
111
|
+
def skip_view?
|
112
|
+
options.fetch(:skip_view, false)
|
113
|
+
end
|
114
|
+
|
115
|
+
# @since 0.5.0
|
116
|
+
# @api private
|
117
|
+
def http_method
|
118
|
+
options.fetch(:method, resourceful_http_method).downcase
|
119
|
+
end
|
120
|
+
|
121
|
+
# @since 0.6.0
|
122
|
+
# @api private
|
123
|
+
def resourceful_http_method
|
124
|
+
RESOURCEFUL_HTTP_METHODS.fetch(@action_name, DEFAULT_HTTP_METHOD)
|
125
|
+
end
|
126
|
+
|
127
|
+
# @since 0.5.0
|
128
|
+
# @api private
|
129
|
+
def route_url
|
130
|
+
options.fetch(:url, "/#{ @controller_pathname }#{ resourceful_route_url_suffix }")
|
131
|
+
end
|
132
|
+
|
133
|
+
# @since 0.6.0
|
134
|
+
# @api private
|
135
|
+
def resourceful_route_url_suffix
|
136
|
+
RESOURCEFUL_ROUTE_URL_SUFFIXES.fetch(@action_name, "")
|
137
|
+
end
|
138
|
+
|
139
|
+
# @since 0.5.0
|
140
|
+
# @api private
|
141
|
+
def route_endpoint
|
142
|
+
"#{ @controller_pathname }#{ ROUTE_ENDPOINT_SEPARATOR }#{ @action_name }".downcase
|
143
|
+
end
|
144
|
+
|
145
|
+
# @since 0.5.0
|
146
|
+
# @api private
|
147
|
+
def known_application_names
|
148
|
+
Dir.glob(applications_path.join('/*')).map do |name|
|
149
|
+
File.basename(name)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# @since 0.5.0
|
154
|
+
# @api private
|
155
|
+
def assert_controller_name!
|
156
|
+
if @controller_name.nil? || @controller_name.empty?
|
157
|
+
raise ArgumentError.new("Unknown controller, please add controllers name with this syntax controller_name#action_name")
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# @since 0.5.0
|
162
|
+
# @api private
|
163
|
+
def assert_action_name!
|
164
|
+
if @action_name.nil? || @action_name.strip == ''
|
165
|
+
raise ArgumentError.new("Unknown action, please add actions name with this syntax controller_name#action_name")
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# @since 0.5.0
|
170
|
+
# @api private
|
171
|
+
def assert_application_name!
|
172
|
+
return if !environment.container?
|
173
|
+
if @application_name.nil? || @application_name.strip == '' || !application_path.exist?
|
174
|
+
existing_apps = known_application_names.join('/')
|
175
|
+
raise ArgumentError.new("Unknown app: `#{ @application_name.downcase }'. Please specify one of (#{ existing_apps }) as application name")
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# @since 0.5.0
|
180
|
+
# @api private
|
181
|
+
def assert_http_method!
|
182
|
+
if !Hanami::Routing::Route::VALID_HTTP_VERBS.include?(http_method.upcase)
|
183
|
+
existing_http_methods = Hanami::Routing::Route::VALID_HTTP_VERBS
|
184
|
+
raise ArgumentError.new("Unknown HTTP method '#{http_method}', please use one of #{ existing_http_methods.join('/') }.")
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def routes_path
|
189
|
+
if environment.container?
|
190
|
+
application_path.join('config', 'routes.rb')
|
191
|
+
else
|
192
|
+
application_path.join('..', 'config', 'routes.rb')
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# The directory of the application
|
197
|
+
# ./app for 'app' architecture
|
198
|
+
# ./apps/APPLICATION_NAME for 'container'
|
199
|
+
def application_path
|
200
|
+
if environment.container?
|
201
|
+
applications_path.join(application_name_as_snake_case)
|
202
|
+
else
|
203
|
+
Pathname.new('app')
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# The parent dir of the application directory.
|
208
|
+
def applications_path
|
209
|
+
Pathname.new('apps')
|
210
|
+
end
|
211
|
+
|
212
|
+
def view_path
|
213
|
+
application_path.join('views', @controller_pathname, "#{@action_name.downcase}.rb")
|
214
|
+
end
|
215
|
+
|
216
|
+
def view_spec_path
|
217
|
+
spec_root.join('views', @controller_pathname, "#{@action_name.downcase}_spec.rb")
|
218
|
+
end
|
219
|
+
|
220
|
+
def template_path
|
221
|
+
application_path.join('templates', @controller_pathname, "#{@action_name.downcase}.html.#{template_engine}")
|
222
|
+
end
|
223
|
+
|
224
|
+
def action_path
|
225
|
+
application_path.join('controllers', @controller_pathname, "#{@action_name.downcase}.rb")
|
226
|
+
end
|
227
|
+
|
228
|
+
def action_spec_path
|
229
|
+
spec_root.join('controllers', @controller_pathname, "#{ @action_name.downcase}_spec.rb")
|
230
|
+
end
|
231
|
+
|
232
|
+
def spec_root
|
233
|
+
Pathname.new('spec').join(app_base_dir)
|
234
|
+
end
|
235
|
+
|
236
|
+
def relative_action_path
|
237
|
+
path = Pathname.new('.').join('..', '..', '..')
|
238
|
+
path = path.join('..') if environment.container?
|
239
|
+
path.join(application_path, 'controllers', @controller_pathname, @action_name.downcase)
|
240
|
+
end
|
241
|
+
|
242
|
+
def relative_view_path
|
243
|
+
path = Pathname.new('.').join('..', '..', '..')
|
244
|
+
path = path.join('..') if environment.container?
|
245
|
+
path.join(application_path, 'views', @controller_pathname, @action_name.downcase)
|
246
|
+
end
|
247
|
+
|
248
|
+
def app_base_dir
|
249
|
+
if environment.container?
|
250
|
+
application_name_as_snake_case
|
251
|
+
else
|
252
|
+
''
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def application_name_as_snake_case
|
257
|
+
@application_name.gsub(/(.)([A-Z])/,'\1_\2').downcase
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
@@ -0,0 +1,116 @@
|
|
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 App < Abstract
|
9
|
+
|
10
|
+
attr_reader :base_path
|
11
|
+
|
12
|
+
def initialize(options, application_name)
|
13
|
+
super(options)
|
14
|
+
|
15
|
+
assert_application_name!(application_name)
|
16
|
+
assert_architecture!
|
17
|
+
|
18
|
+
@application_name = ApplicationName.new(application_name)
|
19
|
+
@base_path = Pathname.pwd
|
20
|
+
end
|
21
|
+
|
22
|
+
def map_templates
|
23
|
+
add_mapping('application.rb.tt', 'application.rb')
|
24
|
+
add_mapping('config/routes.rb.tt', 'config/routes.rb')
|
25
|
+
add_mapping('views/application_layout.rb.tt', 'views/application_layout.rb')
|
26
|
+
add_mapping('templates/application.html.erb.tt', 'templates/application.html.erb')
|
27
|
+
add_mapping('favicon.ico', 'assets/favicon.ico')
|
28
|
+
|
29
|
+
add_mapping('.gitkeep', 'controllers/.gitkeep')
|
30
|
+
add_mapping('.gitkeep', 'assets/images/.gitkeep')
|
31
|
+
add_mapping('.gitkeep', 'assets/javascripts/.gitkeep')
|
32
|
+
add_mapping('.gitkeep', 'assets/stylesheets/.gitkeep')
|
33
|
+
add_mapping('.gitkeep', "../../spec/#{ app_name }/features/.gitkeep")
|
34
|
+
add_mapping('.gitkeep', "../../spec/#{ app_name }/controllers/.gitkeep")
|
35
|
+
add_mapping('.gitkeep', "../../spec/#{ app_name }/views/.gitkeep")
|
36
|
+
end
|
37
|
+
|
38
|
+
def template_options
|
39
|
+
{
|
40
|
+
app_name: app_name,
|
41
|
+
upcase_app_name: upcase_app_name,
|
42
|
+
classified_app_name: classified_app_name,
|
43
|
+
app_base_url: application_base_url,
|
44
|
+
app_base_path: application_base_path,
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def post_process_templates
|
49
|
+
add_require_app
|
50
|
+
add_mount_app
|
51
|
+
add_web_session_secret
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def application_base_url
|
57
|
+
options.fetch(:application_base_url, "/#{app_name}")
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_require_app
|
61
|
+
# Add "require_relative '../apps/web/application'"
|
62
|
+
generator.inject_into_file base_path.join('config/environment.rb'), after: /require_relative '\.\.\/lib\/.*'/ do
|
63
|
+
"\nrequire_relative '../apps/#{ app_name }/application'"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def add_mount_app
|
68
|
+
generator.inject_into_file base_path.join('config/environment.rb'), after: /Hanami::Container.configure do/ do |match|
|
69
|
+
"\n mount #{ classified_app_name }::Application, at: '#{ application_base_url }'"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_web_session_secret
|
74
|
+
['development', 'test'].each do |environment|
|
75
|
+
# Add WEB_SESSIONS_SECRET="abc123" (random hex)
|
76
|
+
generator.append_to_file base_path.join(".env.#{ environment }") do
|
77
|
+
%(#{ upcase_app_name }_SESSIONS_SECRET="#{ SecureRandom.hex(32) }"\n)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def target_path
|
83
|
+
base_path.join(application_base_path)
|
84
|
+
end
|
85
|
+
|
86
|
+
def app_name
|
87
|
+
@application_name.to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
def upcase_app_name
|
91
|
+
@application_name.to_env_s
|
92
|
+
end
|
93
|
+
|
94
|
+
def application_base_path
|
95
|
+
["apps", @application_name].join(::File::SEPARATOR)
|
96
|
+
end
|
97
|
+
|
98
|
+
def classified_app_name
|
99
|
+
Utils::String.new(app_name).classify.tr('::', '')
|
100
|
+
end
|
101
|
+
|
102
|
+
def assert_application_name!(value)
|
103
|
+
if value.nil? || value.strip.empty?
|
104
|
+
raise ArgumentError.new('Application name is nil or empty')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def assert_architecture!
|
109
|
+
if !environment.container?
|
110
|
+
raise ArgumentError.new('App generator is only available for container architecture.')
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require "hanami/commands/generate/abstract"
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module Commands
|
5
|
+
class Generate
|
6
|
+
# @since 0.5.0
|
7
|
+
# @api private
|
8
|
+
class Mailer < Abstract
|
9
|
+
|
10
|
+
attr_reader :name, :name_underscored, :from, :to, :subject
|
11
|
+
|
12
|
+
# @since 0.5.0
|
13
|
+
# @api private
|
14
|
+
TXT_FORMAT = ".txt".freeze
|
15
|
+
|
16
|
+
# @since 0.5.0
|
17
|
+
# @api private
|
18
|
+
HTML_FORMAT = ".html".freeze
|
19
|
+
|
20
|
+
# @since 0.5.0
|
21
|
+
# @api private
|
22
|
+
DEFAULT_ENGINE = "erb".freeze
|
23
|
+
|
24
|
+
# @since 0.5.0
|
25
|
+
# @api private
|
26
|
+
DEFAULT_FROM = "'<from>'".freeze
|
27
|
+
|
28
|
+
# @since 0.5.0
|
29
|
+
# @api private
|
30
|
+
DEFAULT_TO = "'<to>'".freeze
|
31
|
+
|
32
|
+
# @since 0.5.0
|
33
|
+
# @api private
|
34
|
+
DEFAULT_SUBJECT = "'Hello'".freeze
|
35
|
+
|
36
|
+
# @since 0.5.0
|
37
|
+
# @api private
|
38
|
+
def initialize(options, name)
|
39
|
+
super(options)
|
40
|
+
|
41
|
+
@name_underscored = Utils::String.new(name).underscore
|
42
|
+
@name = Utils::String.new(name_underscored).classify
|
43
|
+
@from = options[:from] || DEFAULT_FROM
|
44
|
+
@to = options[:to] || DEFAULT_TO
|
45
|
+
@subject = options[:subject] || DEFAULT_SUBJECT
|
46
|
+
|
47
|
+
assert_name!
|
48
|
+
end
|
49
|
+
|
50
|
+
# @since 0.x.x
|
51
|
+
# @api private
|
52
|
+
def map_templates
|
53
|
+
add_mapping("mailer_spec.rb.tt", mailer_spec_path)
|
54
|
+
add_mapping("mailer.rb.tt", mailer_path)
|
55
|
+
add_mapping("template.txt.tt", txt_template_path)
|
56
|
+
add_mapping("template.html.tt", html_template_path)
|
57
|
+
end
|
58
|
+
|
59
|
+
def template_options
|
60
|
+
{
|
61
|
+
mailer: name,
|
62
|
+
from: from,
|
63
|
+
to: to,
|
64
|
+
subject: subject,
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# @since 0.5.0
|
71
|
+
# @api private
|
72
|
+
def assert_name!
|
73
|
+
if name.nil? || name.strip.empty?
|
74
|
+
raise ArgumentError.new("Missing mailer name")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# @since 0.5.0
|
79
|
+
# @api private
|
80
|
+
def mailer_path
|
81
|
+
core_root.join('mailers', "#{ name_underscored }.rb").to_s
|
82
|
+
end
|
83
|
+
|
84
|
+
# @since 0.5.0
|
85
|
+
# @api private
|
86
|
+
def mailer_spec_path
|
87
|
+
spec_root.join(::File.basename(Dir.getwd), "mailers", "#{ name_underscored }_spec.rb")
|
88
|
+
end
|
89
|
+
|
90
|
+
# @since 0.5.0
|
91
|
+
# @api private
|
92
|
+
def txt_template_path
|
93
|
+
template_path(TXT_FORMAT)
|
94
|
+
end
|
95
|
+
|
96
|
+
# @since 0.5.0
|
97
|
+
# @api private
|
98
|
+
def html_template_path
|
99
|
+
template_path(HTML_FORMAT)
|
100
|
+
end
|
101
|
+
|
102
|
+
# @since 0.5.0
|
103
|
+
# @api private
|
104
|
+
def template_path(format)
|
105
|
+
core_root.join("mailers", "templates", "#{ name_underscored }#{ format }.#{ DEFAULT_ENGINE }")
|
106
|
+
end
|
107
|
+
|
108
|
+
def spec_root
|
109
|
+
Pathname.new("spec")
|
110
|
+
end
|
111
|
+
|
112
|
+
def core_root
|
113
|
+
Pathname.new("lib").join(::File.basename(Dir.getwd))
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|