hanami-cli 2.2.0.beta2 → 2.2.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/CHANGELOG.md +32 -0
- data/lib/hanami/cli/commands/app/command.rb +9 -3
- data/lib/hanami/cli/commands/app/console.rb +1 -5
- data/lib/hanami/cli/commands/app/db/command.rb +80 -4
- data/lib/hanami/cli/commands/app/db/create.rb +2 -0
- data/lib/hanami/cli/commands/app/db/drop.rb +2 -0
- data/lib/hanami/cli/commands/app/db/migrate.rb +10 -1
- data/lib/hanami/cli/commands/app/db/prepare.rb +3 -1
- data/lib/hanami/cli/commands/app/db/seed.rb +5 -1
- data/lib/hanami/cli/commands/app/db/structure/dump.rb +5 -2
- data/lib/hanami/cli/commands/app/db/structure/load.rb +2 -0
- data/lib/hanami/cli/commands/app/db/utils/postgres.rb +5 -2
- data/lib/hanami/cli/commands/app/generate/action.rb +12 -2
- data/lib/hanami/cli/commands/app/generate/component.rb +4 -4
- data/lib/hanami/cli/commands/app/generate/relation.rb +20 -0
- data/lib/hanami/cli/commands/app/generate/slice.rb +16 -3
- data/lib/hanami/cli/commands/app.rb +21 -9
- data/lib/hanami/cli/generators/app/action.rb +27 -15
- data/lib/hanami/cli/generators/app/component.rb +1 -0
- data/lib/hanami/cli/generators/app/migration.rb +3 -1
- data/lib/hanami/cli/generators/app/relation.rb +5 -2
- data/lib/hanami/cli/generators/app/slice.rb +5 -3
- data/lib/hanami/cli/generators/app/slice_context.rb +6 -0
- data/lib/hanami/cli/generators/context.rb +1 -1
- data/lib/hanami/cli/generators/gem/app/gemfile.erb +2 -2
- data/lib/hanami/cli/generators/gem/app/operation.erb +0 -4
- data/lib/hanami/cli/generators/gem/app/seeds.erb +15 -0
- data/lib/hanami/cli/generators/gem/app.rb +3 -2
- data/lib/hanami/cli/repl/irb.rb +2 -2
- data/lib/hanami/cli/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af8c95d39ccda17c32851a787f8ef309b6af8936d1bb1eca4780a8f57969af66
|
4
|
+
data.tar.gz: a4aff54793a12526acf3919a16657fea36d496645fad596f2d214f3baf00e974
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a82b7839e9890b5dc3ed61b6e95ba3cc42dc1ba217d8d2f60b77fe2dd09a566331a1164f3ea8236ecb25f303bc64203388c5d1803ae38f0f5bffc18a9d9c60d
|
7
|
+
data.tar.gz: a3b6a3321bab8c5089c601849e47f159efe839413ac40292042c75f78b1ffd43d976ffc8615ed1ade575aba1e8b8a01fb299ac0cf2265e122cbb509c2dd497f3
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,38 @@
|
|
2
2
|
|
3
3
|
Hanami Command Line Interface
|
4
4
|
|
5
|
+
## v2.2.0 - 2024-11-05
|
6
|
+
|
7
|
+
### Changed
|
8
|
+
|
9
|
+
- [Kyle Plump] Add `--gateway` optiopn to `generate relation` (#261)
|
10
|
+
- [Tim Riley] Depend on stable release of dry-operation in new app `Gemfile` (#262)
|
11
|
+
- [Tim Riley] Depend on newser dry-types with a simpler version constraint in new app `Gemfile` (#263)
|
12
|
+
- [Adam Lassek] Point to Hanami's own migrations guide from generated migration files (#264)
|
13
|
+
|
14
|
+
## v2.2.0.rc1 - 2024-10-29
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
- [Tim Riley, François Beausoleil] Generate a `config/db/seeds.rb` file in new apps (#255, #256)
|
19
|
+
|
20
|
+
### Changed
|
21
|
+
|
22
|
+
- [Tim Riley] Add `--env` and `-e` options to all app commands, for setting the Hanami env (#246)
|
23
|
+
- [Tim Riley] Keep test database in sync by applying `hanami db` commands to both development and test databases when invoked in development environment (#247)
|
24
|
+
- [Kyle Plump] Add `--skip-route` flag to `generate action` and `generate slice` commands (#227)
|
25
|
+
- [Tim Riley] Include a `change do` block in generated migrations (#254)
|
26
|
+
- [Tim Riley] Generate MySQL database URL in `.env` that works with standard Homebrew MySQL installation (#249)
|
27
|
+
- [Tim Riley, Adam Lassek] Remove ROM extension boilerplate in operations generated by `hanami new` and `generate operation` (this is now applied automatically) (#240, #252)
|
28
|
+
- [François Beausoleil] Print a warning when running `db seed` but expected seeds files could not be found (#256)
|
29
|
+
- [Seb Wilgosz] Only register `generate` subcommands if the relevant gems are bundled (#242)
|
30
|
+
- [Anderson Saunders] When both IRB and pry are loaded, use IRB as the default engine for `hanami console` (#182)
|
31
|
+
|
32
|
+
### Fixed
|
33
|
+
|
34
|
+
- [Tim Riley] Fix error dumping structure when there are no migrations (#244)
|
35
|
+
- [Tim Riley] Stop erroneous misconfigured DB warnings from `hanami db` commands when a database is configured once but shared across sliaces (#253)
|
36
|
+
|
5
37
|
## v2.2.0.beta2 - 2024-09-25
|
6
38
|
|
7
39
|
### Added
|
@@ -18,8 +18,8 @@ module Hanami
|
|
18
18
|
# @api private
|
19
19
|
ACTION_SEPARATOR = "." # TODO: rename to container key separator
|
20
20
|
|
21
|
-
# Overloads {Hanami::CLI::Commands::App::Command#call} to ensure an appropriate
|
22
|
-
# environment variable is set.
|
21
|
+
# Overloads {Hanami::CLI::Commands::App::Command#call} to ensure an appropriate
|
22
|
+
# `HANAMI_ENV` environment variable is set.
|
23
23
|
#
|
24
24
|
# Uses an `--env` option if provided, then falls back to an already-set `HANAMI_ENV`
|
25
25
|
# environment variable, and defaults to "development" in the absence of both.
|
@@ -27,6 +27,12 @@ module Hanami
|
|
27
27
|
# @since 2.0.0
|
28
28
|
# @api private
|
29
29
|
module Environment
|
30
|
+
# @since 2.2.0
|
31
|
+
# @api private
|
32
|
+
def self.prepended(klass)
|
33
|
+
klass.option :env, desc: "App environment (development, test, production)", aliases: ["e"]
|
34
|
+
end
|
35
|
+
|
30
36
|
# @since 2.0.0
|
31
37
|
# @api private
|
32
38
|
def call(*args, **opts)
|
@@ -37,7 +43,7 @@ module Hanami
|
|
37
43
|
ENV["HANAMI_ENV"] = hanami_env
|
38
44
|
Hanami::Env.load
|
39
45
|
|
40
|
-
super
|
46
|
+
super
|
41
47
|
end
|
42
48
|
end
|
43
49
|
|
@@ -51,11 +51,7 @@ module Hanami
|
|
51
51
|
private
|
52
52
|
|
53
53
|
def resolve_engine(engine, opts)
|
54
|
-
|
55
|
-
ENGINES.fetch(engine).(app, opts)
|
56
|
-
else
|
57
|
-
ENGINES.map { |(_, loader)| loader.(app, opts) }.compact.first
|
58
|
-
end
|
54
|
+
ENGINES.fetch(engine, ENGINES[DEFAULT_ENGINE]).call(app, opts)
|
59
55
|
end
|
60
56
|
end
|
61
57
|
end
|
@@ -17,15 +17,23 @@ module Hanami
|
|
17
17
|
option :app, required: false, type: :flag, default: false, desc: "Use app database"
|
18
18
|
option :slice, required: false, desc: "Use database for slice"
|
19
19
|
|
20
|
+
# @api private
|
20
21
|
attr_reader :system_call
|
21
22
|
|
23
|
+
# @api private
|
24
|
+
attr_reader :test_env_executor
|
25
|
+
|
22
26
|
def initialize(
|
23
27
|
out:, err:,
|
24
28
|
system_call: SystemCall.new,
|
29
|
+
test_env_executor: InteractiveSystemCall.new(out: out, err: err),
|
30
|
+
nested_command: false,
|
25
31
|
**opts
|
26
32
|
)
|
27
33
|
super(out: out, err: err, **opts)
|
28
34
|
@system_call = system_call
|
35
|
+
@test_env_executor = test_env_executor
|
36
|
+
@nested_command = nested_command
|
29
37
|
end
|
30
38
|
|
31
39
|
def run_command(klass, ...)
|
@@ -34,9 +42,15 @@ module Hanami
|
|
34
42
|
inflector: inflector,
|
35
43
|
fs: fs,
|
36
44
|
system_call: system_call,
|
45
|
+
test_env_executor: test_env_executor,
|
46
|
+
nested_command: true,
|
37
47
|
).call(...)
|
38
48
|
end
|
39
49
|
|
50
|
+
def nested_command?
|
51
|
+
@nested_command
|
52
|
+
end
|
53
|
+
|
40
54
|
private
|
41
55
|
|
42
56
|
def databases(app: false, slice: nil, gateway: nil)
|
@@ -77,7 +91,7 @@ module Hanami
|
|
77
91
|
end
|
78
92
|
end
|
79
93
|
|
80
|
-
def all_databases # rubocop:disable Metrics/AbcSize
|
94
|
+
def all_databases # rubocop:disable Metrics/AbcSize
|
81
95
|
slices = [app] + app.slices.with_nested
|
82
96
|
|
83
97
|
slice_gateways_by_database_url = slices.each_with_object({}) { |slice, hsh|
|
@@ -92,7 +106,9 @@ module Hanami
|
|
92
106
|
|
93
107
|
slice_gateways_by_database_url.each_with_object([]) { |(url, slice_gateways), arr|
|
94
108
|
slice_gateways_with_config = slice_gateways.select {
|
95
|
-
_1[:
|
109
|
+
migrate_dir = _1[:gateway] == :default ? "migrate" : "#{_1[:gateway]}_migrate"
|
110
|
+
|
111
|
+
_1[:slice].root.join("config", "db", migrate_dir).directory?
|
96
112
|
}
|
97
113
|
|
98
114
|
db_slice_gateway = slice_gateways_with_config.first || slice_gateways.first
|
@@ -102,7 +118,7 @@ module Hanami
|
|
102
118
|
system_call: system_call
|
103
119
|
)
|
104
120
|
|
105
|
-
warn_on_misconfigured_database database,
|
121
|
+
warn_on_misconfigured_database database, slice_gateways_with_config.map { _1.fetch(:slice) }
|
106
122
|
|
107
123
|
arr << database
|
108
124
|
}
|
@@ -126,7 +142,7 @@ module Hanami
|
|
126
142
|
|
127
143
|
#{slices.map { "- " + _1.root.relative_path_from(_1.app.root).join("config", "db").to_s }.join("\n")}
|
128
144
|
|
129
|
-
|
145
|
+
Using config in #{database.slice.slice_name.to_s.inspect} slice only.
|
130
146
|
|
131
147
|
STR
|
132
148
|
elsif !database.db_config_dir?
|
@@ -140,6 +156,66 @@ module Hanami
|
|
140
156
|
STR
|
141
157
|
end
|
142
158
|
end
|
159
|
+
|
160
|
+
# Invokes the currently executing `hanami` CLI command again, but with any `--env` args
|
161
|
+
# removed and the `HANAMI_ENV=test` env var set.
|
162
|
+
#
|
163
|
+
# This is called by certain `db` commands only, and runs only if the Hanami env is
|
164
|
+
# `:development`. This behavior important to streamline the local development
|
165
|
+
# experience, making sure that the test databases are kept in sync with operations run
|
166
|
+
# on the development databases.
|
167
|
+
#
|
168
|
+
# Spawning an entirely new process to change the env is a compromise approach until we
|
169
|
+
# can have an API for reinitializing the DB subsystem in-process with a different env.
|
170
|
+
def re_run_development_command_in_test
|
171
|
+
# Only invoke a new process if we've been called as `hanami`. This avoids awkward
|
172
|
+
# failures when testing commands via RSpec, for which the $0 is "/full/path/to/rspec".
|
173
|
+
return unless $0.end_with?("hanami")
|
174
|
+
|
175
|
+
# If this special env key is set, then a re-run has already been invoked. This would
|
176
|
+
# mean the current command is actually a nested command run by another db command. In
|
177
|
+
# this case, don't trigger a re-runs, because one is already in process.
|
178
|
+
return if nested_command?
|
179
|
+
|
180
|
+
# Re-runs in test are for development-env commands only.
|
181
|
+
return unless Hanami.env == :development
|
182
|
+
|
183
|
+
cmd = $0
|
184
|
+
cmd = "bundle exec #{cmd}" if ENV.key?("BUNDLE_BIN_PATH")
|
185
|
+
|
186
|
+
test_env_executor.call(
|
187
|
+
cmd, *argv_without_env_args,
|
188
|
+
env: {
|
189
|
+
"HANAMI_ENV" => "test",
|
190
|
+
"HANAMI_CLI_DB_COMMAND_RE_RUN_IN_TEST" => "true"
|
191
|
+
}
|
192
|
+
)
|
193
|
+
end
|
194
|
+
|
195
|
+
def re_running_in_test?
|
196
|
+
ENV.key?("HANAMI_CLI_DB_COMMAND_RE_RUN_IN_TEST")
|
197
|
+
end
|
198
|
+
|
199
|
+
# Returns the `ARGV` with every option argument included, but the `-e` or `--env` args
|
200
|
+
# removed.
|
201
|
+
def argv_without_env_args
|
202
|
+
new_argv = ARGV.dup
|
203
|
+
|
204
|
+
env_arg_index = new_argv.index {
|
205
|
+
_1 == "-e" || _1 == "--env" || _1.start_with?("-e=") || _1.start_with?("--env=")
|
206
|
+
}
|
207
|
+
|
208
|
+
if env_arg_index
|
209
|
+
# Remove the env argument
|
210
|
+
env_arg = new_argv.delete_at(env_arg_index)
|
211
|
+
|
212
|
+
# If the env argument is not in combined form ("--env foo" rather than "--env=foo"),
|
213
|
+
# then remove the following argument too
|
214
|
+
new_argv.delete_at(env_arg_index) if ["-e", "--env"].include?(env_arg)
|
215
|
+
end
|
216
|
+
|
217
|
+
new_argv
|
218
|
+
end
|
143
219
|
end
|
144
220
|
end
|
145
221
|
end
|
@@ -25,7 +25,16 @@ module Hanami
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
# Only dump for the initial command, not a re-run of the command in test env
|
29
|
+
if dump && !re_running_in_test?
|
30
|
+
run_command(
|
31
|
+
Structure::Dump,
|
32
|
+
app: app, slice: slice, gateway: gateway,
|
33
|
+
command_exit: command_exit
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
re_run_development_command_in_test
|
29
38
|
end
|
30
39
|
|
31
40
|
private
|
@@ -58,7 +58,9 @@ module Hanami
|
|
58
58
|
end
|
59
59
|
|
60
60
|
# Finally, load the seeds for the slice overall, which is a once-per-slice operation.
|
61
|
-
run_command(DB::Seed, app: app, slice: slice)
|
61
|
+
run_command(DB::Seed, app: app, slice: slice) unless re_running_in_test?
|
62
|
+
|
63
|
+
re_run_development_command_in_test
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
@@ -25,7 +25,11 @@ module Hanami
|
|
25
25
|
next if seeded_slices.include?(database.slice)
|
26
26
|
|
27
27
|
seeds_path = database.slice.root.join(SEEDS_PATH)
|
28
|
-
|
28
|
+
|
29
|
+
unless seeds_path.file?
|
30
|
+
out.puts "no seeds found at #{seeds_path.relative_path_from(database.slice.app.root)}"
|
31
|
+
next
|
32
|
+
end
|
29
33
|
|
30
34
|
relative_seeds_path = seeds_path.relative_path_from(database.slice.app.root)
|
31
35
|
measure "seed data loaded from #{relative_seeds_path}" do
|
@@ -31,8 +31,11 @@ module Hanami
|
|
31
31
|
throw :dump_failed, false
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
|
34
|
+
migrations_sql = database.schema_migrations_sql_dump
|
35
|
+
if migrations_sql
|
36
|
+
File.open(database.structure_file, "a") do |f|
|
37
|
+
f.puts "#{migrations_sql}\n"
|
38
|
+
end
|
36
39
|
end
|
37
40
|
|
38
41
|
true
|
@@ -55,11 +55,14 @@ module Hanami
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def schema_migrations_sql_dump
|
58
|
-
|
58
|
+
migrations_sql = super
|
59
|
+
return unless migrations_sql
|
60
|
+
|
61
|
+
search_path = gateway.connection
|
59
62
|
.fetch("SHOW search_path").to_a.first
|
60
63
|
.fetch(:search_path)
|
61
64
|
|
62
|
-
+"SET search_path TO #{search_path};\n\n" <<
|
65
|
+
+"SET search_path TO #{search_path};\n\n" << migrations_sql
|
63
66
|
end
|
64
67
|
|
65
68
|
private
|
@@ -25,6 +25,9 @@ module Hanami
|
|
25
25
|
DEFAULT_SKIP_TESTS = false
|
26
26
|
private_constant :DEFAULT_SKIP_TESTS
|
27
27
|
|
28
|
+
DEFAULT_SKIP_ROUTE = false
|
29
|
+
private_constant :DEFAULT_SKIP_ROUTE
|
30
|
+
|
28
31
|
argument :name, required: true, desc: "Action name"
|
29
32
|
option :url, required: false, type: :string, desc: "Action URL"
|
30
33
|
option :http, required: false, type: :string, desc: "Action HTTP method"
|
@@ -41,6 +44,12 @@ module Hanami
|
|
41
44
|
type: :flag,
|
42
45
|
default: DEFAULT_SKIP_TESTS,
|
43
46
|
desc: "Skip test generation"
|
47
|
+
option \
|
48
|
+
:skip_route,
|
49
|
+
required: false,
|
50
|
+
type: :flag,
|
51
|
+
default: DEFAULT_SKIP_ROUTE,
|
52
|
+
desc: "Skip route generation"
|
44
53
|
option :slice, required: false, desc: "Slice name"
|
45
54
|
|
46
55
|
# rubocop:disable Layout/LineLength
|
@@ -83,7 +92,8 @@ module Hanami
|
|
83
92
|
http: nil,
|
84
93
|
format: DEFAULT_FORMAT,
|
85
94
|
skip_view: DEFAULT_SKIP_VIEW,
|
86
|
-
skip_tests: DEFAULT_SKIP_TESTS, # rubocop:disable Lint/UnusedMethodArgument
|
95
|
+
skip_tests: DEFAULT_SKIP_TESTS, # rubocop:disable Lint/UnusedMethodArgument,
|
96
|
+
skip_route: DEFAULT_SKIP_ROUTE,
|
87
97
|
slice: nil,
|
88
98
|
context: nil,
|
89
99
|
**
|
@@ -96,7 +106,7 @@ module Hanami
|
|
96
106
|
raise InvalidActionNameError.new(name)
|
97
107
|
end
|
98
108
|
|
99
|
-
generator.call(app.namespace, controller, action, url, http, format, skip_view, slice, context: context)
|
109
|
+
generator.call(app.namespace, controller, action, url, http, format, skip_view, skip_route, slice, context: context)
|
100
110
|
end
|
101
111
|
|
102
112
|
# rubocop:enable Metrics/ParameterLists
|
@@ -15,10 +15,10 @@ module Hanami
|
|
15
15
|
option :slice, required: false, desc: "Slice name"
|
16
16
|
|
17
17
|
example [
|
18
|
-
%(
|
19
|
-
%(
|
20
|
-
%(
|
21
|
-
%(
|
18
|
+
%(isbn_decoder (MyApp::IsbnDecoder)),
|
19
|
+
%(recommenders.fiction (MyApp::Recommenders::Fiction)),
|
20
|
+
%(isbn_decoder --slice=admin (Admin::IsbnDecoder)),
|
21
|
+
%(Exporters::Complete::CSV (MyApp::Exporters::Complete::CSV)),
|
22
22
|
]
|
23
23
|
attr_reader :generator
|
24
24
|
private :generator
|
@@ -9,11 +9,13 @@ module Hanami
|
|
9
9
|
# @api private
|
10
10
|
class Relation < Command
|
11
11
|
argument :name, required: true, desc: "Relation name"
|
12
|
+
option :gateway, desc: "Generate relation for gateway"
|
12
13
|
|
13
14
|
example [
|
14
15
|
%(books (MyApp::Relation::Book)),
|
15
16
|
%(books/drafts (MyApp::Relations::Books::Drafts)),
|
16
17
|
%(books --slice=admin (Admin::Relations::Books)),
|
18
|
+
%(books --slice=admin --gateway=extra (Admin::Relations::Books)),
|
17
19
|
]
|
18
20
|
|
19
21
|
# @since 2.2.0
|
@@ -21,6 +23,24 @@ module Hanami
|
|
21
23
|
def generator_class
|
22
24
|
Generators::App::Relation
|
23
25
|
end
|
26
|
+
|
27
|
+
def call(name:, slice: nil, gateway: nil)
|
28
|
+
if slice
|
29
|
+
generator.call(
|
30
|
+
key: name,
|
31
|
+
namespace: slice,
|
32
|
+
base_path: fs.join("slices", inflector.underscore(slice)),
|
33
|
+
gateway: gateway
|
34
|
+
)
|
35
|
+
else
|
36
|
+
generator.call(
|
37
|
+
key: name,
|
38
|
+
namespace: app.namespace,
|
39
|
+
base_path: "app",
|
40
|
+
gateway: gateway
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
24
44
|
end
|
25
45
|
end
|
26
46
|
end
|
@@ -21,13 +21,25 @@ module Hanami
|
|
21
21
|
SKIP_DB_DEFAULT = false
|
22
22
|
private_constant :SKIP_DB_DEFAULT
|
23
23
|
|
24
|
+
# @since 2.2.0
|
25
|
+
# @api private
|
26
|
+
DEFAULT_SKIP_ROUTE = false
|
27
|
+
private_constant :DEFAULT_SKIP_ROUTE
|
28
|
+
|
24
29
|
# @since 2.2.0
|
25
30
|
# @api private
|
26
31
|
option :skip_db,
|
27
|
-
type: :
|
32
|
+
type: :flag,
|
28
33
|
required: false,
|
29
34
|
default: SKIP_DB_DEFAULT,
|
30
35
|
desc: "Skip database"
|
36
|
+
# @since 2.2.0
|
37
|
+
# @api private
|
38
|
+
option :skip_route,
|
39
|
+
type: :flag,
|
40
|
+
required: false,
|
41
|
+
default: DEFAULT_SKIP_ROUTE,
|
42
|
+
desc: "Skip route generation"
|
31
43
|
|
32
44
|
example [
|
33
45
|
"admin # Admin slice (/admin URL prefix)",
|
@@ -50,7 +62,8 @@ module Hanami
|
|
50
62
|
def call(
|
51
63
|
name:,
|
52
64
|
url: nil,
|
53
|
-
skip_db: SKIP_DB_DEFAULT
|
65
|
+
skip_db: SKIP_DB_DEFAULT,
|
66
|
+
skip_route: DEFAULT_SKIP_ROUTE
|
54
67
|
)
|
55
68
|
require "hanami/setup"
|
56
69
|
|
@@ -58,7 +71,7 @@ module Hanami
|
|
58
71
|
name = inflector.underscore(Shellwords.shellescape(name))
|
59
72
|
url = sanitize_url_prefix(name, url)
|
60
73
|
|
61
|
-
generator.call(app, name, url, skip_db: skip_db)
|
74
|
+
generator.call(app, name, url, skip_db: skip_db, skip_route: skip_route)
|
62
75
|
end
|
63
76
|
|
64
77
|
private
|
@@ -41,16 +41,28 @@ module Hanami
|
|
41
41
|
end
|
42
42
|
|
43
43
|
register "generate", aliases: ["g"] do |prefix|
|
44
|
-
prefix.register "action", Generate::Action
|
45
|
-
prefix.register "component", Generate::Component
|
46
|
-
prefix.register "migration", Generate::Migration
|
47
|
-
prefix.register "operation", Generate::Operation
|
48
|
-
prefix.register "part", Generate::Part
|
49
|
-
prefix.register "relation", Generate::Relation
|
50
|
-
prefix.register "repo", Generate::Repo
|
51
44
|
prefix.register "slice", Generate::Slice
|
52
|
-
prefix.register "
|
53
|
-
|
45
|
+
prefix.register "component", Generate::Component
|
46
|
+
|
47
|
+
if Hanami.bundled?("hanami-controller")
|
48
|
+
prefix.register "action", Generate::Action
|
49
|
+
end
|
50
|
+
|
51
|
+
if Hanami.bundled?("dry-operation")
|
52
|
+
prefix.register "operation", Generate::Operation
|
53
|
+
end
|
54
|
+
|
55
|
+
if Hanami.bundled?("hanami-view")
|
56
|
+
prefix.register "view", Generate::View
|
57
|
+
prefix.register "part", Generate::Part
|
58
|
+
end
|
59
|
+
|
60
|
+
if Hanami.bundled?("hanami-db")
|
61
|
+
prefix.register "migration", Generate::Migration
|
62
|
+
prefix.register "relation", Generate::Relation
|
63
|
+
prefix.register "repo", Generate::Repo
|
64
|
+
prefix.register "struct", Generate::Struct
|
65
|
+
end
|
54
66
|
end
|
55
67
|
end
|
56
68
|
end
|
@@ -21,12 +21,12 @@ module Hanami
|
|
21
21
|
|
22
22
|
# @since 2.0.0
|
23
23
|
# @api private
|
24
|
-
def call(app, controller, action, url, http, format, skip_view, slice, context: nil)
|
24
|
+
def call(app, controller, action, url, http, format, skip_view, skip_route, slice, context: nil)
|
25
25
|
context ||= ActionContext.new(inflector, app, slice, controller, action)
|
26
26
|
if slice
|
27
|
-
generate_for_slice(controller, action, url, http, format, skip_view, slice, context)
|
27
|
+
generate_for_slice(controller, action, url, http, format, skip_view, skip_route, slice, context)
|
28
28
|
else
|
29
|
-
generate_for_app(controller, action, url, http, format, skip_view, context)
|
29
|
+
generate_for_app(controller, action, url, http, format, skip_view, skip_route, context)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -72,15 +72,17 @@ module Hanami
|
|
72
72
|
attr_reader :inflector
|
73
73
|
|
74
74
|
# rubocop:disable Metrics/AbcSize
|
75
|
-
def generate_for_slice(controller, action, url, http, format, skip_view, slice, context)
|
75
|
+
def generate_for_slice(controller, action, url, http, format, skip_view, skip_route, slice, context)
|
76
76
|
slice_directory = fs.join("slices", slice)
|
77
77
|
raise MissingSliceError.new(slice) unless fs.directory?(slice_directory)
|
78
78
|
|
79
|
-
|
80
|
-
fs.
|
81
|
-
|
82
|
-
|
83
|
-
|
79
|
+
if generate_route?(skip_route)
|
80
|
+
fs.inject_line_at_block_bottom(
|
81
|
+
fs.join("config", "routes.rb"),
|
82
|
+
slice_matcher(slice),
|
83
|
+
route(controller, action, url, http)
|
84
|
+
)
|
85
|
+
end
|
84
86
|
|
85
87
|
fs.mkdir(directory = fs.join(slice_directory, "actions", controller))
|
86
88
|
fs.write(fs.join(directory, "#{action}.rb"), t("slice_action.erb", context))
|
@@ -95,12 +97,14 @@ module Hanami
|
|
95
97
|
end
|
96
98
|
end
|
97
99
|
|
98
|
-
def generate_for_app(controller, action, url, http, format, skip_view, context)
|
99
|
-
|
100
|
-
fs.
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
def generate_for_app(controller, action, url, http, format, skip_view, skip_route, context)
|
101
|
+
if generate_route?(skip_route)
|
102
|
+
fs.inject_line_at_class_bottom(
|
103
|
+
fs.join("config", "routes.rb"),
|
104
|
+
"class Routes",
|
105
|
+
route(controller, action, url, http)
|
106
|
+
)
|
107
|
+
end
|
104
108
|
|
105
109
|
fs.mkdir(directory = fs.join("app", "actions", controller))
|
106
110
|
fs.write(fs.join(directory, "#{action}.rb"), t("action.erb", context))
|
@@ -137,6 +141,14 @@ module Hanami
|
|
137
141
|
true
|
138
142
|
end
|
139
143
|
|
144
|
+
# @api private
|
145
|
+
# @since 2.2.0
|
146
|
+
def generate_route?(skip_route)
|
147
|
+
return false if skip_route
|
148
|
+
|
149
|
+
true
|
150
|
+
end
|
151
|
+
|
140
152
|
# @api private
|
141
153
|
# @since 2.1.0
|
142
154
|
def generate_restful_view?(view, directory)
|
@@ -55,7 +55,9 @@ module Hanami
|
|
55
55
|
ROM::SQL.migration do
|
56
56
|
# Add your migration here.
|
57
57
|
#
|
58
|
-
# See https://
|
58
|
+
# See https://guides.hanamirb.org/v2.2/database/migrations/ for details.
|
59
|
+
change do
|
60
|
+
end
|
59
61
|
end
|
60
62
|
RUBY
|
61
63
|
private_constant :FILE_CONTENTS
|
@@ -19,8 +19,11 @@ module Hanami
|
|
19
19
|
|
20
20
|
# @since 2.2.0
|
21
21
|
# @api private
|
22
|
-
def call(key:, namespace:, base_path:)
|
22
|
+
def call(key:, namespace:, base_path:, gateway:)
|
23
23
|
schema_name = key.split(KEY_SEPARATOR).last
|
24
|
+
body_content = ["schema :#{schema_name}, infer: true"]
|
25
|
+
|
26
|
+
body_content.prepend("gateway :#{gateway}") if gateway
|
24
27
|
|
25
28
|
RubyFileWriter.new(
|
26
29
|
fs: fs,
|
@@ -31,7 +34,7 @@ module Hanami
|
|
31
34
|
base_path: base_path,
|
32
35
|
extra_namespace: "Relations",
|
33
36
|
relative_parent_class: "DB::Relation",
|
34
|
-
body:
|
37
|
+
body: body_content,
|
35
38
|
)
|
36
39
|
end
|
37
40
|
|
@@ -22,9 +22,11 @@ module Hanami
|
|
22
22
|
def call(app, slice, url, context: nil, **opts)
|
23
23
|
context ||= SliceContext.new(inflector, app, slice, url, **opts)
|
24
24
|
|
25
|
-
|
26
|
-
fs.
|
27
|
-
|
25
|
+
if context.generate_route?
|
26
|
+
fs.inject_line_at_class_bottom(
|
27
|
+
fs.join("config", "routes.rb"), "class Routes", t("routes.erb", context).chomp
|
28
|
+
)
|
29
|
+
end
|
28
30
|
|
29
31
|
fs.mkdir(directory = "slices/#{slice}")
|
30
32
|
|
@@ -14,8 +14,8 @@ source "https://rubygems.org"
|
|
14
14
|
<%= hanami_gem("validations") %>
|
15
15
|
<%= hanami_gem("view") %>
|
16
16
|
|
17
|
-
gem "dry-types", "~> 1.
|
18
|
-
gem "dry-operation"
|
17
|
+
gem "dry-types", "~> 1.7"
|
18
|
+
gem "dry-operation"
|
19
19
|
gem "puma"
|
20
20
|
gem "rake"
|
21
21
|
<%- if generate_sqlite? -%>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# This seeds file should create the database records required to run the app.
|
2
|
+
#
|
3
|
+
# The code should be idempotent so that it can be executed at any time.
|
4
|
+
#
|
5
|
+
# To load the seeds, run `hanami db seed`. Seeds are also loaded as part of `hanami db prepare`.
|
6
|
+
|
7
|
+
# For example, if you have appropriate repos available:
|
8
|
+
#
|
9
|
+
# category_repo = Hanami.app["repos.category_repo"]
|
10
|
+
# category_repo.create(title: "General")
|
11
|
+
#
|
12
|
+
# Alternatively, you can use relations directly:
|
13
|
+
#
|
14
|
+
# categories = Hanami.app["relations.categories"]
|
15
|
+
# categories.insert(title: "General")
|
@@ -78,10 +78,11 @@ module Hanami
|
|
78
78
|
fs.write("app/db/struct.rb", t("struct.erb", context))
|
79
79
|
fs.write("app/structs/.keep", t("keep.erb", context))
|
80
80
|
|
81
|
-
fs.write("config/db/
|
81
|
+
fs.write("config/db/seeds.rb", t("seeds.erb", context))
|
82
|
+
fs.write("config/db/migrate/.keep", t("keep.erb", context))
|
82
83
|
|
83
84
|
if context.generate_sqlite?
|
84
|
-
fs.write("db/.keep"
|
85
|
+
fs.write("db/.keep", t("keep.erb", context))
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
data/lib/hanami/cli/repl/irb.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.2.0
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -308,6 +308,7 @@ files:
|
|
308
308
|
- lib/hanami/cli/generators/gem/app/relation.erb
|
309
309
|
- lib/hanami/cli/generators/gem/app/repo.erb
|
310
310
|
- lib/hanami/cli/generators/gem/app/routes.erb
|
311
|
+
- lib/hanami/cli/generators/gem/app/seeds.erb
|
311
312
|
- lib/hanami/cli/generators/gem/app/settings.erb
|
312
313
|
- lib/hanami/cli/generators/gem/app/struct.erb
|
313
314
|
- lib/hanami/cli/generators/gem/app/types.erb
|
@@ -353,7 +354,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
353
354
|
- !ruby/object:Gem::Version
|
354
355
|
version: '0'
|
355
356
|
requirements: []
|
356
|
-
rubygems_version: 3.5.
|
357
|
+
rubygems_version: 3.5.22
|
357
358
|
signing_key:
|
358
359
|
specification_version: 4
|
359
360
|
summary: Hanami CLI
|