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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +18 -13
  3. data/CHANGELOG.md +15 -0
  4. data/Gemfile +4 -2
  5. data/README.md +11 -7
  6. data/docker-compose.yml +9 -0
  7. data/hanami-cli.gemspec +2 -2
  8. data/lib/hanami/cli/command.rb +1 -1
  9. data/lib/hanami/cli/commands/app/command.rb +2 -16
  10. data/lib/hanami/cli/commands/app/db/command.rb +116 -0
  11. data/lib/hanami/cli/commands/app/db/create.rb +19 -11
  12. data/lib/hanami/cli/commands/app/db/drop.rb +19 -10
  13. data/lib/hanami/cli/commands/app/db/migrate.rb +19 -13
  14. data/lib/hanami/cli/commands/app/db/prepare.rb +42 -0
  15. data/lib/hanami/cli/commands/app/db/seed.rb +11 -22
  16. data/lib/hanami/cli/commands/app/db/structure/dump.rb +30 -7
  17. data/lib/hanami/cli/commands/app/db/structure/load.rb +52 -0
  18. data/lib/hanami/cli/commands/app/db/utils/database.rb +68 -73
  19. data/lib/hanami/cli/commands/app/db/utils/mysql.rb +2 -2
  20. data/lib/hanami/cli/commands/app/db/utils/postgres.rb +38 -19
  21. data/lib/hanami/cli/commands/app/db/utils/sqlite.rb +58 -10
  22. data/lib/hanami/cli/commands/app/db/version.rb +12 -9
  23. data/lib/hanami/cli/commands/app/generate/action.rb +4 -3
  24. data/lib/hanami/cli/commands/app/generate/command.rb +49 -0
  25. data/lib/hanami/cli/commands/app/generate/component.rb +49 -0
  26. data/lib/hanami/cli/commands/app/generate/migration.rb +27 -0
  27. data/lib/hanami/cli/commands/app/generate/operation.rb +26 -0
  28. data/lib/hanami/cli/commands/app/generate/part.rb +1 -1
  29. data/lib/hanami/cli/commands/app/generate/relation.rb +35 -0
  30. data/lib/hanami/cli/commands/app/generate/repo.rb +46 -0
  31. data/lib/hanami/cli/commands/app/generate/slice.rb +20 -3
  32. data/lib/hanami/cli/commands/app/generate/struct.rb +27 -0
  33. data/lib/hanami/cli/commands/app/install.rb +1 -1
  34. data/lib/hanami/cli/commands/app/middleware.rb +1 -1
  35. data/lib/hanami/cli/commands/app/server.rb +2 -2
  36. data/lib/hanami/cli/commands/app.rb +21 -2
  37. data/lib/hanami/cli/commands/gem/new.rb +78 -14
  38. data/lib/hanami/cli/errors.rb +28 -0
  39. data/lib/hanami/cli/generators/app/action_context.rb +5 -13
  40. data/lib/hanami/cli/generators/app/component/component.erb +8 -0
  41. data/lib/hanami/cli/generators/app/component/slice_component.erb +8 -0
  42. data/lib/hanami/cli/generators/app/component.rb +61 -0
  43. data/lib/hanami/cli/generators/app/component_context.rb +82 -0
  44. data/lib/hanami/cli/generators/app/migration.rb +69 -0
  45. data/lib/hanami/cli/generators/app/operation.rb +48 -0
  46. data/lib/hanami/cli/generators/app/part_context.rb +5 -21
  47. data/lib/hanami/cli/generators/app/relation.rb +44 -0
  48. data/lib/hanami/cli/generators/app/repo.rb +40 -0
  49. data/lib/hanami/cli/generators/app/ruby_file_writer.rb +149 -0
  50. data/lib/hanami/cli/generators/app/slice/operation.erb +7 -0
  51. data/lib/hanami/cli/generators/app/slice/relation.erb +8 -0
  52. data/lib/hanami/cli/generators/app/slice/{slice.erb → repo.erb} +3 -1
  53. data/lib/hanami/cli/generators/app/slice/struct.erb +8 -0
  54. data/lib/hanami/cli/generators/app/slice.rb +14 -6
  55. data/lib/hanami/cli/generators/app/slice_context.rb +9 -2
  56. data/lib/hanami/cli/generators/app/struct.rb +39 -0
  57. data/lib/hanami/cli/generators/app/view_context.rb +4 -16
  58. data/lib/hanami/cli/generators/constants.rb +39 -0
  59. data/lib/hanami/cli/generators/context.rb +48 -0
  60. data/lib/hanami/cli/generators/gem/app/action.erb +3 -0
  61. data/lib/hanami/cli/generators/gem/app/env.erb +4 -0
  62. data/lib/hanami/cli/generators/gem/app/gemfile.erb +11 -0
  63. data/lib/hanami/cli/generators/gem/app/gitignore.erb +1 -1
  64. data/lib/hanami/cli/generators/gem/app/operation.erb +13 -0
  65. data/lib/hanami/cli/generators/gem/app/relation.erb +10 -0
  66. data/lib/hanami/cli/generators/gem/app/repo.erb +10 -0
  67. data/lib/hanami/cli/generators/gem/app/struct.erb +10 -0
  68. data/lib/hanami/cli/generators/gem/app.rb +19 -0
  69. data/lib/hanami/cli/ruby_file_generator.rb +123 -0
  70. data/lib/hanami/cli/version.rb +1 -1
  71. metadata +39 -16
  72. data/lib/hanami/cli/commands/app/db/create_migration.rb +0 -32
  73. data/lib/hanami/cli/commands/app/db/reset.rb +0 -28
  74. data/lib/hanami/cli/commands/app/db/rollback.rb +0 -81
  75. data/lib/hanami/cli/commands/app/db/sample_data.rb +0 -42
  76. data/lib/hanami/cli/commands/app/db/setup.rb +0 -26
  77. data/lib/hanami/cli/commands/app/db/utils/database_config.rb +0 -60
  78. data/lib/hanami/cli/generators/app/slice/repository.erb +0 -10
@@ -7,13 +7,24 @@ source "https://rubygems.org"
7
7
  <%= hanami_gem("assets") %>
8
8
  <%- end -%>
9
9
  <%= hanami_gem("controller") %>
10
+ <%- if generate_db? -%>
11
+ <%= hanami_gem("db") %>
12
+ <%- end -%>
10
13
  <%= hanami_gem("router") %>
11
14
  <%= hanami_gem("validations") %>
12
15
  <%= hanami_gem("view") %>
13
16
 
14
17
  gem "dry-types", "~> 1.0", ">= 1.6.1"
18
+ gem "dry-operation", github: "dry-rb/dry-operation"
15
19
  gem "puma"
16
20
  gem "rake"
21
+ <%- if generate_sqlite? -%>
22
+ gem "sqlite3"
23
+ <%- elsif generate_postgres? -%>
24
+ gem "pg"
25
+ <%- elsif generate_mysql? -%>
26
+ gem "mysql2"
27
+ <%- end -%>
17
28
 
18
29
  group :development do
19
30
  <%= hanami_gem("webconsole") %>
@@ -1,4 +1,4 @@
1
- .env
1
+ .env*.local
2
2
  log/*
3
3
  <%- if generate_assets? -%>
4
4
  public/
@@ -0,0 +1,13 @@
1
+ # auto_register: false
2
+ # frozen_string_literal: true
3
+
4
+ require "dry/operation"
5
+
6
+ module <%= camelized_app_name %>
7
+ class Operation < Dry::Operation
8
+ <%- if generate_db? -%>
9
+ # Provide `transaction do ... end` method for database transactions
10
+ include Dry::Operation::Extensions::ROM
11
+ <%- end -%>
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/db/relation"
4
+
5
+ module <%= camelized_app_name %>
6
+ module DB
7
+ class Relation < Hanami::DB::Relation
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/db/repo"
4
+
5
+ module <%= camelized_app_name %>
6
+ module DB
7
+ class Repo < Hanami::DB::Repo
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/db/struct"
4
+
5
+ module <%= camelized_app_name %>
6
+ module DB
7
+ class Struct < Hanami::DB::Struct
8
+ end
9
+ end
10
+ end
@@ -68,6 +68,25 @@ module Hanami
68
68
  fs.write("app/assets/images/favicon.ico", file("favicon.ico"))
69
69
  end
70
70
 
71
+ if context.generate_db?
72
+ fs.write("app/db/relation.rb", t("relation.erb", context))
73
+ fs.write("app/relations/.keep", t("keep.erb", context))
74
+
75
+ fs.write("app/db/repo.rb", t("repo.erb", context))
76
+ fs.write("app/repos/.keep", t("keep.erb", context))
77
+
78
+ fs.write("app/db/struct.rb", t("struct.erb", context))
79
+ fs.write("app/structs/.keep", t("keep.erb", context))
80
+
81
+ fs.write("config/db/migrate/.keep" , t("keep.erb", context))
82
+
83
+ if context.generate_sqlite?
84
+ fs.write("db/.keep" , t("keep.erb", context))
85
+ end
86
+ end
87
+
88
+ fs.write("app/operation.rb", t("operation.erb", context))
89
+
71
90
  fs.write("public/404.html", file("404.html"))
72
91
  fs.write("public/500.html", file("500.html"))
73
92
  end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ripper"
4
+
5
+ module Hanami
6
+ module CLI
7
+ class RubyFileGenerator
8
+ # @api private
9
+ # @since 2.2.0
10
+ class GeneratedUnparseableCodeError < Error
11
+ def initialize(source_code)
12
+ super(
13
+ <<~ERROR_MESSAGE
14
+ Sorry, the code we generated is not valid Ruby.
15
+
16
+ Here's what we got:
17
+
18
+ #{source_code}
19
+
20
+ Please fix the errors and try again.
21
+ ERROR_MESSAGE
22
+ )
23
+ end
24
+ end
25
+
26
+ INDENT = " "
27
+
28
+ def self.class(class_name, **args)
29
+ new(class_name: class_name, **args).to_s
30
+ end
31
+
32
+ def self.module(*names, **args)
33
+ module_names = if names.first.is_a?(Array)
34
+ names.first
35
+ else
36
+ names
37
+ end
38
+
39
+ new(modules: module_names, class_name: nil, parent_class: nil, **args).to_s
40
+ end
41
+
42
+ def initialize(
43
+ class_name: nil,
44
+ parent_class: nil,
45
+ modules: [],
46
+ header: [],
47
+ body: []
48
+ )
49
+ @class_name = class_name
50
+ @parent_class = parent_class
51
+ @modules = modules
52
+ @header = header.any? ? (header + [""]) : []
53
+ @body = body
54
+ end
55
+
56
+ def to_s
57
+ definition = lines(modules).map { |line| "#{line}\n" }.join
58
+ source_code = [header, definition].flatten.join("\n")
59
+ ensure_parseable!(source_code)
60
+ source_code
61
+ end
62
+
63
+ private
64
+
65
+ attr_reader(
66
+ :class_name,
67
+ :parent_class,
68
+ :modules,
69
+ :header,
70
+ :body
71
+ )
72
+
73
+ def lines(remaining_modules)
74
+ this_module, *rest_modules = remaining_modules
75
+ if this_module
76
+ with_module_lines(this_module, lines(rest_modules))
77
+ elsif class_name
78
+ class_lines
79
+ else
80
+ body
81
+ end
82
+ end
83
+
84
+ def with_module_lines(module_name, contents_lines)
85
+ [
86
+ "module #{module_name}",
87
+ *contents_lines.map { |line| indent(line) },
88
+ "end"
89
+ ]
90
+ end
91
+
92
+ def class_lines
93
+ [
94
+ class_definition,
95
+ *body.map { |line| indent(line) },
96
+ "end"
97
+ ].compact
98
+ end
99
+
100
+ def class_definition
101
+ if parent_class
102
+ "class #{class_name} < #{parent_class}"
103
+ else
104
+ "class #{class_name}"
105
+ end
106
+ end
107
+
108
+ def indent(line)
109
+ if line.strip.empty?
110
+ ""
111
+ else
112
+ INDENT + line
113
+ end
114
+ end
115
+
116
+ def ensure_parseable!(source_code)
117
+ unless Ripper.sexp(source_code)
118
+ raise GeneratedUnparseableCodeError.new(source_code)
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -6,6 +6,6 @@ module Hanami
6
6
  #
7
7
  # @api public
8
8
  # @since 2.0.0
9
- VERSION = "2.1.1"
9
+ VERSION = "2.2.0.beta1"
10
10
  end
11
11
  end
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.1.1
4
+ version: 2.2.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: 2024-03-19 00:00:00.000000000 Z
11
+ date: 2024-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -31,9 +31,9 @@ dependencies:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.0'
34
- - - "<"
34
+ - - ">="
35
35
  - !ruby/object:Gem::Version
36
- version: '2'
36
+ version: 1.1.0
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
@@ -41,9 +41,9 @@ dependencies:
41
41
  - - "~>"
42
42
  - !ruby/object:Gem::Version
43
43
  version: '1.0'
44
- - - "<"
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: '2'
46
+ version: 1.1.0
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: dry-files
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -183,6 +183,7 @@ files:
183
183
  - Rakefile
184
184
  - bin/console
185
185
  - bin/setup
186
+ - docker-compose.yml
186
187
  - exe/hanami
187
188
  - hanami-cli.gemspec
188
189
  - lib/hanami-cli.rb
@@ -197,18 +198,15 @@ files:
197
198
  - lib/hanami/cli/commands/app/assets/watch.rb
198
199
  - lib/hanami/cli/commands/app/command.rb
199
200
  - lib/hanami/cli/commands/app/console.rb
201
+ - lib/hanami/cli/commands/app/db/command.rb
200
202
  - lib/hanami/cli/commands/app/db/create.rb
201
- - lib/hanami/cli/commands/app/db/create_migration.rb
202
203
  - lib/hanami/cli/commands/app/db/drop.rb
203
204
  - lib/hanami/cli/commands/app/db/migrate.rb
204
- - lib/hanami/cli/commands/app/db/reset.rb
205
- - lib/hanami/cli/commands/app/db/rollback.rb
206
- - lib/hanami/cli/commands/app/db/sample_data.rb
205
+ - lib/hanami/cli/commands/app/db/prepare.rb
207
206
  - lib/hanami/cli/commands/app/db/seed.rb
208
- - lib/hanami/cli/commands/app/db/setup.rb
209
207
  - lib/hanami/cli/commands/app/db/structure/dump.rb
208
+ - lib/hanami/cli/commands/app/db/structure/load.rb
210
209
  - lib/hanami/cli/commands/app/db/utils/database.rb
211
- - lib/hanami/cli/commands/app/db/utils/database_config.rb
212
210
  - lib/hanami/cli/commands/app/db/utils/mysql.rb
213
211
  - lib/hanami/cli/commands/app/db/utils/postgres.rb
214
212
  - lib/hanami/cli/commands/app/db/utils/sqlite.rb
@@ -216,8 +214,15 @@ files:
216
214
  - lib/hanami/cli/commands/app/dev.rb
217
215
  - lib/hanami/cli/commands/app/generate.rb
218
216
  - lib/hanami/cli/commands/app/generate/action.rb
217
+ - lib/hanami/cli/commands/app/generate/command.rb
218
+ - lib/hanami/cli/commands/app/generate/component.rb
219
+ - lib/hanami/cli/commands/app/generate/migration.rb
220
+ - lib/hanami/cli/commands/app/generate/operation.rb
219
221
  - lib/hanami/cli/commands/app/generate/part.rb
222
+ - lib/hanami/cli/commands/app/generate/relation.rb
223
+ - lib/hanami/cli/commands/app/generate/repo.rb
220
224
  - lib/hanami/cli/commands/app/generate/slice.rb
225
+ - lib/hanami/cli/commands/app/generate/struct.rb
221
226
  - lib/hanami/cli/commands/app/generate/view.rb
222
227
  - lib/hanami/cli/commands/app/install.rb
223
228
  - lib/hanami/cli/commands/app/middleware.rb
@@ -238,12 +243,21 @@ files:
238
243
  - lib/hanami/cli/generators/app/action/template.html.erb
239
244
  - lib/hanami/cli/generators/app/action/view.erb
240
245
  - lib/hanami/cli/generators/app/action_context.rb
246
+ - lib/hanami/cli/generators/app/component.rb
247
+ - lib/hanami/cli/generators/app/component/component.erb
248
+ - lib/hanami/cli/generators/app/component/slice_component.erb
249
+ - lib/hanami/cli/generators/app/component_context.rb
250
+ - lib/hanami/cli/generators/app/migration.rb
251
+ - lib/hanami/cli/generators/app/operation.rb
241
252
  - lib/hanami/cli/generators/app/part.rb
242
253
  - lib/hanami/cli/generators/app/part/app_base_part.erb
243
254
  - lib/hanami/cli/generators/app/part/app_part.erb
244
255
  - lib/hanami/cli/generators/app/part/slice_base_part.erb
245
256
  - lib/hanami/cli/generators/app/part/slice_part.erb
246
257
  - lib/hanami/cli/generators/app/part_context.rb
258
+ - lib/hanami/cli/generators/app/relation.rb
259
+ - lib/hanami/cli/generators/app/repo.rb
260
+ - lib/hanami/cli/generators/app/ruby_file_writer.rb
247
261
  - lib/hanami/cli/generators/app/slice.rb
248
262
  - lib/hanami/cli/generators/app/slice/action.erb
249
263
  - lib/hanami/cli/generators/app/slice/app_css.erb
@@ -253,17 +267,21 @@ files:
253
267
  - lib/hanami/cli/generators/app/slice/favicon.ico
254
268
  - lib/hanami/cli/generators/app/slice/helpers.erb
255
269
  - lib/hanami/cli/generators/app/slice/keep.erb
256
- - lib/hanami/cli/generators/app/slice/repository.erb
270
+ - lib/hanami/cli/generators/app/slice/operation.erb
271
+ - lib/hanami/cli/generators/app/slice/relation.erb
272
+ - lib/hanami/cli/generators/app/slice/repo.erb
257
273
  - lib/hanami/cli/generators/app/slice/routes.erb
258
- - lib/hanami/cli/generators/app/slice/slice.erb
274
+ - lib/hanami/cli/generators/app/slice/struct.erb
259
275
  - lib/hanami/cli/generators/app/slice/view.erb
260
276
  - lib/hanami/cli/generators/app/slice_context.rb
277
+ - lib/hanami/cli/generators/app/struct.rb
261
278
  - lib/hanami/cli/generators/app/view.rb
262
279
  - lib/hanami/cli/generators/app/view/app_template.html.erb
263
280
  - lib/hanami/cli/generators/app/view/app_view.erb
264
281
  - lib/hanami/cli/generators/app/view/slice_template.html.erb
265
282
  - lib/hanami/cli/generators/app/view/slice_view.erb
266
283
  - lib/hanami/cli/generators/app/view_context.rb
284
+ - lib/hanami/cli/generators/constants.rb
267
285
  - lib/hanami/cli/generators/context.rb
268
286
  - lib/hanami/cli/generators/gem/app.rb
269
287
  - lib/hanami/cli/generators/gem/app/404.html
@@ -282,13 +300,17 @@ files:
282
300
  - lib/hanami/cli/generators/gem/app/gitignore.erb
283
301
  - lib/hanami/cli/generators/gem/app/helpers.erb
284
302
  - lib/hanami/cli/generators/gem/app/keep.erb
303
+ - lib/hanami/cli/generators/gem/app/operation.erb
285
304
  - lib/hanami/cli/generators/gem/app/package.json.erb
286
305
  - lib/hanami/cli/generators/gem/app/procfile.erb
287
306
  - lib/hanami/cli/generators/gem/app/puma.erb
288
307
  - lib/hanami/cli/generators/gem/app/rakefile.erb
289
308
  - lib/hanami/cli/generators/gem/app/readme.erb
309
+ - lib/hanami/cli/generators/gem/app/relation.erb
310
+ - lib/hanami/cli/generators/gem/app/repo.erb
290
311
  - lib/hanami/cli/generators/gem/app/routes.erb
291
312
  - lib/hanami/cli/generators/gem/app/settings.erb
313
+ - lib/hanami/cli/generators/gem/app/struct.erb
292
314
  - lib/hanami/cli/generators/gem/app/types.erb
293
315
  - lib/hanami/cli/generators/gem/app/validator.erb
294
316
  - lib/hanami/cli/generators/gem/app/view.erb
@@ -300,6 +322,7 @@ files:
300
322
  - lib/hanami/cli/repl/core.rb
301
323
  - lib/hanami/cli/repl/irb.rb
302
324
  - lib/hanami/cli/repl/pry.rb
325
+ - lib/hanami/cli/ruby_file_generator.rb
303
326
  - lib/hanami/cli/server.rb
304
327
  - lib/hanami/cli/system_call.rb
305
328
  - lib/hanami/cli/url.rb
@@ -324,14 +347,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
324
347
  requirements:
325
348
  - - ">="
326
349
  - !ruby/object:Gem::Version
327
- version: '3.0'
350
+ version: '3.1'
328
351
  required_rubygems_version: !ruby/object:Gem::Requirement
329
352
  requirements:
330
353
  - - ">="
331
354
  - !ruby/object:Gem::Version
332
355
  version: '0'
333
356
  requirements: []
334
- rubygems_version: 3.5.3
357
+ rubygems_version: 3.5.9
335
358
  signing_key:
336
359
  specification_version: 4
337
360
  summary: Hanami CLI
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../../app/command"
4
- require_relative "structure/dump"
5
-
6
- module Hanami
7
- module CLI
8
- module Commands
9
- module App
10
- # @api private
11
- module DB
12
- # @api private
13
- class CreateMigration < App::Command
14
- desc "Create new migration file"
15
-
16
- argument :name, desc: "Migration file name"
17
-
18
- # @api private
19
- def call(name:, **)
20
- migrator = database.migrator
21
- version = migrator.generate_version
22
-
23
- measure "migration #{version}_#{name} created" do
24
- migrator.create_file(name, version)
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../../app/command"
4
- require_relative "create"
5
- require_relative "drop"
6
- require_relative "migrate"
7
-
8
- module Hanami
9
- module CLI
10
- module Commands
11
- module App
12
- module DB
13
- # @api private
14
- class Reset < App::Command
15
- desc "Drop, create, and migrate database"
16
-
17
- # @api private
18
- def call(**)
19
- run_command Drop
20
- run_command Create
21
- run_command Migrate
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../../app/command"
4
- require_relative "structure/dump"
5
-
6
- module Hanami
7
- module CLI
8
- module Commands
9
- module App
10
- module DB
11
- # @api private
12
- class Rollback < App::Command
13
- desc "Rollback database to a previous migration"
14
-
15
- option :target, desc: "Target migration number", aliases: ["-t"]
16
- option :dump, desc: "Dump structure after rolling back"
17
-
18
- # @api private
19
- def call(target: nil, dump: true, **)
20
- migration_code, migration_name = find_migration(target)
21
-
22
- if migration_name.nil?
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
30
- return
31
- end
32
-
33
- measure "database #{database.name} rolled back to #{migration_name}" do
34
- database.run_migrations(target: Integer(migration_code))
35
-
36
- true
37
- end
38
-
39
- run_command Structure::Dump if dump
40
- end
41
-
42
- private
43
-
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 =
63
- if code
64
- applied_migrations.detect { |m| m.split("_").first == code }
65
- else
66
- applied_migrations[-2]
67
- end
68
-
69
- return unless migration
70
-
71
- migration_code = code || migration.split("_").first
72
- migration_name = File.basename(migration, ".*")
73
-
74
- [migration_code, migration_name]
75
- end
76
- end
77
- end
78
- end
79
- end
80
- end
81
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../../app/command"
4
- require_relative "structure/dump"
5
-
6
- module Hanami
7
- module CLI
8
- module Commands
9
- module App
10
- module DB
11
- # @api private
12
- class SampleData < App::Command
13
- FILE_PATH = "db/sample_data.rb"
14
-
15
- desc "Load sample data"
16
-
17
- # @api private
18
- def call(**)
19
- if has_file?
20
- measure "sample data loaded from #{FILE_PATH}" do
21
- load full_file_path
22
- end
23
- else
24
- out.puts "=> #{FILE_PATH} not found"
25
- end
26
- end
27
-
28
- private
29
-
30
- def full_file_path
31
- File.join(app.root, FILE_PATH)
32
- end
33
-
34
- def has_file?
35
- File.exist?(full_file_path)
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../../app/command"
4
- require_relative "create"
5
- require_relative "migrate"
6
-
7
- module Hanami
8
- module CLI
9
- module Commands
10
- module App
11
- module DB
12
- # @api private
13
- class Setup < App::Command
14
- desc "Setup database"
15
-
16
- # @api private
17
- def call(**)
18
- run_command Create
19
- run_command Migrate
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "uri"
4
-
5
- module Hanami
6
- module CLI
7
- module Commands
8
- module App
9
- module DB
10
- # @api private
11
- module Utils
12
- # @api private
13
- class DatabaseConfig
14
- # @api private
15
- attr_reader :uri
16
-
17
- # @api private
18
- def initialize(database_url)
19
- @uri = URI(database_url)
20
- end
21
-
22
- # @api private
23
- def hostname
24
- uri.hostname
25
- end
26
- alias_method :host, :hostname
27
-
28
- # @api private
29
- def user
30
- uri.user
31
- end
32
- alias_method :username, :user
33
-
34
- # @api private
35
- def password
36
- uri.password
37
- end
38
- alias_method :pass, :password
39
-
40
- # @api private
41
- def port
42
- uri.port
43
- end
44
-
45
- # @api private
46
- def db_name
47
- @db_name ||= uri.path.gsub(/\A\//, "")
48
- end
49
-
50
- # @api private
51
- def db_type
52
- uri.scheme
53
- end
54
- end
55
- end
56
- end
57
- end
58
- end
59
- end
60
- end