hanami-cli 2.0.0 → 2.1.0
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 +2 -0
- data/{.action_hero.yml → .repobot.yml} +1 -3
- data/.rubocop.yml +6 -0
- data/CHANGELOG.md +115 -0
- data/Gemfile +7 -2
- data/LICENSE.md +1 -1
- data/README.md +1 -1
- data/hanami-cli.gemspec +1 -1
- data/lib/hanami/cli/bundler.rb +26 -9
- data/lib/hanami/cli/command.rb +28 -6
- data/lib/hanami/cli/commands/app/assets/command.rb +155 -0
- data/lib/hanami/cli/commands/app/assets/compile.rb +35 -0
- data/lib/hanami/cli/commands/app/assets/watch.rb +29 -0
- data/lib/hanami/cli/commands/app/assets.rb +16 -0
- data/lib/hanami/cli/commands/app/command.rb +5 -3
- 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/dev.rb +50 -0
- data/lib/hanami/cli/commands/app/generate/action.rb +38 -9
- data/lib/hanami/cli/commands/app/generate/part.rb +57 -0
- data/lib/hanami/cli/commands/app/generate/slice.rb +6 -3
- data/lib/hanami/cli/commands/app/generate/view.rb +56 -0
- data/lib/hanami/cli/commands/app/generate.rb +2 -2
- data/lib/hanami/cli/commands/app/install.rb +16 -1
- data/lib/hanami/cli/commands/app/server.rb +6 -10
- data/lib/hanami/cli/commands/app.rb +10 -0
- data/lib/hanami/cli/commands/gem/new.rb +70 -12
- data/lib/hanami/cli/errors.rb +30 -0
- data/lib/hanami/cli/files.rb +8 -2
- data/lib/hanami/cli/generators/app/action/action.erb +5 -1
- data/lib/hanami/cli/generators/app/action/slice_action.erb +5 -1
- data/lib/hanami/cli/generators/app/action/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 +74 -22
- data/lib/hanami/cli/generators/app/action_context.rb +1 -1
- data/lib/hanami/cli/generators/app/part/app_base_part.erb +9 -0
- data/lib/hanami/cli/generators/app/part/app_part.erb +13 -0
- data/lib/hanami/cli/generators/app/part/slice_base_part.erb +9 -0
- data/lib/hanami/cli/generators/app/part/slice_part.erb +13 -0
- data/lib/hanami/cli/generators/app/part.rb +101 -0
- data/lib/hanami/cli/generators/app/part_context.rb +98 -0
- data/lib/hanami/cli/generators/app/slice/app_css.erb +5 -0
- data/lib/hanami/cli/generators/app/slice/app_js.erb +1 -0
- data/lib/hanami/cli/generators/app/slice/app_layout.erb +18 -0
- data/lib/hanami/cli/generators/app/slice/favicon.ico +0 -0
- data/lib/hanami/cli/generators/app/slice/helpers.erb +10 -0
- data/lib/hanami/cli/generators/app/slice/view.erb +0 -2
- data/lib/hanami/cli/generators/app/slice.rb +20 -6
- data/lib/hanami/cli/generators/app/slice_context.rb +18 -0
- 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 +72 -5
- data/lib/hanami/cli/generators/gem/app/404.html +82 -0
- data/lib/hanami/cli/generators/gem/app/500.html +82 -0
- data/lib/hanami/cli/generators/gem/app/app_css.erb +5 -0
- data/lib/hanami/cli/generators/gem/app/app_js.erb +1 -0
- data/lib/hanami/cli/generators/gem/app/app_layout.erb +18 -0
- data/lib/hanami/cli/generators/gem/app/assets.js +16 -0
- data/lib/hanami/cli/generators/gem/app/dev +8 -0
- data/lib/hanami/cli/generators/gem/app/favicon.ico +0 -0
- data/lib/hanami/cli/generators/gem/app/gemfile.erb +14 -6
- data/lib/hanami/cli/generators/gem/app/gitignore.erb +6 -0
- data/lib/hanami/cli/generators/gem/app/helpers.erb +10 -0
- data/lib/hanami/cli/generators/gem/app/package.json.erb +8 -0
- data/lib/hanami/cli/generators/gem/app/procfile.erb +4 -0
- data/lib/hanami/cli/generators/gem/app/puma.erb +39 -7
- data/lib/hanami/cli/generators/gem/app/routes.erb +1 -1
- data/lib/hanami/cli/generators/gem/app/view.erb +9 -0
- data/lib/hanami/cli/generators/gem/app.rb +25 -1
- data/lib/hanami/cli/generators/version.rb +14 -2
- data/lib/hanami/cli/interactive_system_call.rb +65 -0
- data/lib/hanami/cli/naming.rb +25 -0
- data/lib/hanami/cli/system_call.rb +8 -2
- data/lib/hanami/cli/url.rb +1 -1
- data/lib/hanami/cli/version.rb +1 -1
- metadata +47 -6
|
@@ -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,23 @@ 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"), t("app_layout.erb", context))
|
|
34
|
+
|
|
35
|
+
if context.bundled_assets?
|
|
36
|
+
fs.write(fs.join(directory, "assets", "js", "app.js"), t("app_js.erb", context))
|
|
37
|
+
fs.write(fs.join(directory, "assets", "css", "app.css"), t("app_css.erb", context))
|
|
38
|
+
fs.write(fs.join(directory, "assets", "images", "favicon.ico"), file("favicon.ico"))
|
|
39
|
+
end
|
|
40
|
+
|
|
32
41
|
# fs.write(fs.join(directory, "/entities.rb"), t("entities.erb", context))
|
|
33
42
|
# fs.write(fs.join(directory, "/repository.rb"), t("repository.erb", context))
|
|
34
43
|
|
|
35
44
|
fs.write(fs.join(directory, "actions/.keep"), t("keep.erb", context))
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
45
|
+
fs.write(fs.join(directory, "views/.keep"), t("keep.erb", context))
|
|
46
|
+
fs.write(fs.join(directory, "templates/.keep"), t("keep.erb", context))
|
|
47
|
+
fs.write(fs.join(directory, "templates/layouts/.keep"), t("keep.erb", context))
|
|
39
48
|
# fs.write(fs.join(directory, entities/.keep"), t("keep.erb", context))
|
|
40
49
|
# fs.write(fs.join(directory, repositories/.keep"), t("keep.erb", context))
|
|
41
50
|
end
|
|
@@ -50,11 +59,16 @@ module Hanami
|
|
|
50
59
|
require "erb"
|
|
51
60
|
|
|
52
61
|
ERB.new(
|
|
53
|
-
File.read(__dir__ + "/slice/#{path}")
|
|
62
|
+
File.read(__dir__ + "/slice/#{path}"),
|
|
63
|
+
trim_mode: "-"
|
|
54
64
|
).result(context.ctx)
|
|
55
65
|
end
|
|
56
66
|
|
|
57
67
|
alias_method :t, :template
|
|
68
|
+
|
|
69
|
+
def file(path)
|
|
70
|
+
File.read(File.join(__dir__, "slice", path))
|
|
71
|
+
end
|
|
58
72
|
end
|
|
59
73
|
end
|
|
60
74
|
end
|
|
@@ -29,6 +29,24 @@ module Hanami
|
|
|
29
29
|
inflector.underscore(slice)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
# @since 2.1.0
|
|
33
|
+
# @api private
|
|
34
|
+
def humanized_slice_name
|
|
35
|
+
inflector.humanize(slice)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @since 2.1.0
|
|
39
|
+
# @api private
|
|
40
|
+
def stylesheet_erb_tag
|
|
41
|
+
%(<%= stylesheet_tag "app" %>)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @since 2.1.0
|
|
45
|
+
# @api private
|
|
46
|
+
def javascript_erb_tag
|
|
47
|
+
%(<%= javascript_tag "app" %>)
|
|
48
|
+
end
|
|
49
|
+
|
|
32
50
|
private
|
|
33
51
|
|
|
34
52
|
attr_reader :slice
|
|
@@ -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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "
|
|
3
|
+
require_relative "version"
|
|
4
4
|
|
|
5
5
|
module Hanami
|
|
6
6
|
module CLI
|
|
@@ -12,9 +12,10 @@ module Hanami
|
|
|
12
12
|
class Context
|
|
13
13
|
# @since 2.0.0
|
|
14
14
|
# @api private
|
|
15
|
-
def initialize(inflector, app)
|
|
15
|
+
def initialize(inflector, app, **options)
|
|
16
16
|
@inflector = inflector
|
|
17
17
|
@app = app
|
|
18
|
+
@options = options
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
# @since 2.0.0
|
|
@@ -23,16 +24,36 @@ module Hanami
|
|
|
23
24
|
binding
|
|
24
25
|
end
|
|
25
26
|
|
|
27
|
+
def hanami_gem(name)
|
|
28
|
+
gem_name = name == "hanami" ? "hanami" : "hanami-#{name}"
|
|
29
|
+
|
|
30
|
+
%(gem "#{gem_name}", #{hanami_gem_version(name)})
|
|
31
|
+
end
|
|
32
|
+
|
|
26
33
|
# @since 2.0.0
|
|
27
34
|
# @api private
|
|
28
|
-
def
|
|
29
|
-
|
|
35
|
+
def hanami_gem_version(gem_name)
|
|
36
|
+
if hanami_head?
|
|
37
|
+
%(github: "hanami/#{gem_name}", branch: "main")
|
|
38
|
+
else
|
|
39
|
+
%("#{Version.gem_requirement}")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @since 2.1.0
|
|
44
|
+
# @api private
|
|
45
|
+
def hanami_assets_npm_package
|
|
46
|
+
if hanami_head?
|
|
47
|
+
%("hanami-assets": "hanami/assets-js#main")
|
|
48
|
+
else
|
|
49
|
+
%("hanami-assets": "#{Version.npm_package_requirement}")
|
|
50
|
+
end
|
|
30
51
|
end
|
|
31
52
|
|
|
32
53
|
# @since 2.0.0
|
|
33
54
|
# @api private
|
|
34
55
|
def camelized_app_name
|
|
35
|
-
inflector.camelize(app)
|
|
56
|
+
inflector.camelize(app).gsub(/[^\p{Alnum}]/, "")
|
|
36
57
|
end
|
|
37
58
|
|
|
38
59
|
# @since 2.0.0
|
|
@@ -41,11 +62,57 @@ module Hanami
|
|
|
41
62
|
inflector.underscore(app)
|
|
42
63
|
end
|
|
43
64
|
|
|
65
|
+
# @since 2.1.0
|
|
66
|
+
# @api private
|
|
67
|
+
def humanized_app_name
|
|
68
|
+
inflector.humanize(app)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @since 2.1.0
|
|
72
|
+
# @api private
|
|
73
|
+
def hanami_head?
|
|
74
|
+
options.fetch(:head)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @since 2.1.0
|
|
78
|
+
# @api private
|
|
79
|
+
def generate_assets?
|
|
80
|
+
!options.fetch(:skip_assets, false)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# @since 2.1.0
|
|
84
|
+
# @api private
|
|
85
|
+
def bundled_views?
|
|
86
|
+
Hanami.bundled?("hanami-view")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# @since 2.1.0
|
|
90
|
+
# @api private
|
|
91
|
+
def bundled_assets?
|
|
92
|
+
Hanami.bundled?("hanami-assets")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# @since 2.1.0
|
|
96
|
+
# @api private
|
|
97
|
+
#
|
|
98
|
+
# @see https://rubyreferences.github.io/rubychanges/3.1.html#values-in-hash-literals-and-keyword-arguments-can-be-omitted
|
|
99
|
+
def ruby_omit_hash_values?
|
|
100
|
+
RUBY_VERSION >= "3.1"
|
|
101
|
+
end
|
|
102
|
+
|
|
44
103
|
private
|
|
45
104
|
|
|
105
|
+
# @since 2.0.0
|
|
106
|
+
# @api private
|
|
46
107
|
attr_reader :inflector
|
|
47
108
|
|
|
109
|
+
# @since 2.0.0
|
|
110
|
+
# @api private
|
|
48
111
|
attr_reader :app
|
|
112
|
+
|
|
113
|
+
# @since 2.1.0
|
|
114
|
+
# @api private
|
|
115
|
+
attr_reader :options
|
|
49
116
|
end
|
|
50
117
|
end
|
|
51
118
|
end
|
|
@@ -0,0 +1,82 @@
|
|
|
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>The page you were looking for doesn’t exist (404)</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root {
|
|
9
|
+
--foreground-rgb: 0, 0, 0;
|
|
10
|
+
--background-rgb: 255, 255, 255;
|
|
11
|
+
--font-sans: ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@media (prefers-color-scheme: dark) {
|
|
15
|
+
:root {
|
|
16
|
+
--foreground-rgb: 255, 255, 255;
|
|
17
|
+
--background-rgb: 0, 0, 0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
* {
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
margin: 0;
|
|
24
|
+
padding: 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
body,
|
|
28
|
+
html {
|
|
29
|
+
max-width: 100vw;
|
|
30
|
+
overflow-x: hidden;
|
|
31
|
+
font-size: 100%;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
body {
|
|
35
|
+
color: rgb(var(--foreground-rgb));
|
|
36
|
+
background: rgb(var(--background-rgb));
|
|
37
|
+
font-family: var(--font-sans);
|
|
38
|
+
font-style: normal;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
main {
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: center;
|
|
46
|
+
height: 100vh;
|
|
47
|
+
padding: 0 4vw;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.message {
|
|
51
|
+
display: flex;
|
|
52
|
+
gap: 1rem;
|
|
53
|
+
flex-direction: column;
|
|
54
|
+
text-align: center;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.message h1 {
|
|
58
|
+
font-size: 2rem;
|
|
59
|
+
font-weight: 500;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
p {
|
|
63
|
+
line-height: 1.6;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@media (prefers-color-scheme: dark) {
|
|
67
|
+
html {
|
|
68
|
+
color-scheme: dark;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
</style>
|
|
72
|
+
</head>
|
|
73
|
+
<body>
|
|
74
|
+
<!-- This file lives in public/404.html -->
|
|
75
|
+
<main>
|
|
76
|
+
<div class="message">
|
|
77
|
+
<h1>404</h1>
|
|
78
|
+
<p>The page you were looking for doesn’t exist.</p>
|
|
79
|
+
</div>
|
|
80
|
+
</main>
|
|
81
|
+
</body>
|
|
82
|
+
</html>
|
|
@@ -0,0 +1,82 @@
|
|
|
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>We’re sorry, but something went wrong (500)</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root {
|
|
9
|
+
--foreground-rgb: 0, 0, 0;
|
|
10
|
+
--background-rgb: 255, 255, 255;
|
|
11
|
+
--font-sans: ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@media (prefers-color-scheme: dark) {
|
|
15
|
+
:root {
|
|
16
|
+
--foreground-rgb: 255, 255, 255;
|
|
17
|
+
--background-rgb: 0, 0, 0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
* {
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
margin: 0;
|
|
24
|
+
padding: 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
body,
|
|
28
|
+
html {
|
|
29
|
+
max-width: 100vw;
|
|
30
|
+
overflow-x: hidden;
|
|
31
|
+
font-size: 100%;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
body {
|
|
35
|
+
color: rgb(var(--foreground-rgb));
|
|
36
|
+
background: rgb(var(--background-rgb));
|
|
37
|
+
font-family: var(--font-sans);
|
|
38
|
+
font-style: normal;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
main {
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: center;
|
|
46
|
+
height: 100vh;
|
|
47
|
+
padding: 0 4vw;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.message {
|
|
51
|
+
display: flex;
|
|
52
|
+
gap: 1rem;
|
|
53
|
+
flex-direction: column;
|
|
54
|
+
text-align: center;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.message h1 {
|
|
58
|
+
font-size: 2rem;
|
|
59
|
+
font-weight: 500;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
p {
|
|
63
|
+
line-height: 1.6;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@media (prefers-color-scheme: dark) {
|
|
67
|
+
html {
|
|
68
|
+
color-scheme: dark;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
</style>
|
|
72
|
+
</head>
|
|
73
|
+
<body>
|
|
74
|
+
<!-- This file lives in public/500.html -->
|
|
75
|
+
<main>
|
|
76
|
+
<div class="message">
|
|
77
|
+
<h1>500</h1>
|
|
78
|
+
<p>We’re sorry, but something went wrong.</p>
|
|
79
|
+
</div>
|
|
80
|
+
</main>
|
|
81
|
+
</body>
|
|
82
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "../css/app.css";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title><%= humanized_app_name %></title>
|
|
7
|
+
<%- if generate_assets? -%>
|
|
8
|
+
<%%= favicon_tag %>
|
|
9
|
+
<%%= stylesheet_tag "app" %>
|
|
10
|
+
<%- end -%>
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<%%= yield %>
|
|
14
|
+
<%- if generate_assets? -%>
|
|
15
|
+
<%%= javascript_tag "app" %>
|
|
16
|
+
<%- end -%>
|
|
17
|
+
</body>
|
|
18
|
+
</html>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as assets from "hanami-assets";
|
|
2
|
+
|
|
3
|
+
await assets.run();
|
|
4
|
+
|
|
5
|
+
// To provide additional esbuild (https://esbuild.github.io) options, use the following:
|
|
6
|
+
//
|
|
7
|
+
// Read more at: https://guides.hanamirb.org/assets/customization/
|
|
8
|
+
//
|
|
9
|
+
// await assets.run({
|
|
10
|
+
// esbuildOptionsFn: (args, esbuildOptions) => {
|
|
11
|
+
// // Add to esbuildOptions here. Use `args.watch` as a condition for different options for
|
|
12
|
+
// // compile vs watch.
|
|
13
|
+
//
|
|
14
|
+
// return esbuildOptions;
|
|
15
|
+
// }
|
|
16
|
+
// });
|
|
Binary file
|
|
@@ -2,23 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
source "https://rubygems.org"
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
<%= hanami_gem("hanami") %>
|
|
6
|
+
<%- if generate_assets? -%>
|
|
7
|
+
<%= hanami_gem("assets") %>
|
|
8
|
+
<%- end -%>
|
|
9
|
+
<%= hanami_gem("controller") %>
|
|
10
|
+
<%= hanami_gem("router") %>
|
|
11
|
+
<%= hanami_gem("validations") %>
|
|
12
|
+
<%= hanami_gem("view") %>
|
|
9
13
|
|
|
10
14
|
gem "dry-types", "~> 1.0", ">= 1.6.1"
|
|
11
15
|
gem "puma"
|
|
12
16
|
gem "rake"
|
|
13
17
|
|
|
18
|
+
group :development do
|
|
19
|
+
<%= hanami_gem("webconsole") %>
|
|
20
|
+
end
|
|
21
|
+
|
|
14
22
|
group :development, :test do
|
|
15
23
|
gem "dotenv"
|
|
16
24
|
end
|
|
17
25
|
|
|
18
26
|
group :cli, :development do
|
|
19
|
-
|
|
27
|
+
<%= hanami_gem("reloader") %>
|
|
20
28
|
end
|
|
21
29
|
|
|
22
30
|
group :cli, :development, :test do
|
|
23
|
-
|
|
31
|
+
<%= hanami_gem("rspec") %>
|
|
24
32
|
end
|