hanami-cli 2.0.3 → 2.1.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/CHANGELOG.md +15 -0
- data/LICENSE.md +1 -1
- data/README.md +1 -1
- data/lib/hanami/cli/bundler.rb +2 -2
- data/lib/hanami/cli/commands/app/db/rollback.rb +30 -6
- data/lib/hanami/cli/commands/app/db/utils/database.rb +5 -1
- data/lib/hanami/cli/commands/app/generate/action.rb +2 -2
- data/lib/hanami/cli/commands/app/generate/view.rb +57 -0
- data/lib/hanami/cli/commands/app/generate.rb +2 -2
- data/lib/hanami/cli/commands/app.rb +1 -0
- data/lib/hanami/cli/generators/app/action/slice_template.html.erb +1 -0
- data/lib/hanami/cli/generators/app/action/slice_view.erb +10 -0
- data/lib/hanami/cli/generators/app/action/template.html.erb +1 -2
- data/lib/hanami/cli/generators/app/action/view.erb +2 -5
- data/lib/hanami/cli/generators/app/action.rb +31 -16
- data/lib/hanami/cli/generators/app/action_context.rb +1 -1
- data/lib/hanami/cli/generators/app/slice/helpers.erb +10 -0
- data/lib/hanami/cli/generators/app/slice/layouts_app.html.erb +1 -0
- data/lib/hanami/cli/generators/app/slice/view.erb +0 -2
- data/lib/hanami/cli/generators/app/slice.rb +8 -5
- data/lib/hanami/cli/generators/app/view/app_template.html.erb +1 -0
- data/lib/hanami/cli/generators/app/view/app_view.erb +10 -0
- data/lib/hanami/cli/generators/app/view/slice_template.html.erb +1 -0
- data/lib/hanami/cli/generators/app/view/slice_view.erb +10 -0
- data/lib/hanami/cli/generators/app/view.rb +89 -0
- data/lib/hanami/cli/generators/app/view_context.rb +100 -0
- data/lib/hanami/cli/generators/context.rb +1 -1
- data/lib/hanami/cli/generators/gem/app/404.html +11 -0
- data/lib/hanami/cli/generators/gem/app/500.html +11 -0
- data/lib/hanami/cli/generators/gem/app/gemfile.erb +2 -0
- data/lib/hanami/cli/generators/gem/app/helpers.erb +10 -0
- data/lib/hanami/cli/generators/gem/app/layouts_app.html.erb +1 -0
- data/lib/hanami/cli/generators/gem/app/puma.erb +5 -3
- data/lib/hanami/cli/generators/gem/app/view.erb +9 -0
- data/lib/hanami/cli/generators/gem/app.rb +6 -0
- data/lib/hanami/cli/url.rb +1 -1
- data/lib/hanami/cli/version.rb +1 -1
- metadata +21 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '078a7a10f1196ed8635a9c27ee48ac10178cdcff50d2646138f61b55f79f86a7'
|
|
4
|
+
data.tar.gz: 870c056fc5da9f5952daf357ca2861f0e276510c6ca1e63a2f821af76ebdd09a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d70ee9d87779f442c25517abfefde102460848e8a29ba9ef30ae28cc2b2593f73027dad42b99e5617820952a84fd22013a8de5d039fb2e6161a64fd2eef706a1
|
|
7
|
+
data.tar.gz: 815418cd1c416bea1f7a77c56dff20ed143b582795bbcd79904260509c8c62c7d62a7be76c11305d26dc793dd2c2a13fcba0532c365ad47278212159e40eff69
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
Hanami Command Line Interface
|
|
4
4
|
|
|
5
|
+
## v2.1.0.beta1 - 2023-06-29
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- [Tim Riley] `hanami new` to generate default views, templates, and helpers
|
|
10
|
+
- [Tim Riley] `hanami generate slice` to generate default views, templates, and helpers
|
|
11
|
+
- [Tim Riley] `hanami generate action` to generate associated view and template
|
|
12
|
+
- [Tim Riley] Introduced `hanami generate view`
|
|
13
|
+
- [Tim Riley] `hanami new` to generate `Gemfile` with `hanami-view` and `hanami-webconsole` gems
|
|
14
|
+
- [Tim Riley] `hanami new` to generate default error pages for `404` and `500` HTTP errors
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- [Philip Arndt] `hanami server` to start only one Puma worker by default
|
|
19
|
+
|
|
5
20
|
## v2.0.3 - 2023-02-01
|
|
6
21
|
|
|
7
22
|
### Added
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
data/lib/hanami/cli/bundler.rb
CHANGED
|
@@ -20,12 +20,20 @@ module Hanami
|
|
|
20
20
|
migration_code, migration_name = find_migration(target)
|
|
21
21
|
|
|
22
22
|
if migration_name.nil?
|
|
23
|
-
|
|
23
|
+
output = if target
|
|
24
|
+
"==> migration file for target #{target} was not found"
|
|
25
|
+
else
|
|
26
|
+
"==> no migrations to rollback"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
out.puts output
|
|
24
30
|
return
|
|
25
31
|
end
|
|
26
32
|
|
|
27
33
|
measure "database #{database.name} rolled back to #{migration_name}" do
|
|
28
34
|
database.run_migrations(target: Integer(migration_code))
|
|
35
|
+
|
|
36
|
+
true
|
|
29
37
|
end
|
|
30
38
|
|
|
31
39
|
run_command Structure::Dump if dump
|
|
@@ -33,14 +41,30 @@ module Hanami
|
|
|
33
41
|
|
|
34
42
|
private
|
|
35
43
|
|
|
36
|
-
def find_migration(code)
|
|
37
|
-
|
|
44
|
+
def find_migration(code) # rubocop:disable Metrics/PerceivedComplexity
|
|
45
|
+
applied_migrations = database.applied_migrations
|
|
46
|
+
|
|
47
|
+
return if applied_migrations.empty?
|
|
48
|
+
|
|
49
|
+
# Rollback to initial state if we have only one migration and
|
|
50
|
+
# no target is specified. In this case the rollback target
|
|
51
|
+
# will be the current migration timestamp minus 1
|
|
52
|
+
if applied_migrations.one? && code.nil?
|
|
53
|
+
migration = applied_migrations.first
|
|
54
|
+
|
|
55
|
+
migration_code = Integer(migration.split("_").first) - 1
|
|
56
|
+
migration_name = "initial state"
|
|
57
|
+
|
|
58
|
+
return [migration_code, migration_name]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Otherwise rollback to target or to previous migration
|
|
62
|
+
migration =
|
|
38
63
|
if code
|
|
39
|
-
|
|
64
|
+
applied_migrations.detect { |m| m.split("_").first == code }
|
|
40
65
|
else
|
|
41
|
-
|
|
66
|
+
applied_migrations[-2]
|
|
42
67
|
end
|
|
43
|
-
}
|
|
44
68
|
|
|
45
69
|
return unless migration
|
|
46
70
|
|
|
@@ -139,7 +139,11 @@ module Hanami
|
|
|
139
139
|
@sequel_migrator ||= begin
|
|
140
140
|
require "sequel"
|
|
141
141
|
Sequel.extension :migration
|
|
142
|
-
|
|
142
|
+
|
|
143
|
+
require "rom/sql"
|
|
144
|
+
ROM::SQL.with_gateway(gateway) do
|
|
145
|
+
Sequel::TimestampMigrator.new(migrator.connection, migrations_path, {})
|
|
146
|
+
end
|
|
143
147
|
end
|
|
144
148
|
end
|
|
145
149
|
|
|
@@ -26,8 +26,8 @@ module Hanami
|
|
|
26
26
|
option :url, required: false, type: :string, desc: "Action URL"
|
|
27
27
|
option :http, required: false, type: :string, desc: "Action HTTP method"
|
|
28
28
|
# option :format, required: false, type: :string, default: DEFAULT_FORMAT, desc: "Template format"
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
option :skip_view, required: false, type: :boolean, default: DEFAULT_SKIP_VIEW,
|
|
30
|
+
desc: "Skip view and template generation"
|
|
31
31
|
option :slice, required: false, desc: "Slice name"
|
|
32
32
|
|
|
33
33
|
# rubocop:disable Layout/LineLength
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/inflector"
|
|
4
|
+
require "dry/files"
|
|
5
|
+
require "shellwords"
|
|
6
|
+
require_relative "../../../naming"
|
|
7
|
+
require_relative "../../../errors"
|
|
8
|
+
|
|
9
|
+
module Hanami
|
|
10
|
+
module CLI
|
|
11
|
+
module Commands
|
|
12
|
+
module App
|
|
13
|
+
module Generate
|
|
14
|
+
# @since 2.0.0
|
|
15
|
+
# @api private
|
|
16
|
+
class View < App::Command
|
|
17
|
+
# TODO: make this configurable
|
|
18
|
+
DEFAULT_FORMAT = "html"
|
|
19
|
+
private_constant :DEFAULT_FORMAT
|
|
20
|
+
|
|
21
|
+
# TODO: make engine configurable
|
|
22
|
+
|
|
23
|
+
argument :name, required: true, desc: "View name"
|
|
24
|
+
option :slice, required: false, desc: "Slice name"
|
|
25
|
+
|
|
26
|
+
example [
|
|
27
|
+
%(books.index (MyApp::Actions::Books::Index)),
|
|
28
|
+
%(books.index --slice=admin (Admin::Actions::Books::Index)),
|
|
29
|
+
]
|
|
30
|
+
attr_reader :generator
|
|
31
|
+
private :generator
|
|
32
|
+
|
|
33
|
+
# @since 2.0.0
|
|
34
|
+
# @api private
|
|
35
|
+
def initialize(
|
|
36
|
+
fs: Hanami::CLI::Files.new,
|
|
37
|
+
inflector: Dry::Inflector.new,
|
|
38
|
+
generator: Generators::App::View.new(fs: fs, inflector: inflector),
|
|
39
|
+
**
|
|
40
|
+
)
|
|
41
|
+
@generator = generator
|
|
42
|
+
super(fs: fs)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @since 2.0.0
|
|
46
|
+
# @api private
|
|
47
|
+
def call(name:, format: DEFAULT_FORMAT, slice: nil, **)
|
|
48
|
+
slice = inflector.underscore(Shellwords.shellescape(slice)) if slice
|
|
49
|
+
|
|
50
|
+
generator.call(app.namespace, name, format, slice)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<h1><%= camelized_slice_name %>::Views::<%= camelized_controller_name %>::<%= camelized_action_name %></h1>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module <%= camelized_slice_name %>
|
|
4
|
+
module Views
|
|
5
|
+
<%= module_controller_declaration %>
|
|
6
|
+
<%= module_controller_offset %>class <%= camelized_action_name %> < <%= camelized_slice_name %>::View
|
|
7
|
+
<%= module_controller_offset %>end
|
|
8
|
+
<%= module_controller_end %>
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
<h1><%=
|
|
2
|
-
<h2><%= template_path %></h2>
|
|
1
|
+
<h1><%= camelized_app_name %>::Views::<%= camelized_controller_name %>::<%= camelized_action_name %></h1>
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
# auto_register: false
|
|
2
1
|
# frozen_string_literal: true
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
module <%= camelized_slice_name %>
|
|
3
|
+
module <%= camelized_app_name %>
|
|
7
4
|
module Views
|
|
8
5
|
<%= module_controller_declaration %>
|
|
9
|
-
<%= module_controller_offset %>class <%= camelized_action_name %> < <%=
|
|
6
|
+
<%= module_controller_offset %>class <%= camelized_action_name %> < <%= camelized_app_name %>::View
|
|
10
7
|
<%= module_controller_offset %>end
|
|
11
8
|
<%= module_controller_end %>
|
|
12
9
|
end
|
|
@@ -66,7 +66,8 @@ module Hanami
|
|
|
66
66
|
|
|
67
67
|
attr_reader :inflector
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
# rubocop:disable Metrics/AbcSize
|
|
70
|
+
def generate_for_slice(controller, action, url, http, format, skip_view, slice, context)
|
|
70
71
|
slice_directory = fs.join("slices", slice)
|
|
71
72
|
raise MissingSliceError.new(slice) unless fs.directory?(slice_directory)
|
|
72
73
|
|
|
@@ -79,16 +80,17 @@ module Hanami
|
|
|
79
80
|
fs.mkdir(directory = fs.join(slice_directory, "actions", controller))
|
|
80
81
|
fs.write(fs.join(directory, "#{action}.rb"), t("slice_action.erb", context))
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
83
|
+
unless skip_view
|
|
84
|
+
fs.mkdir(directory = fs.join(slice_directory, "views", controller))
|
|
85
|
+
fs.write(fs.join(directory, "#{action}.rb"), t("slice_view.erb", context))
|
|
86
|
+
|
|
87
|
+
fs.mkdir(directory = fs.join(slice_directory, "templates", controller))
|
|
88
|
+
fs.write(fs.join(directory, "#{action}.#{format}.erb"),
|
|
89
|
+
t(template_with_format_ext("slice_template", format), context))
|
|
90
|
+
end
|
|
89
91
|
end
|
|
90
92
|
|
|
91
|
-
def generate_for_app(controller, action, url, http,
|
|
93
|
+
def generate_for_app(controller, action, url, http, format, skip_view, context)
|
|
92
94
|
fs.inject_line_at_class_bottom(
|
|
93
95
|
fs.join("config", "routes.rb"),
|
|
94
96
|
"class Routes",
|
|
@@ -97,7 +99,17 @@ module Hanami
|
|
|
97
99
|
|
|
98
100
|
fs.mkdir(directory = fs.join("app", "actions", controller))
|
|
99
101
|
fs.write(fs.join(directory, "#{action}.rb"), t("action.erb", context))
|
|
102
|
+
|
|
103
|
+
unless skip_view
|
|
104
|
+
fs.mkdir(directory = fs.join("app", "views", controller))
|
|
105
|
+
fs.write(fs.join(directory, "#{action}.rb"), t("view.erb", context))
|
|
106
|
+
|
|
107
|
+
fs.mkdir(directory = fs.join("app", "templates", controller))
|
|
108
|
+
fs.write(fs.join(directory, "#{action}.#{format}.erb"),
|
|
109
|
+
t(template_with_format_ext("template", format), context))
|
|
110
|
+
end
|
|
100
111
|
end
|
|
112
|
+
# rubocop:enable Metrics/AbcSize
|
|
101
113
|
|
|
102
114
|
def slice_matcher(slice)
|
|
103
115
|
/slice[[:space:]]*:#{slice}/
|
|
@@ -108,13 +120,16 @@ module Hanami
|
|
|
108
120
|
http)} "#{route_url(controller, action, url)}", to: "#{controller.join('.')}.#{action}")
|
|
109
121
|
end
|
|
110
122
|
|
|
111
|
-
def
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
123
|
+
def template_with_format_ext(name, format)
|
|
124
|
+
ext =
|
|
125
|
+
case format.to_sym
|
|
126
|
+
when :html
|
|
127
|
+
".html.erb"
|
|
128
|
+
else
|
|
129
|
+
".erb"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
"#{name}#{ext}"
|
|
118
133
|
end
|
|
119
134
|
|
|
120
135
|
def template(path, context)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= yield %>
|
|
@@ -19,7 +19,7 @@ module Hanami
|
|
|
19
19
|
|
|
20
20
|
# @since 2.0.0
|
|
21
21
|
# @api private
|
|
22
|
-
def call(app, slice, url, context: SliceContext.new(inflector, app, slice, url))
|
|
22
|
+
def call(app, slice, url, context: SliceContext.new(inflector, app, slice, url)) # rubocop:disable Metrics/AbcSize
|
|
23
23
|
fs.inject_line_at_class_bottom(
|
|
24
24
|
fs.join("config", "routes.rb"), "class Routes", t("routes.erb", context).chomp
|
|
25
25
|
)
|
|
@@ -28,14 +28,17 @@ module Hanami
|
|
|
28
28
|
|
|
29
29
|
# fs.write("#{directory}/config/slice.rb", t("slice.erb", context))
|
|
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
|
+
fs.write(fs.join(directory, "views", "helpers.rb"), t("helpers.erb", context))
|
|
33
|
+
fs.write(fs.join(directory, "templates", "layouts", "app.html.erb"),
|
|
34
|
+
File.read(File.join(__dir__, "slice", "layouts_app.html.erb")))
|
|
32
35
|
# fs.write(fs.join(directory, "/entities.rb"), t("entities.erb", context))
|
|
33
36
|
# fs.write(fs.join(directory, "/repository.rb"), t("repository.erb", context))
|
|
34
37
|
|
|
35
38
|
fs.write(fs.join(directory, "actions/.keep"), t("keep.erb", context))
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
fs.write(fs.join(directory, "views/.keep"), t("keep.erb", context))
|
|
40
|
+
fs.write(fs.join(directory, "templates/.keep"), t("keep.erb", context))
|
|
41
|
+
fs.write(fs.join(directory, "templates/layouts/.keep"), t("keep.erb", context))
|
|
39
42
|
# fs.write(fs.join(directory, entities/.keep"), t("keep.erb", context))
|
|
40
43
|
# fs.write(fs.join(directory, repositories/.keep"), t("keep.erb", context))
|
|
41
44
|
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<h1><%= camelized_app_name %>::Views::<%= camelized_namespace %>::<%= camelized_name %></h1>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module <%= camelized_app_name %>
|
|
4
|
+
module Views
|
|
5
|
+
<%= module_namespace_declaration %>
|
|
6
|
+
<%= module_namespace_offset %>class <%= camelized_name %> < <%= camelized_app_name %>::View
|
|
7
|
+
<%= module_namespace_offset %>end
|
|
8
|
+
<%= module_namespace_end %>
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<h1><%= camelized_slice_name %>::Views::<%= camelized_namespace %>::<%= camelized_name %></h1>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module <%= camelized_slice_name %>
|
|
4
|
+
module Views
|
|
5
|
+
<%= module_namespace_declaration %>
|
|
6
|
+
<%= module_namespace_offset %>class <%= camelized_name %> < <%= camelized_slice_name %>::View
|
|
7
|
+
<%= module_namespace_offset %>end
|
|
8
|
+
<%= module_namespace_end %>
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
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.0.0
|
|
12
|
+
# @api private
|
|
13
|
+
class View
|
|
14
|
+
# @since 2.0.0
|
|
15
|
+
# @api private
|
|
16
|
+
def initialize(fs:, inflector:)
|
|
17
|
+
@fs = fs
|
|
18
|
+
@inflector = inflector
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @since 2.0.0
|
|
22
|
+
# @api private
|
|
23
|
+
def call(app, key, format, slice)
|
|
24
|
+
context = ViewContext.new(inflector, app, slice, key)
|
|
25
|
+
|
|
26
|
+
if slice
|
|
27
|
+
generate_for_slice(context, format, slice)
|
|
28
|
+
else
|
|
29
|
+
generate_for_app(context, format, slice)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
attr_reader :fs
|
|
36
|
+
|
|
37
|
+
attr_reader :inflector
|
|
38
|
+
|
|
39
|
+
# rubocop:disable Metrics/AbcSize
|
|
40
|
+
|
|
41
|
+
def generate_for_slice(context, format, slice)
|
|
42
|
+
slice_directory = fs.join("slices", slice)
|
|
43
|
+
raise MissingSliceError.new(slice) unless fs.directory?(slice_directory)
|
|
44
|
+
|
|
45
|
+
fs.mkdir(directory = fs.join(slice_directory, "views", context.namespaces))
|
|
46
|
+
fs.write(fs.join(directory, "#{context.name}.rb"), t("slice_view.erb", context))
|
|
47
|
+
|
|
48
|
+
fs.mkdir(directory = fs.join(slice_directory, "templates", context.namespaces))
|
|
49
|
+
fs.write(fs.join(directory, "#{context.name}.#{format}.erb"),
|
|
50
|
+
t(template_with_format_ext("slice_template", format), context))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def generate_for_app(context, format, _slice)
|
|
54
|
+
fs.mkdir(directory = fs.join("app", "views", context.namespaces))
|
|
55
|
+
fs.write(fs.join(directory, "#{context.name}.rb"), t("app_view.erb", context))
|
|
56
|
+
|
|
57
|
+
fs.mkdir(directory = fs.join("app", "templates", context.namespaces))
|
|
58
|
+
fs.write(fs.join(directory, "#{context.name}.#{format}.erb"),
|
|
59
|
+
t(template_with_format_ext("app_template", format), context))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# rubocop:enable Metrics/AbcSize
|
|
63
|
+
|
|
64
|
+
def template_with_format_ext(name, format)
|
|
65
|
+
ext =
|
|
66
|
+
case format.to_sym
|
|
67
|
+
when :html
|
|
68
|
+
".html.erb"
|
|
69
|
+
else
|
|
70
|
+
".erb"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
"#{name}#{ext}"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def template(path, context)
|
|
77
|
+
require "erb"
|
|
78
|
+
|
|
79
|
+
ERB.new(
|
|
80
|
+
File.read(__dir__ + "/view/#{path}")
|
|
81
|
+
).result(context.ctx)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
alias_method :t, :template
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
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 ViewContext < SliceContext
|
|
15
|
+
# TODO: move these constants somewhere that will let us reuse them
|
|
16
|
+
KEY_SEPARATOR = "."
|
|
17
|
+
private_constant :KEY_SEPARATOR
|
|
18
|
+
|
|
19
|
+
NAMESPACE_SEPARATOR = "::"
|
|
20
|
+
private_constant :NAMESPACE_SEPARATOR
|
|
21
|
+
|
|
22
|
+
INDENTATION = " "
|
|
23
|
+
private_constant :INDENTATION
|
|
24
|
+
|
|
25
|
+
OFFSET = INDENTATION * 2
|
|
26
|
+
private_constant :OFFSET
|
|
27
|
+
|
|
28
|
+
# @since 2.1.0
|
|
29
|
+
# @api private
|
|
30
|
+
attr_reader :key
|
|
31
|
+
|
|
32
|
+
# @since 2.1.0
|
|
33
|
+
# @api private
|
|
34
|
+
def initialize(inflector, app, slice, key)
|
|
35
|
+
@key = key
|
|
36
|
+
super(inflector, app, slice, nil)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @since 2.1.0
|
|
40
|
+
# @api private
|
|
41
|
+
def namespaces
|
|
42
|
+
@namespaces ||= key.split(KEY_SEPARATOR)[..-2]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @since 2.1.0
|
|
46
|
+
# @api private
|
|
47
|
+
def name
|
|
48
|
+
@name ||= key.split(KEY_SEPARATOR)[-1]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @since 2.1.0
|
|
52
|
+
# @api private
|
|
53
|
+
def camelized_namespace
|
|
54
|
+
namespaces.map { inflector.camelize(_1) }.join(NAMESPACE_SEPARATOR)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @since 2.1.0
|
|
58
|
+
# @api private
|
|
59
|
+
def camelized_name
|
|
60
|
+
inflector.camelize(name)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @since 2.1.0
|
|
64
|
+
# @api private
|
|
65
|
+
def underscored_namespace
|
|
66
|
+
namespaces.map { inflector.underscore(_1) }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @since 2.1.0
|
|
70
|
+
# @api private
|
|
71
|
+
def underscored_name
|
|
72
|
+
inflector.underscore(name)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @since 2.1.0
|
|
76
|
+
# @api private
|
|
77
|
+
def module_namespace_declaration
|
|
78
|
+
namespaces.each_with_index.map { |token, i|
|
|
79
|
+
"#{OFFSET}#{INDENTATION * i}module #{inflector.camelize(token)}"
|
|
80
|
+
}.join($/)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# @since 2.1.0
|
|
84
|
+
# @api private
|
|
85
|
+
def module_namespace_end
|
|
86
|
+
namespaces.each_with_index.map { |_, i|
|
|
87
|
+
"#{OFFSET}#{INDENTATION * i}end"
|
|
88
|
+
}.reverse.join($/)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @since 2.1.0
|
|
92
|
+
# @api private
|
|
93
|
+
def module_namespace_offset
|
|
94
|
+
"#{OFFSET}#{INDENTATION * namespaces.count}"
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The page you were looking for doesn’t exist (404)</title>
|
|
5
|
+
</head>
|
|
6
|
+
<body>
|
|
7
|
+
<!-- This file lives in public/404.html -->
|
|
8
|
+
<h1>The page you were looking for doesn’t exist.</h1>
|
|
9
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
|
10
|
+
</body>
|
|
11
|
+
</html>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>We’re sorry, but something went wrong (500)</title>
|
|
5
|
+
</head>
|
|
6
|
+
<body>
|
|
7
|
+
<!-- This file lives in public/500.html -->
|
|
8
|
+
<h1>We’re sorry, but something went wrong.</h1>
|
|
9
|
+
<p>If you are the application owner, check the logs for more information.</p>
|
|
10
|
+
</body>
|
|
11
|
+
</html>
|
|
@@ -6,6 +6,8 @@ gem "hanami", "<%= hanami_version %>"
|
|
|
6
6
|
gem "hanami-router", "<%= hanami_version %>"
|
|
7
7
|
gem "hanami-controller", "<%= hanami_version %>"
|
|
8
8
|
gem "hanami-validations", "<%= hanami_version %>"
|
|
9
|
+
gem "hanami-view", "<%= hanami_version %>"
|
|
10
|
+
gem "hanami-webconsole", "<%= hanami_version %>"
|
|
9
11
|
|
|
10
12
|
gem "dry-types", "~> 1.0", ">= 1.6.1"
|
|
11
13
|
gem "puma"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= yield %>
|
|
@@ -6,10 +6,12 @@ threads min_threads_count, max_threads_count
|
|
|
6
6
|
|
|
7
7
|
port ENV.fetch("<%= Hanami::Port::ENV_VAR %>", <%= Hanami::Port::DEFAULT %>)
|
|
8
8
|
environment ENV.fetch("HANAMI_ENV", "development")
|
|
9
|
-
workers ENV.fetch("HANAMI_WEB_CONCURRENCY",
|
|
9
|
+
workers ENV.fetch("HANAMI_WEB_CONCURRENCY", 0)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
if ENV.fetch("HANAMI_WEB_CONCURRENCY", 0) > 0
|
|
12
|
+
on_worker_boot do
|
|
13
|
+
Hanami.shutdown
|
|
14
|
+
end
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
preload_app!
|
|
@@ -52,6 +52,12 @@ module Hanami
|
|
|
52
52
|
|
|
53
53
|
fs.write("app/actions/.keep", t("keep.erb", context))
|
|
54
54
|
fs.write("app/action.rb", t("action.erb", context))
|
|
55
|
+
fs.write("app/view.rb", t("view.erb", context))
|
|
56
|
+
fs.write("app/views/helpers.rb", t("helpers.erb", context))
|
|
57
|
+
fs.write("app/templates/layouts/app.html.erb", File.read(File.join(__dir__, "app", "layouts_app.html.erb")))
|
|
58
|
+
|
|
59
|
+
fs.write("public/404.html", File.read(File.join(__dir__, "app", "404.html")))
|
|
60
|
+
fs.write("public/500.html", File.read(File.join(__dir__, "app", "500.html")))
|
|
55
61
|
end
|
|
56
62
|
|
|
57
63
|
def template(path, context)
|
data/lib/hanami/cli/url.rb
CHANGED
data/lib/hanami/cli/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hanami-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.1.0.beta1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Luca Guidi
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-06-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -212,6 +212,7 @@ files:
|
|
|
212
212
|
- lib/hanami/cli/commands/app/generate.rb
|
|
213
213
|
- lib/hanami/cli/commands/app/generate/action.rb
|
|
214
214
|
- lib/hanami/cli/commands/app/generate/slice.rb
|
|
215
|
+
- lib/hanami/cli/commands/app/generate/view.rb
|
|
215
216
|
- lib/hanami/cli/commands/app/install.rb
|
|
216
217
|
- lib/hanami/cli/commands/app/middleware.rb
|
|
217
218
|
- lib/hanami/cli/commands/app/routes.rb
|
|
@@ -225,6 +226,8 @@ files:
|
|
|
225
226
|
- lib/hanami/cli/generators/app/action.rb
|
|
226
227
|
- lib/hanami/cli/generators/app/action/action.erb
|
|
227
228
|
- lib/hanami/cli/generators/app/action/slice_action.erb
|
|
229
|
+
- lib/hanami/cli/generators/app/action/slice_template.html.erb
|
|
230
|
+
- lib/hanami/cli/generators/app/action/slice_view.erb
|
|
228
231
|
- lib/hanami/cli/generators/app/action/template.erb
|
|
229
232
|
- lib/hanami/cli/generators/app/action/template.html.erb
|
|
230
233
|
- lib/hanami/cli/generators/app/action/view.erb
|
|
@@ -232,21 +235,33 @@ files:
|
|
|
232
235
|
- lib/hanami/cli/generators/app/slice.rb
|
|
233
236
|
- lib/hanami/cli/generators/app/slice/action.erb
|
|
234
237
|
- lib/hanami/cli/generators/app/slice/entities.erb
|
|
238
|
+
- lib/hanami/cli/generators/app/slice/helpers.erb
|
|
235
239
|
- lib/hanami/cli/generators/app/slice/keep.erb
|
|
240
|
+
- lib/hanami/cli/generators/app/slice/layouts_app.html.erb
|
|
236
241
|
- lib/hanami/cli/generators/app/slice/repository.erb
|
|
237
242
|
- lib/hanami/cli/generators/app/slice/routes.erb
|
|
238
243
|
- lib/hanami/cli/generators/app/slice/slice.erb
|
|
239
244
|
- lib/hanami/cli/generators/app/slice/view.erb
|
|
240
245
|
- lib/hanami/cli/generators/app/slice_context.rb
|
|
246
|
+
- lib/hanami/cli/generators/app/view.rb
|
|
247
|
+
- lib/hanami/cli/generators/app/view/app_template.html.erb
|
|
248
|
+
- lib/hanami/cli/generators/app/view/app_view.erb
|
|
249
|
+
- lib/hanami/cli/generators/app/view/slice_template.html.erb
|
|
250
|
+
- lib/hanami/cli/generators/app/view/slice_view.erb
|
|
251
|
+
- lib/hanami/cli/generators/app/view_context.rb
|
|
241
252
|
- lib/hanami/cli/generators/context.rb
|
|
242
253
|
- lib/hanami/cli/generators/gem/app.rb
|
|
254
|
+
- lib/hanami/cli/generators/gem/app/404.html
|
|
255
|
+
- lib/hanami/cli/generators/gem/app/500.html
|
|
243
256
|
- lib/hanami/cli/generators/gem/app/action.erb
|
|
244
257
|
- lib/hanami/cli/generators/gem/app/app.erb
|
|
245
258
|
- lib/hanami/cli/generators/gem/app/config_ru.erb
|
|
246
259
|
- lib/hanami/cli/generators/gem/app/env.erb
|
|
247
260
|
- lib/hanami/cli/generators/gem/app/gemfile.erb
|
|
248
261
|
- lib/hanami/cli/generators/gem/app/gitignore.erb
|
|
262
|
+
- lib/hanami/cli/generators/gem/app/helpers.erb
|
|
249
263
|
- lib/hanami/cli/generators/gem/app/keep.erb
|
|
264
|
+
- lib/hanami/cli/generators/gem/app/layouts_app.html.erb
|
|
250
265
|
- lib/hanami/cli/generators/gem/app/puma.erb
|
|
251
266
|
- lib/hanami/cli/generators/gem/app/rakefile.erb
|
|
252
267
|
- lib/hanami/cli/generators/gem/app/readme.erb
|
|
@@ -254,6 +269,7 @@ files:
|
|
|
254
269
|
- lib/hanami/cli/generators/gem/app/settings.erb
|
|
255
270
|
- lib/hanami/cli/generators/gem/app/types.erb
|
|
256
271
|
- lib/hanami/cli/generators/gem/app/validator.erb
|
|
272
|
+
- lib/hanami/cli/generators/gem/app/view.erb
|
|
257
273
|
- lib/hanami/cli/generators/version.rb
|
|
258
274
|
- lib/hanami/cli/middleware_stack_inspector.rb
|
|
259
275
|
- lib/hanami/cli/naming.rb
|
|
@@ -288,11 +304,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
288
304
|
version: '3.0'
|
|
289
305
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
290
306
|
requirements:
|
|
291
|
-
- - "
|
|
307
|
+
- - ">"
|
|
292
308
|
- !ruby/object:Gem::Version
|
|
293
|
-
version:
|
|
309
|
+
version: 1.3.1
|
|
294
310
|
requirements: []
|
|
295
|
-
rubygems_version: 3.4.
|
|
311
|
+
rubygems_version: 3.4.13
|
|
296
312
|
signing_key:
|
|
297
313
|
specification_version: 4
|
|
298
314
|
summary: Hanami CLI
|