hanami-cli 2.1.0.beta1 → 2.1.0.rc1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/Gemfile +5 -2
- data/hanami-cli.gemspec +1 -1
- data/lib/hanami/cli/bundler.rb +19 -5
- data/lib/hanami/cli/command.rb +4 -4
- data/lib/hanami/cli/commands/app/assets/command.rb +69 -0
- data/lib/hanami/cli/commands/app/assets/compile.rb +32 -0
- data/lib/hanami/cli/commands/app/assets/watch.rb +32 -0
- data/lib/hanami/cli/commands/app/assets.rb +16 -0
- data/lib/hanami/cli/commands/app/command.rb +2 -2
- data/lib/hanami/cli/commands/app/dev.rb +45 -0
- data/lib/hanami/cli/commands/app/generate/action.rb +3 -2
- data/lib/hanami/cli/commands/app/generate/part.rb +49 -0
- data/lib/hanami/cli/commands/app/install.rb +16 -1
- data/lib/hanami/cli/commands/app.rb +9 -0
- data/lib/hanami/cli/commands/gem/new.rb +57 -7
- data/lib/hanami/cli/errors.rb +30 -0
- data/lib/hanami/cli/files.rb +8 -2
- data/lib/hanami/cli/generators/app/action/action.erb +5 -1
- data/lib/hanami/cli/generators/app/action/slice_action.erb +5 -1
- data/lib/hanami/cli/generators/app/action.rb +49 -12
- data/lib/hanami/cli/generators/app/part/app_base_part.erb +9 -0
- data/lib/hanami/cli/generators/app/part/app_part.erb +13 -0
- data/lib/hanami/cli/generators/app/part/slice_base_part.erb +9 -0
- data/lib/hanami/cli/generators/app/part/slice_part.erb +13 -0
- data/lib/hanami/cli/generators/app/part.rb +101 -0
- data/lib/hanami/cli/generators/app/part_context.rb +98 -0
- data/lib/hanami/cli/generators/app/slice/app_css.erb +5 -0
- data/lib/hanami/cli/generators/app/slice/app_js.erb +1 -0
- data/lib/hanami/cli/generators/app/slice/app_layout.erb +18 -0
- data/lib/hanami/cli/generators/app/slice.rb +9 -3
- data/lib/hanami/cli/generators/app/slice_context.rb +18 -0
- data/lib/hanami/cli/generators/context.rb +70 -3
- data/lib/hanami/cli/generators/gem/app/404.html +76 -5
- data/lib/hanami/cli/generators/gem/app/500.html +76 -5
- data/lib/hanami/cli/generators/gem/app/app_css.erb +5 -0
- data/lib/hanami/cli/generators/gem/app/app_js.erb +1 -0
- data/lib/hanami/cli/generators/gem/app/app_layout.erb +18 -0
- data/lib/hanami/cli/generators/gem/app/assets.mjs +14 -0
- data/lib/hanami/cli/generators/gem/app/dev +8 -0
- data/lib/hanami/cli/generators/gem/app/favicon.ico +0 -0
- data/lib/hanami/cli/generators/gem/app/gemfile.erb +14 -8
- data/lib/hanami/cli/generators/gem/app/gitignore.erb +4 -0
- data/lib/hanami/cli/generators/gem/app/package.json.erb +10 -0
- data/lib/hanami/cli/generators/gem/app/procfile.erb +4 -0
- data/lib/hanami/cli/generators/gem/app/puma.erb +37 -7
- data/lib/hanami/cli/generators/gem/app/routes.erb +1 -1
- data/lib/hanami/cli/generators/gem/app.rb +21 -4
- data/lib/hanami/cli/generators/version.rb +12 -0
- data/lib/hanami/cli/interactive_system_call.rb +64 -0
- data/lib/hanami/cli/system_call.rb +8 -2
- data/lib/hanami/cli/version.rb +1 -1
- metadata +28 -6
- data/lib/hanami/cli/generators/app/slice/layouts_app.html.erb +0 -1
- data/lib/hanami/cli/generators/gem/app/layouts_app.html.erb +0 -1
data/lib/hanami/cli/errors.rb
CHANGED
|
@@ -2,60 +2,90 @@
|
|
|
2
2
|
|
|
3
3
|
module Hanami
|
|
4
4
|
module CLI
|
|
5
|
+
# @since 0.1.0
|
|
6
|
+
# @api public
|
|
5
7
|
class Error < StandardError
|
|
6
8
|
end
|
|
7
9
|
|
|
10
|
+
# @since 2.0.0
|
|
11
|
+
# @api public
|
|
8
12
|
class NotImplementedError < Error
|
|
9
13
|
end
|
|
10
14
|
|
|
15
|
+
# @since 2.0.0
|
|
16
|
+
# @api public
|
|
11
17
|
class BundleInstallError < Error
|
|
12
18
|
def initialize(message)
|
|
13
19
|
super("`bundle install' failed\n\n\n#{message.inspect}")
|
|
14
20
|
end
|
|
15
21
|
end
|
|
16
22
|
|
|
23
|
+
# @since 2.0.0
|
|
24
|
+
# @api public
|
|
17
25
|
class HanamiInstallError < Error
|
|
18
26
|
def initialize(message)
|
|
19
27
|
super("`hanami install' failed\n\n\n#{message.inspect}")
|
|
20
28
|
end
|
|
21
29
|
end
|
|
22
30
|
|
|
31
|
+
# @since 2.1.0
|
|
32
|
+
# @api public
|
|
33
|
+
class HanamiExecError < Error
|
|
34
|
+
def initialize(cmd, message)
|
|
35
|
+
super("`bundle exec hanami #{cmd}' failed\n\n\n#{message.inspect}")
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @since 2.0.0
|
|
40
|
+
# @api public
|
|
23
41
|
class PathAlreadyExistsError < Error
|
|
24
42
|
def initialize(path)
|
|
25
43
|
super("Cannot create new Hanami app in an existing path: `#{path}'")
|
|
26
44
|
end
|
|
27
45
|
end
|
|
28
46
|
|
|
47
|
+
# @since 2.0.0
|
|
48
|
+
# @api public
|
|
29
49
|
class MissingSliceError < Error
|
|
30
50
|
def initialize(slice)
|
|
31
51
|
super("slice `#{slice}' is missing, please generate with `hanami generate slice #{slice}'")
|
|
32
52
|
end
|
|
33
53
|
end
|
|
34
54
|
|
|
55
|
+
# @since 2.0.0
|
|
56
|
+
# @api public
|
|
35
57
|
class InvalidURLError < Error
|
|
36
58
|
def initialize(url)
|
|
37
59
|
super("invalid URL: `#{url}'")
|
|
38
60
|
end
|
|
39
61
|
end
|
|
40
62
|
|
|
63
|
+
# @since 2.0.0
|
|
64
|
+
# @api public
|
|
41
65
|
class InvalidURLPrefixError < Error
|
|
42
66
|
def initialize(url)
|
|
43
67
|
super("invalid URL prefix: `#{url}'")
|
|
44
68
|
end
|
|
45
69
|
end
|
|
46
70
|
|
|
71
|
+
# @since 2.0.0
|
|
72
|
+
# @api public
|
|
47
73
|
class InvalidActionNameError < Error
|
|
48
74
|
def initialize(name)
|
|
49
75
|
super("cannot parse controller and action name: `#{name}'\n\texample: `hanami generate action users.show'")
|
|
50
76
|
end
|
|
51
77
|
end
|
|
52
78
|
|
|
79
|
+
# @since 2.0.0
|
|
80
|
+
# @api public
|
|
53
81
|
class UnknownHTTPMethodError < Error
|
|
54
82
|
def initialize(name)
|
|
55
83
|
super("unknown HTTP method: `#{name}'")
|
|
56
84
|
end
|
|
57
85
|
end
|
|
58
86
|
|
|
87
|
+
# @since 2.0.0
|
|
88
|
+
# @api public
|
|
59
89
|
class UnsupportedDatabaseSchemeError < Error
|
|
60
90
|
def initialize(scheme)
|
|
61
91
|
super("`#{scheme}' is not a supported db scheme")
|
data/lib/hanami/cli/files.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "dry/files"
|
|
4
|
+
|
|
3
5
|
module Hanami
|
|
4
6
|
module CLI
|
|
5
7
|
# @since 2.0.0
|
|
@@ -29,7 +31,7 @@ module Hanami
|
|
|
29
31
|
def mkdir(path)
|
|
30
32
|
unless exist?(path)
|
|
31
33
|
super
|
|
32
|
-
created(
|
|
34
|
+
created(_path(path))
|
|
33
35
|
end
|
|
34
36
|
end
|
|
35
37
|
|
|
@@ -53,7 +55,11 @@ module Hanami
|
|
|
53
55
|
end
|
|
54
56
|
|
|
55
57
|
def within_folder(path)
|
|
56
|
-
out.puts "-> Within #{path}
|
|
58
|
+
out.puts "-> Within #{_path(path)}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def _path(path)
|
|
62
|
+
path + ::File::SEPARATOR
|
|
57
63
|
end
|
|
58
64
|
end
|
|
59
65
|
end
|
|
@@ -4,8 +4,12 @@ module <%= camelized_app_name %>
|
|
|
4
4
|
module Actions
|
|
5
5
|
<%= module_controller_declaration %>
|
|
6
6
|
<%= module_controller_offset %>class <%= camelized_action_name %> < <%= camelized_app_name %>::Action
|
|
7
|
-
|
|
7
|
+
<%- if bundled_views? -%>
|
|
8
|
+
<%= module_controller_offset %> def handle(request, response)
|
|
9
|
+
<%- else -%>
|
|
10
|
+
<%= module_controller_offset %> def handle(request, response)
|
|
8
11
|
<%= module_controller_offset %> response.body = self.class.name
|
|
12
|
+
<%- end -%>
|
|
9
13
|
<%= module_controller_offset %> end
|
|
10
14
|
<%= module_controller_offset %>end
|
|
11
15
|
<%= module_controller_end %>
|
|
@@ -4,8 +4,12 @@ module <%= camelized_slice_name %>
|
|
|
4
4
|
module Actions
|
|
5
5
|
<%= module_controller_declaration %>
|
|
6
6
|
<%= module_controller_offset %>class <%= camelized_action_name %> < <%= camelized_slice_name %>::Action
|
|
7
|
-
|
|
7
|
+
<%- if bundled_views? -%>
|
|
8
|
+
<%= module_controller_offset %> def handle(request, response)
|
|
9
|
+
<%- else -%>
|
|
10
|
+
<%= module_controller_offset %> def handle(request, response)
|
|
8
11
|
<%= module_controller_offset %> response.body = self.class.name
|
|
12
|
+
<%- end -%>
|
|
9
13
|
<%= module_controller_offset %> end
|
|
10
14
|
<%= module_controller_offset %>end
|
|
11
15
|
<%= module_controller_end %>
|
|
@@ -19,11 +19,10 @@ module Hanami
|
|
|
19
19
|
@inflector = inflector
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
# rubocop:disable Layout/LineLength
|
|
23
|
-
|
|
24
22
|
# @since 2.0.0
|
|
25
23
|
# @api private
|
|
26
|
-
def call(app, controller, action, url, http, format, skip_view, slice, context:
|
|
24
|
+
def call(app, controller, action, url, http, format, skip_view, slice, context: nil)
|
|
25
|
+
context ||= ActionContext.new(inflector, app, slice, controller, action)
|
|
27
26
|
if slice
|
|
28
27
|
generate_for_slice(controller, action, url, http, format, skip_view, slice, context)
|
|
29
28
|
else
|
|
@@ -31,8 +30,6 @@ module Hanami
|
|
|
31
30
|
end
|
|
32
31
|
end
|
|
33
32
|
|
|
34
|
-
# rubocop:enable Layout/LineLength
|
|
35
|
-
|
|
36
33
|
private
|
|
37
34
|
|
|
38
35
|
ROUTE_HTTP_METHODS = %w[get post delete put patch trace options link unlink].freeze
|
|
@@ -59,6 +56,14 @@ module Hanami
|
|
|
59
56
|
}.freeze
|
|
60
57
|
private_constant :ROUTE_RESTFUL_URL_SUFFIXES
|
|
61
58
|
|
|
59
|
+
# @api private
|
|
60
|
+
# @since 2.1.0
|
|
61
|
+
RESTFUL_COUNTERPART_VIEWS = {
|
|
62
|
+
"create" => "new",
|
|
63
|
+
"update" => "edit"
|
|
64
|
+
}.freeze
|
|
65
|
+
private_constant :RESTFUL_COUNTERPART_VIEWS
|
|
66
|
+
|
|
62
67
|
PATH_SEPARATOR = "/"
|
|
63
68
|
private_constant :PATH_SEPARATOR
|
|
64
69
|
|
|
@@ -80,7 +85,7 @@ module Hanami
|
|
|
80
85
|
fs.mkdir(directory = fs.join(slice_directory, "actions", controller))
|
|
81
86
|
fs.write(fs.join(directory, "#{action}.rb"), t("slice_action.erb", context))
|
|
82
87
|
|
|
83
|
-
|
|
88
|
+
if generate_view?(skip_view, action, directory)
|
|
84
89
|
fs.mkdir(directory = fs.join(slice_directory, "views", controller))
|
|
85
90
|
fs.write(fs.join(directory, "#{action}.rb"), t("slice_view.erb", context))
|
|
86
91
|
|
|
@@ -100,12 +105,15 @@ module Hanami
|
|
|
100
105
|
fs.mkdir(directory = fs.join("app", "actions", controller))
|
|
101
106
|
fs.write(fs.join(directory, "#{action}.rb"), t("action.erb", context))
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
fs.write(fs.join(directory, "#{action}.rb"), t("view.erb", context))
|
|
108
|
+
view = action
|
|
109
|
+
view_directory = fs.join("app", "views", controller)
|
|
106
110
|
|
|
107
|
-
|
|
108
|
-
fs.
|
|
111
|
+
if generate_view?(skip_view, view, view_directory)
|
|
112
|
+
fs.mkdir(view_directory)
|
|
113
|
+
fs.write(fs.join(view_directory, "#{view}.rb"), t("view.erb", context))
|
|
114
|
+
|
|
115
|
+
fs.mkdir(template_directory = fs.join("app", "templates", controller))
|
|
116
|
+
fs.write(fs.join(template_directory, "#{view}.#{format}.erb"),
|
|
109
117
|
t(template_with_format_ext("template", format), context))
|
|
110
118
|
end
|
|
111
119
|
end
|
|
@@ -120,6 +128,35 @@ module Hanami
|
|
|
120
128
|
http)} "#{route_url(controller, action, url)}", to: "#{controller.join('.')}.#{action}")
|
|
121
129
|
end
|
|
122
130
|
|
|
131
|
+
# @api private
|
|
132
|
+
# @since 2.1.0
|
|
133
|
+
def generate_view?(skip_view, view, directory)
|
|
134
|
+
return false if skip_view
|
|
135
|
+
return generate_restful_view?(view, directory) if rest_view?(view)
|
|
136
|
+
|
|
137
|
+
true
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# @api private
|
|
141
|
+
# @since 2.1.0
|
|
142
|
+
def generate_restful_view?(view, directory)
|
|
143
|
+
corresponding_action = corresponding_restful_view(view)
|
|
144
|
+
|
|
145
|
+
!fs.exist?(fs.join(directory, "#{corresponding_action}.rb"))
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# @api private
|
|
149
|
+
# @since 2.1.0
|
|
150
|
+
def rest_view?(view)
|
|
151
|
+
RESTFUL_COUNTERPART_VIEWS.keys.include?(view)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# @api private
|
|
155
|
+
# @since 2.1.0
|
|
156
|
+
def corresponding_restful_view(view)
|
|
157
|
+
RESTFUL_COUNTERPART_VIEWS.fetch(view, nil)
|
|
158
|
+
end
|
|
159
|
+
|
|
123
160
|
def template_with_format_ext(name, format)
|
|
124
161
|
ext =
|
|
125
162
|
case format.to_sym
|
|
@@ -136,7 +173,7 @@ module Hanami
|
|
|
136
173
|
require "erb"
|
|
137
174
|
|
|
138
175
|
ERB.new(
|
|
139
|
-
File.read(__dir__ + "/action/#{path}")
|
|
176
|
+
File.read(__dir__ + "/action/#{path}"), trim_mode: "-",
|
|
140
177
|
).result(context.ctx)
|
|
141
178
|
end
|
|
142
179
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# auto_register: false
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module <%= camelized_app_name %>
|
|
5
|
+
module Views
|
|
6
|
+
module Parts
|
|
7
|
+
<%= module_namespace_declaration -%>
|
|
8
|
+
<%= module_namespace_offset %>class <%= camelized_name %> < <%= camelized_app_name %>::Views::Part
|
|
9
|
+
<%= module_namespace_offset %>end
|
|
10
|
+
<%= module_namespace_end -%>
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# auto_register: false
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module <%= camelized_slice_name %>
|
|
5
|
+
module Views
|
|
6
|
+
module Parts
|
|
7
|
+
<%= module_namespace_declaration -%>
|
|
8
|
+
<%= module_namespace_offset %>class <%= camelized_name %> < <%= camelized_slice_name %>::Views::Part
|
|
9
|
+
<%= module_namespace_offset %>end
|
|
10
|
+
<%= module_namespace_end -%>
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "erb"
|
|
4
|
+
require "dry/files"
|
|
5
|
+
require_relative "../../errors"
|
|
6
|
+
|
|
7
|
+
module Hanami
|
|
8
|
+
module CLI
|
|
9
|
+
module Generators
|
|
10
|
+
module App
|
|
11
|
+
# @since 2.1.0
|
|
12
|
+
# @api private
|
|
13
|
+
class Part
|
|
14
|
+
# @since 2.1.0
|
|
15
|
+
# @api private
|
|
16
|
+
def initialize(fs:, inflector:)
|
|
17
|
+
@fs = fs
|
|
18
|
+
@inflector = inflector
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @since 2.1.0
|
|
22
|
+
# @api private
|
|
23
|
+
def call(app, key, slice)
|
|
24
|
+
context = PartContext.new(inflector, app, slice, key)
|
|
25
|
+
|
|
26
|
+
if slice
|
|
27
|
+
generate_for_slice(context, slice)
|
|
28
|
+
else
|
|
29
|
+
generate_for_app(context)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
# @since 2.1.0
|
|
36
|
+
# @api private
|
|
37
|
+
attr_reader :fs
|
|
38
|
+
|
|
39
|
+
# @since 2.1.0
|
|
40
|
+
# @api private
|
|
41
|
+
attr_reader :inflector
|
|
42
|
+
|
|
43
|
+
# @since 2.1.0
|
|
44
|
+
# @api private
|
|
45
|
+
def generate_for_slice(context, slice)
|
|
46
|
+
slice_directory = fs.join("slices", slice)
|
|
47
|
+
raise MissingSliceError.new(slice) unless fs.directory?(slice_directory)
|
|
48
|
+
|
|
49
|
+
generate_base_part_for_app(context)
|
|
50
|
+
generate_base_part_for_slice(context, slice)
|
|
51
|
+
|
|
52
|
+
fs.mkdir(directory = fs.join(slice_directory, "views", "parts", *context.underscored_namespace))
|
|
53
|
+
fs.write(fs.join(directory, "#{context.underscored_name}.rb"), t("slice_part.erb", context))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @since 2.1.0
|
|
57
|
+
# @api private
|
|
58
|
+
def generate_for_app(context)
|
|
59
|
+
generate_base_part_for_app(context)
|
|
60
|
+
|
|
61
|
+
fs.mkdir(directory = fs.join("app", "views", "parts", *context.underscored_namespace))
|
|
62
|
+
fs.write(fs.join(directory, "#{context.underscored_name}.rb"), t("app_part.erb", context))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @since 2.1.0
|
|
66
|
+
# @api private
|
|
67
|
+
def generate_base_part_for_app(context)
|
|
68
|
+
path = fs.join("app", "views", "part.rb")
|
|
69
|
+
return if fs.exist?(path)
|
|
70
|
+
|
|
71
|
+
fs.write(path, t("app_base_part.erb", context))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# @since 2.1.0
|
|
75
|
+
# @api private
|
|
76
|
+
def generate_base_part_for_slice(context, slice)
|
|
77
|
+
path = fs.join("slices", slice, "views", "part.rb")
|
|
78
|
+
return if fs.exist?(path)
|
|
79
|
+
|
|
80
|
+
fs.write(path, t("slice_base_part.erb", context))
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# @since 2.1.0
|
|
84
|
+
# @api private
|
|
85
|
+
def template(path, context)
|
|
86
|
+
require "erb"
|
|
87
|
+
|
|
88
|
+
ERB.new(
|
|
89
|
+
File.read(__dir__ + "/part/#{path}"),
|
|
90
|
+
trim_mode: "-"
|
|
91
|
+
).result(context.ctx)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# @since 2.1.0
|
|
95
|
+
# @api private
|
|
96
|
+
alias_method :t, :template
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "slice_context"
|
|
4
|
+
require "dry/files/path"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
module CLI
|
|
8
|
+
module Generators
|
|
9
|
+
# @since 2.1.0
|
|
10
|
+
# @api private
|
|
11
|
+
module App
|
|
12
|
+
# @since 2.1.0
|
|
13
|
+
# @api private
|
|
14
|
+
class PartContext < SliceContext
|
|
15
|
+
# TODO: move these constants somewhere that will let us reuse them
|
|
16
|
+
|
|
17
|
+
# @since 2.1.0
|
|
18
|
+
# @api private
|
|
19
|
+
KEY_SEPARATOR = "."
|
|
20
|
+
private_constant :KEY_SEPARATOR
|
|
21
|
+
|
|
22
|
+
# @since 2.1.0
|
|
23
|
+
# @api private
|
|
24
|
+
INDENTATION = " "
|
|
25
|
+
private_constant :INDENTATION
|
|
26
|
+
|
|
27
|
+
# @since 2.1.0
|
|
28
|
+
# @api private
|
|
29
|
+
OFFSET = INDENTATION * 2
|
|
30
|
+
private_constant :OFFSET
|
|
31
|
+
|
|
32
|
+
# @since 2.1.0
|
|
33
|
+
# @api private
|
|
34
|
+
attr_reader :key
|
|
35
|
+
|
|
36
|
+
# @since 2.1.0
|
|
37
|
+
# @api private
|
|
38
|
+
def initialize(inflector, app, slice, key)
|
|
39
|
+
@key = key
|
|
40
|
+
super(inflector, app, slice, nil)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @since 2.1.0
|
|
44
|
+
# @api private
|
|
45
|
+
def namespaces
|
|
46
|
+
@namespaces ||= key.split(KEY_SEPARATOR)[..-2]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @since 2.1.0
|
|
50
|
+
# @api private
|
|
51
|
+
def name
|
|
52
|
+
@name ||= key.split(KEY_SEPARATOR)[-1]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @since 2.1.0
|
|
56
|
+
# @api private
|
|
57
|
+
def camelized_name
|
|
58
|
+
inflector.camelize(name)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @since 2.1.0
|
|
62
|
+
# @api private
|
|
63
|
+
def underscored_namespace
|
|
64
|
+
namespaces.map { inflector.underscore(_1) }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @since 2.1.0
|
|
68
|
+
# @api private
|
|
69
|
+
def underscored_name
|
|
70
|
+
inflector.underscore(name)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @since 2.1.0
|
|
74
|
+
# @api private
|
|
75
|
+
def module_namespace_declaration
|
|
76
|
+
namespaces.each_with_index.map { |token, i|
|
|
77
|
+
"#{OFFSET}#{INDENTATION * i}module #{inflector.camelize(token)}"
|
|
78
|
+
}.join($/)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @since 2.1.0
|
|
82
|
+
# @api private
|
|
83
|
+
def module_namespace_end
|
|
84
|
+
namespaces.each_with_index.map { |_, i|
|
|
85
|
+
"#{OFFSET}#{INDENTATION * i}end"
|
|
86
|
+
}.reverse.join($/)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# @since 2.1.0
|
|
90
|
+
# @api private
|
|
91
|
+
def module_namespace_offset
|
|
92
|
+
"#{OFFSET}#{INDENTATION * namespaces.count}"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "../css/app.css";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title><%= humanized_app_name %> - <%= humanized_slice_name %></title>
|
|
7
|
+
<%- if bundled_assets? -%>
|
|
8
|
+
<%%= favicon %>
|
|
9
|
+
<%= stylesheet_erb_tag %>
|
|
10
|
+
<%- end -%>
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<%%= yield %>
|
|
14
|
+
<%- if bundled_assets? -%>
|
|
15
|
+
<%= javascript_erb_tag %>
|
|
16
|
+
<%- end -%>
|
|
17
|
+
</body>
|
|
18
|
+
</html>
|
|
@@ -30,8 +30,13 @@ module Hanami
|
|
|
30
30
|
fs.write(fs.join(directory, "action.rb"), t("action.erb", context))
|
|
31
31
|
fs.write(fs.join(directory, "view.rb"), t("view.erb", context))
|
|
32
32
|
fs.write(fs.join(directory, "views", "helpers.rb"), t("helpers.erb", context))
|
|
33
|
-
fs.write(fs.join(directory, "templates", "layouts", "app.html.erb"),
|
|
34
|
-
|
|
33
|
+
fs.write(fs.join(directory, "templates", "layouts", "app.html.erb"), t("app_layout.erb", context))
|
|
34
|
+
|
|
35
|
+
if context.bundled_assets?
|
|
36
|
+
fs.write(fs.join(directory, "assets", "js", "app.js"), t("app_js.erb", context))
|
|
37
|
+
fs.write(fs.join(directory, "assets", "css", "app.css"), t("app_css.erb", context))
|
|
38
|
+
end
|
|
39
|
+
|
|
35
40
|
# fs.write(fs.join(directory, "/entities.rb"), t("entities.erb", context))
|
|
36
41
|
# fs.write(fs.join(directory, "/repository.rb"), t("repository.erb", context))
|
|
37
42
|
|
|
@@ -53,7 +58,8 @@ module Hanami
|
|
|
53
58
|
require "erb"
|
|
54
59
|
|
|
55
60
|
ERB.new(
|
|
56
|
-
File.read(__dir__ + "/slice/#{path}")
|
|
61
|
+
File.read(__dir__ + "/slice/#{path}"),
|
|
62
|
+
trim_mode: "-"
|
|
57
63
|
).result(context.ctx)
|
|
58
64
|
end
|
|
59
65
|
|
|
@@ -29,6 +29,24 @@ module Hanami
|
|
|
29
29
|
inflector.underscore(slice)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
# @since 2.1.0
|
|
33
|
+
# @api private
|
|
34
|
+
def humanized_slice_name
|
|
35
|
+
inflector.humanize(slice)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @since 2.1.0
|
|
39
|
+
# @api private
|
|
40
|
+
def stylesheet_erb_tag
|
|
41
|
+
%(<%= css "#{slice}/app" %>)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @since 2.1.0
|
|
45
|
+
# @api private
|
|
46
|
+
def javascript_erb_tag
|
|
47
|
+
%(<%= js "#{slice}/app" %>)
|
|
48
|
+
end
|
|
49
|
+
|
|
32
50
|
private
|
|
33
51
|
|
|
34
52
|
attr_reader :slice
|