hanami-cli 2.3.0.beta1 → 2.3.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -3
  3. data/.rubocop.yml +2 -0
  4. data/.rubocop_todo.yml +150 -0
  5. data/CHANGELOG.md +44 -0
  6. data/README.md +1 -4
  7. data/hanami-cli.gemspec +3 -3
  8. data/lib/hanami/cli/commands/app/command.rb +5 -1
  9. data/lib/hanami/cli/commands/app/console.rb +10 -1
  10. data/lib/hanami/cli/commands/app/db/migrate.rb +5 -2
  11. data/lib/hanami/cli/commands/app/db/rollback.rb +26 -14
  12. data/lib/hanami/cli/commands/app/db/structure/dump.rb +7 -3
  13. data/lib/hanami/cli/commands/app/db/utils/database.rb +22 -0
  14. data/lib/hanami/cli/commands/app/db/utils/mysql.rb +3 -1
  15. data/lib/hanami/cli/commands/app/db/utils/postgres.rb +16 -3
  16. data/lib/hanami/cli/commands/app/db/utils/sqlite.rb +1 -1
  17. data/lib/hanami/cli/commands/app/db/version.rb +2 -0
  18. data/lib/hanami/cli/commands/app/generate/action.rb +9 -12
  19. data/lib/hanami/cli/commands/app/generate/slice.rb +8 -8
  20. data/lib/hanami/cli/commands/app/run.rb +108 -0
  21. data/lib/hanami/cli/commands/app.rb +1 -0
  22. data/lib/hanami/cli/commands/gem/new.rb +33 -11
  23. data/lib/hanami/cli/errors.rb +2 -0
  24. data/lib/hanami/cli/generators/app/action.rb +11 -5
  25. data/lib/hanami/cli/generators/app/component.rb +1 -1
  26. data/lib/hanami/cli/generators/app/relation.rb +1 -1
  27. data/lib/hanami/cli/generators/app/ruby_file.rb +7 -12
  28. data/lib/hanami/cli/generators/app/slice.rb +19 -8
  29. data/lib/hanami/cli/generators/app/view.rb +1 -1
  30. data/lib/hanami/cli/generators/constants.rb +1 -1
  31. data/lib/hanami/cli/generators/context.rb +12 -1
  32. data/lib/hanami/cli/generators/gem/app/context.erb +10 -0
  33. data/lib/hanami/cli/generators/gem/app/gemfile.erb +3 -2
  34. data/lib/hanami/cli/generators/gem/app/readme.erb +6 -6
  35. data/lib/hanami/cli/generators/gem/app/setup.erb +27 -0
  36. data/lib/hanami/cli/generators/gem/app/types.erb +1 -1
  37. data/lib/hanami/cli/generators/gem/app.rb +4 -0
  38. data/lib/hanami/cli/generators/version.rb +5 -7
  39. data/lib/hanami/cli/interactive_system_call.rb +1 -2
  40. data/lib/hanami/cli/system_call.rb +1 -1
  41. data/lib/hanami/cli/version.rb +1 -1
  42. data/lib/hanami/console/context.rb +3 -0
  43. data/lib/hanami/console/plugins/unbooted_slice_warnings.rb +40 -0
  44. data/script/ci +31 -0
  45. metadata +10 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c770a27b290fd7bb7fcdd8db847ebd27723088374f8799b59d6e707e59404da0
4
- data.tar.gz: 35aeda59b2833925c79d5ca3f604c410bb5512ec608c9f9527d7d8cbd1818c47
3
+ metadata.gz: d249cea2b03d5af4fa6ff0942f25dbe3d7f1d5e270a7394fc3389bc197bd25db
4
+ data.tar.gz: 3b80a633266846dbf078b037b40c8387c75a00c33d703db4ea5fa5984786b2cb
5
5
  SHA512:
6
- metadata.gz: e8a06cf2ca8224b1216c62d62356af0dc3ab4620b762fef531f0dec5b2c792816afe7f5a9a828170621a94f58370f04047ce0c86922e2730465417df9793169c
7
- data.tar.gz: fb87833f3c11436dd3f313d9a3900d89395f6a8edef49a14a5e7b5c981081ec0bf859c11892d43502a005afd427bff7e8331faa733d1ec016875cef7fe59ad18
6
+ metadata.gz: 0b8ddb4a723343bcd936988680c8c279874663d94f442edec386d29611a164f05defdf88d4346e1b50670c1891365ff6dfc2f9551d3711d984045d3e81a59098
7
+ data.tar.gz: '083efc0c155519462aa9ebd82575b265961b65ca784c9056cd29f82b3d9be23d53c43aab31d47bc8d73a7f2afe0b6c884ea3ee3c13ca8c0951d4ff76f896b64c'
@@ -1,6 +1,6 @@
1
1
  name: ci
2
2
 
3
- "on":
3
+ on:
4
4
  push:
5
5
  paths:
6
6
  - ".github/workflows/ci.yml"
@@ -27,7 +27,6 @@ jobs:
27
27
  - "3.4"
28
28
  - "3.3"
29
29
  - "3.2"
30
- - "3.1"
31
30
  rack:
32
31
  - "~> 2.0"
33
32
  - "~> 3.0"
@@ -46,7 +45,7 @@ jobs:
46
45
  env:
47
46
  RACK_VERSION_CONSTRAINT: ${{matrix.rack}}
48
47
  - name: Run all tests
49
- run: bundle exec rake spec
48
+ run: script/ci
50
49
  env:
51
50
  RACK_VERSION_CONSTRAINT: ${{matrix.rack}}
52
51
  services:
data/.rubocop.yml CHANGED
@@ -3,7 +3,9 @@
3
3
  AllCops:
4
4
  SuggestExtensions: false
5
5
  inherit_from:
6
+ - .rubocop_todo.yml
6
7
  - https://raw.githubusercontent.com/hanami/devtools/main/.rubocop.yml
8
+
7
9
  Layout/LineLength:
8
10
  Exclude:
9
11
  - Gemfile
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,150 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp`
3
+ # using RuboCop version 1.81.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # This cop supports safe autocorrection (--autocorrect).
10
+ # Configuration parameters: AllowedMethods, AllowedPatterns.
11
+ Lint/AmbiguousBlockAssociation:
12
+ Exclude:
13
+ - 'lib/hanami/cli/commands/app/db/command.rb'
14
+
15
+ # Configuration parameters: AllowedParentClasses.
16
+ Lint/MissingSuper:
17
+ Exclude:
18
+ - 'lib/hanami/cli/commands/app/install.rb'
19
+
20
+ # This cop supports safe autocorrection (--autocorrect).
21
+ # Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
22
+ Lint/UnusedBlockArgument:
23
+ Exclude:
24
+ - 'spec/unit/hanami/cli/commands/app/db/rollback_spec.rb'
25
+
26
+ # This cop supports safe autocorrection (--autocorrect).
27
+ # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
28
+ # NotImplementedExceptions: NotImplementedError
29
+ Lint/UnusedMethodArgument:
30
+ Exclude:
31
+ - 'lib/hanami/cli/commands/app/install.rb'
32
+ - 'lib/hanami/cli/generators/app/action.rb'
33
+ - 'lib/hanami/cli/generators/app/part.rb'
34
+
35
+ # This cop supports safe autocorrection (--autocorrect).
36
+ Lint/UselessAssignment:
37
+ Exclude:
38
+ - 'spec/support/postgres.rb'
39
+
40
+ # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
41
+ Metrics/AbcSize:
42
+ Exclude:
43
+ - 'lib/hanami/cli/commands/app.rb'
44
+ - 'lib/hanami/cli/commands/app/db/prepare.rb'
45
+ - 'lib/hanami/cli/commands/app/db/rollback.rb'
46
+ - 'lib/hanami/cli/commands/app/db/structure/dump.rb'
47
+ - 'lib/hanami/cli/commands/app/db/structure/load.rb'
48
+ - 'lib/hanami/cli/commands/app/db/utils/postgres.rb'
49
+ - 'lib/hanami/cli/generators/app/slice.rb'
50
+
51
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
52
+ Metrics/CyclomaticComplexity:
53
+ Exclude:
54
+ - 'lib/hanami/cli/commands/app/db/rollback.rb'
55
+
56
+ # Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters.
57
+ Metrics/ParameterLists:
58
+ Exclude:
59
+ - 'lib/hanami/cli/commands/app/db/command.rb'
60
+ - 'lib/hanami/cli/commands/app/db/migrate.rb'
61
+ - 'lib/hanami/cli/commands/app/db/rollback.rb'
62
+ - 'lib/hanami/cli/generators/app/ruby_file.rb'
63
+
64
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
65
+ Metrics/PerceivedComplexity:
66
+ Exclude:
67
+ - 'lib/hanami/cli/commands/app/db/command.rb'
68
+ - 'lib/hanami/cli/commands/app/db/rollback.rb'
69
+
70
+ # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
71
+ # SupportedStyles: snake_case, normalcase, non_integer
72
+ # AllowedIdentifiers: TLS1_1, TLS1_2, capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64
73
+ Naming/VariableNumber:
74
+ Exclude:
75
+ - 'spec/support/hanami_cli_environment.rb'
76
+ - 'spec/unit/hanami/cli/commands/app/db/structure/dump_spec.rb'
77
+
78
+ # This cop supports unsafe autocorrection (--autocorrect-all).
79
+ Style/CombinableLoops:
80
+ Exclude:
81
+ - 'lib/hanami/cli/commands/app/db/prepare.rb'
82
+
83
+ # This cop supports unsafe autocorrection (--autocorrect-all).
84
+ Style/FileNull:
85
+ Exclude:
86
+ - 'spec/integration/hanami/cli/commands/app/server_spec.rb'
87
+
88
+ # This cop supports safe autocorrection (--autocorrect).
89
+ # Configuration parameters: MaxUnannotatedPlaceholdersAllowed, Mode, AllowedMethods, AllowedPatterns.
90
+ # SupportedStyles: annotated, template, unannotated
91
+ Style/FormatStringToken:
92
+ EnforcedStyle: template
93
+
94
+ # This cop supports unsafe autocorrection (--autocorrect-all).
95
+ # Configuration parameters: EnforcedStyle.
96
+ # SupportedStyles: always, always_true, never
97
+ Style/FrozenStringLiteralComment:
98
+ Exclude:
99
+ - '**/*.arb'
100
+ - 'spec/support/matchers.rb'
101
+
102
+ # This cop supports unsafe autocorrection (--autocorrect-all).
103
+ Style/MapToHash:
104
+ Exclude:
105
+ - 'lib/hanami/cli/commands/app/db/utils/database.rb'
106
+
107
+ # Configuration parameters: EnforcedStyle.
108
+ # SupportedStyles: allow_single_line, disallow
109
+ Style/NumberedParameters:
110
+ Exclude:
111
+ - 'lib/hanami/cli/commands/app/db/command.rb'
112
+
113
+ # This cop supports unsafe autocorrection (--autocorrect-all).
114
+ # Configuration parameters: EnforcedStyle, AllowedMethods, AllowedPatterns.
115
+ # SupportedStyles: predicate, comparison
116
+ Style/NumericPredicate:
117
+ Exclude:
118
+ - 'spec/**/*'
119
+ - 'lib/hanami/cli/commands/app/db/create.rb'
120
+ - 'lib/hanami/cli/commands/app/db/drop.rb'
121
+ - 'lib/hanami/cli/commands/app/db/structure/dump.rb'
122
+ - 'lib/hanami/cli/commands/app/db/structure/load.rb'
123
+
124
+ # This cop supports safe autocorrection (--autocorrect).
125
+ Style/RedundantBegin:
126
+ Exclude:
127
+ - 'lib/hanami/cli/commands/app/db/utils/sqlite.rb'
128
+
129
+ # This cop supports safe autocorrection (--autocorrect).
130
+ Style/RedundantInterpolationUnfreeze:
131
+ Exclude:
132
+ - 'lib/hanami/cli/commands/app/db/utils/postgres.rb'
133
+
134
+ # This cop supports safe autocorrection (--autocorrect).
135
+ Style/RedundantRegexpEscape:
136
+ Exclude:
137
+ - 'lib/hanami/cli/generators/constants.rb'
138
+
139
+ # This cop supports safe autocorrection (--autocorrect).
140
+ # Configuration parameters: AllowMultipleReturnValues.
141
+ Style/RedundantReturn:
142
+ Exclude:
143
+ - 'lib/hanami/cli/commands/app/db/rollback.rb'
144
+
145
+ # This cop supports safe autocorrection (--autocorrect).
146
+ # Configuration parameters: EnforcedStyle.
147
+ # SupportedStyles: implicit, explicit
148
+ Style/RescueStandardError:
149
+ Exclude:
150
+ - 'lib/hanami/cli/commands/app/db/utils/sqlite.rb'
data/CHANGELOG.md CHANGED
@@ -4,6 +4,50 @@ Hanami Command Line Interface
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## v2.3.0 - 2025-11-12
8
+
9
+ ### Added
10
+
11
+ - Generate a `bin/setup` when generating new apps. (@davidcelis in #359)
12
+ - Generate `bin/hanami` and `bin/rake` binstubs when generating new apps. (@jaredcwhite in #344)
13
+ - Generate a view context class when generating new apps or slices. (@afomera in #350)
14
+ - Add `--gem-source` option to `hanami new`, to specify the gem source for your `Gemfile`. For example: `hanami new my_app --gem-source=gem.coop`. (@svooop in #356)
15
+
16
+ ### Changed
17
+
18
+ - Print a one-time warning when accessing an un-booted slice’s `keys` in the console. (@timriley in #349)
19
+ - Add `--boot` flag to `console` command, which boots the Hanami app before loading the console. (@kyleplump in #331)
20
+ - In new apps, require dry-operation v1.0.1 in the generated `Gemfile`. This is necessary to pull in a fix required for Hanami’s automatic integration of Dry Operation with the database layer. (@timriley in #351)
21
+ - When generating new apps with `--head`, use the new GitHub repo names in the `Gemfile` (`"hanami/hanami-view"` instead of `"hanami/view"`). (@afomera in #354)
22
+ - When generating new apps with `--head`, add `"hanami-utils"` to the `Gemfile`. (@timriley in #362)
23
+ - In new apps, include a patch-level version (e.g. "~> 2.3.0") for Hanami gems in generated `Gemfile`, ensuring updates to the next minor version are only done intentionally. (@timriley in #367)
24
+
25
+ ### Fixed
26
+
27
+ - When running `db rollback` in development, also rollback the test database. (@timriley in #355)
28
+ - Remove "restrict" and "unrestrict" statements (which constantly change, even if there are no structure changes) from Postgres structure dumps. (@rickenharp in #336)
29
+ - Remove "-- Dumped from" version comments from Postgres dumps (which will change based on the local client version). (@davidcelis in #358)
30
+ - Check for Postgres database existence in a more robust way. The previous method could fail if both the Postgres username and database name were the same. (@rickenharp in #332)
31
+ - Fix structure dump and load for MySQL 9.5.0. (@timriley in #348)
32
+ - Preserve Bundler environment variables when commands make system calls. (@robyurkowski in 346)
33
+
34
+ ## v2.3.0.beta2 - 2025-10-17
35
+
36
+ ### Added
37
+
38
+ - Add `hanami run` command, to run your own code. For example, `hanami run path/to/script.rb` or `hanami run 'puts Hanami.app["repos.user_repo"].all.count'`. (@afomera in #338)
39
+
40
+ ### Changed
41
+
42
+ - Add `--skip-tests` flag to `generate action` command. (@kyleplump in #335)
43
+ - In new apps, updated generated types module to `Dry.Types(default: :strict)`. (@minaslater in #323)
44
+ - When generators add routes, add those routes to per-slice routes files (`config/routes.rb` within slice directories) if they exist. (@stephannv in #342)
45
+ - Drop support for Ruby 3.1
46
+
47
+ ### Fixed
48
+
49
+ - Handle mixed case names given to `generate` subcommands. (@cllns in #327)
50
+
7
51
  ## v2.3.0.beta1 - 2025-10-03
8
52
 
9
53
  ### Added
data/README.md CHANGED
@@ -9,8 +9,7 @@ Please update your Gemfiles accordingly.
9
9
  ## Status
10
10
 
11
11
  [![Gem Version](https://badge.fury.io/rb/hanami-cli.svg)](https://badge.fury.io/rb/hanami-cli)
12
- [![CI](https://github.com/hanami/cli/actions/workflows/ci.yml/badge.svg)](https://github.com/hanami/cli/actions?query=workflow%3Aci+branch%3Amain)
13
- [![Depfu](https://badges.depfu.com/badges/a8545fb67cf32a2c75b6227bc0821027/overview.svg)](https://depfu.com/github/hanami/cli?project=Bundler)
12
+ [![CI](https://github.com/hanami/hanami-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/hanami/hanami-cli/actions?query=workflow%3Aci+branch%3Amain)
14
13
 
15
14
  ## Contact
16
15
 
@@ -22,8 +21,6 @@ Please update your Gemfiles accordingly.
22
21
 
23
22
  ## Installation
24
23
 
25
- **Hanami::CLI** supports Ruby (MRI) 3.1+
26
-
27
24
  This library is a dependency of the main `hanami` gem, so installing that is the best way to get and use this gem.
28
25
 
29
26
  ## Usage
data/hanami-cli.gemspec CHANGED
@@ -5,8 +5,8 @@ require_relative "lib/hanami/cli/version"
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "hanami-cli"
7
7
  spec.version = Hanami::CLI::VERSION
8
- spec.authors = ["Luca Guidi"]
9
- spec.email = ["me@lucaguidi.com"]
8
+ spec.authors = ["Hanakai team"]
9
+ spec.email = ["info@hanakai.org"]
10
10
 
11
11
  spec.summary = "Hanami CLI"
12
12
  spec.description = "Hanami command line"
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
30
30
  spec.metadata["rubygems_mfa_required"] = "true"
31
- spec.required_ruby_version = ">= 3.1"
31
+ spec.required_ruby_version = ">= 3.2"
32
32
 
33
33
  spec.add_dependency "bundler", "~> 2.1"
34
34
  spec.add_dependency "dry-cli", "~> 1.0", ">= 1.1.0"
@@ -26,7 +26,11 @@ module Hanami
26
26
  # @since 2.2.0
27
27
  # @api private
28
28
  def self.prepended(klass)
29
- klass.option :env, desc: "App environment (development, test, production)", aliases: ["e"]
29
+ # This module is included each time the class is inherited from
30
+ # Without this check, the --env option is duplicated each time
31
+ unless klass.options.map(&:name).include?(:env)
32
+ klass.option :env, desc: "App environment (development, test, production)", aliases: ["e"]
33
+ end
30
34
  end
31
35
 
32
36
  # @since 2.0.0
@@ -31,13 +31,22 @@ module Hanami
31
31
  DEFAULT_ENGINE = "irb"
32
32
  private_constant :DEFAULT_ENGINE
33
33
 
34
+ # @since 2.2.0
35
+ # @api private
36
+ DEFAULT_BOOT = false
37
+ private_constant :DEFAULT_BOOT
38
+
34
39
  desc "Start app console (REPL)"
35
40
 
36
41
  option :engine, required: false, desc: "Console engine", values: ENGINES.keys
37
42
 
43
+ option :boot, required: false, desc: "Auto-boot containers", type: :flag, default: DEFAULT_BOOT
44
+
38
45
  # @since 2.0.0
39
46
  # @api private
40
- def call(engine: nil, **opts)
47
+ def call(engine: nil, boot: DEFAULT_BOOT, **opts)
48
+ app.boot if boot
49
+
41
50
  engine ||= app.config.console.engine.to_s
42
51
  console_engine = resolve_engine(engine, opts)
43
52
 
@@ -11,8 +11,11 @@ module Hanami
11
11
 
12
12
  option :gateway, required: false, desc: "Use database for gateway"
13
13
  option :target, desc: "Target migration number", aliases: ["-t"]
14
- option :dump, required: false, type: :boolean, default: true,
15
- desc: "Dump the database structure after migrating"
14
+ option :dump,
15
+ required: false,
16
+ type: :boolean,
17
+ default: true,
18
+ desc: "Dump the database structure after migrating"
16
19
 
17
20
  def call(target: nil, app: false, slice: nil, gateway: nil, dump: true, command_exit: method(:exit), **)
18
21
  databases(app: app, slice: slice, gateway: gateway).each do |database|
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "../../app/command"
3
4
  require_relative "structure/dump"
4
5
 
@@ -15,7 +16,16 @@ module Hanami
15
16
  option :dump, desc: "Dump structure after rolling back", default: true
16
17
  option :gateway, required: false, desc: "Use database for gateway"
17
18
 
18
- def call(steps: nil, app: false, slice: nil, gateway: nil, target: nil, dump: true, command_exit: method(:exit), **)
19
+ def call(
20
+ steps: nil,
21
+ app: false,
22
+ slice: nil,
23
+ gateway: nil,
24
+ target: nil,
25
+ dump: true,
26
+ command_exit: method(:exit),
27
+ **
28
+ )
19
29
  # We allow either a number of steps or a target migration number to be provided
20
30
  # If steps is provided and target is not, we use steps as the target migration number, but we also have to
21
31
  # make sure steps is a number, hence some additional logic around checking and converting to number
@@ -45,15 +55,17 @@ module Hanami
45
55
  true
46
56
  end
47
57
 
48
- return unless dump && !re_running_in_test?
58
+ if dump && !re_running_in_test?
59
+ run_command(
60
+ Structure::Dump,
61
+ app: database.slice == self.app,
62
+ slice: database.slice == self.app ? nil : database.slice.slice_name.to_s,
63
+ gateway: database.gateway_name == :default ? nil : database.gateway_name.to_s,
64
+ command_exit: command_exit
65
+ )
66
+ end
49
67
 
50
- run_command(
51
- Structure::Dump,
52
- app: database.slice == self.app,
53
- slice: database.slice == self.app ? nil : database.slice.slice_name.to_s,
54
- gateway: database.gateway_name == :default ? nil : database.gateway_name.to_s,
55
- command_exit: command_exit
56
- )
68
+ re_run_development_command_in_test
57
69
  end
58
70
 
59
71
  private
@@ -98,7 +110,7 @@ module Hanami
98
110
 
99
111
  def resolve_app_database(gateway, command_exit)
100
112
  databases = build_databases(app)
101
-
113
+
102
114
  if gateway
103
115
  database = databases[gateway.to_sym]
104
116
  unless database
@@ -117,7 +129,7 @@ module Hanami
117
129
 
118
130
  def resolve_default_database(command_exit)
119
131
  all_dbs = all_databases
120
-
132
+
121
133
  if all_dbs.empty?
122
134
  err.puts "No databases found"
123
135
  command_exit.(1)
@@ -142,13 +154,13 @@ module Hanami
142
154
  def resolve_slice(slice_name, command_exit)
143
155
  slice_name_sym = inflector.underscore(Shellwords.shellescape(slice_name)).to_sym
144
156
  slice = app.slices[slice_name_sym]
145
-
157
+
146
158
  unless slice
147
159
  err.puts %(Slice "#{slice_name}" not found)
148
160
  command_exit.(1)
149
161
  return
150
162
  end
151
-
163
+
152
164
  ensure_database_slice(slice)
153
165
  slice
154
166
  end
@@ -171,7 +183,7 @@ module Hanami
171
183
  # If we have migrations [A, B, C, D] and want to rollback 2 steps from D,
172
184
  # we want to target B (index -3, since we go back 2 steps + 1 for the target)
173
185
  target_index = -(steps_count + 1)
174
-
186
+
175
187
  if target_index.abs > applied_migrations.size
176
188
  return initial_state(applied_migrations)
177
189
  else
@@ -23,7 +23,7 @@ module Hanami
23
23
 
24
24
  measure("#{database.name} structure dumped to #{relative_structure_path}") do
25
25
  catch :dump_failed do
26
- result = database.exec_dump_command
26
+ result = database.structure_sql_dump
27
27
  exit_codes << result.exit_code if result.respond_to?(:exit_code)
28
28
 
29
29
  unless result.successful?
@@ -31,9 +31,13 @@ module Hanami
31
31
  throw :dump_failed, false
32
32
  end
33
33
 
34
+ structure_sql = result.sql
35
+
34
36
  migrations_sql = database.schema_migrations_sql_dump
35
- if migrations_sql
36
- File.open(database.structure_file, "a") do |f|
37
+
38
+ File.open(database.structure_file, "w") do |f|
39
+ f.puts "#{structure_sql}\n"
40
+ if migrations_sql
37
41
  f.puts "#{migrations_sql}\n"
38
42
  end
39
43
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "uri"
4
+ require "delegate"
4
5
 
5
6
  module Hanami
6
7
  module CLI
@@ -11,6 +12,17 @@ module Hanami
11
12
  # @api private
12
13
  # @since 2.2.0
13
14
  class Database
15
+ class DumpResult < DelegateClass(Hanami::CLI::SystemCall::Result)
16
+ def initialize(result, post_process: -> sql { sql })
17
+ @post_process = post_process
18
+ super(result)
19
+ end
20
+
21
+ def sql
22
+ @post_process.call(out)
23
+ end
24
+ end
25
+
14
26
  DATABASE_CLASS_RESOLVER = Hash.new { |_, key|
15
27
  raise "#{key} is not a supported db scheme"
16
28
  }.update(
@@ -167,6 +179,10 @@ module Hanami
167
179
  end
168
180
  end
169
181
 
182
+ def structure_sql_dump
183
+ DumpResult.new(exec_dump_command, post_process: method(:post_process_dump))
184
+ end
185
+
170
186
  def schema_migrations_sql_dump
171
187
  return unless migrations_dir?
172
188
 
@@ -175,6 +191,12 @@ module Hanami
175
191
  sql << ";"
176
192
  sql
177
193
  end
194
+
195
+ private
196
+
197
+ def post_process_dump(sql)
198
+ sql
199
+ end
178
200
  end
179
201
  end
180
202
  end
@@ -39,10 +39,11 @@ module Hanami
39
39
  def exec_dump_command
40
40
  exec_cli(
41
41
  "mysqldump",
42
- "--no-data --routines --skip-comments --result-file=#{structure_file} #{escaped_name}"
42
+ "--no-data --routines --skip-comments --set-gtid-purged=off #{escaped_name}"
43
43
  )
44
44
  end
45
45
 
46
+ # rubocop:disable Layout/LineLength
46
47
  # @api private
47
48
  # @since 2.2.0
48
49
  def exec_load_command
@@ -51,6 +52,7 @@ module Hanami
51
52
  %(--commands --execute "SET FOREIGN_KEY_CHECKS = 0; SOURCE #{structure_file}; SET FOREIGN_KEY_CHECKS = 1" --database #{escaped_name})
52
53
  )
53
54
  end
55
+ # rubocop:enable Layout/LineLength
54
56
 
55
57
  private
56
58
 
@@ -13,6 +13,11 @@ module Hanami
13
13
  # @api private
14
14
  # @since 2.2.0
15
15
  class Postgres < Database
16
+ SCHEMA_DUMP_FILTERS = [
17
+ /^\\(un)?restrict/,
18
+ /^-- Dumped (from|by) (database version|pg_dump version)/,
19
+ ].freeze
20
+
16
21
  # @api private
17
22
  # @since 2.2.0
18
23
  def exec_create_command
@@ -32,7 +37,7 @@ module Hanami
32
37
  # @api private
33
38
  # @since 2.2.0
34
39
  def exists?
35
- result = system_call.call("psql -t -A -c '\\list #{escaped_name}'", env: cli_env_vars)
40
+ result = system_call.call("psql -t -A -c '\\list #{escaped_name}' template1", env: cli_env_vars)
36
41
  raise Hanami::CLI::DatabaseExistenceCheckError.new(result.err) unless result.successful?
37
42
 
38
43
  result.out.include?("#{name}|") # start_with?
@@ -42,11 +47,12 @@ module Hanami
42
47
  # @since 2.2.0
43
48
  def exec_dump_command
44
49
  system_call.call(
45
- "pg_dump --schema-only --no-privileges --no-owner --file #{structure_file} #{escaped_name}",
50
+ "pg_dump --schema-only --no-privileges --no-owner #{escaped_name}",
46
51
  env: cli_env_vars
47
52
  )
48
53
  end
49
54
 
55
+ # rubocop:disable Layout/LineLength
50
56
  # @api private
51
57
  # @since 2.2.0
52
58
  def exec_load_command
@@ -55,11 +61,12 @@ module Hanami
55
61
  env: cli_env_vars
56
62
  )
57
63
  end
64
+ # rubocop:enable Layout/LineLength
58
65
 
59
66
  def schema_migrations_sql_dump
60
67
  migrations_sql = super
61
68
  return unless migrations_sql
62
-
69
+
63
70
  search_path = gateway.connection
64
71
  .fetch("SHOW search_path").to_a.first
65
72
  .fetch(:search_path)
@@ -69,6 +76,12 @@ module Hanami
69
76
 
70
77
  private
71
78
 
79
+ def post_process_dump(sql)
80
+ sql.lines.reject do |line|
81
+ SCHEMA_DUMP_FILTERS.any? { |filter| line =~ filter }
82
+ end.join
83
+ end
84
+
72
85
  def escaped_name
73
86
  Shellwords.escape(name)
74
87
  end
@@ -55,7 +55,7 @@ module Hanami
55
55
  # @api private
56
56
  # @since 2.2.0
57
57
  def exec_dump_command
58
- system_call.call(%(sqlite3 #{file_path} ".schema --indent --nosys" > #{structure_file}))
58
+ system_call.call(%(sqlite3 #{file_path} ".schema --indent --nosys"))
59
59
  end
60
60
 
61
61
  # @api private
@@ -11,6 +11,7 @@ module Hanami
11
11
 
12
12
  option :gateway, required: false, desc: "Use database for gateway"
13
13
 
14
+ # rubocop:disable Layout/LineLength
14
15
  # @api private
15
16
  def call(app: false, slice: nil, gateway: nil, **)
16
17
  databases(app: app, slice: slice, gateway: gateway).each do |database|
@@ -25,6 +26,7 @@ module Hanami
25
26
 
26
27
  out.puts "=> #{database.name} current schema version is #{version}"
27
28
  end
29
+ # rubocop:enable Layout/LineLength
28
30
  end
29
31
  end
30
32
  end