hanami-cli 2.1.0.beta1 → 2.1.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/Gemfile +5 -2
- data/hanami-cli.gemspec +1 -1
- data/lib/hanami/cli/bundler.rb +19 -5
- data/lib/hanami/cli/command.rb +4 -4
- data/lib/hanami/cli/commands/app/assets/command.rb +69 -0
- data/lib/hanami/cli/commands/app/assets/compile.rb +32 -0
- data/lib/hanami/cli/commands/app/assets/watch.rb +32 -0
- data/lib/hanami/cli/commands/app/assets.rb +16 -0
- data/lib/hanami/cli/commands/app/command.rb +2 -2
- data/lib/hanami/cli/commands/app/dev.rb +45 -0
- data/lib/hanami/cli/commands/app/generate/action.rb +3 -2
- data/lib/hanami/cli/commands/app/generate/part.rb +49 -0
- data/lib/hanami/cli/commands/app/install.rb +16 -1
- data/lib/hanami/cli/commands/app.rb +9 -0
- data/lib/hanami/cli/commands/gem/new.rb +57 -7
- data/lib/hanami/cli/errors.rb +30 -0
- data/lib/hanami/cli/files.rb +8 -2
- data/lib/hanami/cli/generators/app/action/action.erb +5 -1
- data/lib/hanami/cli/generators/app/action/slice_action.erb +5 -1
- data/lib/hanami/cli/generators/app/action.rb +49 -12
- data/lib/hanami/cli/generators/app/part/app_base_part.erb +9 -0
- data/lib/hanami/cli/generators/app/part/app_part.erb +13 -0
- data/lib/hanami/cli/generators/app/part/slice_base_part.erb +9 -0
- data/lib/hanami/cli/generators/app/part/slice_part.erb +13 -0
- data/lib/hanami/cli/generators/app/part.rb +101 -0
- data/lib/hanami/cli/generators/app/part_context.rb +98 -0
- data/lib/hanami/cli/generators/app/slice/app_css.erb +5 -0
- data/lib/hanami/cli/generators/app/slice/app_js.erb +1 -0
- data/lib/hanami/cli/generators/app/slice/app_layout.erb +18 -0
- data/lib/hanami/cli/generators/app/slice.rb +9 -3
- data/lib/hanami/cli/generators/app/slice_context.rb +18 -0
- data/lib/hanami/cli/generators/context.rb +70 -3
- data/lib/hanami/cli/generators/gem/app/404.html +76 -5
- data/lib/hanami/cli/generators/gem/app/500.html +76 -5
- data/lib/hanami/cli/generators/gem/app/app_css.erb +5 -0
- data/lib/hanami/cli/generators/gem/app/app_js.erb +1 -0
- data/lib/hanami/cli/generators/gem/app/app_layout.erb +18 -0
- data/lib/hanami/cli/generators/gem/app/assets.mjs +14 -0
- data/lib/hanami/cli/generators/gem/app/dev +8 -0
- data/lib/hanami/cli/generators/gem/app/favicon.ico +0 -0
- data/lib/hanami/cli/generators/gem/app/gemfile.erb +14 -8
- data/lib/hanami/cli/generators/gem/app/gitignore.erb +4 -0
- data/lib/hanami/cli/generators/gem/app/package.json.erb +10 -0
- data/lib/hanami/cli/generators/gem/app/procfile.erb +4 -0
- data/lib/hanami/cli/generators/gem/app/puma.erb +37 -7
- data/lib/hanami/cli/generators/gem/app/routes.erb +1 -1
- data/lib/hanami/cli/generators/gem/app.rb +21 -4
- data/lib/hanami/cli/generators/version.rb +12 -0
- data/lib/hanami/cli/interactive_system_call.rb +64 -0
- data/lib/hanami/cli/system_call.rb +8 -2
- data/lib/hanami/cli/version.rb +1 -1
- metadata +28 -6
- data/lib/hanami/cli/generators/app/slice/layouts_app.html.erb +0 -1
- data/lib/hanami/cli/generators/gem/app/layouts_app.html.erb +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz: '
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '054178514bf7e420e00cd8da8a148cd4d479609668c180507fadbcd7a086f15d'
|
|
4
|
+
data.tar.gz: 3ef8c388ad8c8734179ce042d3eb966dea6df881b72e7615f0b104a1890106a5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c8e1abc0ded22d56ee2acd5dec6d9f7079c0331d187b1d4ff4b26858faf50ff870016e1adfa6b785673d39b6d0dcf097dca7c1b0526da442e1939ce0952f3799
|
|
7
|
+
data.tar.gz: 8ecc3ceefc10856cbd2f60ec24bd1ecde442764610dbb7d179f064080ac434fa4829374efb05513c67420ab8b76b0280ad594fd566824fdfba0e8d14afc209fb
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
Hanami Command Line Interface
|
|
4
4
|
|
|
5
|
+
## v2.1.0.rc1 - 2023-11-01
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- [Tim Riley] `hanami new` to generate `bin/dev` as configuration for `hanami dev`
|
|
10
|
+
- [Luca Guidi] Introducing `hanami generate part` to generate view parts
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- [Luca Guidi] `hanami new` generates a fully documented Puma configuration in `config/puma.rb`
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- [Tim Riley] `hanami new` generates a `config/assets.mjs` as Assets configuration
|
|
19
|
+
- [Tim Riley] `hanami new` generates a leaner `package.json`
|
|
20
|
+
- [Tim Riley] `hanami new` doesn't generate a default root route anymore
|
|
21
|
+
- [Aaron Moodie & Tim Riley] `hanami new` to generate a redesigned 404 and 500 error pages
|
|
22
|
+
- [Luca Guidi] When generating a RESTful action, skip `create`, if `new` is present, and `update`, if `edit` is present
|
|
23
|
+
|
|
24
|
+
## v2.1.0.beta2 - 2023-10-04
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- [Luca Guidi] `hanami new` generates `Procfile.dev`
|
|
29
|
+
- [Luca Guidi] `hanami new` generates basic app assets, if `hanami-assets` is bundled by the app
|
|
30
|
+
- [Luca Guidi] `hanami new` accepts `--head` to generate the app using Hanami HEAD version from GitHub
|
|
31
|
+
- [Luca Guidi] `hanami generate slice` generates basic slice assets, if `hanami-assets` is bundled by the app
|
|
32
|
+
- [Ryan Bigg] `hanami generate action` generates corresponding view, if `hanami-view` is bundled by the app
|
|
33
|
+
- [Luca Guidi] `hanami assets compile` to compile assets at the deploy time
|
|
34
|
+
- [Luca Guidi] `hanami assets watch` to watch and compile assets at the development time
|
|
35
|
+
- [Luca Guidi] `hanami dev` to start the processes in `Procfile.dev`
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- [Luca Guidi] `hanami new` generates a `Gemfile` with `hanami-webconsole` in `:development` group
|
|
40
|
+
- [Luca Guidi] `hanami new` generates a `Gemfile` with versioned `hanami-webconsole`, `hanami-rspec`, and `hanami-reloader`
|
|
41
|
+
|
|
5
42
|
## v2.1.0.beta1 - 2023-06-29
|
|
6
43
|
|
|
7
44
|
### Added
|
data/Gemfile
CHANGED
|
@@ -10,9 +10,12 @@ unless ENV["CI"]
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
gem "hanami", github: "hanami/hanami", branch: "main"
|
|
13
|
-
gem "hanami-
|
|
14
|
-
gem "hanami-router", github: "hanami/router", branch: "main"
|
|
13
|
+
gem "hanami-assets", github: "hanami/assets", branch: "main"
|
|
15
14
|
gem "hanami-controller", github: "hanami/controller", branch: "main"
|
|
15
|
+
gem "hanami-router", github: "hanami/router", branch: "main"
|
|
16
|
+
gem "hanami-utils", github: "hanami/utils", branch: "main"
|
|
17
|
+
|
|
18
|
+
gem "dry-files", github: "dry-rb/dry-files", branch: "main"
|
|
16
19
|
|
|
17
20
|
gem "rack"
|
|
18
21
|
|
data/hanami-cli.gemspec
CHANGED
|
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
|
32
32
|
|
|
33
33
|
spec.add_dependency "bundler", "~> 2.1"
|
|
34
34
|
spec.add_dependency "dry-cli", "~> 1.0", "< 2"
|
|
35
|
-
spec.add_dependency "dry-files", "~> 1.0", ">= 1.0.
|
|
35
|
+
spec.add_dependency "dry-files", "~> 1.0", ">= 1.0.2", "< 2"
|
|
36
36
|
spec.add_dependency "dry-inflector", "~> 1.0", "< 2"
|
|
37
37
|
spec.add_dependency "rake", "~> 13.0"
|
|
38
38
|
spec.add_dependency "zeitwerk", "~> 2.6"
|
data/lib/hanami/cli/bundler.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require "bundler"
|
|
4
4
|
require "open3"
|
|
5
5
|
require "etc"
|
|
6
|
-
|
|
6
|
+
require_relative "files"
|
|
7
7
|
require_relative "system_call"
|
|
8
8
|
require_relative "errors"
|
|
9
9
|
|
|
@@ -45,12 +45,12 @@ module Hanami
|
|
|
45
45
|
|
|
46
46
|
# Returns a new bundler.
|
|
47
47
|
#
|
|
48
|
-
# @param fs [
|
|
48
|
+
# @param fs [Hanami::CLI::Files] the filesystem interaction object
|
|
49
49
|
# @param system_call [SystemCall] convenience object for making system calls
|
|
50
50
|
#
|
|
51
51
|
# @since 2.0.0
|
|
52
52
|
# @api public
|
|
53
|
-
def initialize(fs:
|
|
53
|
+
def initialize(fs: Hanami::CLI::Files.new, system_call: SystemCall.new)
|
|
54
54
|
@fs = fs
|
|
55
55
|
@system_call = system_call
|
|
56
56
|
end
|
|
@@ -71,7 +71,7 @@ module Hanami
|
|
|
71
71
|
#
|
|
72
72
|
# @return [SystemCall::Result] the result of the `bundle` command execution
|
|
73
73
|
#
|
|
74
|
-
# @raise [
|
|
74
|
+
# @raise [Hanami::CLI::BundleInstallError] if the `bundle` command does not execute successfully
|
|
75
75
|
#
|
|
76
76
|
# @since 2.0.0
|
|
77
77
|
# @api public
|
|
@@ -81,6 +81,20 @@ module Hanami
|
|
|
81
81
|
end
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
+
# Runs the given Hanami CLI command via `bundle exec hanami`
|
|
85
|
+
#
|
|
86
|
+
# @return [SystemCall::Result] the result of the command execution
|
|
87
|
+
#
|
|
88
|
+
# @raise [Hanami::CLI::HanamiExecError] if the does not execute successfully
|
|
89
|
+
#
|
|
90
|
+
# @since 2.1.0
|
|
91
|
+
# @api public
|
|
92
|
+
def hanami_exec(cmd, env: nil, &blk)
|
|
93
|
+
exec("hanami #{cmd}", env: env, &blk).tap do |result|
|
|
94
|
+
raise HanamiExecError.new(cmd, result.err) unless result.successful?
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
84
98
|
# Executes the given command prefixed by `bundle exec`.
|
|
85
99
|
#
|
|
86
100
|
# @return [SystemCall::Result] the result of the command execution
|
|
@@ -127,7 +141,7 @@ module Hanami
|
|
|
127
141
|
|
|
128
142
|
private
|
|
129
143
|
|
|
130
|
-
# @return [
|
|
144
|
+
# @return [Hanami::CLI::Files]
|
|
131
145
|
#
|
|
132
146
|
# @since 2.0.0
|
|
133
147
|
# @api public
|
data/lib/hanami/cli/command.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "dry/cli"
|
|
4
|
-
require "dry/files"
|
|
5
4
|
require "dry/inflector"
|
|
5
|
+
require_relative "files"
|
|
6
6
|
|
|
7
7
|
module Hanami
|
|
8
8
|
module CLI
|
|
@@ -19,12 +19,12 @@ module Hanami
|
|
|
19
19
|
#
|
|
20
20
|
# @param out [IO] I/O stream for standard command output
|
|
21
21
|
# @param err [IO] I/O stream for comment errror output
|
|
22
|
-
# @param fs [
|
|
22
|
+
# @param fs [Hanami::CLI::Files] object for managing file system interactions
|
|
23
23
|
# @param inflector [Dry::Inflector] inflector for any command-level inflections
|
|
24
24
|
#
|
|
25
25
|
# @since 2.0.0
|
|
26
26
|
# @api public
|
|
27
|
-
def initialize(out: $stdout, err: $stderr, fs:
|
|
27
|
+
def initialize(out: $stdout, err: $stderr, fs: Hanami::CLI::Files.new, inflector: Dry::Inflector.new)
|
|
28
28
|
super()
|
|
29
29
|
@out = out
|
|
30
30
|
@err = err
|
|
@@ -52,7 +52,7 @@ module Hanami
|
|
|
52
52
|
|
|
53
53
|
# Returns the object for managing file system interactions.
|
|
54
54
|
#
|
|
55
|
-
# @return [
|
|
55
|
+
# @return [Hanami::CLI::Files]
|
|
56
56
|
#
|
|
57
57
|
# @since 2.0.0
|
|
58
58
|
# @api public
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "shellwords"
|
|
4
|
+
require_relative "../command"
|
|
5
|
+
require_relative "../../../system_call"
|
|
6
|
+
|
|
7
|
+
module Hanami
|
|
8
|
+
module CLI
|
|
9
|
+
module Commands
|
|
10
|
+
module App
|
|
11
|
+
module Assets
|
|
12
|
+
# @since 2.1.0
|
|
13
|
+
# @api private
|
|
14
|
+
class Command < App::Command
|
|
15
|
+
def initialize(config: app.config.assets, system_call: SystemCall.new, **)
|
|
16
|
+
super()
|
|
17
|
+
@system_call = system_call
|
|
18
|
+
@config = config
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @since 2.1.0
|
|
22
|
+
# @api private
|
|
23
|
+
def call(**)
|
|
24
|
+
cmd, *args = cmd_with_args
|
|
25
|
+
|
|
26
|
+
system_call.call(cmd, *args)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
# @since 2.1.0
|
|
32
|
+
# @api private
|
|
33
|
+
attr_reader :config
|
|
34
|
+
|
|
35
|
+
# @since 2.1.0
|
|
36
|
+
# @api private
|
|
37
|
+
attr_reader :system_call
|
|
38
|
+
|
|
39
|
+
# @since 2.1.0
|
|
40
|
+
# @api private
|
|
41
|
+
def cmd_with_args
|
|
42
|
+
[config.package_manager_run_command, "assets"]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @since 2.1.0
|
|
46
|
+
# @api private
|
|
47
|
+
def entry_points
|
|
48
|
+
config.entry_points.map do |entry_point|
|
|
49
|
+
escape(entry_point)
|
|
50
|
+
end.join(" ")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @since 2.1.0
|
|
54
|
+
# @api private
|
|
55
|
+
def destination
|
|
56
|
+
escape(config.destination)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @since 2.1.0
|
|
60
|
+
# @api private
|
|
61
|
+
def escape(str)
|
|
62
|
+
Shellwords.shellescape(str)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "command"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
module App
|
|
9
|
+
module Assets
|
|
10
|
+
# @since 2.1.0
|
|
11
|
+
# @api private
|
|
12
|
+
class Compile < Assets::Command
|
|
13
|
+
desc "Compile assets for deployments"
|
|
14
|
+
|
|
15
|
+
# @since 2.1.0
|
|
16
|
+
# @api private
|
|
17
|
+
def cmd_with_args
|
|
18
|
+
result = super
|
|
19
|
+
|
|
20
|
+
if config.subresource_integrity.any?
|
|
21
|
+
result << "--"
|
|
22
|
+
result << "--sri=#{config.subresource_integrity.join(',')}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
result
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "command"
|
|
4
|
+
require_relative "../../../interactive_system_call"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
module CLI
|
|
8
|
+
module Commands
|
|
9
|
+
module App
|
|
10
|
+
module Assets
|
|
11
|
+
# @since 2.1.0
|
|
12
|
+
# @api private
|
|
13
|
+
class Watch < Assets::Command
|
|
14
|
+
desc "Start assets watch mode"
|
|
15
|
+
|
|
16
|
+
def initialize(config: app.config.assets, system_call: InteractiveSystemCall.new, **)
|
|
17
|
+
super(config: config, system_call: system_call)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
# @since 2.1.0
|
|
23
|
+
# @api private
|
|
24
|
+
def cmd_with_args
|
|
25
|
+
super + ["--", "--watch"]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "dry/files"
|
|
4
3
|
require "hanami/env"
|
|
5
4
|
require_relative "db/utils/database"
|
|
5
|
+
require_relative "../../files"
|
|
6
6
|
|
|
7
7
|
module Hanami
|
|
8
8
|
module CLI
|
|
@@ -75,7 +75,7 @@ module Hanami
|
|
|
75
75
|
klass.new(
|
|
76
76
|
out: out,
|
|
77
77
|
inflector: app.inflector,
|
|
78
|
-
fs:
|
|
78
|
+
fs: Hanami::CLI::Files,
|
|
79
79
|
).call(*args)
|
|
80
80
|
end
|
|
81
81
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../interactive_system_call"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
module App
|
|
9
|
+
# @since 2.1.0
|
|
10
|
+
# @api private
|
|
11
|
+
class Dev < App::Command
|
|
12
|
+
# @since 2.1.0
|
|
13
|
+
# @api private
|
|
14
|
+
desc "Start the application in development mode"
|
|
15
|
+
|
|
16
|
+
# @since 2.1.0
|
|
17
|
+
# @api private
|
|
18
|
+
def initialize(interactive_system_call: InteractiveSystemCall.new, **)
|
|
19
|
+
@interactive_system_call = interactive_system_call
|
|
20
|
+
super()
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @since 2.1.0
|
|
24
|
+
# @api private
|
|
25
|
+
def call(**)
|
|
26
|
+
bin, args = executable
|
|
27
|
+
interactive_system_call.call(bin, *args)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# @since 2.1.0
|
|
33
|
+
# @api private
|
|
34
|
+
attr_reader :interactive_system_call
|
|
35
|
+
|
|
36
|
+
# @since 2.1.0
|
|
37
|
+
# @api private
|
|
38
|
+
def executable
|
|
39
|
+
[::File.join("bin", "dev")]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -60,7 +60,8 @@ module Hanami
|
|
|
60
60
|
|
|
61
61
|
# @since 2.0.0
|
|
62
62
|
# @api private
|
|
63
|
-
def call(name:, url: nil, http: nil, format: DEFAULT_FORMAT, skip_view: DEFAULT_SKIP_VIEW, slice: nil,
|
|
63
|
+
def call(name:, url: nil, http: nil, format: DEFAULT_FORMAT, skip_view: DEFAULT_SKIP_VIEW, slice: nil,
|
|
64
|
+
context: nil, **)
|
|
64
65
|
slice = inflector.underscore(Shellwords.shellescape(slice)) if slice
|
|
65
66
|
name = naming.action_name(name)
|
|
66
67
|
*controller, action = name.split(ACTION_SEPARATOR)
|
|
@@ -69,7 +70,7 @@ module Hanami
|
|
|
69
70
|
raise InvalidActionNameError.new(name)
|
|
70
71
|
end
|
|
71
72
|
|
|
72
|
-
generator.call(app.namespace, controller, action, url, http, format, skip_view, slice)
|
|
73
|
+
generator.call(app.namespace, controller, action, url, http, format, skip_view, slice, context: context)
|
|
73
74
|
end
|
|
74
75
|
|
|
75
76
|
# rubocop:enable Metrics/ParameterLists
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/inflector"
|
|
4
|
+
require "dry/files"
|
|
5
|
+
require "shellwords"
|
|
6
|
+
|
|
7
|
+
module Hanami
|
|
8
|
+
module CLI
|
|
9
|
+
module Commands
|
|
10
|
+
module App
|
|
11
|
+
module Generate
|
|
12
|
+
# @since 2.1.0
|
|
13
|
+
# @api private
|
|
14
|
+
class Part < App::Command
|
|
15
|
+
argument :name, required: true, desc: "Part name"
|
|
16
|
+
option :slice, required: false, desc: "Slice name"
|
|
17
|
+
|
|
18
|
+
example [
|
|
19
|
+
%(book (MyApp::Views::Parts::Book)),
|
|
20
|
+
%(book --slice=admin (Admin::Views::Parts::Book)),
|
|
21
|
+
]
|
|
22
|
+
attr_reader :generator
|
|
23
|
+
private :generator
|
|
24
|
+
|
|
25
|
+
# @since 2.0.0
|
|
26
|
+
# @api private
|
|
27
|
+
def initialize(
|
|
28
|
+
fs: Hanami::CLI::Files.new,
|
|
29
|
+
inflector: Dry::Inflector.new,
|
|
30
|
+
generator: Generators::App::Part.new(fs: fs, inflector: inflector),
|
|
31
|
+
**
|
|
32
|
+
)
|
|
33
|
+
@generator = generator
|
|
34
|
+
super(fs: fs)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @since 2.0.0
|
|
38
|
+
# @api private
|
|
39
|
+
def call(name:, slice: nil, **)
|
|
40
|
+
slice = inflector.underscore(Shellwords.shellescape(slice)) if slice
|
|
41
|
+
|
|
42
|
+
generator.call(app.namespace, name, slice)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../../system_call"
|
|
4
|
+
|
|
3
5
|
module Hanami
|
|
4
6
|
module CLI
|
|
5
7
|
module Commands
|
|
@@ -18,9 +20,22 @@ module Hanami
|
|
|
18
20
|
# @since 2.0.0
|
|
19
21
|
# @api private
|
|
20
22
|
class Install < Command
|
|
23
|
+
# @since 2.1.0
|
|
24
|
+
# @api private
|
|
25
|
+
DEFAULT_HEAD = false
|
|
26
|
+
private_constant :DEFAULT_HEAD
|
|
27
|
+
|
|
28
|
+
# @since 2.1.0
|
|
29
|
+
# @api private
|
|
21
30
|
desc "Install Hanami third-party plugins"
|
|
22
31
|
|
|
23
|
-
|
|
32
|
+
# @since 2.1.0
|
|
33
|
+
# @api private
|
|
34
|
+
option :head, type: :boolean, desc: "Install head deps", default: DEFAULT_HEAD
|
|
35
|
+
|
|
36
|
+
# @since 2.0.0
|
|
37
|
+
# @api private
|
|
38
|
+
def call(head: DEFAULT_HEAD, **)
|
|
24
39
|
end
|
|
25
40
|
end
|
|
26
41
|
end
|
|
@@ -14,15 +14,24 @@ module Hanami
|
|
|
14
14
|
base.module_eval do
|
|
15
15
|
register "version", Commands::App::Version, aliases: ["v", "-v", "--version"]
|
|
16
16
|
register "install", Commands::App::Install
|
|
17
|
+
register "dev", Commands::App::Dev
|
|
17
18
|
register "console", Commands::App::Console, aliases: ["c"]
|
|
18
19
|
register "server", Commands::App::Server, aliases: ["s"]
|
|
19
20
|
register "routes", Commands::App::Routes
|
|
20
21
|
register "middleware", Commands::App::Middleware
|
|
21
22
|
|
|
23
|
+
if Hanami.bundled?("hanami-assets")
|
|
24
|
+
register "assets" do |prefix|
|
|
25
|
+
prefix.register "compile", Assets::Compile
|
|
26
|
+
prefix.register "watch", Assets::Watch
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
22
30
|
register "generate", aliases: ["g"] do |prefix|
|
|
23
31
|
prefix.register "slice", Generate::Slice
|
|
24
32
|
prefix.register "action", Generate::Action
|
|
25
33
|
prefix.register "view", Generate::View
|
|
34
|
+
prefix.register "part", Generate::Part
|
|
26
35
|
end
|
|
27
36
|
end
|
|
28
37
|
end
|
|
@@ -10,21 +10,55 @@ 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
|
|
13
15
|
SKIP_INSTALL_DEFAULT = false
|
|
14
16
|
private_constant :SKIP_INSTALL_DEFAULT
|
|
15
17
|
|
|
18
|
+
# @since 2.1.0
|
|
19
|
+
# @api private
|
|
20
|
+
HEAD_DEFAULT = false
|
|
21
|
+
private_constant :HEAD_DEFAULT
|
|
22
|
+
|
|
23
|
+
# @since 2.1.0
|
|
24
|
+
# @api private
|
|
25
|
+
SKIP_ASSETS_DEFAULT = false
|
|
26
|
+
private_constant :SKIP_ASSETS_DEFAULT
|
|
27
|
+
|
|
16
28
|
desc "Generate a new Hanami app"
|
|
17
29
|
|
|
30
|
+
# @since 2.0.0
|
|
31
|
+
# @api private
|
|
18
32
|
argument :app, required: true, desc: "App name"
|
|
19
33
|
|
|
34
|
+
# @since 2.0.0
|
|
35
|
+
# @api private
|
|
20
36
|
option :skip_install, type: :boolean, required: false,
|
|
21
37
|
default: SKIP_INSTALL_DEFAULT,
|
|
22
38
|
desc: "Skip app installation (Bundler, third-party Hanami plugins)"
|
|
23
39
|
|
|
40
|
+
# @since 2.1.0
|
|
41
|
+
# @api private
|
|
42
|
+
option :head, type: :boolean, required: false,
|
|
43
|
+
default: HEAD_DEFAULT,
|
|
44
|
+
desc: "Use Hanami HEAD version (from GitHub `main` branches)"
|
|
45
|
+
|
|
46
|
+
# @since 2.1.0
|
|
47
|
+
# @api private
|
|
48
|
+
option :skip_assets, type: :boolean, required: false,
|
|
49
|
+
default: SKIP_ASSETS_DEFAULT,
|
|
50
|
+
desc: "Skip assets"
|
|
51
|
+
|
|
52
|
+
# rubocop:disable Layout/LineLength
|
|
24
53
|
example [
|
|
25
|
-
"bookshelf # Generate a new Hanami app in `bookshelf/' directory, using `Bookshelf' namespace",
|
|
26
|
-
"bookshelf --
|
|
54
|
+
"bookshelf # Generate a new Hanami app in `bookshelf/' directory, using `Bookshelf' namespace",
|
|
55
|
+
"bookshelf --head # Generate a new Hanami app, using Hanami HEAD version from GitHub `main' branches",
|
|
56
|
+
"bookshelf --skip-install # Generate a new Hanami app, but it skips Hanami installation",
|
|
57
|
+
"bookshelf --skip-assets # Generate a new Hanami app without assets"
|
|
27
58
|
]
|
|
59
|
+
# rubocop:enable Layout/LineLength
|
|
60
|
+
|
|
61
|
+
# rubocop:disable Metrics/ParameterLists
|
|
28
62
|
|
|
29
63
|
# @since 2.0.0
|
|
30
64
|
# @api private
|
|
@@ -33,42 +67,58 @@ module Hanami
|
|
|
33
67
|
inflector: Dry::Inflector.new,
|
|
34
68
|
bundler: CLI::Bundler.new(fs: fs),
|
|
35
69
|
generator: Generators::Gem::App.new(fs: fs, inflector: inflector),
|
|
70
|
+
system_call: SystemCall.new,
|
|
36
71
|
**other
|
|
37
72
|
)
|
|
38
73
|
@bundler = bundler
|
|
39
74
|
@generator = generator
|
|
75
|
+
@system_call = system_call
|
|
40
76
|
super(fs: fs, inflector: inflector, **other)
|
|
41
77
|
end
|
|
42
78
|
|
|
79
|
+
# rubocop:enable Metrics/ParameterLists
|
|
80
|
+
|
|
81
|
+
# rubocop:disable Metrics/AbcSize
|
|
82
|
+
|
|
43
83
|
# @since 2.0.0
|
|
44
84
|
# @api private
|
|
45
|
-
def call(app:, skip_install: SKIP_INSTALL_DEFAULT, **)
|
|
85
|
+
def call(app:, head: HEAD_DEFAULT, skip_install: SKIP_INSTALL_DEFAULT, skip_assets: SKIP_ASSETS_DEFAULT, **)
|
|
46
86
|
app = inflector.underscore(app)
|
|
47
87
|
|
|
48
88
|
raise PathAlreadyExistsError.new(app) if fs.exist?(app)
|
|
49
89
|
|
|
50
90
|
fs.mkdir(app)
|
|
51
91
|
fs.chdir(app) do
|
|
52
|
-
|
|
92
|
+
context = Generators::Context.new(inflector, app, head: head, skip_assets: skip_assets)
|
|
93
|
+
generator.call(app, context: context) do
|
|
53
94
|
if skip_install
|
|
54
95
|
out.puts "Skipping installation, please enter `#{app}' directory and run `bundle exec hanami install'"
|
|
55
96
|
else
|
|
56
97
|
out.puts "Running Bundler install..."
|
|
57
98
|
bundler.install!
|
|
99
|
+
|
|
100
|
+
unless skip_assets
|
|
101
|
+
out.puts "Running npm install..."
|
|
102
|
+
system_call.call("npm", ["install"])
|
|
103
|
+
end
|
|
104
|
+
|
|
58
105
|
out.puts "Running Hanami install..."
|
|
59
|
-
run_install_commmand!
|
|
106
|
+
run_install_commmand!(head: head)
|
|
60
107
|
end
|
|
61
108
|
end
|
|
62
109
|
end
|
|
63
110
|
end
|
|
111
|
+
# rubocop:enable Metrics/AbcSize
|
|
64
112
|
|
|
65
113
|
private
|
|
66
114
|
|
|
67
115
|
attr_reader :bundler
|
|
68
116
|
attr_reader :generator
|
|
117
|
+
attr_reader :system_call
|
|
69
118
|
|
|
70
|
-
def run_install_commmand!
|
|
71
|
-
|
|
119
|
+
def run_install_commmand!(head:)
|
|
120
|
+
head_flag = head ? " --head" : ""
|
|
121
|
+
bundler.exec("hanami install#{head_flag}").tap do |result|
|
|
72
122
|
raise HanamiInstallError.new(result.err) unless result.successful?
|
|
73
123
|
end
|
|
74
124
|
end
|