hanami-cli 2.3.5 → 3.0.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 +38 -5
- data/README.md +6 -1
- data/hanami-cli.gemspec +2 -3
- data/lib/hanami/cli/commands/app/db/migrate.rb +4 -4
- data/lib/hanami/cli/commands/app/db/utils/postgres.rb +4 -6
- data/lib/hanami/cli/commands/app/generate/action.rb +31 -7
- data/lib/hanami/cli/commands/app/generate/component.rb +2 -0
- data/lib/hanami/cli/commands/app/generate/mailer.rb +52 -0
- data/lib/hanami/cli/commands/app/generate/operation.rb +6 -0
- data/lib/hanami/cli/commands/app/generate/part.rb +4 -8
- data/lib/hanami/cli/commands/app/generate/provider.rb +27 -0
- data/lib/hanami/cli/commands/app/generate/relation.rb +7 -3
- data/lib/hanami/cli/commands/app/generate/repo.rb +3 -1
- data/lib/hanami/cli/commands/app/generate/slice.rb +16 -10
- data/lib/hanami/cli/commands/app/generate/struct.rb +2 -0
- data/lib/hanami/cli/commands/app/generate/view.rb +24 -1
- data/lib/hanami/cli/commands/app/middleware.rb +3 -3
- data/lib/hanami/cli/commands/app/routes.rb +5 -5
- data/lib/hanami/cli/commands/app/server.rb +2 -2
- data/lib/hanami/cli/commands/app.rb +6 -1
- data/lib/hanami/cli/commands/gem/new.rb +63 -82
- data/lib/hanami/cli/errors.rb +1 -1
- data/lib/hanami/cli/files.rb +9 -2
- data/lib/hanami/cli/generators/app/action.rb +39 -21
- data/lib/hanami/cli/generators/app/component.rb +2 -2
- data/lib/hanami/cli/generators/app/mailer.rb +81 -0
- data/lib/hanami/cli/generators/app/migration.rb +1 -1
- data/lib/hanami/cli/generators/app/operation.rb +2 -2
- data/lib/hanami/cli/generators/app/part.rb +4 -4
- data/lib/hanami/cli/generators/app/provider.rb +54 -0
- data/lib/hanami/cli/generators/app/relation.rb +2 -2
- data/lib/hanami/cli/generators/app/repo.rb +2 -2
- data/lib/hanami/cli/generators/app/ruby_file.rb +8 -4
- data/lib/hanami/cli/generators/app/slice.rb +37 -14
- data/lib/hanami/cli/generators/app/struct.rb +2 -2
- data/lib/hanami/cli/generators/app/view.rb +20 -10
- data/lib/hanami/cli/generators/context.rb +32 -52
- data/lib/hanami/cli/generators/gem/app/app.erb +3 -0
- data/lib/hanami/cli/generators/gem/app/app_layout.haml.erb +15 -0
- data/lib/hanami/cli/generators/gem/app/app_layout.slim.erb +15 -0
- data/lib/hanami/cli/generators/gem/app/assets.js +1 -1
- data/lib/hanami/cli/generators/gem/app/context.erb +1 -1
- data/lib/hanami/cli/generators/gem/app/env.erb +18 -1
- data/lib/hanami/cli/generators/gem/app/gemfile.erb +50 -6
- data/lib/hanami/cli/generators/gem/app/package.json.erb +1 -0
- data/lib/hanami/cli/generators/gem/app/puma.erb +0 -3
- data/lib/hanami/cli/generators/gem/app/readme.erb +2 -2
- data/lib/hanami/cli/generators/gem/app/routes.erb +1 -1
- data/lib/hanami/cli/generators/gem/app.rb +26 -1
- data/lib/hanami/cli/generators/i18n.yml +3 -0
- data/lib/hanami/cli/version.rb +1 -1
- metadata +11 -5
|
@@ -16,6 +16,7 @@ module Hanami
|
|
|
16
16
|
base_path:,
|
|
17
17
|
extra_namespace: nil,
|
|
18
18
|
auto_register: nil,
|
|
19
|
+
requires: [],
|
|
19
20
|
body: [],
|
|
20
21
|
**_opts
|
|
21
22
|
)
|
|
@@ -26,12 +27,13 @@ module Hanami
|
|
|
26
27
|
@base_path = base_path
|
|
27
28
|
@extra_namespace = extra_namespace&.downcase
|
|
28
29
|
@auto_register = auto_register
|
|
30
|
+
@requires = requires
|
|
29
31
|
@body = body
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
# @api private
|
|
33
|
-
def create
|
|
34
|
-
fs.create(path, file_contents)
|
|
35
|
+
def create(force: false)
|
|
36
|
+
fs.create(path, file_contents, force:)
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
# @api private
|
|
@@ -42,7 +44,7 @@ module Hanami
|
|
|
42
44
|
# @api private
|
|
43
45
|
def fully_qualified_name
|
|
44
46
|
inflector.camelize(
|
|
45
|
-
[namespace, extra_namespace, *key_segments].join("/")
|
|
47
|
+
[namespace, extra_namespace, *key_segments].compact.join("/")
|
|
46
48
|
)
|
|
47
49
|
end
|
|
48
50
|
|
|
@@ -62,6 +64,7 @@ module Hanami
|
|
|
62
64
|
:namespace,
|
|
63
65
|
:extra_namespace,
|
|
64
66
|
:auto_register,
|
|
67
|
+
:requires,
|
|
65
68
|
:body
|
|
66
69
|
)
|
|
67
70
|
|
|
@@ -108,7 +111,8 @@ module Hanami
|
|
|
108
111
|
[
|
|
109
112
|
# Intentional ternary logic. Skip if nil, else 'true' or 'false'
|
|
110
113
|
("# auto_register: #{auto_register}" unless auto_register.nil?),
|
|
111
|
-
"# frozen_string_literal: true"
|
|
114
|
+
"# frozen_string_literal: true",
|
|
115
|
+
*(requires.any? ? ["", *requires.map { |name| %(require "#{name}") }] : [])
|
|
112
116
|
].compact
|
|
113
117
|
end
|
|
114
118
|
|
|
@@ -19,7 +19,7 @@ module Hanami
|
|
|
19
19
|
|
|
20
20
|
# @since 2.0.0
|
|
21
21
|
# @api private
|
|
22
|
-
def call(app, slice, url, **opts) # rubocop:disable Metrics/AbcSize
|
|
22
|
+
def call(app, slice, url, force: false, **opts) # rubocop:disable Metrics/AbcSize
|
|
23
23
|
skip_route = opts.fetch(:skip_route, false)
|
|
24
24
|
|
|
25
25
|
unless skip_route
|
|
@@ -44,7 +44,7 @@ module Hanami
|
|
|
44
44
|
base_path: directory,
|
|
45
45
|
parent_class_name: "#{Hanami.app.namespace}::Action",
|
|
46
46
|
auto_register: false
|
|
47
|
-
).create
|
|
47
|
+
).create(force:)
|
|
48
48
|
|
|
49
49
|
RubyClassFile.new(
|
|
50
50
|
fs: fs,
|
|
@@ -54,7 +54,21 @@ module Hanami
|
|
|
54
54
|
base_path: directory,
|
|
55
55
|
parent_class_name: "#{Hanami.app.namespace}::View",
|
|
56
56
|
auto_register: false
|
|
57
|
-
).create
|
|
57
|
+
).create(force:)
|
|
58
|
+
|
|
59
|
+
if Hanami.bundled?("hanami-mailer")
|
|
60
|
+
RubyClassFile.new(
|
|
61
|
+
fs:, inflector:,
|
|
62
|
+
namespace: slice,
|
|
63
|
+
key: "mailer",
|
|
64
|
+
base_path: directory,
|
|
65
|
+
parent_class_name: "#{Hanami.app.namespace}::Mailer",
|
|
66
|
+
auto_register: false,
|
|
67
|
+
body: ["# Add common mailer behavior here. See https://hanakai.org/learn/hanami/mailers for details."]
|
|
68
|
+
).create(force:)
|
|
69
|
+
|
|
70
|
+
fs.touch(fs.join(directory, "mailers/.keep"))
|
|
71
|
+
end
|
|
58
72
|
|
|
59
73
|
RubyModuleFile.new(
|
|
60
74
|
fs: fs,
|
|
@@ -64,7 +78,7 @@ module Hanami
|
|
|
64
78
|
base_path: directory,
|
|
65
79
|
auto_register: false,
|
|
66
80
|
body: ["# Add your view helpers here"]
|
|
67
|
-
).create
|
|
81
|
+
).create(force:)
|
|
68
82
|
|
|
69
83
|
RubyClassFile.new(
|
|
70
84
|
fs: fs,
|
|
@@ -74,14 +88,21 @@ module Hanami
|
|
|
74
88
|
base_path: directory,
|
|
75
89
|
parent_class_name: "#{Hanami.app.namespace}::View::Context",
|
|
76
90
|
auto_register: false,
|
|
77
|
-
body: ["# Define your view context here. See https://
|
|
78
|
-
).create
|
|
91
|
+
body: ["# Define your view context here. See https://hanakai.org/learn/hanami/views/context/ for details."] # rubocop:disable Layout/LineLength
|
|
92
|
+
).create(force:)
|
|
79
93
|
|
|
80
94
|
fs.create(
|
|
81
95
|
fs.join(directory, "templates", "layouts", "app.html.erb"),
|
|
82
96
|
app_layout_template(
|
|
83
97
|
page_title: "#{inflector.humanize(app)} - #{inflector.humanize(slice)}"
|
|
84
|
-
)
|
|
98
|
+
),
|
|
99
|
+
force:
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
fs.create(
|
|
103
|
+
fs.join(directory, "config", "i18n", "en.yml"),
|
|
104
|
+
File.read(File.join(__dir__, "..", "i18n.yml")),
|
|
105
|
+
force:
|
|
85
106
|
)
|
|
86
107
|
|
|
87
108
|
if Hanami.bundled?("dry-operation")
|
|
@@ -93,25 +114,27 @@ module Hanami
|
|
|
93
114
|
base_path: directory,
|
|
94
115
|
parent_class_name: "#{Hanami.app.namespace}::Operation",
|
|
95
116
|
auto_register: false
|
|
96
|
-
).create
|
|
117
|
+
).create(force:)
|
|
97
118
|
end
|
|
98
119
|
|
|
99
120
|
if Hanami.bundled?("hanami-assets")
|
|
100
121
|
fs.create(
|
|
101
122
|
fs.join(directory, "assets", "js", "app.js"),
|
|
102
|
-
%(import "../css/app.css";\n)
|
|
123
|
+
%(import "../css/app.css";\n),
|
|
124
|
+
force:
|
|
103
125
|
)
|
|
104
126
|
fs.create(
|
|
105
127
|
fs.join(directory, "assets", "css", "app.css"),
|
|
106
|
-
<<~CSS
|
|
128
|
+
<<~CSS,
|
|
107
129
|
body {
|
|
108
130
|
background-color: #fff;
|
|
109
131
|
color: #000;
|
|
110
132
|
font-family: sans-serif;
|
|
111
133
|
}
|
|
112
134
|
CSS
|
|
135
|
+
force:
|
|
113
136
|
)
|
|
114
|
-
fs.create(fs.join(directory, "assets", "images", "favicon.ico"), file("favicon.ico"))
|
|
137
|
+
fs.create(fs.join(directory, "assets", "images", "favicon.ico"), file("favicon.ico"), force:)
|
|
115
138
|
end
|
|
116
139
|
|
|
117
140
|
if Hanami.bundled?("hanami-db") && !opts.fetch(:skip_db, false)
|
|
@@ -122,7 +145,7 @@ module Hanami
|
|
|
122
145
|
key: "db.relation",
|
|
123
146
|
base_path: directory,
|
|
124
147
|
parent_class_name: "#{Hanami.app.namespace}::DB::Relation"
|
|
125
|
-
).create
|
|
148
|
+
).create(force:)
|
|
126
149
|
|
|
127
150
|
RubyClassFile.new(
|
|
128
151
|
fs: fs,
|
|
@@ -131,7 +154,7 @@ module Hanami
|
|
|
131
154
|
key: "db.repo",
|
|
132
155
|
base_path: directory,
|
|
133
156
|
parent_class_name: "#{Hanami.app.namespace}::DB::Repo"
|
|
134
|
-
).create
|
|
157
|
+
).create(force:)
|
|
135
158
|
|
|
136
159
|
RubyClassFile.new(
|
|
137
160
|
fs: fs,
|
|
@@ -140,7 +163,7 @@ module Hanami
|
|
|
140
163
|
key: "db.struct",
|
|
141
164
|
base_path: directory,
|
|
142
165
|
parent_class_name: "#{Hanami.app.namespace}::DB::Struct"
|
|
143
|
-
).create
|
|
166
|
+
).create(force:)
|
|
144
167
|
|
|
145
168
|
fs.touch(fs.join(directory, "relations", ".keep"))
|
|
146
169
|
fs.touch(fs.join(directory, "repos", ".keep"))
|
|
@@ -17,7 +17,7 @@ module Hanami
|
|
|
17
17
|
|
|
18
18
|
# @since 2.2.0
|
|
19
19
|
# @api private
|
|
20
|
-
def call(key:, namespace:, base_path:)
|
|
20
|
+
def call(key:, namespace:, base_path:, force: false)
|
|
21
21
|
RubyClassFile.new(
|
|
22
22
|
fs: fs,
|
|
23
23
|
inflector: inflector,
|
|
@@ -26,7 +26,7 @@ module Hanami
|
|
|
26
26
|
base_path: base_path,
|
|
27
27
|
extra_namespace: "Structs",
|
|
28
28
|
parent_class_name: "#{inflector.camelize(namespace)}::DB::Struct"
|
|
29
|
-
).create
|
|
29
|
+
).create(force:)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
private
|
|
@@ -17,6 +17,9 @@ module Hanami
|
|
|
17
17
|
TEMPLATES_FOLDER = "templates"
|
|
18
18
|
private_constant :TEMPLATES_FOLDER
|
|
19
19
|
|
|
20
|
+
DEFAULT_TEMPLATE_ENGINE = "erb"
|
|
21
|
+
private_constant :DEFAULT_TEMPLATE_ENGINE
|
|
22
|
+
|
|
20
23
|
# @since 2.0.0
|
|
21
24
|
# @api private
|
|
22
25
|
def initialize(fs:, inflector:, out: $stdout)
|
|
@@ -27,11 +30,11 @@ module Hanami
|
|
|
27
30
|
|
|
28
31
|
# @since 2.0.0
|
|
29
32
|
# @api private
|
|
30
|
-
def call(key:, namespace:, base_path:)
|
|
33
|
+
def call(key:, namespace:, base_path:, template_engine: DEFAULT_TEMPLATE_ENGINE, force: false)
|
|
31
34
|
view_class_file(key:, namespace:, base_path:).then do |view_class|
|
|
32
|
-
view_class.create
|
|
35
|
+
view_class.create(force:)
|
|
33
36
|
view_class_name = view_class.fully_qualified_name
|
|
34
|
-
create_template_file(key:, base_path:, view_class_name:)
|
|
37
|
+
create_template_file(key:, base_path:, view_class_name:, template_engine:, force:)
|
|
35
38
|
end
|
|
36
39
|
end
|
|
37
40
|
|
|
@@ -51,7 +54,7 @@ module Hanami
|
|
|
51
54
|
)
|
|
52
55
|
end
|
|
53
56
|
|
|
54
|
-
def create_template_file(key:, base_path:, view_class_name:)
|
|
57
|
+
def create_template_file(key:, base_path:, view_class_name:, template_engine:, force: false)
|
|
55
58
|
key_parts = key.split(KEY_SEPARATOR)
|
|
56
59
|
class_name_from_key = key_parts.pop # takes last segment as the class name
|
|
57
60
|
module_names_from_key = key_parts # the rest of the segments are the module names
|
|
@@ -60,23 +63,30 @@ module Hanami
|
|
|
60
63
|
base_path,
|
|
61
64
|
TEMPLATES_FOLDER,
|
|
62
65
|
module_names_from_key,
|
|
63
|
-
template_file_name(class_name_from_key, DEFAULT_FORMAT)
|
|
66
|
+
template_file_name(class_name_from_key, DEFAULT_FORMAT, template_engine)
|
|
64
67
|
)
|
|
65
|
-
|
|
66
|
-
fs.create(file_path, body)
|
|
68
|
+
fs.create(file_path, body_for_engine(view_class_name, template_engine), force:)
|
|
67
69
|
end
|
|
68
70
|
|
|
69
|
-
def template_file_name(name, format)
|
|
71
|
+
def template_file_name(name, format, engine)
|
|
70
72
|
ext =
|
|
71
73
|
case format.to_sym
|
|
72
74
|
when :html
|
|
73
|
-
".html
|
|
75
|
+
".html.#{engine}"
|
|
74
76
|
else
|
|
75
|
-
"
|
|
77
|
+
".#{engine}"
|
|
76
78
|
end
|
|
77
79
|
|
|
78
80
|
"#{name}#{ext}"
|
|
79
81
|
end
|
|
82
|
+
|
|
83
|
+
def body_for_engine(view_class_name, engine)
|
|
84
|
+
case engine
|
|
85
|
+
when "erb" then "<h1>#{view_class_name}</h1>\n"
|
|
86
|
+
when "haml" then "%h1 #{view_class_name}\n"
|
|
87
|
+
when "slim" then "h1 #{view_class_name}\n"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
80
90
|
end
|
|
81
91
|
end
|
|
82
92
|
end
|
|
@@ -4,22 +4,15 @@ require_relative "version"
|
|
|
4
4
|
|
|
5
5
|
module Hanami
|
|
6
6
|
module CLI
|
|
7
|
-
# @since 2.0.0
|
|
8
|
-
# @api private
|
|
9
7
|
module Generators
|
|
10
|
-
# @since 2.0.0
|
|
11
8
|
# @api private
|
|
12
9
|
class Context
|
|
13
|
-
# @since 2.0.0
|
|
14
|
-
# @api private
|
|
15
10
|
def initialize(inflector, app, **options)
|
|
16
11
|
@inflector = inflector
|
|
17
12
|
@app = app
|
|
18
13
|
@options = options
|
|
19
14
|
end
|
|
20
15
|
|
|
21
|
-
# @since 2.0.0
|
|
22
|
-
# @api private
|
|
23
16
|
def ctx
|
|
24
17
|
binding
|
|
25
18
|
end
|
|
@@ -30,8 +23,6 @@ module Hanami
|
|
|
30
23
|
%(gem "#{gem_name}", #{hanami_gem_version(name)})
|
|
31
24
|
end
|
|
32
25
|
|
|
33
|
-
# @since 2.0.0
|
|
34
|
-
# @api private
|
|
35
26
|
def hanami_gem_version(name)
|
|
36
27
|
gem_name = name == "hanami" ? "hanami" : "hanami-#{name}"
|
|
37
28
|
|
|
@@ -42,8 +33,9 @@ module Hanami
|
|
|
42
33
|
end
|
|
43
34
|
end
|
|
44
35
|
|
|
45
|
-
#
|
|
46
|
-
|
|
36
|
+
# Minimum esbuild version. Keep this in with the hanami-assets peer dependency.
|
|
37
|
+
ESBUILD_NPM_REQUIREMENT = "^0.28.1"
|
|
38
|
+
|
|
47
39
|
def hanami_assets_npm_package
|
|
48
40
|
if hanami_head?
|
|
49
41
|
%("hanami-assets": "hanami/assets-js#main")
|
|
@@ -52,32 +44,26 @@ module Hanami
|
|
|
52
44
|
end
|
|
53
45
|
end
|
|
54
46
|
|
|
55
|
-
|
|
56
|
-
|
|
47
|
+
def esbuild_npm_package
|
|
48
|
+
%("esbuild": "#{ESBUILD_NPM_REQUIREMENT}")
|
|
49
|
+
end
|
|
50
|
+
|
|
57
51
|
def camelized_app_name
|
|
58
52
|
inflector.camelize(app).gsub(/[^\p{Alnum}]/, "")
|
|
59
53
|
end
|
|
60
54
|
|
|
61
|
-
# @since 2.0.0
|
|
62
|
-
# @api private
|
|
63
55
|
def underscored_app_name
|
|
64
56
|
inflector.underscore(app)
|
|
65
57
|
end
|
|
66
58
|
|
|
67
|
-
# @since 2.1.0
|
|
68
|
-
# @api private
|
|
69
59
|
def humanized_app_name
|
|
70
60
|
inflector.humanize(app)
|
|
71
61
|
end
|
|
72
62
|
|
|
73
|
-
# @since 2.1.0
|
|
74
|
-
# @api private
|
|
75
63
|
def hanami_head?
|
|
76
64
|
options.fetch(:head)
|
|
77
65
|
end
|
|
78
66
|
|
|
79
|
-
# @since 2.3.0
|
|
80
|
-
# @api private
|
|
81
67
|
def gem_source
|
|
82
68
|
value = options.fetch(:gem_source)
|
|
83
69
|
return value if value.match? %r{\A\w+://}
|
|
@@ -85,44 +71,39 @@ module Hanami
|
|
|
85
71
|
"https://#{value}"
|
|
86
72
|
end
|
|
87
73
|
|
|
88
|
-
|
|
89
|
-
|
|
74
|
+
def gem_coop?
|
|
75
|
+
value = options.fetch(:gem_source)
|
|
76
|
+
value.match? %r{(\A\w+://)?gem.coop}
|
|
77
|
+
end
|
|
78
|
+
|
|
90
79
|
def generate_assets?
|
|
91
80
|
!options.fetch(:skip_assets, false)
|
|
92
81
|
end
|
|
93
82
|
|
|
94
|
-
# @since 2.2.0
|
|
95
|
-
# @api private
|
|
96
83
|
def generate_db?
|
|
97
84
|
!options.fetch(:skip_db, false)
|
|
98
85
|
end
|
|
99
86
|
|
|
100
|
-
# @since 2.2.0
|
|
101
|
-
# @api private
|
|
102
87
|
def generate_view?
|
|
103
88
|
!options.fetch(:skip_view, false)
|
|
104
89
|
end
|
|
105
90
|
|
|
106
|
-
|
|
107
|
-
|
|
91
|
+
def generate_mailer?
|
|
92
|
+
!options.fetch(:skip_mailer, false)
|
|
93
|
+
end
|
|
94
|
+
|
|
108
95
|
def generate_sqlite?
|
|
109
96
|
generate_db? && database_option == Commands::Gem::New::DATABASE_SQLITE
|
|
110
97
|
end
|
|
111
98
|
|
|
112
|
-
# @since 2.2.0
|
|
113
|
-
# @api private
|
|
114
99
|
def generate_postgres?
|
|
115
100
|
generate_db? && database_option == Commands::Gem::New::DATABASE_POSTGRES
|
|
116
101
|
end
|
|
117
102
|
|
|
118
|
-
# @since 2.2.0
|
|
119
|
-
# @api private
|
|
120
103
|
def generate_mysql?
|
|
121
104
|
generate_db? && database_option == Commands::Gem::New::DATABASE_MYSQL
|
|
122
105
|
end
|
|
123
106
|
|
|
124
|
-
# @since 2.2.0
|
|
125
|
-
# @api private
|
|
126
107
|
def database_url
|
|
127
108
|
if generate_sqlite?
|
|
128
109
|
"sqlite://db/#{app}.sqlite"
|
|
@@ -135,48 +116,47 @@ module Hanami
|
|
|
135
116
|
end
|
|
136
117
|
end
|
|
137
118
|
|
|
138
|
-
# @since 2.1.0
|
|
139
|
-
# @api private
|
|
140
119
|
def bundled_views?
|
|
141
120
|
Hanami.bundled?("hanami-view")
|
|
142
121
|
end
|
|
143
122
|
|
|
144
|
-
# @since 2.1.0
|
|
145
|
-
# @api private
|
|
146
123
|
def bundled_assets?
|
|
147
124
|
Hanami.bundled?("hanami-assets")
|
|
148
125
|
end
|
|
149
126
|
|
|
150
|
-
# @since 2.2.0
|
|
151
|
-
# @api private
|
|
152
127
|
def bundled_dry_monads?
|
|
153
128
|
Hanami.bundled?("dry-monads")
|
|
154
129
|
end
|
|
155
130
|
|
|
156
|
-
# @since 2.1.0
|
|
157
|
-
# @api private
|
|
158
|
-
#
|
|
159
131
|
# @see https://rubyreferences.github.io/rubychanges/3.1.html#values-in-hash-literals-and-keyword-arguments-can-be-omitted
|
|
160
132
|
def ruby_omit_hash_values?
|
|
161
133
|
RUBY_VERSION >= "3.1"
|
|
162
134
|
end
|
|
163
135
|
|
|
136
|
+
def template_engine
|
|
137
|
+
options.fetch(:template_engine)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def generate_rspec?
|
|
141
|
+
test_framework_option == "rspec"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def generate_minitest?
|
|
145
|
+
test_framework_option == "minitest"
|
|
146
|
+
end
|
|
147
|
+
|
|
164
148
|
private
|
|
165
149
|
|
|
166
150
|
def database_option
|
|
167
151
|
options.fetch(:database, Commands::Gem::New::DATABASE_SQLITE)
|
|
168
152
|
end
|
|
169
153
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
154
|
+
def test_framework_option
|
|
155
|
+
options.fetch(:test_framework, Commands::Gem::New::TEST_FRAMEWORK_DEFAULT)
|
|
156
|
+
end
|
|
173
157
|
|
|
174
|
-
|
|
175
|
-
# @api private
|
|
158
|
+
attr_reader :inflector
|
|
176
159
|
attr_reader :app
|
|
177
|
-
|
|
178
|
-
# @since 2.1.0
|
|
179
|
-
# @api private
|
|
180
160
|
attr_reader :options
|
|
181
161
|
end
|
|
182
162
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
!!!
|
|
2
|
+
%html{:lang => "en"}
|
|
3
|
+
%head
|
|
4
|
+
%meta{:charset => "UTF-8"}/
|
|
5
|
+
%meta{:content => "width=device-width, initial-scale=1.0", :name => "viewport"}/
|
|
6
|
+
%title <%= humanized_app_name %>
|
|
7
|
+
<%- if generate_assets? -%>
|
|
8
|
+
= favicon_tag
|
|
9
|
+
= stylesheet_tag "app"
|
|
10
|
+
<%- end -%>
|
|
11
|
+
%body
|
|
12
|
+
= yield
|
|
13
|
+
<%- if generate_assets? -%>
|
|
14
|
+
= javascript_tag "app"
|
|
15
|
+
<%- end -%>
|
|
@@ -0,0 +1,15 @@
|
|
|
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 %>
|
|
7
|
+
<%- if generate_assets? -%>
|
|
8
|
+
= favicon_tag
|
|
9
|
+
= stylesheet_tag "app"
|
|
10
|
+
<%- end -%>
|
|
11
|
+
body
|
|
12
|
+
= yield
|
|
13
|
+
<%- if generate_assets? -%>
|
|
14
|
+
= javascript_tag "app"
|
|
15
|
+
<%- end -%>
|
|
@@ -3,7 +3,7 @@ import * as assets from "hanami-assets";
|
|
|
3
3
|
// Assets are managed by esbuild (https://esbuild.github.io), and can be
|
|
4
4
|
// customized below.
|
|
5
5
|
//
|
|
6
|
-
// Learn more at https://
|
|
6
|
+
// Learn more at https://hanakai.org/learn/hanami/assets/customization/.
|
|
7
7
|
|
|
8
8
|
await assets.run({
|
|
9
9
|
esbuildOptionsFn: (args, esbuildOptions) => {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
module <%= camelized_app_name %>
|
|
5
5
|
module Views
|
|
6
6
|
class Context < Hanami::View::Context
|
|
7
|
-
# Define your view context here. See https://
|
|
7
|
+
# Define your view context here. See https://hanakai.org/learn/hanami/views/context/ for details.
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
end
|
|
@@ -1,4 +1,21 @@
|
|
|
1
|
-
# This is checked into source control, so put sensitive values into `.env.local
|
|
1
|
+
# This is checked into source control, so put sensitive values into `.env.local`.
|
|
2
|
+
#
|
|
3
|
+
# See https://hanakai.org/learn/hanami/app/settings for how `.env` files are loaded.
|
|
2
4
|
<%- if generate_db? -%>
|
|
5
|
+
|
|
3
6
|
DATABASE_URL=<%= database_url %>
|
|
4
7
|
<%- end -%>
|
|
8
|
+
<%- if generate_mailer? -%>
|
|
9
|
+
|
|
10
|
+
# SMTP delivery for Hanami Mailer (in development and production envs only).
|
|
11
|
+
#
|
|
12
|
+
# See https://hanakai.org/learn/hanami/mailers for details.
|
|
13
|
+
#
|
|
14
|
+
# Set these in `.env.local` or another `.env` file not checked into source control.
|
|
15
|
+
#
|
|
16
|
+
# SMTP_ADDRESS=smtp.example.com
|
|
17
|
+
# SMTP_PORT=587
|
|
18
|
+
# SMTP_USERNAME=mailer@example.com
|
|
19
|
+
# SMTP_PASSWORD=s3cr3t
|
|
20
|
+
# SMTP_AUTHENTICATION=plain
|
|
21
|
+
<%- end -%>
|
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
source "<%= gem_source %>"
|
|
4
4
|
|
|
5
|
+
<%- if gem_coop? and !hanami_head? -%>
|
|
6
|
+
source "https://gem.coop/@hanami" do
|
|
7
|
+
<%= hanami_gem("hanami") %>
|
|
8
|
+
<%- if generate_assets? -%>
|
|
9
|
+
<%= hanami_gem("assets") %>
|
|
10
|
+
<%- end -%>
|
|
11
|
+
<%= hanami_gem("action") %>
|
|
12
|
+
<%- if generate_db? -%>
|
|
13
|
+
<%= hanami_gem("db") %>
|
|
14
|
+
<%- end -%>
|
|
15
|
+
<%= hanami_gem("router") %>
|
|
16
|
+
<%- if generate_view? -%>
|
|
17
|
+
<%= hanami_gem("view") %>
|
|
18
|
+
<%- end -%>
|
|
19
|
+
end
|
|
20
|
+
<%- else -%>
|
|
5
21
|
<%= hanami_gem("hanami") %>
|
|
6
22
|
<%- if hanami_head? -%>
|
|
7
23
|
<%= hanami_gem("cli") %>
|
|
@@ -10,19 +26,33 @@ source "<%= gem_source %>"
|
|
|
10
26
|
<%- if generate_assets? -%>
|
|
11
27
|
<%= hanami_gem("assets") %>
|
|
12
28
|
<%- end -%>
|
|
13
|
-
<%= hanami_gem("
|
|
29
|
+
<%= hanami_gem("action") %>
|
|
14
30
|
<%- if generate_db? -%>
|
|
15
31
|
<%= hanami_gem("db") %>
|
|
16
32
|
<%- end -%>
|
|
33
|
+
<%- if generate_mailer? -%>
|
|
34
|
+
<%= hanami_gem("mailer") %>
|
|
35
|
+
<%- end -%>
|
|
17
36
|
<%= hanami_gem("router") %>
|
|
18
|
-
<%= hanami_gem("validations") %>
|
|
19
37
|
<%- if generate_view? -%>
|
|
20
38
|
<%= hanami_gem("view") %>
|
|
21
39
|
<%- end -%>
|
|
40
|
+
<%- end -%>
|
|
41
|
+
|
|
42
|
+
<%- if gem_coop? -%>
|
|
43
|
+
source "https://gem.coop/@dry" do
|
|
44
|
+
gem "dry-types", "~> 1.7"
|
|
45
|
+
gem "dry-operation", ">= 1.0.1"
|
|
46
|
+
gem "dry-validation", "~> 1.11"
|
|
47
|
+
end
|
|
22
48
|
|
|
49
|
+
<%- else -%>
|
|
23
50
|
gem "dry-types", "~> 1.7"
|
|
24
51
|
gem "dry-operation", ">= 1.0.1"
|
|
25
|
-
gem "
|
|
52
|
+
gem "dry-validation", "~> 1.11"
|
|
53
|
+
<%- end -%>
|
|
54
|
+
gem "i18n", "~> 1.14"
|
|
55
|
+
gem "puma", ">= 7.1"
|
|
26
56
|
gem "rake"
|
|
27
57
|
<%- if generate_sqlite? -%>
|
|
28
58
|
gem "sqlite3"
|
|
@@ -31,19 +61,33 @@ gem "pg"
|
|
|
31
61
|
<%- elsif generate_mysql? -%>
|
|
32
62
|
gem "mysql2"
|
|
33
63
|
<%- end -%>
|
|
64
|
+
<%- if generate_view? && template_engine == "haml" -%>
|
|
65
|
+
gem "haml"
|
|
66
|
+
<%- end -%>
|
|
67
|
+
<%- if generate_view? && template_engine == "slim" -%>
|
|
68
|
+
gem "slim"
|
|
69
|
+
<%- end -%>
|
|
34
70
|
|
|
35
71
|
group :development do
|
|
36
|
-
<%= hanami_gem("webconsole") %>
|
|
72
|
+
<%= hanami_gem("webconsole") %><%- if gem_coop? -%>, source: "https://gem.coop/@hanami"<% end %>
|
|
37
73
|
end
|
|
38
74
|
|
|
39
75
|
group :development, :test do
|
|
40
76
|
gem "dotenv"
|
|
77
|
+
<%- if generate_db? -%>
|
|
78
|
+
# Syntax highlighting SQL logs
|
|
79
|
+
gem "rouge"
|
|
80
|
+
<%- end -%>
|
|
41
81
|
end
|
|
42
82
|
|
|
43
83
|
group :cli, :development do
|
|
44
|
-
<%= hanami_gem("reloader") %>
|
|
84
|
+
<%= hanami_gem("reloader") %><%- if gem_coop? -%>, source: "https://gem.coop/@hanami"<% end %>
|
|
45
85
|
end
|
|
46
86
|
|
|
47
87
|
group :cli, :development, :test do
|
|
48
|
-
|
|
88
|
+
<%- if generate_rspec? -%>
|
|
89
|
+
<%= hanami_gem("rspec") %><%- if gem_coop? -%>, source: "https://gem.coop/@hanami"<% end %>
|
|
90
|
+
<%- elsif generate_minitest? -%>
|
|
91
|
+
<%= hanami_gem("minitest") %><%- if gem_coop? -%>, source: "https://gem.coop/@hanami"<% end %>
|
|
92
|
+
<%- end -%>
|
|
49
93
|
end
|
|
@@ -32,9 +32,6 @@ workers puma_concurrency
|
|
|
32
32
|
#
|
|
33
33
|
|
|
34
34
|
if puma_cluster_mode
|
|
35
|
-
# Preload the application before starting the workers. Only in cluster mode.
|
|
36
|
-
preload_app!
|
|
37
|
-
|
|
38
35
|
# Code to run immediately before master process forks workers (once on boot).
|
|
39
36
|
#
|
|
40
37
|
# These hooks can block if necessary to wait for background operations unknown
|