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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -5
  3. data/README.md +6 -1
  4. data/hanami-cli.gemspec +2 -3
  5. data/lib/hanami/cli/commands/app/db/migrate.rb +4 -4
  6. data/lib/hanami/cli/commands/app/db/utils/postgres.rb +4 -6
  7. data/lib/hanami/cli/commands/app/generate/action.rb +31 -7
  8. data/lib/hanami/cli/commands/app/generate/component.rb +2 -0
  9. data/lib/hanami/cli/commands/app/generate/mailer.rb +52 -0
  10. data/lib/hanami/cli/commands/app/generate/operation.rb +6 -0
  11. data/lib/hanami/cli/commands/app/generate/part.rb +4 -8
  12. data/lib/hanami/cli/commands/app/generate/provider.rb +27 -0
  13. data/lib/hanami/cli/commands/app/generate/relation.rb +7 -3
  14. data/lib/hanami/cli/commands/app/generate/repo.rb +3 -1
  15. data/lib/hanami/cli/commands/app/generate/slice.rb +16 -10
  16. data/lib/hanami/cli/commands/app/generate/struct.rb +2 -0
  17. data/lib/hanami/cli/commands/app/generate/view.rb +24 -1
  18. data/lib/hanami/cli/commands/app/middleware.rb +3 -3
  19. data/lib/hanami/cli/commands/app/routes.rb +5 -5
  20. data/lib/hanami/cli/commands/app/server.rb +2 -2
  21. data/lib/hanami/cli/commands/app.rb +6 -1
  22. data/lib/hanami/cli/commands/gem/new.rb +63 -82
  23. data/lib/hanami/cli/errors.rb +1 -1
  24. data/lib/hanami/cli/files.rb +9 -2
  25. data/lib/hanami/cli/generators/app/action.rb +39 -21
  26. data/lib/hanami/cli/generators/app/component.rb +2 -2
  27. data/lib/hanami/cli/generators/app/mailer.rb +81 -0
  28. data/lib/hanami/cli/generators/app/migration.rb +1 -1
  29. data/lib/hanami/cli/generators/app/operation.rb +2 -2
  30. data/lib/hanami/cli/generators/app/part.rb +4 -4
  31. data/lib/hanami/cli/generators/app/provider.rb +54 -0
  32. data/lib/hanami/cli/generators/app/relation.rb +2 -2
  33. data/lib/hanami/cli/generators/app/repo.rb +2 -2
  34. data/lib/hanami/cli/generators/app/ruby_file.rb +8 -4
  35. data/lib/hanami/cli/generators/app/slice.rb +37 -14
  36. data/lib/hanami/cli/generators/app/struct.rb +2 -2
  37. data/lib/hanami/cli/generators/app/view.rb +20 -10
  38. data/lib/hanami/cli/generators/context.rb +32 -52
  39. data/lib/hanami/cli/generators/gem/app/app.erb +3 -0
  40. data/lib/hanami/cli/generators/gem/app/app_layout.haml.erb +15 -0
  41. data/lib/hanami/cli/generators/gem/app/app_layout.slim.erb +15 -0
  42. data/lib/hanami/cli/generators/gem/app/assets.js +1 -1
  43. data/lib/hanami/cli/generators/gem/app/context.erb +1 -1
  44. data/lib/hanami/cli/generators/gem/app/env.erb +18 -1
  45. data/lib/hanami/cli/generators/gem/app/gemfile.erb +50 -6
  46. data/lib/hanami/cli/generators/gem/app/package.json.erb +1 -0
  47. data/lib/hanami/cli/generators/gem/app/puma.erb +0 -3
  48. data/lib/hanami/cli/generators/gem/app/readme.erb +2 -2
  49. data/lib/hanami/cli/generators/gem/app/routes.erb +1 -1
  50. data/lib/hanami/cli/generators/gem/app.rb +26 -1
  51. data/lib/hanami/cli/generators/i18n.yml +3 -0
  52. data/lib/hanami/cli/version.rb +1 -1
  53. 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://guides.hanamirb.org/views/context/ for details."]
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
- body = "<h1>#{view_class_name}</h1>\n"
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.erb"
75
+ ".html.#{engine}"
74
76
  else
75
- ".erb"
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
- # @since 2.1.0
46
- # @api private
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
- # @since 2.0.0
56
- # @api private
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
- # @since 2.1.0
89
- # @api private
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
- # @since 2.2.0
107
- # @api private
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
- # @since 2.0.0
171
- # @api private
172
- attr_reader :inflector
154
+ def test_framework_option
155
+ options.fetch(:test_framework, Commands::Gem::New::TEST_FRAMEWORK_DEFAULT)
156
+ end
173
157
 
174
- # @since 2.0.0
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
@@ -4,5 +4,8 @@ require "hanami"
4
4
 
5
5
  module <%= camelized_app_name %>
6
6
  class App < Hanami::App
7
+ <%- if generate_view? && template_engine != "erb" -%>
8
+ config.views.default_template_engine = "<%= template_engine %>"
9
+ <%- end -%>
7
10
  end
8
11
  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://guides.hanamirb.org/assets/customization/.
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://guides.hanamirb.org/views/context/ for details.
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("controller") %>
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 "puma"
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
- <%= hanami_gem("rspec") %>
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
@@ -3,6 +3,7 @@
3
3
  "private": true,
4
4
  "type": "module",
5
5
  "dependencies": {
6
+ <%= esbuild_npm_package %>,
6
7
  <%= hanami_assets_npm_package %>
7
8
  }
8
9
  }
@@ -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
@@ -11,5 +11,5 @@
11
11
 
12
12
  ## Useful links
13
13
 
14
- - [Hanami](http://hanamirb.org)
15
- - [Hanami guides](https://guides.hanamirb.org/)
14
+ - [Hanami](https://hanakai.org/hanami)
15
+ - [Hanami guides](https://hanakai.org/learn#hanami)