hanami-cli 2.1.1 → 2.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +18 -13
- data/CHANGELOG.md +15 -0
- data/Gemfile +4 -2
- data/README.md +11 -7
- data/docker-compose.yml +9 -0
- data/hanami-cli.gemspec +2 -2
- data/lib/hanami/cli/command.rb +1 -1
- data/lib/hanami/cli/commands/app/command.rb +2 -16
- data/lib/hanami/cli/commands/app/db/command.rb +116 -0
- data/lib/hanami/cli/commands/app/db/create.rb +19 -11
- data/lib/hanami/cli/commands/app/db/drop.rb +19 -10
- data/lib/hanami/cli/commands/app/db/migrate.rb +19 -13
- data/lib/hanami/cli/commands/app/db/prepare.rb +42 -0
- data/lib/hanami/cli/commands/app/db/seed.rb +11 -22
- data/lib/hanami/cli/commands/app/db/structure/dump.rb +30 -7
- data/lib/hanami/cli/commands/app/db/structure/load.rb +52 -0
- data/lib/hanami/cli/commands/app/db/utils/database.rb +68 -73
- data/lib/hanami/cli/commands/app/db/utils/mysql.rb +2 -2
- data/lib/hanami/cli/commands/app/db/utils/postgres.rb +38 -19
- data/lib/hanami/cli/commands/app/db/utils/sqlite.rb +58 -10
- data/lib/hanami/cli/commands/app/db/version.rb +12 -9
- data/lib/hanami/cli/commands/app/generate/action.rb +4 -3
- data/lib/hanami/cli/commands/app/generate/command.rb +49 -0
- data/lib/hanami/cli/commands/app/generate/component.rb +49 -0
- data/lib/hanami/cli/commands/app/generate/migration.rb +27 -0
- data/lib/hanami/cli/commands/app/generate/operation.rb +26 -0
- data/lib/hanami/cli/commands/app/generate/part.rb +1 -1
- data/lib/hanami/cli/commands/app/generate/relation.rb +35 -0
- data/lib/hanami/cli/commands/app/generate/repo.rb +46 -0
- data/lib/hanami/cli/commands/app/generate/slice.rb +20 -3
- data/lib/hanami/cli/commands/app/generate/struct.rb +27 -0
- data/lib/hanami/cli/commands/app/install.rb +1 -1
- data/lib/hanami/cli/commands/app/middleware.rb +1 -1
- data/lib/hanami/cli/commands/app/server.rb +2 -2
- data/lib/hanami/cli/commands/app.rb +21 -2
- data/lib/hanami/cli/commands/gem/new.rb +78 -14
- data/lib/hanami/cli/errors.rb +28 -0
- data/lib/hanami/cli/generators/app/action_context.rb +5 -13
- data/lib/hanami/cli/generators/app/component/component.erb +8 -0
- data/lib/hanami/cli/generators/app/component/slice_component.erb +8 -0
- data/lib/hanami/cli/generators/app/component.rb +61 -0
- data/lib/hanami/cli/generators/app/component_context.rb +82 -0
- data/lib/hanami/cli/generators/app/migration.rb +69 -0
- data/lib/hanami/cli/generators/app/operation.rb +48 -0
- data/lib/hanami/cli/generators/app/part_context.rb +5 -21
- data/lib/hanami/cli/generators/app/relation.rb +44 -0
- data/lib/hanami/cli/generators/app/repo.rb +40 -0
- data/lib/hanami/cli/generators/app/ruby_file_writer.rb +149 -0
- data/lib/hanami/cli/generators/app/slice/operation.erb +7 -0
- data/lib/hanami/cli/generators/app/slice/relation.erb +8 -0
- data/lib/hanami/cli/generators/app/slice/{slice.erb → repo.erb} +3 -1
- data/lib/hanami/cli/generators/app/slice/struct.erb +8 -0
- data/lib/hanami/cli/generators/app/slice.rb +14 -6
- data/lib/hanami/cli/generators/app/slice_context.rb +9 -2
- data/lib/hanami/cli/generators/app/struct.rb +39 -0
- data/lib/hanami/cli/generators/app/view_context.rb +4 -16
- data/lib/hanami/cli/generators/constants.rb +39 -0
- data/lib/hanami/cli/generators/context.rb +48 -0
- data/lib/hanami/cli/generators/gem/app/action.erb +3 -0
- data/lib/hanami/cli/generators/gem/app/env.erb +4 -0
- data/lib/hanami/cli/generators/gem/app/gemfile.erb +11 -0
- data/lib/hanami/cli/generators/gem/app/gitignore.erb +1 -1
- data/lib/hanami/cli/generators/gem/app/operation.erb +13 -0
- data/lib/hanami/cli/generators/gem/app/relation.erb +10 -0
- data/lib/hanami/cli/generators/gem/app/repo.erb +10 -0
- data/lib/hanami/cli/generators/gem/app/struct.erb +10 -0
- data/lib/hanami/cli/generators/gem/app.rb +19 -0
- data/lib/hanami/cli/ruby_file_generator.rb +123 -0
- data/lib/hanami/cli/version.rb +1 -1
- metadata +39 -16
- data/lib/hanami/cli/commands/app/db/create_migration.rb +0 -32
- data/lib/hanami/cli/commands/app/db/reset.rb +0 -28
- data/lib/hanami/cli/commands/app/db/rollback.rb +0 -81
- data/lib/hanami/cli/commands/app/db/sample_data.rb +0 -42
- data/lib/hanami/cli/commands/app/db/setup.rb +0 -26
- data/lib/hanami/cli/commands/app/db/utils/database_config.rb +0 -60
- data/lib/hanami/cli/generators/app/slice/repository.erb +0 -10
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../constants"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
module CLI
|
7
|
+
module Generators
|
8
|
+
module App
|
9
|
+
# @since 2.2.0
|
10
|
+
# @api private
|
11
|
+
class Operation
|
12
|
+
# @since 2.2.0
|
13
|
+
# @api private
|
14
|
+
def initialize(fs:, inflector:, out: $stdout)
|
15
|
+
@fs = fs
|
16
|
+
@inflector = inflector
|
17
|
+
@out = out
|
18
|
+
end
|
19
|
+
|
20
|
+
# @since 2.2.0
|
21
|
+
# @api private
|
22
|
+
def call(app_namespace, key, slice)
|
23
|
+
RubyFileWriter.new(
|
24
|
+
fs: fs,
|
25
|
+
inflector: inflector,
|
26
|
+
app_namespace: app_namespace,
|
27
|
+
key: key,
|
28
|
+
slice: slice,
|
29
|
+
relative_parent_class: "Operation",
|
30
|
+
body: ["def call", "end"],
|
31
|
+
).call
|
32
|
+
|
33
|
+
unless key.match?(KEY_SEPARATOR)
|
34
|
+
out.puts(
|
35
|
+
" Note: We generated a top-level operation. " \
|
36
|
+
"To generate into a directory, add a namespace: `my_namespace.add_book`"
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_reader :fs, :inflector, :out
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "slice_context"
|
4
3
|
require "dry/files/path"
|
4
|
+
require_relative "slice_context"
|
5
|
+
require_relative "../constants"
|
5
6
|
|
6
7
|
module Hanami
|
7
8
|
module CLI
|
@@ -12,23 +13,6 @@ module Hanami
|
|
12
13
|
# @since 2.1.0
|
13
14
|
# @api private
|
14
15
|
class PartContext < SliceContext
|
15
|
-
# TODO: move these constants somewhere that will let us reuse them
|
16
|
-
|
17
|
-
# @since 2.1.0
|
18
|
-
# @api private
|
19
|
-
KEY_SEPARATOR = "."
|
20
|
-
private_constant :KEY_SEPARATOR
|
21
|
-
|
22
|
-
# @since 2.1.0
|
23
|
-
# @api private
|
24
|
-
INDENTATION = " "
|
25
|
-
private_constant :INDENTATION
|
26
|
-
|
27
|
-
# @since 2.1.0
|
28
|
-
# @api private
|
29
|
-
OFFSET = INDENTATION * 2
|
30
|
-
private_constant :OFFSET
|
31
|
-
|
32
16
|
# @since 2.1.0
|
33
17
|
# @api private
|
34
18
|
attr_reader :key
|
@@ -74,7 +58,7 @@ module Hanami
|
|
74
58
|
# @api private
|
75
59
|
def module_namespace_declaration
|
76
60
|
namespaces.each_with_index.map { |token, i|
|
77
|
-
"#{
|
61
|
+
"#{NESTED_OFFSET}#{INDENTATION * i}module #{inflector.camelize(token)}"
|
78
62
|
}.join($/)
|
79
63
|
end
|
80
64
|
|
@@ -82,14 +66,14 @@ module Hanami
|
|
82
66
|
# @api private
|
83
67
|
def module_namespace_end
|
84
68
|
namespaces.each_with_index.map { |_, i|
|
85
|
-
"#{
|
69
|
+
"#{NESTED_OFFSET}#{INDENTATION * i}end"
|
86
70
|
}.reverse.join($/)
|
87
71
|
end
|
88
72
|
|
89
73
|
# @since 2.1.0
|
90
74
|
# @api private
|
91
75
|
def module_namespace_offset
|
92
|
-
"#{
|
76
|
+
"#{NESTED_OFFSET}#{INDENTATION * namespaces.count}"
|
93
77
|
end
|
94
78
|
end
|
95
79
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../constants"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
module CLI
|
7
|
+
module Generators
|
8
|
+
module App
|
9
|
+
# @since 2.2.0
|
10
|
+
# @api private
|
11
|
+
class Relation
|
12
|
+
# @since 2.2.0
|
13
|
+
# @api private
|
14
|
+
def initialize(fs:, inflector:, out: $stdout)
|
15
|
+
@fs = fs
|
16
|
+
@inflector = inflector
|
17
|
+
@out = out
|
18
|
+
end
|
19
|
+
|
20
|
+
# @since 2.2.0
|
21
|
+
# @api private
|
22
|
+
def call(app_namespace, key, slice)
|
23
|
+
schema_name = key.split(KEY_SEPARATOR).last
|
24
|
+
|
25
|
+
RubyFileWriter.new(
|
26
|
+
fs: fs,
|
27
|
+
inflector: inflector,
|
28
|
+
app_namespace: app_namespace,
|
29
|
+
key: key,
|
30
|
+
slice: slice,
|
31
|
+
extra_namespace: "Relations",
|
32
|
+
relative_parent_class: "DB::Relation",
|
33
|
+
body: ["schema :#{schema_name}, infer: true"],
|
34
|
+
).call
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_reader :fs, :inflector, :out
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module CLI
|
5
|
+
module Generators
|
6
|
+
module App
|
7
|
+
# @since 2.2.0
|
8
|
+
# @api private
|
9
|
+
class Repo
|
10
|
+
# @since 2.2.0
|
11
|
+
# @api private
|
12
|
+
def initialize(fs:, inflector:, out: $stdout)
|
13
|
+
@fs = fs
|
14
|
+
@inflector = inflector
|
15
|
+
@out = out
|
16
|
+
end
|
17
|
+
|
18
|
+
# @since 2.2.0
|
19
|
+
# @api private
|
20
|
+
def call(app_namespace, key, slice)
|
21
|
+
RubyFileWriter.new(
|
22
|
+
fs: fs,
|
23
|
+
inflector: inflector,
|
24
|
+
app_namespace: app_namespace,
|
25
|
+
key: key,
|
26
|
+
slice: slice,
|
27
|
+
extra_namespace: "Repos",
|
28
|
+
relative_parent_class: "DB::Repo",
|
29
|
+
body: [],
|
30
|
+
).call
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :fs, :inflector, :out
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "erb"
|
4
|
+
require "dry/files"
|
5
|
+
require_relative "../constants"
|
6
|
+
require_relative "../../errors"
|
7
|
+
|
8
|
+
module Hanami
|
9
|
+
module CLI
|
10
|
+
module Generators
|
11
|
+
module App
|
12
|
+
# @since 2.2.0
|
13
|
+
# @api private
|
14
|
+
class RubyFileWriter
|
15
|
+
# @since 2.2.0
|
16
|
+
# @api private
|
17
|
+
def initialize(
|
18
|
+
fs:,
|
19
|
+
inflector:,
|
20
|
+
app_namespace:,
|
21
|
+
key:,
|
22
|
+
slice:,
|
23
|
+
relative_parent_class:,
|
24
|
+
extra_namespace: nil,
|
25
|
+
body: []
|
26
|
+
)
|
27
|
+
@fs = fs
|
28
|
+
@inflector = inflector
|
29
|
+
@app_namespace = app_namespace
|
30
|
+
@key = key
|
31
|
+
@slice = slice
|
32
|
+
@extra_namespace = extra_namespace&.downcase
|
33
|
+
@relative_parent_class = relative_parent_class
|
34
|
+
@body = body
|
35
|
+
raise_missing_slice_error_if_missing(slice) if slice
|
36
|
+
end
|
37
|
+
|
38
|
+
# @since 2.2.0
|
39
|
+
# @api private
|
40
|
+
def call
|
41
|
+
fs.mkdir(directory)
|
42
|
+
fs.write(path, file_contents)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# @since 2.2.0
|
48
|
+
# @api private
|
49
|
+
attr_reader(
|
50
|
+
:fs,
|
51
|
+
:inflector,
|
52
|
+
:app_namespace,
|
53
|
+
:key,
|
54
|
+
:slice,
|
55
|
+
:extra_namespace,
|
56
|
+
:relative_parent_class,
|
57
|
+
:body,
|
58
|
+
)
|
59
|
+
|
60
|
+
# @since 2.2.0
|
61
|
+
# @api private
|
62
|
+
def file_contents
|
63
|
+
class_definition(
|
64
|
+
class_name: class_name,
|
65
|
+
container_namespace: container_namespace,
|
66
|
+
local_namespaces: local_namespaces,
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @since 2.2.0
|
71
|
+
# @api private
|
72
|
+
def class_name
|
73
|
+
key.split(KEY_SEPARATOR)[-1]
|
74
|
+
end
|
75
|
+
|
76
|
+
# @since 2.2.0
|
77
|
+
# @api private
|
78
|
+
def container_namespace
|
79
|
+
slice || app_namespace
|
80
|
+
end
|
81
|
+
|
82
|
+
# @since 2.2.0
|
83
|
+
# @api private
|
84
|
+
def local_namespaces
|
85
|
+
Array(extra_namespace) + key.split(KEY_SEPARATOR)[..-2]
|
86
|
+
end
|
87
|
+
|
88
|
+
# @since 2.2.0
|
89
|
+
# @api private
|
90
|
+
def directory
|
91
|
+
base = if slice
|
92
|
+
fs.join("slices", slice)
|
93
|
+
else
|
94
|
+
fs.join("app")
|
95
|
+
end
|
96
|
+
|
97
|
+
@directory ||= if local_namespaces.any?
|
98
|
+
fs.join(base, local_namespaces)
|
99
|
+
else
|
100
|
+
fs.join(base)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# @since 2.2.0
|
105
|
+
# @api private
|
106
|
+
def path
|
107
|
+
fs.join(directory, "#{class_name}.rb")
|
108
|
+
end
|
109
|
+
|
110
|
+
# @since 2.2.0
|
111
|
+
# @api private
|
112
|
+
def class_definition(class_name:, container_namespace:, local_namespaces:)
|
113
|
+
container_module = normalize(container_namespace)
|
114
|
+
|
115
|
+
modules = local_namespaces
|
116
|
+
.map { normalize(_1) }
|
117
|
+
.compact
|
118
|
+
.prepend(container_module)
|
119
|
+
|
120
|
+
parent_class = [container_module, relative_parent_class].join("::")
|
121
|
+
|
122
|
+
RubyFileGenerator.class(
|
123
|
+
normalize(class_name),
|
124
|
+
parent_class: parent_class,
|
125
|
+
modules: modules,
|
126
|
+
header: ["# frozen_string_literal: true"],
|
127
|
+
body: body
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
131
|
+
# @since 2.2.0
|
132
|
+
# @api private
|
133
|
+
def normalize(name)
|
134
|
+
inflector.camelize(name).gsub(/[^\p{Alnum}]/, "")
|
135
|
+
end
|
136
|
+
|
137
|
+
# @since 2.2.0
|
138
|
+
# @api private
|
139
|
+
def raise_missing_slice_error_if_missing(slice)
|
140
|
+
if slice
|
141
|
+
slice_directory = fs.join("slices", slice)
|
142
|
+
raise MissingSliceError.new(slice) unless fs.directory?(slice_directory)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -19,18 +19,20 @@ module Hanami
|
|
19
19
|
|
20
20
|
# @since 2.0.0
|
21
21
|
# @api private
|
22
|
-
def call(app, slice, url, context:
|
22
|
+
def call(app, slice, url, context: nil, **opts)
|
23
|
+
context ||= SliceContext.new(inflector, app, slice, url, **opts)
|
24
|
+
|
23
25
|
fs.inject_line_at_class_bottom(
|
24
26
|
fs.join("config", "routes.rb"), "class Routes", t("routes.erb", context).chomp
|
25
27
|
)
|
26
28
|
|
27
29
|
fs.mkdir(directory = "slices/#{slice}")
|
28
30
|
|
29
|
-
# fs.write("#{directory}/config/slice.rb", t("slice.erb", context))
|
30
31
|
fs.write(fs.join(directory, "action.rb"), t("action.erb", context))
|
31
32
|
fs.write(fs.join(directory, "view.rb"), t("view.erb", context))
|
32
33
|
fs.write(fs.join(directory, "views", "helpers.rb"), t("helpers.erb", context))
|
33
34
|
fs.write(fs.join(directory, "templates", "layouts", "app.html.erb"), t("app_layout.erb", context))
|
35
|
+
fs.write(fs.join(directory, "operation.rb"), t("operation.erb", context))
|
34
36
|
|
35
37
|
if context.bundled_assets?
|
36
38
|
fs.write(fs.join(directory, "assets", "js", "app.js"), t("app_js.erb", context))
|
@@ -38,15 +40,21 @@ module Hanami
|
|
38
40
|
fs.write(fs.join(directory, "assets", "images", "favicon.ico"), file("favicon.ico"))
|
39
41
|
end
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
+
if context.generate_db?
|
44
|
+
fs.write(fs.join(directory, "db", "relation.rb"), t("relation.erb", context))
|
45
|
+
fs.write(fs.join(directory, "relations", ".keep"), t("keep.erb", context))
|
46
|
+
|
47
|
+
fs.write(fs.join(directory, "db", "repo.rb"), t("repo.erb", context))
|
48
|
+
fs.write(fs.join(directory, "repos", ".keep"), t("keep.erb", context))
|
49
|
+
|
50
|
+
fs.write(fs.join(directory, "db", "struct.rb"), t("struct.erb", context))
|
51
|
+
fs.write(fs.join(directory, "structs", ".keep"), t("keep.erb", context))
|
52
|
+
end
|
43
53
|
|
44
54
|
fs.write(fs.join(directory, "actions/.keep"), t("keep.erb", context))
|
45
55
|
fs.write(fs.join(directory, "views/.keep"), t("keep.erb", context))
|
46
56
|
fs.write(fs.join(directory, "templates/.keep"), t("keep.erb", context))
|
47
57
|
fs.write(fs.join(directory, "templates/layouts/.keep"), t("keep.erb", context))
|
48
|
-
# fs.write(fs.join(directory, entities/.keep"), t("keep.erb", context))
|
49
|
-
# fs.write(fs.join(directory, repositories/.keep"), t("keep.erb", context))
|
50
58
|
end
|
51
59
|
|
52
60
|
private
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "../context"
|
4
|
+
require_relative "../constants"
|
4
5
|
|
5
6
|
module Hanami
|
6
7
|
module CLI
|
@@ -11,10 +12,10 @@ module Hanami
|
|
11
12
|
class SliceContext < Generators::Context
|
12
13
|
# @since 2.0.0
|
13
14
|
# @api private
|
14
|
-
def initialize(inflector, app, slice, url)
|
15
|
+
def initialize(inflector, app, slice, url, **options)
|
15
16
|
@slice = slice
|
16
17
|
@url = url
|
17
|
-
super(inflector, app)
|
18
|
+
super(inflector, app, **options)
|
18
19
|
end
|
19
20
|
|
20
21
|
# @since 2.0.0
|
@@ -47,6 +48,12 @@ module Hanami
|
|
47
48
|
%(<%= javascript_tag "app" %>)
|
48
49
|
end
|
49
50
|
|
51
|
+
# @since 2.2.0
|
52
|
+
# @api private
|
53
|
+
def generate_db?
|
54
|
+
!options.fetch(:skip_db, false)
|
55
|
+
end
|
56
|
+
|
50
57
|
private
|
51
58
|
|
52
59
|
attr_reader :slice
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module CLI
|
5
|
+
module Generators
|
6
|
+
module App
|
7
|
+
# @since 2.2.0
|
8
|
+
# @api private
|
9
|
+
class Struct
|
10
|
+
# @since 2.2.0
|
11
|
+
# @api private
|
12
|
+
def initialize(fs:, inflector:, out: $stdout)
|
13
|
+
@fs = fs
|
14
|
+
@inflector = inflector
|
15
|
+
@out = out
|
16
|
+
end
|
17
|
+
|
18
|
+
# @since 2.2.0
|
19
|
+
# @api private
|
20
|
+
def call(app_namespace, key, slice)
|
21
|
+
RubyFileWriter.new(
|
22
|
+
fs: fs,
|
23
|
+
inflector: inflector,
|
24
|
+
app_namespace: app_namespace,
|
25
|
+
key: key,
|
26
|
+
slice: slice,
|
27
|
+
extra_namespace: "Structs",
|
28
|
+
relative_parent_class: "DB::Struct",
|
29
|
+
).call
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :fs, :inflector, :out
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "slice_context"
|
4
4
|
require "dry/files/path"
|
5
|
+
require_relative "../constants"
|
5
6
|
|
6
7
|
module Hanami
|
7
8
|
module CLI
|
@@ -12,19 +13,6 @@ module Hanami
|
|
12
13
|
# @since 2.1.0
|
13
14
|
# @api private
|
14
15
|
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
16
|
# @since 2.1.0
|
29
17
|
# @api private
|
30
18
|
attr_reader :key
|
@@ -76,7 +64,7 @@ module Hanami
|
|
76
64
|
# @api private
|
77
65
|
def module_namespace_declaration
|
78
66
|
namespaces.each_with_index.map { |token, i|
|
79
|
-
"#{
|
67
|
+
"#{NESTED_OFFSET}#{INDENTATION * i}module #{inflector.camelize(token)}"
|
80
68
|
}.join($/)
|
81
69
|
end
|
82
70
|
|
@@ -84,14 +72,14 @@ module Hanami
|
|
84
72
|
# @api private
|
85
73
|
def module_namespace_end
|
86
74
|
namespaces.each_with_index.map { |_, i|
|
87
|
-
"#{
|
75
|
+
"#{NESTED_OFFSET}#{INDENTATION * i}end"
|
88
76
|
}.reverse.join($/)
|
89
77
|
end
|
90
78
|
|
91
79
|
# @since 2.1.0
|
92
80
|
# @api private
|
93
81
|
def module_namespace_offset
|
94
|
-
"#{
|
82
|
+
"#{NESTED_OFFSET}#{INDENTATION * namespaces.count}"
|
95
83
|
end
|
96
84
|
end
|
97
85
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module CLI
|
5
|
+
# @since 2.2.0
|
6
|
+
# @api private
|
7
|
+
module Generators
|
8
|
+
# @since 2.2.0
|
9
|
+
# @api private
|
10
|
+
INDENTATION = " "
|
11
|
+
private_constant :INDENTATION
|
12
|
+
|
13
|
+
# @since 2.2.0
|
14
|
+
# @api private
|
15
|
+
OFFSET = INDENTATION
|
16
|
+
private_constant :OFFSET
|
17
|
+
|
18
|
+
# @since 2.2.0
|
19
|
+
# @api private
|
20
|
+
NESTED_OFFSET = INDENTATION * 2
|
21
|
+
private_constant :OFFSET
|
22
|
+
|
23
|
+
# @since 2.2.0
|
24
|
+
# @api private
|
25
|
+
KEY_SEPARATOR = %r{[.\/]}
|
26
|
+
private_constant :KEY_SEPARATOR
|
27
|
+
|
28
|
+
# @since 2.2.0
|
29
|
+
# @api private
|
30
|
+
MATCHER_PATTERN = /::|\./
|
31
|
+
private_constant :MATCHER_PATTERN
|
32
|
+
|
33
|
+
# @since 2.2.0
|
34
|
+
# @api private
|
35
|
+
NAMESPACE_SEPARATOR = "::"
|
36
|
+
private_constant :NAMESPACE_SEPARATOR
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -80,6 +80,44 @@ module Hanami
|
|
80
80
|
!options.fetch(:skip_assets, false)
|
81
81
|
end
|
82
82
|
|
83
|
+
# @since 2.2.0
|
84
|
+
# @api private
|
85
|
+
def generate_db?
|
86
|
+
!options.fetch(:skip_db, false)
|
87
|
+
end
|
88
|
+
|
89
|
+
# @since 2.2.0
|
90
|
+
# @api private
|
91
|
+
def generate_sqlite?
|
92
|
+
database_option == Commands::Gem::New::DATABASE_SQLITE
|
93
|
+
end
|
94
|
+
|
95
|
+
# @since 2.2.0
|
96
|
+
# @api private
|
97
|
+
def generate_postgres?
|
98
|
+
database_option == Commands::Gem::New::DATABASE_POSTGRES
|
99
|
+
end
|
100
|
+
|
101
|
+
# @since 2.2.0
|
102
|
+
# @api private
|
103
|
+
def generate_mysql?
|
104
|
+
database_option == Commands::Gem::New::DATABASE_MYSQL
|
105
|
+
end
|
106
|
+
|
107
|
+
# @since 2.2.0
|
108
|
+
# @api private
|
109
|
+
def database_url
|
110
|
+
if generate_sqlite?
|
111
|
+
"sqlite://db/#{app}.sqlite"
|
112
|
+
elsif generate_postgres?
|
113
|
+
"postgres://localhost/#{app}"
|
114
|
+
elsif generate_mysql?
|
115
|
+
"mysql://localhost/#{app}"
|
116
|
+
else
|
117
|
+
raise "Unknown database option: #{database_option}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
83
121
|
# @since 2.1.0
|
84
122
|
# @api private
|
85
123
|
def bundled_views?
|
@@ -92,6 +130,12 @@ module Hanami
|
|
92
130
|
Hanami.bundled?("hanami-assets")
|
93
131
|
end
|
94
132
|
|
133
|
+
# @since 2.2.0
|
134
|
+
# @api private
|
135
|
+
def bundled_dry_monads?
|
136
|
+
Hanami.bundled?("dry-monads")
|
137
|
+
end
|
138
|
+
|
95
139
|
# @since 2.1.0
|
96
140
|
# @api private
|
97
141
|
#
|
@@ -102,6 +146,10 @@ module Hanami
|
|
102
146
|
|
103
147
|
private
|
104
148
|
|
149
|
+
def database_option
|
150
|
+
options.fetch(:database, Commands::Gem::New::DATABASE_SQLITE)
|
151
|
+
end
|
152
|
+
|
105
153
|
# @since 2.0.0
|
106
154
|
# @api private
|
107
155
|
attr_reader :inflector
|
@@ -2,8 +2,11 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "hanami/action"
|
5
|
+
require "dry/monads"
|
5
6
|
|
6
7
|
module <%= camelized_app_name %>
|
7
8
|
class Action < Hanami::Action
|
9
|
+
# Provide `Success` and `Failure` for pattern matching on operation results
|
10
|
+
include Dry::Monads[:result]
|
8
11
|
end
|
9
12
|
end
|