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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +2 -2
- data/.rubocop.yml +2 -0
- data/.rubocop_todo.yml +150 -0
- data/CHANGELOG.md +33 -0
- data/README.md +1 -4
- data/hanami-cli.gemspec +2 -2
- data/lib/hanami/cli/commands/app/command.rb +5 -1
- data/lib/hanami/cli/commands/app/console.rb +10 -1
- data/lib/hanami/cli/commands/app/db/migrate.rb +5 -2
- data/lib/hanami/cli/commands/app/db/rollback.rb +26 -14
- data/lib/hanami/cli/commands/app/db/structure/dump.rb +7 -3
- data/lib/hanami/cli/commands/app/db/utils/database.rb +22 -0
- data/lib/hanami/cli/commands/app/db/utils/mysql.rb +3 -1
- data/lib/hanami/cli/commands/app/db/utils/postgres.rb +16 -3
- data/lib/hanami/cli/commands/app/db/utils/sqlite.rb +1 -1
- data/lib/hanami/cli/commands/app/db/version.rb +2 -0
- data/lib/hanami/cli/commands/app/generate/action.rb +8 -11
- data/lib/hanami/cli/commands/app/generate/slice.rb +8 -8
- data/lib/hanami/cli/commands/gem/new.rb +33 -11
- data/lib/hanami/cli/errors.rb +3 -1
- data/lib/hanami/cli/generators/app/action.rb +1 -1
- data/lib/hanami/cli/generators/app/slice.rb +19 -8
- data/lib/hanami/cli/generators/context.rb +12 -1
- data/lib/hanami/cli/generators/gem/app/context.erb +10 -0
- data/lib/hanami/cli/generators/gem/app/gemfile.erb +3 -2
- data/lib/hanami/cli/generators/gem/app/readme.erb +6 -6
- data/lib/hanami/cli/generators/gem/app/setup.erb +27 -0
- data/lib/hanami/cli/generators/gem/app.rb +4 -0
- data/lib/hanami/cli/generators/version.rb +5 -7
- data/lib/hanami/cli/interactive_system_call.rb +1 -2
- data/lib/hanami/cli/system_call.rb +1 -1
- data/lib/hanami/cli/version.rb +1 -1
- data/lib/hanami/console/context.rb +3 -0
- data/lib/hanami/console/plugins/unbooted_slice_warnings.rb +40 -0
- data/script/ci +31 -0
- metadata +8 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6939575ae1e35a1e103d2d439b73080cb033f837ece81f4652e539dd7cf413fc
|
|
4
|
+
data.tar.gz: 9d94856acc062c3bdc0924a4c7dcfbf4badcd862b7d428a7e0e68e52aac8d46e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5f7d591b5fbf9dd4bcaf1cbc3bf942fa93bb1f90526d05e72c5f21251ec402c9f536059184aab555ee5c80c6d51504f9c61b5a44d119fcc13e48f41149161276
|
|
7
|
+
data.tar.gz: becdd694c75f85bca07452647a67241cd9ca03a8d1095b23dd8e6202f41de41ec693332de1c1b7ea2ee434e7b3e4d9291bcb434adfea84b5d58db7f37b3d7ff0
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: ci
|
|
2
2
|
|
|
3
|
-
|
|
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:
|
|
48
|
+
run: script/ci
|
|
49
49
|
env:
|
|
50
50
|
RACK_VERSION_CONSTRAINT: ${{matrix.rack}}
|
|
51
51
|
services:
|
data/.rubocop.yml
CHANGED
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
|
[](https://badge.fury.io/rb/hanami-cli)
|
|
12
|
-
[](https://github.com/hanami/cli/actions?query=workflow%3Aci+branch%3Amain)
|
|
13
|
-
[](https://depfu.com/github/hanami/cli?project=Bundler)
|
|
12
|
+
[](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 = ["
|
|
9
|
-
spec.email = ["
|
|
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
|
-
|
|
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,
|
|
15
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
36
|
-
|
|
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 --
|
|
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
|
|
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"
|
|
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
|
|
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
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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|
|
data/lib/hanami/cli/errors.rb
CHANGED
|
@@ -47,7 +47,7 @@ module Hanami
|
|
|
47
47
|
# @api public
|
|
48
48
|
class FileAlreadyExistsError < Error
|
|
49
49
|
ERROR_MESSAGE = <<~ERROR.chomp
|
|
50
|
-
The file
|
|
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
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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>#{
|
|
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(
|
|
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?
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
source "
|
|
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
|
|
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
|
|
12
|
+
## Useful links
|
|
12
13
|
|
|
13
|
-
- [Hanami
|
|
14
|
-
- [Hanami
|
|
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.
|
|
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.
|
|
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.
|
|
21
|
+
::Bundler.with_original_env do
|
|
23
22
|
threads = []
|
|
24
23
|
exit_status = 0
|
|
25
24
|
|
data/lib/hanami/cli/version.rb
CHANGED
|
@@ -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.
|
|
4
|
+
version: 2.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
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
|
-
-
|
|
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
|