hanami-cli 2.2.0 → 2.3.0.beta1
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/.github/workflows/ci.yml +9 -0
- data/CHANGELOG.md +43 -0
- data/Gemfile +3 -1
- data/hanami-cli.gemspec +2 -0
- data/lib/hanami/cli/command.rb +5 -11
- data/lib/hanami/cli/commands/app/command.rb +5 -5
- data/lib/hanami/cli/commands/app/console.rb +1 -0
- data/lib/hanami/cli/commands/app/db/command.rb +0 -1
- data/lib/hanami/cli/commands/app/db/drop.rb +2 -2
- data/lib/hanami/cli/commands/app/db/rollback.rb +204 -0
- data/lib/hanami/cli/commands/app/db/utils/mysql.rb +3 -2
- data/lib/hanami/cli/commands/app/db/utils/postgres.rb +3 -1
- data/lib/hanami/cli/commands/app/generate/action.rb +32 -40
- data/lib/hanami/cli/commands/app/generate/command.rb +54 -17
- data/lib/hanami/cli/commands/app/generate/component.rb +4 -19
- data/lib/hanami/cli/commands/app/generate/part.rb +4 -21
- data/lib/hanami/cli/commands/app/generate/slice.rb +2 -2
- data/lib/hanami/cli/commands/app/generate/view.rb +5 -24
- data/lib/hanami/cli/commands/app/install.rb +12 -0
- data/lib/hanami/cli/commands/app/server.rb +0 -1
- data/lib/hanami/cli/commands/app.rb +1 -0
- data/lib/hanami/cli/commands/gem/new.rb +37 -7
- data/lib/hanami/cli/errors.rb +26 -0
- data/lib/hanami/cli/files.rb +20 -6
- data/lib/hanami/cli/generators/app/action.rb +78 -101
- data/lib/hanami/cli/generators/app/component.rb +11 -33
- data/lib/hanami/cli/generators/app/migration.rb +1 -1
- data/lib/hanami/cli/generators/app/operation.rb +4 -5
- data/lib/hanami/cli/generators/app/part.rb +42 -65
- data/lib/hanami/cli/generators/app/relation.rb +4 -5
- data/lib/hanami/cli/generators/app/repo.rb +3 -5
- data/lib/hanami/cli/generators/app/ruby_class_file.rb +32 -0
- data/lib/hanami/cli/generators/app/ruby_file.rb +128 -0
- data/lib/hanami/cli/generators/app/ruby_module_file.rb +28 -0
- data/lib/hanami/cli/generators/app/slice.rb +130 -37
- data/lib/hanami/cli/generators/app/struct.rb +3 -4
- data/lib/hanami/cli/generators/app/view.rb +40 -45
- data/lib/hanami/cli/generators/context.rb +6 -0
- data/lib/hanami/cli/generators/gem/app/assets.js +14 -13
- data/lib/hanami/cli/generators/gem/app/dev +1 -1
- data/lib/hanami/cli/generators/gem/app/gemfile.erb +5 -0
- data/lib/hanami/cli/generators/gem/app/gitignore.erb +3 -1
- data/lib/hanami/cli/generators/gem/app/rakefile.erb +3 -0
- data/lib/hanami/cli/generators/gem/app/readme.erb +14 -0
- data/lib/hanami/cli/generators/gem/app.rb +40 -37
- data/lib/hanami/cli/ruby_file_generator.rb +17 -8
- data/lib/hanami/cli/server.rb +15 -1
- data/lib/hanami/cli/version.rb +1 -1
- data/lib/hanami/console/context.rb +5 -0
- metadata +35 -41
- data/lib/hanami/cli/generators/app/action/action.erb +0 -17
- data/lib/hanami/cli/generators/app/action/slice_action.erb +0 -17
- data/lib/hanami/cli/generators/app/action/slice_template.html.erb +0 -1
- data/lib/hanami/cli/generators/app/action/slice_view.erb +0 -10
- data/lib/hanami/cli/generators/app/action/template.erb +0 -0
- data/lib/hanami/cli/generators/app/action/template.html.erb +0 -1
- data/lib/hanami/cli/generators/app/action/view.erb +0 -10
- data/lib/hanami/cli/generators/app/action_context.rb +0 -90
- data/lib/hanami/cli/generators/app/component/component.erb +0 -8
- data/lib/hanami/cli/generators/app/component/slice_component.erb +0 -8
- data/lib/hanami/cli/generators/app/component_context.rb +0 -82
- data/lib/hanami/cli/generators/app/part/app_base_part.erb +0 -9
- data/lib/hanami/cli/generators/app/part/app_part.erb +0 -13
- data/lib/hanami/cli/generators/app/part/slice_base_part.erb +0 -9
- data/lib/hanami/cli/generators/app/part/slice_part.erb +0 -13
- data/lib/hanami/cli/generators/app/part_context.rb +0 -82
- data/lib/hanami/cli/generators/app/ruby_file_writer.rb +0 -151
- data/lib/hanami/cli/generators/app/slice/action.erb +0 -7
- data/lib/hanami/cli/generators/app/slice/app_css.erb +0 -5
- data/lib/hanami/cli/generators/app/slice/app_js.erb +0 -1
- data/lib/hanami/cli/generators/app/slice/app_layout.erb +0 -18
- data/lib/hanami/cli/generators/app/slice/helpers.erb +0 -10
- data/lib/hanami/cli/generators/app/slice/keep.erb +0 -0
- data/lib/hanami/cli/generators/app/slice/operation.erb +0 -7
- data/lib/hanami/cli/generators/app/slice/relation.erb +0 -8
- data/lib/hanami/cli/generators/app/slice/repo.erb +0 -8
- data/lib/hanami/cli/generators/app/slice/routes.erb +0 -3
- data/lib/hanami/cli/generators/app/slice/struct.erb +0 -8
- data/lib/hanami/cli/generators/app/slice/view.erb +0 -7
- data/lib/hanami/cli/generators/app/slice_context.rb +0 -72
- data/lib/hanami/cli/generators/app/view/app_template.html.erb +0 -1
- data/lib/hanami/cli/generators/app/view/app_view.erb +0 -10
- data/lib/hanami/cli/generators/app/view/slice_template.html.erb +0 -1
- data/lib/hanami/cli/generators/app/view/slice_view.erb +0 -10
- data/lib/hanami/cli/generators/app/view_context.rb +0 -88
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "erb"
|
4
3
|
require "dry/files"
|
4
|
+
require_relative "../constants"
|
5
5
|
require_relative "../../errors"
|
6
6
|
|
7
7
|
# rubocop:disable Metrics/ParameterLists
|
@@ -14,20 +14,25 @@ module Hanami
|
|
14
14
|
class Action
|
15
15
|
# @since 2.0.0
|
16
16
|
# @api private
|
17
|
-
def initialize(fs:, inflector:)
|
17
|
+
def initialize(fs:, inflector:, out: $stdout)
|
18
18
|
@fs = fs
|
19
19
|
@inflector = inflector
|
20
|
+
@out = out
|
21
|
+
@view_generator = Generators::App::View.new(
|
22
|
+
fs: fs,
|
23
|
+
inflector: inflector,
|
24
|
+
out: out
|
25
|
+
)
|
20
26
|
end
|
21
27
|
|
22
28
|
# @since 2.0.0
|
23
29
|
# @api private
|
24
|
-
def call(
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
30
|
+
def call(key:, namespace:, base_path:, url_path:, http_method:, skip_view:, skip_route:)
|
31
|
+
insert_route(key:, namespace:, url_path:, http_method:) unless skip_route
|
32
|
+
|
33
|
+
generate_action(key:, namespace:, base_path:, include_placeholder_body: skip_view)
|
34
|
+
|
35
|
+
generate_view(key:, namespace:, base_path:) unless skip_view
|
31
36
|
end
|
32
37
|
|
33
38
|
private
|
@@ -67,86 +72,76 @@ module Hanami
|
|
67
72
|
PATH_SEPARATOR = "/"
|
68
73
|
private_constant :PATH_SEPARATOR
|
69
74
|
|
70
|
-
attr_reader :fs
|
71
|
-
|
72
|
-
attr_reader :inflector
|
73
|
-
|
74
|
-
# rubocop:disable Metrics/AbcSize
|
75
|
-
def generate_for_slice(controller, action, url, http, format, skip_view, skip_route, slice, context)
|
76
|
-
slice_directory = fs.join("slices", slice)
|
77
|
-
raise MissingSliceError.new(slice) unless fs.directory?(slice_directory)
|
78
|
-
|
79
|
-
if generate_route?(skip_route)
|
80
|
-
fs.inject_line_at_block_bottom(
|
81
|
-
fs.join("config", "routes.rb"),
|
82
|
-
slice_matcher(slice),
|
83
|
-
route(controller, action, url, http)
|
84
|
-
)
|
85
|
-
end
|
86
|
-
|
87
|
-
fs.mkdir(directory = fs.join(slice_directory, "actions", controller))
|
88
|
-
fs.write(fs.join(directory, "#{action}.rb"), t("slice_action.erb", context))
|
75
|
+
attr_reader :fs, :inflector, :out, :view_generator
|
89
76
|
|
90
|
-
|
91
|
-
|
92
|
-
|
77
|
+
# @api private
|
78
|
+
# @since 2.2.2
|
79
|
+
def insert_route(key:, namespace:, url_path:, http_method:)
|
80
|
+
routes_location = fs.join("config", "routes.rb")
|
81
|
+
route = route_definition(key:, url_path:, http_method:)
|
93
82
|
|
94
|
-
|
95
|
-
fs.
|
96
|
-
|
83
|
+
if namespace == Hanami.app.namespace
|
84
|
+
fs.inject_line_at_class_bottom(routes_location, "class Routes", route)
|
85
|
+
else
|
86
|
+
slice_matcher = /slice[[:space:]]*:#{namespace}/
|
87
|
+
fs.inject_line_at_block_bottom(routes_location, slice_matcher, route)
|
97
88
|
end
|
98
89
|
end
|
99
90
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
91
|
+
# @api private
|
92
|
+
# @since 2.2.2
|
93
|
+
def generate_action(key:, namespace:, base_path:, include_placeholder_body:)
|
94
|
+
RubyClassFile.new(
|
95
|
+
fs: fs,
|
96
|
+
inflector: inflector,
|
97
|
+
namespace: namespace,
|
98
|
+
key: inflector.underscore(key),
|
99
|
+
base_path: base_path,
|
100
|
+
parent_class_name: "#{inflector.camelize(namespace)}::Action",
|
101
|
+
extra_namespace: "Actions",
|
102
|
+
body: [
|
103
|
+
"def handle(request, response)",
|
104
|
+
(" response.body = self.class.name" if include_placeholder_body),
|
105
|
+
"end"
|
106
|
+
].compact
|
107
|
+
).create
|
108
|
+
end
|
111
109
|
|
112
|
-
|
113
|
-
|
110
|
+
# @api private
|
111
|
+
# @since 2.2.2
|
112
|
+
def generate_view(key:, namespace:, base_path:)
|
113
|
+
*controller_name_parts, action_name = key.split(KEY_SEPARATOR)
|
114
114
|
|
115
|
-
|
116
|
-
fs.mkdir(view_directory)
|
117
|
-
fs.write(fs.join(view_directory, "#{view}.rb"), t("view.erb", context))
|
115
|
+
view_directory = fs.join(base_path, "views", controller_name_parts)
|
118
116
|
|
119
|
-
|
120
|
-
|
121
|
-
|
117
|
+
if generate_view?(action_name, view_directory)
|
118
|
+
view_generator.call(
|
119
|
+
key: key,
|
120
|
+
namespace: namespace,
|
121
|
+
base_path: base_path,
|
122
|
+
)
|
122
123
|
end
|
123
124
|
end
|
124
|
-
# rubocop:enable Metrics/AbcSize
|
125
|
-
|
126
|
-
def slice_matcher(slice)
|
127
|
-
/slice[[:space:]]*:#{slice}/
|
128
|
-
end
|
129
|
-
|
130
|
-
def route(controller, action, url, http)
|
131
|
-
%(#{route_http(action,
|
132
|
-
http)} "#{route_url(controller, action, url)}", to: "#{controller.join('.')}.#{action}")
|
133
|
-
end
|
134
125
|
|
135
126
|
# @api private
|
136
|
-
# @since 2.
|
137
|
-
def
|
138
|
-
|
139
|
-
|
127
|
+
# @since 2.2.2
|
128
|
+
def route_definition(key:, url_path:, http_method:)
|
129
|
+
*controller_name_parts, action_name = key.split(KEY_SEPARATOR)
|
130
|
+
|
131
|
+
method = route_http(action_name, http_method)
|
132
|
+
path = route_url(controller_name_parts, action_name, url_path)
|
140
133
|
|
141
|
-
|
134
|
+
%(#{method} "#{path}", to: "#{key}")
|
142
135
|
end
|
143
136
|
|
144
137
|
# @api private
|
145
|
-
# @since 2.
|
146
|
-
def
|
147
|
-
|
148
|
-
|
149
|
-
|
138
|
+
# @since 2.1.0
|
139
|
+
def generate_view?(action_name, directory)
|
140
|
+
if rest_view?(action_name)
|
141
|
+
generate_restful_view?(action_name, directory)
|
142
|
+
else
|
143
|
+
true
|
144
|
+
end
|
150
145
|
end
|
151
146
|
|
152
147
|
# @api private
|
@@ -169,40 +164,22 @@ module Hanami
|
|
169
164
|
RESTFUL_COUNTERPART_VIEWS.fetch(view, nil)
|
170
165
|
end
|
171
166
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
when :html
|
176
|
-
".html.erb"
|
177
|
-
else
|
178
|
-
".erb"
|
179
|
-
end
|
180
|
-
|
181
|
-
"#{name}#{ext}"
|
182
|
-
end
|
183
|
-
|
184
|
-
def template(path, context)
|
185
|
-
require "erb"
|
186
|
-
|
187
|
-
ERB.new(
|
188
|
-
File.read(__dir__ + "/action/#{path}"), trim_mode: "-",
|
189
|
-
).result(context.ctx)
|
190
|
-
end
|
191
|
-
|
192
|
-
alias_method :t, :template
|
193
|
-
|
194
|
-
def route_url(controller, action, url)
|
167
|
+
# @api private
|
168
|
+
# @since 2.1.0
|
169
|
+
def route_url(controller, action, url_path)
|
195
170
|
action = ROUTE_RESTFUL_URL_SUFFIXES.fetch(action) { [action] }
|
196
|
-
|
171
|
+
url_path ||= "#{PATH_SEPARATOR}#{(controller + action).join(PATH_SEPARATOR)}"
|
197
172
|
|
198
|
-
CLI::URL.call(
|
173
|
+
CLI::URL.call(url_path)
|
199
174
|
end
|
200
175
|
|
201
|
-
|
202
|
-
|
176
|
+
# @api private
|
177
|
+
# @since 2.1.0
|
178
|
+
def route_http(action, http_method)
|
179
|
+
result = (http_method ||= ROUTE_RESTFUL_HTTP_METHODS.fetch(action, ROUTE_DEFAULT_HTTP_METHOD)).downcase
|
203
180
|
|
204
181
|
unless ROUTE_HTTP_METHODS.include?(result)
|
205
|
-
raise UnknownHTTPMethodError.new(
|
182
|
+
raise UnknownHTTPMethodError.new(http_method)
|
206
183
|
end
|
207
184
|
|
208
185
|
result
|
@@ -12,49 +12,27 @@ module Hanami
|
|
12
12
|
class Component
|
13
13
|
# @api private
|
14
14
|
# @since 2.2.0
|
15
|
-
def initialize(fs:, inflector:)
|
15
|
+
def initialize(fs:, inflector:, out: $stdout)
|
16
16
|
@fs = fs
|
17
17
|
@inflector = inflector
|
18
|
+
@out = out
|
18
19
|
end
|
19
20
|
|
20
21
|
# @api private
|
21
22
|
# @since 2.2.0
|
22
|
-
def call(
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
def call(key:, namespace:, base_path:)
|
24
|
+
RubyClassFile.new(
|
25
|
+
fs: fs,
|
26
|
+
inflector: inflector,
|
27
|
+
key: inflector.underscore(key),
|
28
|
+
namespace: namespace,
|
29
|
+
base_path: base_path,
|
30
|
+
).create
|
30
31
|
end
|
31
32
|
|
32
33
|
private
|
33
34
|
|
34
|
-
attr_reader :fs
|
35
|
-
|
36
|
-
attr_reader :inflector
|
37
|
-
|
38
|
-
def generate_for_slice(context, slice)
|
39
|
-
slice_directory = fs.join("slices", slice)
|
40
|
-
raise MissingSliceError.new(slice) unless fs.directory?(slice_directory)
|
41
|
-
|
42
|
-
fs.mkdir(directory = fs.join(slice_directory, context.namespaces))
|
43
|
-
fs.write(fs.join(directory, "#{context.underscored_name}.rb"), t("slice_component.erb", context))
|
44
|
-
end
|
45
|
-
|
46
|
-
def generate_for_app(context)
|
47
|
-
fs.mkdir(directory = fs.join("app", context.namespaces))
|
48
|
-
fs.write(fs.join(directory, "#{context.underscored_name}.rb"), t("component.erb", context))
|
49
|
-
end
|
50
|
-
|
51
|
-
def template(path, context)
|
52
|
-
ERB.new(
|
53
|
-
File.read(__dir__ + "/component/#{path}")
|
54
|
-
).result(context.ctx)
|
55
|
-
end
|
56
|
-
|
57
|
-
alias_method :t, :template
|
35
|
+
attr_reader :fs, :inflector, :out
|
58
36
|
end
|
59
37
|
end
|
60
38
|
end
|
@@ -20,16 +20,15 @@ module Hanami
|
|
20
20
|
# @since 2.2.0
|
21
21
|
# @api private
|
22
22
|
def call(key:, namespace:, base_path:)
|
23
|
-
|
23
|
+
RubyClassFile.new(
|
24
24
|
fs: fs,
|
25
25
|
inflector: inflector,
|
26
|
-
|
26
|
+
key: key,
|
27
27
|
namespace: namespace,
|
28
28
|
base_path: base_path,
|
29
|
-
|
30
|
-
relative_parent_class: "Operation",
|
29
|
+
parent_class_name: "#{inflector.camelize(namespace)}::Operation",
|
31
30
|
body: ["def call", "end"],
|
32
|
-
)
|
31
|
+
).create
|
33
32
|
|
34
33
|
unless key.match?(KEY_SEPARATOR)
|
35
34
|
out.puts(
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require "erb"
|
4
4
|
require "dry/files"
|
5
|
-
require_relative "../../errors"
|
6
5
|
|
7
6
|
module Hanami
|
8
7
|
module CLI
|
@@ -13,87 +12,65 @@ module Hanami
|
|
13
12
|
class Part
|
14
13
|
# @since 2.1.0
|
15
14
|
# @api private
|
16
|
-
def initialize(fs:, inflector:)
|
15
|
+
def initialize(fs:, inflector:, out: $stdout)
|
17
16
|
@fs = fs
|
18
17
|
@inflector = inflector
|
18
|
+
@out = out
|
19
19
|
end
|
20
20
|
|
21
21
|
# @since 2.1.0
|
22
22
|
# @api private
|
23
|
-
def call(
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
generate_for_slice(context, slice)
|
28
|
-
else
|
29
|
-
generate_for_app(context)
|
30
|
-
end
|
23
|
+
def call(key:, namespace:, base_path:, **)
|
24
|
+
create_app_base_part_if_missing(key:, namespace:, base_path:)
|
25
|
+
create_slice_part_if_missing(key:, namespace:, base_path:) unless namespace == Hanami.app.namespace
|
26
|
+
create_generated_part(key:, namespace:, base_path:)
|
31
27
|
end
|
32
28
|
|
33
29
|
private
|
34
30
|
|
35
31
|
# @since 2.1.0
|
36
32
|
# @api private
|
37
|
-
attr_reader :fs
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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))
|
33
|
+
attr_reader :fs, :inflector, :out
|
34
|
+
|
35
|
+
def create_app_base_part_if_missing(key:, namespace:, base_path:)
|
36
|
+
return if fs.exist?(fs.join(base_path, "views", "part.rb"))
|
37
|
+
|
38
|
+
RubyClassFile.new(
|
39
|
+
fs: fs,
|
40
|
+
inflector: inflector,
|
41
|
+
namespace: Hanami.app.namespace,
|
42
|
+
key: "views.part",
|
43
|
+
base_path: APP_DIR,
|
44
|
+
parent_class_name: "Hanami::View::Part",
|
45
|
+
auto_register: false
|
46
|
+
).create
|
72
47
|
end
|
73
48
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
49
|
+
def create_slice_part_if_missing(key:, namespace:, base_path:)
|
50
|
+
return if fs.exist?(fs.join(base_path, "views", "part.rb"))
|
51
|
+
|
52
|
+
RubyClassFile.new(
|
53
|
+
fs: fs,
|
54
|
+
inflector: inflector,
|
55
|
+
namespace: namespace,
|
56
|
+
key: "views.part",
|
57
|
+
base_path: base_path,
|
58
|
+
parent_class_name: "#{Hanami.app.namespace}::Views::Part",
|
59
|
+
auto_register: false
|
60
|
+
).create
|
81
61
|
end
|
82
62
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
63
|
+
def create_generated_part(key:, namespace:, base_path:)
|
64
|
+
RubyClassFile.new(
|
65
|
+
fs: fs,
|
66
|
+
inflector: inflector,
|
67
|
+
namespace: namespace,
|
68
|
+
key: inflector.underscore("views.parts.#{key}"),
|
69
|
+
base_path: base_path,
|
70
|
+
parent_class_name: "#{inflector.camelize(namespace)}::Views::Part",
|
71
|
+
auto_register: false
|
72
|
+
).create
|
92
73
|
end
|
93
|
-
|
94
|
-
# @since 2.1.0
|
95
|
-
# @api private
|
96
|
-
alias_method :t, :template
|
97
74
|
end
|
98
75
|
end
|
99
76
|
end
|
@@ -25,17 +25,16 @@ module Hanami
|
|
25
25
|
|
26
26
|
body_content.prepend("gateway :#{gateway}") if gateway
|
27
27
|
|
28
|
-
|
28
|
+
RubyClassFile.new(
|
29
29
|
fs: fs,
|
30
30
|
inflector: inflector,
|
31
|
-
).call(
|
32
|
-
namespace: namespace,
|
33
31
|
key: key,
|
32
|
+
namespace: namespace,
|
34
33
|
base_path: base_path,
|
35
34
|
extra_namespace: "Relations",
|
36
|
-
|
35
|
+
parent_class_name: "#{inflector.camelize(namespace)}::DB::Relation",
|
37
36
|
body: body_content,
|
38
|
-
)
|
37
|
+
).create
|
39
38
|
end
|
40
39
|
|
41
40
|
private
|
@@ -18,17 +18,15 @@ module Hanami
|
|
18
18
|
# @since 2.2.0
|
19
19
|
# @api private
|
20
20
|
def call(key:, namespace:, base_path:)
|
21
|
-
|
21
|
+
RubyClassFile.new(
|
22
22
|
fs: fs,
|
23
23
|
inflector: inflector,
|
24
|
-
).call(
|
25
24
|
key: key,
|
26
25
|
namespace: namespace,
|
27
26
|
base_path: base_path,
|
28
27
|
extra_namespace: "Repos",
|
29
|
-
|
30
|
-
|
31
|
-
)
|
28
|
+
parent_class_name: "#{inflector.camelize(namespace)}::DB::Repo",
|
29
|
+
).create
|
32
30
|
end
|
33
31
|
|
34
32
|
private
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../constants"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
module CLI
|
7
|
+
module Generators
|
8
|
+
module App
|
9
|
+
# @api private
|
10
|
+
class RubyClassFile < RubyFile
|
11
|
+
def initialize(parent_class_name: nil, **args)
|
12
|
+
super
|
13
|
+
|
14
|
+
@parent_class_name = parent_class_name
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :parent_class_name
|
20
|
+
|
21
|
+
def class_name
|
22
|
+
constant_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def modules
|
26
|
+
namespace_modules
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../constants"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
module CLI
|
7
|
+
module Generators
|
8
|
+
module App
|
9
|
+
# @api private
|
10
|
+
class RubyFile
|
11
|
+
def initialize(
|
12
|
+
fs:,
|
13
|
+
inflector:,
|
14
|
+
key:,
|
15
|
+
namespace:,
|
16
|
+
base_path:,
|
17
|
+
extra_namespace: nil,
|
18
|
+
auto_register: nil,
|
19
|
+
body: [],
|
20
|
+
**opts
|
21
|
+
)
|
22
|
+
@fs = fs
|
23
|
+
@inflector = inflector
|
24
|
+
@key = key
|
25
|
+
@namespace = namespace
|
26
|
+
@base_path = base_path
|
27
|
+
@extra_namespace = extra_namespace&.downcase
|
28
|
+
@auto_register = auto_register
|
29
|
+
@body = body
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
def create
|
34
|
+
fs.create(path, file_contents)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @api private
|
38
|
+
def write
|
39
|
+
fs.write(path, file_contents)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @api private
|
43
|
+
def fully_qualified_name
|
44
|
+
inflector.camelize(
|
45
|
+
[namespace, extra_namespace, *key_parts].join("/"),
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
# @api private
|
50
|
+
def path
|
51
|
+
fs.join(directory, "#{key_parts.last}.rb")
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# @api private
|
57
|
+
attr_reader(
|
58
|
+
:fs,
|
59
|
+
:inflector,
|
60
|
+
:key,
|
61
|
+
:base_path,
|
62
|
+
:namespace,
|
63
|
+
:extra_namespace,
|
64
|
+
:auto_register,
|
65
|
+
:body,
|
66
|
+
)
|
67
|
+
|
68
|
+
# @api private
|
69
|
+
def file_contents
|
70
|
+
RubyFileGenerator.new(
|
71
|
+
# These first three must be implemented by subclasses
|
72
|
+
class_name: class_name,
|
73
|
+
parent_class_name: parent_class_name,
|
74
|
+
modules: modules,
|
75
|
+
header: headers,
|
76
|
+
body: body
|
77
|
+
).call
|
78
|
+
end
|
79
|
+
|
80
|
+
# @api private
|
81
|
+
def local_namespaces
|
82
|
+
Array(extra_namespace) + key_parts[..-2]
|
83
|
+
end
|
84
|
+
|
85
|
+
# @api private
|
86
|
+
def namespace_modules
|
87
|
+
[namespace, *local_namespaces]
|
88
|
+
.map { normalize(_1) }
|
89
|
+
.compact
|
90
|
+
end
|
91
|
+
|
92
|
+
# @api private
|
93
|
+
def directory
|
94
|
+
@directory ||= if local_namespaces.any?
|
95
|
+
fs.join(base_path, local_namespaces)
|
96
|
+
else
|
97
|
+
base_path
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# @api private
|
102
|
+
def constant_name
|
103
|
+
normalize(key_parts.last)
|
104
|
+
end
|
105
|
+
|
106
|
+
# @api private
|
107
|
+
def headers
|
108
|
+
[
|
109
|
+
# Intentional ternary logic. Skip if nil, else 'true' or 'false'
|
110
|
+
("# auto_register: #{auto_register}" unless auto_register.nil?),
|
111
|
+
"# frozen_string_literal: true",
|
112
|
+
].compact
|
113
|
+
end
|
114
|
+
|
115
|
+
# @api private
|
116
|
+
def normalize(name)
|
117
|
+
inflector.camelize(name).gsub(/[^\p{Alnum}]/, "")
|
118
|
+
end
|
119
|
+
|
120
|
+
# @api private
|
121
|
+
def key_parts
|
122
|
+
key.split(KEY_SEPARATOR)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|