hanami-cli 2.3.0.beta2 → 2.3.1

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -2
  3. data/.rubocop.yml +2 -0
  4. data/.rubocop_todo.yml +150 -0
  5. data/CHANGELOG.md +33 -0
  6. data/README.md +1 -4
  7. data/hanami-cli.gemspec +2 -2
  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 +8 -11
  19. data/lib/hanami/cli/commands/app/generate/slice.rb +8 -8
  20. data/lib/hanami/cli/commands/gem/new.rb +33 -11
  21. data/lib/hanami/cli/errors.rb +3 -1
  22. data/lib/hanami/cli/generators/app/action.rb +1 -1
  23. data/lib/hanami/cli/generators/app/slice.rb +19 -8
  24. data/lib/hanami/cli/generators/context.rb +12 -1
  25. data/lib/hanami/cli/generators/gem/app/context.erb +10 -0
  26. data/lib/hanami/cli/generators/gem/app/gemfile.erb +3 -2
  27. data/lib/hanami/cli/generators/gem/app/readme.erb +6 -6
  28. data/lib/hanami/cli/generators/gem/app/setup.erb +27 -0
  29. data/lib/hanami/cli/generators/gem/app.rb +4 -0
  30. data/lib/hanami/cli/generators/version.rb +5 -7
  31. data/lib/hanami/cli/interactive_system_call.rb +1 -2
  32. data/lib/hanami/cli/system_call.rb +1 -1
  33. data/lib/hanami/cli/version.rb +1 -1
  34. data/lib/hanami/console/context.rb +3 -0
  35. data/lib/hanami/console/plugins/unbooted_slice_warnings.rb +40 -0
  36. data/script/ci +31 -0
  37. metadata +8 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a260c1daad682ef7898890f677c8768f548512fdb591b2af60414ecaccc38fb
4
- data.tar.gz: 58e9910a76e011243775ca794fc8dcd1769a1e31224136c5c8636a13a4e62f9d
3
+ metadata.gz: 6939575ae1e35a1e103d2d439b73080cb033f837ece81f4652e539dd7cf413fc
4
+ data.tar.gz: 9d94856acc062c3bdc0924a4c7dcfbf4badcd862b7d428a7e0e68e52aac8d46e
5
5
  SHA512:
6
- metadata.gz: 8f871a3391a7c985202dd517dc4775dfef0d4c7aa9c498e11d60ac235c12833b3de59ee0a5356ab48069753e95f166f3d41d1a3c3acb3b5b9acc5ec9c8d68376
7
- data.tar.gz: 4649a2c721659508d58b5a90c1ec7d955d321d50277f254a2db187222539c96086bd5bdce91ab55f0a1ba5b5244e08a76ddd767be6aec2f3c223b532928bf225
6
+ metadata.gz: 5f7d591b5fbf9dd4bcaf1cbc3bf942fa93bb1f90526d05e72c5f21251ec402c9f536059184aab555ee5c80c6d51504f9c61b5a44d119fcc13e48f41149161276
7
+ data.tar.gz: becdd694c75f85bca07452647a67241cd9ca03a8d1095b23dd8e6202f41de41ec693332de1c1b7ea2ee434e7b3e4d9291bcb434adfea84b5d58db7f37b3d7ff0
@@ -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"
@@ -45,7 +45,7 @@ jobs:
45
45
  env:
46
46
  RACK_VERSION_CONSTRAINT: ${{matrix.rack}}
47
47
  - name: Run all tests
48
- run: bundle exec rake spec
48
+ run: script/ci
49
49
  env:
50
50
  RACK_VERSION_CONSTRAINT: ${{matrix.rack}}
51
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,39 @@ Hanami Command Line Interface
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## v2.3.1 - 2025-11-14
8
+
9
+ ### Fixed
10
+
11
+ - Fix stray wording in `README.md` in new apps. (@davidcelis in #368)
12
+
13
+ ## v2.3.0 - 2025-11-12
14
+
15
+ ### Added
16
+
17
+ - Generate a `bin/setup` when generating new apps. (@davidcelis in #359)
18
+ - Generate `bin/hanami` and `bin/rake` binstubs when generating new apps. (@jaredcwhite in #344)
19
+ - Generate a view context class when generating new apps or slices. (@afomera in #350)
20
+ - 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)
21
+
22
+ ### Changed
23
+
24
+ - Print a one-time warning when accessing an un-booted slice’s `keys` in the console. (@timriley in #349)
25
+ - Add `--boot` flag to `console` command, which boots the Hanami app before loading the console. (@kyleplump in #331)
26
+ - 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)
27
+ - 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)
28
+ - When generating new apps with `--head`, add `"hanami-utils"` to the `Gemfile`. (@timriley in #362)
29
+ - 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)
30
+
31
+ ### Fixed
32
+
33
+ - When running `db rollback` in development, also rollback the test database. (@timriley in #355)
34
+ - Remove "restrict" and "unrestrict" statements (which constantly change, even if there are no structure changes) from Postgres structure dumps. (@rickenharp in #336)
35
+ - Remove "-- Dumped from" version comments from Postgres dumps (which will change based on the local client version). (@davidcelis in #358)
36
+ - 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)
37
+ - Fix structure dump and load for MySQL 9.5.0. (@timriley in #348)
38
+ - Preserve Bundler environment variables when commands make system calls. (@robyurkowski in 346)
39
+
7
40
  ## v2.3.0.beta2 - 2025-10-17
8
41
 
9
42
  ### 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"
@@ -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
@@ -59,7 +59,6 @@ module Hanami
59
59
 
60
60
  # option :format, required: false, type: :string, default: DEFAULT_FORMAT, desc: "Template format"
61
61
 
62
- # rubocop:disable Layout/LineLength
63
62
  example [
64
63
  %(books.index # GET /books to: "books.index" (MyApp::Actions::Books::Index)),
65
64
  %(books.new # GET /books/new to: "books.new" (MyApp::Actions::Books::New)),
@@ -73,15 +72,13 @@ module Hanami
73
72
  %(authors.update --http=put # PUT /authors/:id to: "authors.update" (MyApp::Actions::Authors::Update)),
74
73
  %(users.index --slice=admin # GET /admin/users to: "users.index" (Admin::Actions::Users::Update))
75
74
  ]
76
- # rubocop:enable Layout/LineLength
77
-
78
75
  def generator_class
79
76
  Generators::App::Action
80
77
  end
81
78
 
82
79
  # @since 2.0.0
83
80
  # @api private
84
- # rubocop:disable Lint/ParameterLists
81
+ # rubocop:disable Metrics/ParameterLists
85
82
  def call(
86
83
  name:,
87
84
  slice: nil,
@@ -96,16 +93,16 @@ module Hanami
96
93
  raise InvalidActionNameError.new(name) unless name.include?(".")
97
94
 
98
95
  super(
99
- name:,
100
- slice:,
101
- url_path:,
102
- skip_route:,
103
- http_method:,
96
+ name: name,
97
+ slice: slice,
98
+ url_path: url_path,
99
+ skip_route: skip_route,
100
+ http_method: http_method,
104
101
  skip_view: skip_view || !Hanami.bundled?("hanami-view"),
105
- skip_tests:
102
+ skip_tests: skip_tests
106
103
  )
107
104
  end
108
- # rubocop:enable Lint/ParameterLists
105
+ # rubocop:enable Metrics/ParameterLists
109
106
  end
110
107
  end
111
108
  end
@@ -29,17 +29,17 @@ module Hanami
29
29
  # @since 2.2.0
30
30
  # @api private
31
31
  option :skip_db,
32
- type: :flag,
33
- required: false,
34
- default: SKIP_DB_DEFAULT,
35
- desc: "Skip database"
32
+ type: :flag,
33
+ required: false,
34
+ default: SKIP_DB_DEFAULT,
35
+ desc: "Skip database"
36
36
  # @since 2.2.0
37
37
  # @api private
38
38
  option :skip_route,
39
- type: :flag,
40
- required: false,
41
- default: DEFAULT_SKIP_ROUTE,
42
- desc: "Skip route generation"
39
+ type: :flag,
40
+ required: false,
41
+ default: DEFAULT_SKIP_ROUTE,
42
+ desc: "Skip route generation"
43
43
 
44
44
  example [
45
45
  "admin # Admin slice (/admin URL prefix)",
@@ -10,16 +10,21 @@ module Hanami
10
10
  # @since 2.0.0
11
11
  # @api private
12
12
  class New < Command
13
- # @since 2.0.0
14
- # @api private
15
- SKIP_INSTALL_DEFAULT = false
16
- private_constant :SKIP_INSTALL_DEFAULT
17
-
18
13
  # @since 2.1.0
19
14
  # @api private
20
15
  HEAD_DEFAULT = false
21
16
  private_constant :HEAD_DEFAULT
22
17
 
18
+ # @since 2.3.0
19
+ # @api private
20
+ GEM_SOURCE_DEFAULT = "rubygems.org"
21
+ private_constant :GEM_SOURCE_DEFAULT
22
+
23
+ # @since 2.0.0
24
+ # @api private
25
+ SKIP_INSTALL_DEFAULT = false
26
+ private_constant :SKIP_INSTALL_DEFAULT
27
+
23
28
  # @since 2.1.0
24
29
  # @api private
25
30
  SKIP_ASSETS_DEFAULT = false
@@ -60,18 +65,24 @@ module Hanami
60
65
  # @api private
61
66
  argument :app, required: true, desc: "App name"
62
67
 
63
- # @since 2.0.0
64
- # @api private
65
- option :skip_install, type: :flag, required: false,
66
- default: SKIP_INSTALL_DEFAULT,
67
- desc: "Skip app installation (Bundler, third-party Hanami plugins)"
68
-
69
68
  # @since 2.1.0
70
69
  # @api private
71
70
  option :head, type: :flag, required: false,
72
71
  default: HEAD_DEFAULT,
73
72
  desc: "Use Hanami HEAD version (from GitHub `main` branches)"
74
73
 
74
+ # @since 2.3.0
75
+ # @api private
76
+ option :gem_source, required: true,
77
+ default: GEM_SOURCE_DEFAULT,
78
+ desc: "Where to source Ruby gems from"
79
+
80
+ # @since 2.0.0
81
+ # @api private
82
+ option :skip_install, type: :flag, required: false,
83
+ default: SKIP_INSTALL_DEFAULT,
84
+ desc: "Skip app installation (Bundler, third-party Hanami plugins)"
85
+
75
86
  # @since 2.1.0
76
87
  # @api private
77
88
  option :skip_assets, type: :flag, required: false,
@@ -100,6 +111,7 @@ module Hanami
100
111
  example [
101
112
  "bookshelf # Generate a new Hanami app in `bookshelf/' directory, using `Bookshelf' namespace",
102
113
  "bookshelf --head # Generate a new Hanami app, using Hanami HEAD version from GitHub `main' branches",
114
+ "bookshelf --gem-source=gem.coop # Generate a new Hanami app, using https://gem.coop as Ruby gem source",
103
115
  "bookshelf --skip-install # Generate a new Hanami app, but it skips Hanami installation",
104
116
  "bookshelf --skip-assets # Generate a new Hanami app without hanami-assets",
105
117
  "bookshelf --skip-db # Generate a new Hanami app without hanami-db",
@@ -132,6 +144,7 @@ module Hanami
132
144
  def call(
133
145
  app:,
134
146
  head: HEAD_DEFAULT,
147
+ gem_source: GEM_SOURCE_DEFAULT,
135
148
  skip_install: SKIP_INSTALL_DEFAULT,
136
149
  skip_assets: SKIP_ASSETS_DEFAULT,
137
150
  skip_db: SKIP_DB_DEFAULT,
@@ -152,6 +165,7 @@ module Hanami
152
165
  inflector,
153
166
  app,
154
167
  head: head,
168
+ gem_source: gem_source,
155
169
  skip_assets: skip_assets,
156
170
  skip_db: skip_db,
157
171
  skip_view: skip_view,
@@ -177,6 +191,9 @@ module Hanami
177
191
  out.puts "Running hanami install..."
178
192
  run_install_command!(head: head)
179
193
 
194
+ out.puts "Running bundle binstubs hanami-cli rake..."
195
+ install_binstubs!
196
+
180
197
  out.puts "Initializing git repository..."
181
198
  init_git_repository
182
199
  end
@@ -215,6 +232,11 @@ module Hanami
215
232
  end
216
233
  end
217
234
 
235
+ # @api private
236
+ def install_binstubs!
237
+ bundler.bundle("binstubs hanami-cli rake")
238
+ end
239
+
218
240
  # @api private
219
241
  def init_git_repository
220
242
  system_call.call("git", ["init"]).tap do |result|
@@ -47,7 +47,7 @@ module Hanami
47
47
  # @api public
48
48
  class FileAlreadyExistsError < Error
49
49
  ERROR_MESSAGE = <<~ERROR.chomp
50
- The file `%<file_path>s` could not be generated because it already exists.
50
+ The file `%{file_path}` could not be generated because it already exists.
51
51
  ERROR
52
52
 
53
53
  def initialize(file_path)
@@ -110,6 +110,7 @@ module Hanami
110
110
  end
111
111
  end
112
112
 
113
+ # rubocop:disable Layout/LineLength
113
114
  # @since 2.2.0
114
115
  # @api public
115
116
  class DatabaseNotSupportedError < Error
@@ -117,6 +118,7 @@ module Hanami
117
118
  super("`#{invalid_database}' is not a supported database. Supported databases are: #{supported_databases.join(', ')}")
118
119
  end
119
120
  end
121
+ # rubocop:enable Layout/LineLength
120
122
 
121
123
  # @since 2.2.0
122
124
  # @api public
@@ -30,7 +30,7 @@ module Hanami
30
30
  def call(key:, namespace:, base_path:, url_path:, http_method:, skip_view:, skip_route:, skip_tests:)
31
31
  insert_route(key:, namespace:, url_path:, http_method:) unless skip_route
32
32
 
33
- generate_action(key:, namespace:, base_path:, include_placeholder_body: skip_view)
33
+ generate_action(key: key, namespace: namespace, base_path: base_path, include_placeholder_body: skip_view)
34
34
 
35
35
  generate_view(key:, namespace:, base_path:) unless skip_view
36
36
  end
@@ -66,6 +66,17 @@ module Hanami
66
66
  body: ["# Add your view helpers here"]
67
67
  ).create
68
68
 
69
+ RubyClassFile.new(
70
+ fs: fs,
71
+ inflector: inflector,
72
+ namespace: slice,
73
+ key: "views.context",
74
+ base_path: directory,
75
+ parent_class_name: "#{Hanami.app.namespace}::View::Context",
76
+ auto_register: false,
77
+ body: ["# Define your view context here. See https://guides.hanamirb.org/views/context/ for details."]
78
+ ).create
79
+
69
80
  fs.create(
70
81
  fs.join(directory, "templates", "layouts", "app.html.erb"),
71
82
  app_layout_template(
@@ -93,11 +104,11 @@ module Hanami
93
104
  fs.create(
94
105
  fs.join(directory, "assets", "css", "app.css"),
95
106
  <<~CSS
96
- body {
97
- background-color: #fff;
98
- color: #000;
99
- font-family: sans-serif;
100
- }
107
+ body {
108
+ background-color: #fff;
109
+ color: #000;
110
+ font-family: sans-serif;
111
+ }
101
112
  CSS
102
113
  )
103
114
  fs.create(fs.join(directory, "assets", "images", "favicon.ico"), file("favicon.ico"))
@@ -161,9 +172,9 @@ module Hanami
161
172
  <head>
162
173
  <meta charset="UTF-8">
163
174
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
164
- <title>#{ page_title }</title>
165
- #{'<%= favicon_tag %>' if bundled_assets }
166
- #{'<%= stylesheet_tag "app" %>' if bundled_assets }
175
+ <title>#{page_title}</title>
176
+ #{'<%= favicon_tag %>' if bundled_assets}
177
+ #{'<%= stylesheet_tag "app" %>' if bundled_assets}
167
178
  </head>
168
179
  <body>
169
180
  <%= yield %>
@@ -32,7 +32,9 @@ module Hanami
32
32
 
33
33
  # @since 2.0.0
34
34
  # @api private
35
- def hanami_gem_version(gem_name)
35
+ def hanami_gem_version(name)
36
+ gem_name = name == "hanami" ? "hanami" : "hanami-#{name}"
37
+
36
38
  if hanami_head?
37
39
  %(github: "hanami/#{gem_name}", branch: "main")
38
40
  else
@@ -74,6 +76,15 @@ module Hanami
74
76
  options.fetch(:head)
75
77
  end
76
78
 
79
+ # @since 2.3.0
80
+ # @api private
81
+ def gem_source
82
+ value = options.fetch(:gem_source)
83
+ return value if value.match? %r{\A\w+://}
84
+
85
+ "https://#{value}"
86
+ end
87
+
77
88
  # @since 2.1.0
78
89
  # @api private
79
90
  def generate_assets?
@@ -0,0 +1,10 @@
1
+ # auto_register: false
2
+ # frozen_string_literal: true
3
+
4
+ module <%= camelized_app_name %>
5
+ module Views
6
+ class Context < Hanami::View::Context
7
+ # Define your view context here. See https://guides.hanamirb.org/views/context/ for details.
8
+ end
9
+ end
10
+ end
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source "https://rubygems.org"
3
+ source "<%= gem_source %>"
4
4
 
5
5
  <%= hanami_gem("hanami") %>
6
6
  <%- if hanami_head? -%>
7
7
  <%= hanami_gem("cli") %>
8
+ <%= hanami_gem("utils") %>
8
9
  <%- end -%>
9
10
  <%- if generate_assets? -%>
10
11
  <%= hanami_gem("assets") %>
@@ -20,7 +21,7 @@ source "https://rubygems.org"
20
21
  <%- end -%>
21
22
 
22
23
  gem "dry-types", "~> 1.7"
23
- gem "dry-operation"
24
+ gem "dry-operation", ">= 1.0.1"
24
25
  gem "puma"
25
26
  gem "rake"
26
27
  <%- if generate_sqlite? -%>
@@ -1,15 +1,15 @@
1
1
  # <%= camelized_app_name %>
2
2
 
3
- Welcome to your Hanami app!
3
+ 🌸 Welcome to your Hanami app!
4
4
 
5
- ## Getting Started
5
+ ## Getting started
6
6
 
7
+ - Set up the project with `bin/setup`
7
8
  - Run the server with `bin/dev`
8
9
  - View the app at [http://localhost:2300](http://localhost:2300)
9
10
  - Run the tests with `bundle exec rake`
10
11
 
11
- ## Useful Links
12
+ ## Useful links
12
13
 
13
- - [Hanami Home](http://hanamirb.org)
14
- - [Hanami Guides](https://guides.hanamirb.org/)
15
- - [Hanami API Doc](https://gemdocs.org/gems/hanami/latest)
14
+ - [Hanami](http://hanamirb.org)
15
+ - [Hanami guides](https://guides.hanamirb.org/)
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ # This script is a way to set up and keep your development environment updated
6
+ # automatically. It is meant to be idempotent so that you can run it at any
7
+ # time to get the same result. Add any new necessary setup steps to this file
8
+ # as your application evolves.
9
+
10
+ announce() {
11
+ local bold='\033[1m'
12
+ local reset='\033[0m'
13
+ printf "${bold}${1}${reset}\n"
14
+ }
15
+
16
+ announce "Running bundle install..."
17
+ bundle check || bundle install
18
+
19
+ announce "\nRunning npm install..."
20
+ npm install
21
+
22
+ <%- if generate_db? -%>
23
+ announce "\nPreparing the database..."
24
+ hanami db prepare
25
+
26
+ <%- end -%>
27
+ announce "\n🌸 Setup complete!"
@@ -46,6 +46,9 @@ module Hanami
46
46
  fs.create("bin/dev", file("dev"))
47
47
  fs.chmod("bin/dev", 0o755)
48
48
 
49
+ fs.create("bin/setup", t("setup.erb", context))
50
+ fs.chmod("bin/setup", 0o755)
51
+
49
52
  fs.create("config/app.rb", t("app.erb", context))
50
53
  fs.create("config/settings.rb", t("settings.erb", context))
51
54
  fs.create("config/routes.rb", t("routes.erb", context))
@@ -60,6 +63,7 @@ module Hanami
60
63
  if context.generate_view?
61
64
  fs.create("app/view.rb", t("view.erb", context))
62
65
  fs.create("app/views/helpers.rb", t("helpers.erb", context))
66
+ fs.create("app/views/context.rb", t("context.erb", context))
63
67
  fs.create("app/templates/layouts/app.html.erb", t("app_layout.erb", context))
64
68
 
65
69
  fs.create("public/404.html", file("404.html"))
@@ -38,27 +38,25 @@ module Hanami
38
38
  "^#{result}"
39
39
  end
40
40
 
41
- # @since 2.0.0
42
41
  # @api private
43
42
  def self.prerelease?
44
43
  version.match?(/alpha|beta|rc/)
45
44
  end
46
45
 
47
46
  # @example
48
- # Hanami::VERSION # => 2.0.0
49
- # Hanami::CLI::Generators::Version.stable_version # => "2.0"
47
+ # Hanami::VERSION # => 2.3.1
48
+ # Hanami::CLI::Generators::Version.stable_version # => "2.3.0"
50
49
  #
51
- # @since 2.0.0
52
50
  # @api private
53
51
  def self.stable_version
54
- version.scan(/\A\d{1,2}\.\d{1,2}/).first
52
+ major_minor = version.scan(/\A\d{1,2}\.\d{1,2}/).first
53
+ "#{major_minor}.0"
55
54
  end
56
55
 
57
56
  # @example
58
57
  # Hanami::VERSION # => 2.0.0.alpha8.1
59
- # Hanami::CLI::Generators::Version.stable_version # => "2.0.0.alpha"
58
+ # Hanami::CLI::Generators::Version.prerelease_version # => "2.0.0.alpha"
60
59
  #
61
- # @since 2.0.0
62
60
  # @api private
63
61
  def self.prerelease_version
64
62
  version.sub(/[[[:digit:]].]*\Z/, "")
@@ -13,13 +13,12 @@ module Hanami
13
13
  @out = out
14
14
  @err = err
15
15
  @exit_after = exit_after
16
- super()
17
16
  end
18
17
 
19
18
  # @api private
20
19
  # @since 2.1.0
21
20
  def call(cmd, *args, env: {}, out_prefix: "")
22
- ::Bundler.with_unbundled_env do
21
+ ::Bundler.with_original_env do
23
22
  threads = []
24
23
  exit_status = 0
25
24
 
@@ -90,7 +90,7 @@ module Hanami
90
90
  out = nil
91
91
  err = nil
92
92
 
93
- ::Bundler.with_unbundled_env do
93
+ ::Bundler.with_original_env do
94
94
  Open3.popen3(env, command(cmd, *args)) do |stdin, stdout, stderr, wait_thr|
95
95
  yield stdin, stdout, stderr, wait_thr if block_given?
96
96
 
@@ -6,6 +6,6 @@ module Hanami
6
6
  #
7
7
  # @api public
8
8
  # @since 2.0.0
9
- VERSION = "2.3.0.beta2"
9
+ VERSION = "2.3.1"
10
10
  end
11
11
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "plugins/slice_readers"
4
+ require_relative "plugins/unbooted_slice_warnings"
4
5
 
5
6
  module Hanami
6
7
  # @since 2.0.0
@@ -21,6 +22,8 @@ module Hanami
21
22
 
22
23
  define_context_methods
23
24
  include Plugins::SliceReaders.new(app)
25
+
26
+ Plugins::UnbootedSliceWarnings.activate
24
27
  end
25
28
 
26
29
  private
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ module Console
5
+ module Plugins
6
+ # Console plugin that prints a one-time warning when an unbooted slice is asked for its
7
+ # `.keys`.
8
+ #
9
+ # @api private
10
+ module UnbootedSliceWarnings
11
+ module SliceExtension
12
+ end
13
+
14
+ def self.activate
15
+ warning_shown_for_slice = {}
16
+
17
+ # Define the wrapper method with access to the context via closure
18
+ SliceExtension.define_method(:keys) do
19
+ if !booted? && !warning_shown_for_slice[self]
20
+ message = <<~TEXT
21
+ Warning: #{self} is not booted. Run `#{self}.boot` to load all components, or launch the console with `--boot`.
22
+ TEXT
23
+ warn message
24
+
25
+ warning_shown_for_slice[self] = true
26
+ end
27
+
28
+ super()
29
+ end
30
+
31
+ Hanami::Slice::ClassMethods.prepend(SliceExtension)
32
+ end
33
+
34
+ def self.deactivate
35
+ SliceExtension.remove_method :keys
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
data/script/ci ADDED
@@ -0,0 +1,31 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ prepare_build() {
6
+ if [ -d coverage ]; then
7
+ rm -rf coverage
8
+ fi
9
+ }
10
+
11
+ print_ruby_version() {
12
+ echo "Using $(ruby -v)"
13
+ echo
14
+ }
15
+
16
+ run_code_quality_checks() {
17
+ bundle exec rubocop .
18
+ }
19
+
20
+ run_unit_tests() {
21
+ bundle exec rake spec
22
+ }
23
+
24
+ main() {
25
+ prepare_build
26
+ print_ruby_version
27
+ run_code_quality_checks
28
+ run_unit_tests
29
+ }
30
+
31
+ main
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0.beta2
4
+ version: 2.3.1
5
5
  platform: ruby
6
6
  authors:
7
- - Luca Guidi
7
+ - Hanakai team
8
8
  bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
@@ -189,7 +189,7 @@ dependencies:
189
189
  version: '0'
190
190
  description: Hanami command line
191
191
  email:
192
- - me@lucaguidi.com
192
+ - info@hanakai.org
193
193
  executables:
194
194
  - hanami
195
195
  extensions: []
@@ -201,6 +201,7 @@ files:
201
201
  - ".repobot.yml"
202
202
  - ".rspec"
203
203
  - ".rubocop.yml"
204
+ - ".rubocop_todo.yml"
204
205
  - ".yardopts"
205
206
  - CHANGELOG.md
206
207
  - CODE_OF_CONDUCT.md
@@ -289,6 +290,7 @@ files:
289
290
  - lib/hanami/cli/generators/gem/app/app_layout.erb
290
291
  - lib/hanami/cli/generators/gem/app/assets.js
291
292
  - lib/hanami/cli/generators/gem/app/config_ru.erb
293
+ - lib/hanami/cli/generators/gem/app/context.erb
292
294
  - lib/hanami/cli/generators/gem/app/dev
293
295
  - lib/hanami/cli/generators/gem/app/env.erb
294
296
  - lib/hanami/cli/generators/gem/app/favicon.ico
@@ -307,6 +309,7 @@ files:
307
309
  - lib/hanami/cli/generators/gem/app/routes.erb
308
310
  - lib/hanami/cli/generators/gem/app/seeds.erb
309
311
  - lib/hanami/cli/generators/gem/app/settings.erb
312
+ - lib/hanami/cli/generators/gem/app/setup.erb
310
313
  - lib/hanami/cli/generators/gem/app/struct.erb
311
314
  - lib/hanami/cli/generators/gem/app/types.erb
312
315
  - lib/hanami/cli/generators/gem/app/validator.erb
@@ -326,7 +329,9 @@ files:
326
329
  - lib/hanami/cli/version.rb
327
330
  - lib/hanami/console/context.rb
328
331
  - lib/hanami/console/plugins/slice_readers.rb
332
+ - lib/hanami/console/plugins/unbooted_slice_warnings.rb
329
333
  - project.yml
334
+ - script/ci
330
335
  homepage: https://hanamirb.org
331
336
  licenses:
332
337
  - MIT