hanami-cli 2.0.3 → 2.1.0.beta2
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 +33 -0
- data/Gemfile +3 -2
- data/LICENSE.md +1 -1
- data/README.md +1 -1
- data/hanami-cli.gemspec +1 -1
- data/lib/hanami/cli/bundler.rb +21 -7
- data/lib/hanami/cli/command.rb +4 -4
- data/lib/hanami/cli/commands/app/assets/command.rb +82 -0
- data/lib/hanami/cli/commands/app/assets/compile.rb +32 -0
- data/lib/hanami/cli/commands/app/assets/watch.rb +36 -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/db/rollback.rb +30 -6
- data/lib/hanami/cli/commands/app/db/utils/database.rb +5 -1
- data/lib/hanami/cli/commands/app/dev.rb +57 -0
- data/lib/hanami/cli/commands/app/generate/action.rb +5 -4
- data/lib/hanami/cli/commands/app/generate/view.rb +57 -0
- data/lib/hanami/cli/commands/app/generate.rb +2 -2
- data/lib/hanami/cli/commands/app/install.rb +44 -1
- data/lib/hanami/cli/commands/app.rb +9 -0
- data/lib/hanami/cli/commands/gem/new.rb +41 -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/slice_template.html.erb +1 -0
- data/lib/hanami/cli/generators/app/action/slice_view.erb +10 -0
- data/lib/hanami/cli/generators/app/action/template.html.erb +1 -2
- data/lib/hanami/cli/generators/app/action/view.erb +2 -5
- data/lib/hanami/cli/generators/app/action.rb +34 -22
- data/lib/hanami/cli/generators/app/action_context.rb +1 -1
- 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/helpers.erb +10 -0
- data/lib/hanami/cli/generators/app/slice/view.erb +0 -2
- data/lib/hanami/cli/generators/app/slice.rb +15 -6
- data/lib/hanami/cli/generators/app/slice_context.rb +18 -0
- data/lib/hanami/cli/generators/app/view/app_template.html.erb +1 -0
- data/lib/hanami/cli/generators/app/view/app_view.erb +10 -0
- data/lib/hanami/cli/generators/app/view/slice_template.html.erb +1 -0
- data/lib/hanami/cli/generators/app/view/slice_view.erb +10 -0
- data/lib/hanami/cli/generators/app/view.rb +89 -0
- data/lib/hanami/cli/generators/app/view_context.rb +100 -0
- data/lib/hanami/cli/generators/context.rb +53 -4
- data/lib/hanami/cli/generators/gem/app/404.html +11 -0
- data/lib/hanami/cli/generators/gem/app/500.html +11 -0
- 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/favicon.ico +0 -0
- data/lib/hanami/cli/generators/gem/app/gemfile.erb +14 -6
- data/lib/hanami/cli/generators/gem/app/gitignore.erb +4 -0
- data/lib/hanami/cli/generators/gem/app/helpers.erb +10 -0
- data/lib/hanami/cli/generators/gem/app/procfile.erb +4 -0
- data/lib/hanami/cli/generators/gem/app/puma.erb +5 -3
- data/lib/hanami/cli/generators/gem/app/view.erb +9 -0
- data/lib/hanami/cli/generators/gem/app.rb +15 -1
- data/lib/hanami/cli/interactive_system_call.rb +64 -0
- data/lib/hanami/cli/system_call.rb +8 -2
- data/lib/hanami/cli/url.rb +1 -1
- data/lib/hanami/cli/version.rb +1 -1
- metadata +35 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85a528645e9205c15ccdf4b81cc32a3fb0789a8a7f07c56554c1b8b0e66b9e91
|
4
|
+
data.tar.gz: 5937fd333d11a7f5131d0298dc609c8a92e233249bc0b2e9e8f28705977f20b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df19a905d03fec4665ce80dd89730dee6337312e32e0e923e9424a387d66b8f9605e8392a5a73bd4627251b96c57b4a95f4df32062d8a53d42041d69841c10d6
|
7
|
+
data.tar.gz: e4931266c0517de1bb33bc0f862c73da58366d6d5707c0eacf48fd38b08b8d7ae767e8fd7c81f1f048b96ffda5977674e556e281c51ab1f2a4eb30c6ceaa7ade
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,39 @@
|
|
2
2
|
|
3
3
|
Hanami Command Line Interface
|
4
4
|
|
5
|
+
## v2.1.0.beta2 - 2023-10-04
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
- [Luca Guidi] `hanami new` generates `Procfile.dev`
|
10
|
+
- [Luca Guidi] `hanami new` generates basic app assets, if `hanami-assets` is bundled by the app
|
11
|
+
- [Luca Guidi] `hanami new` accepts `--head` to generate the app using Hanami HEAD version from GitHub
|
12
|
+
- [Luca Guidi] `hanami generate slice` generates basic slice assets, if `hanami-assets` is bundled by the app
|
13
|
+
- [Ryan Bigg] `hanami generate action` generates corresponding view, if `hanami-view` is bundled by the app
|
14
|
+
- [Luca Guidi] `hanami assets compile` to compile assets at the deploy time
|
15
|
+
- [Luca Guidi] `hanami assets watch` to watch and compile assets at the development time
|
16
|
+
- [Luca Guidi] `hanami dev` to start the processes in `Procfile.dev`
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
|
20
|
+
- [Luca Guidi] `hanami new` generates a `Gemfile` with `hanami-webconsole` in `:development` group
|
21
|
+
- [Luca Guidi] `hanami new` generates a `Gemfile` with versioned `hanami-webconsole`, `hanami-rspec`, and `hanami-reloader`
|
22
|
+
|
23
|
+
## v2.1.0.beta1 - 2023-06-29
|
24
|
+
|
25
|
+
### Added
|
26
|
+
|
27
|
+
- [Tim Riley] `hanami new` to generate default views, templates, and helpers
|
28
|
+
- [Tim Riley] `hanami generate slice` to generate default views, templates, and helpers
|
29
|
+
- [Tim Riley] `hanami generate action` to generate associated view and template
|
30
|
+
- [Tim Riley] Introduced `hanami generate view`
|
31
|
+
- [Tim Riley] `hanami new` to generate `Gemfile` with `hanami-view` and `hanami-webconsole` gems
|
32
|
+
- [Tim Riley] `hanami new` to generate default error pages for `404` and `500` HTTP errors
|
33
|
+
|
34
|
+
### Fixed
|
35
|
+
|
36
|
+
- [Philip Arndt] `hanami server` to start only one Puma worker by default
|
37
|
+
|
5
38
|
## v2.0.3 - 2023-02-01
|
6
39
|
|
7
40
|
### Added
|
data/Gemfile
CHANGED
@@ -10,9 +10,10 @@ 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"
|
16
17
|
|
17
18
|
gem "rack"
|
18
19
|
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
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,9 +3,9 @@
|
|
3
3
|
require "bundler"
|
4
4
|
require "open3"
|
5
5
|
require "etc"
|
6
|
-
|
7
|
-
require_relative "
|
8
|
-
require_relative "
|
6
|
+
require_relative "files"
|
7
|
+
require_relative "system_call"
|
8
|
+
require_relative "errors"
|
9
9
|
|
10
10
|
module Hanami
|
11
11
|
module CLI
|
@@ -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,82 @@
|
|
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, env: env)
|
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
|
+
[
|
43
|
+
config.package_manager_executable,
|
44
|
+
config.package_manager_command,
|
45
|
+
config.executable
|
46
|
+
]
|
47
|
+
end
|
48
|
+
|
49
|
+
# @since 2.1.0
|
50
|
+
# @api private
|
51
|
+
def env
|
52
|
+
ENV.to_h.merge(
|
53
|
+
"ESBUILD_ENTRY_POINTS" => entry_points,
|
54
|
+
"ESBUILD_OUTDIR" => destination
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @since 2.1.0
|
59
|
+
# @api private
|
60
|
+
def entry_points
|
61
|
+
config.entry_points.map do |entry_point|
|
62
|
+
escape(entry_point)
|
63
|
+
end.join(" ")
|
64
|
+
end
|
65
|
+
|
66
|
+
# @since 2.1.0
|
67
|
+
# @api private
|
68
|
+
def destination
|
69
|
+
escape(config.destination)
|
70
|
+
end
|
71
|
+
|
72
|
+
# @since 2.1.0
|
73
|
+
# @api private
|
74
|
+
def escape(str)
|
75
|
+
Shellwords.shellescape(str)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
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,36 @@
|
|
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 +
|
26
|
+
[
|
27
|
+
"--",
|
28
|
+
"--watch"
|
29
|
+
]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
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
|
|
@@ -20,12 +20,20 @@ module Hanami
|
|
20
20
|
migration_code, migration_name = find_migration(target)
|
21
21
|
|
22
22
|
if migration_name.nil?
|
23
|
-
|
23
|
+
output = if target
|
24
|
+
"==> migration file for target #{target} was not found"
|
25
|
+
else
|
26
|
+
"==> no migrations to rollback"
|
27
|
+
end
|
28
|
+
|
29
|
+
out.puts output
|
24
30
|
return
|
25
31
|
end
|
26
32
|
|
27
33
|
measure "database #{database.name} rolled back to #{migration_name}" do
|
28
34
|
database.run_migrations(target: Integer(migration_code))
|
35
|
+
|
36
|
+
true
|
29
37
|
end
|
30
38
|
|
31
39
|
run_command Structure::Dump if dump
|
@@ -33,14 +41,30 @@ module Hanami
|
|
33
41
|
|
34
42
|
private
|
35
43
|
|
36
|
-
def find_migration(code)
|
37
|
-
|
44
|
+
def find_migration(code) # rubocop:disable Metrics/PerceivedComplexity
|
45
|
+
applied_migrations = database.applied_migrations
|
46
|
+
|
47
|
+
return if applied_migrations.empty?
|
48
|
+
|
49
|
+
# Rollback to initial state if we have only one migration and
|
50
|
+
# no target is specified. In this case the rollback target
|
51
|
+
# will be the current migration timestamp minus 1
|
52
|
+
if applied_migrations.one? && code.nil?
|
53
|
+
migration = applied_migrations.first
|
54
|
+
|
55
|
+
migration_code = Integer(migration.split("_").first) - 1
|
56
|
+
migration_name = "initial state"
|
57
|
+
|
58
|
+
return [migration_code, migration_name]
|
59
|
+
end
|
60
|
+
|
61
|
+
# Otherwise rollback to target or to previous migration
|
62
|
+
migration =
|
38
63
|
if code
|
39
|
-
|
64
|
+
applied_migrations.detect { |m| m.split("_").first == code }
|
40
65
|
else
|
41
|
-
|
66
|
+
applied_migrations[-2]
|
42
67
|
end
|
43
|
-
}
|
44
68
|
|
45
69
|
return unless migration
|
46
70
|
|
@@ -139,7 +139,11 @@ module Hanami
|
|
139
139
|
@sequel_migrator ||= begin
|
140
140
|
require "sequel"
|
141
141
|
Sequel.extension :migration
|
142
|
-
|
142
|
+
|
143
|
+
require "rom/sql"
|
144
|
+
ROM::SQL.with_gateway(gateway) do
|
145
|
+
Sequel::TimestampMigrator.new(migrator.connection, migrations_path, {})
|
146
|
+
end
|
143
147
|
end
|
144
148
|
end
|
145
149
|
|
@@ -0,0 +1,57 @@
|
|
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
|
+
option :procfile, type: :string, desc: "Path to Procfile", aliases: ["-f"]
|
19
|
+
|
20
|
+
# @since 2.1.0
|
21
|
+
# @api private
|
22
|
+
example [
|
23
|
+
"-f /path/to/Procfile",
|
24
|
+
]
|
25
|
+
|
26
|
+
# @since 2.1.0
|
27
|
+
# @api private
|
28
|
+
def initialize(interactive_system_call: InteractiveSystemCall.new, **)
|
29
|
+
@interactive_system_call = interactive_system_call
|
30
|
+
super()
|
31
|
+
end
|
32
|
+
|
33
|
+
# @since 2.1.0
|
34
|
+
# @api private
|
35
|
+
def call(procfile: nil, **)
|
36
|
+
bin, args = executable(procfile: procfile)
|
37
|
+
interactive_system_call.call(bin, *args)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# @since 2.1.0
|
43
|
+
# @api private
|
44
|
+
attr_reader :interactive_system_call
|
45
|
+
|
46
|
+
# @since 2.1.0
|
47
|
+
# @api private
|
48
|
+
def executable(procfile: nil)
|
49
|
+
# TODO: support other implementations of Foreman
|
50
|
+
# See: https://github.com/ddollar/foreman#ports
|
51
|
+
["foreman", ["start", "-f", procfile || "Procfile.dev"]]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -26,8 +26,8 @@ module Hanami
|
|
26
26
|
option :url, required: false, type: :string, desc: "Action URL"
|
27
27
|
option :http, required: false, type: :string, desc: "Action HTTP method"
|
28
28
|
# option :format, required: false, type: :string, default: DEFAULT_FORMAT, desc: "Template format"
|
29
|
-
|
30
|
-
|
29
|
+
option :skip_view, required: false, type: :boolean, default: DEFAULT_SKIP_VIEW,
|
30
|
+
desc: "Skip view and template generation"
|
31
31
|
option :slice, required: false, desc: "Slice name"
|
32
32
|
|
33
33
|
# rubocop:disable Layout/LineLength
|
@@ -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,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/inflector"
|
4
|
+
require "dry/files"
|
5
|
+
require "shellwords"
|
6
|
+
require_relative "../../../naming"
|
7
|
+
require_relative "../../../errors"
|
8
|
+
|
9
|
+
module Hanami
|
10
|
+
module CLI
|
11
|
+
module Commands
|
12
|
+
module App
|
13
|
+
module Generate
|
14
|
+
# @since 2.0.0
|
15
|
+
# @api private
|
16
|
+
class View < App::Command
|
17
|
+
# TODO: make this configurable
|
18
|
+
DEFAULT_FORMAT = "html"
|
19
|
+
private_constant :DEFAULT_FORMAT
|
20
|
+
|
21
|
+
# TODO: make engine configurable
|
22
|
+
|
23
|
+
argument :name, required: true, desc: "View name"
|
24
|
+
option :slice, required: false, desc: "Slice name"
|
25
|
+
|
26
|
+
example [
|
27
|
+
%(books.index (MyApp::Actions::Books::Index)),
|
28
|
+
%(books.index --slice=admin (Admin::Actions::Books::Index)),
|
29
|
+
]
|
30
|
+
attr_reader :generator
|
31
|
+
private :generator
|
32
|
+
|
33
|
+
# @since 2.0.0
|
34
|
+
# @api private
|
35
|
+
def initialize(
|
36
|
+
fs: Hanami::CLI::Files.new,
|
37
|
+
inflector: Dry::Inflector.new,
|
38
|
+
generator: Generators::App::View.new(fs: fs, inflector: inflector),
|
39
|
+
**
|
40
|
+
)
|
41
|
+
@generator = generator
|
42
|
+
super(fs: fs)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @since 2.0.0
|
46
|
+
# @api private
|
47
|
+
def call(name:, format: DEFAULT_FORMAT, slice: nil, **)
|
48
|
+
slice = inflector.underscore(Shellwords.shellescape(slice)) if slice
|
49
|
+
|
50
|
+
generator.call(app.namespace, name, format, slice)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
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,50 @@ 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.1.0
|
37
|
+
# @api private
|
38
|
+
def initialize(system_call: SystemCall.new, **)
|
39
|
+
@system_call = system_call
|
40
|
+
super()
|
41
|
+
end
|
42
|
+
|
43
|
+
# @since 2.0.0
|
44
|
+
# @api private
|
45
|
+
def call(head: DEFAULT_HEAD, **)
|
46
|
+
install_hanami_assets!(head: head)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# @since 2.1.0
|
52
|
+
# @api private
|
53
|
+
attr_reader :system_call
|
54
|
+
|
55
|
+
# @since 2.1.0
|
56
|
+
# @api private
|
57
|
+
def install_hanami_assets!(head:)
|
58
|
+
return unless Hanami.bundled?("hanami-assets")
|
59
|
+
|
60
|
+
system_call.call("npm", ["init", "-y"])
|
61
|
+
|
62
|
+
if head
|
63
|
+
system_call.call("npm", %w[install https://github.com/hanami/assets-js])
|
64
|
+
else
|
65
|
+
system_call.call("npm", %w[install hanami-assets])
|
66
|
+
end
|
24
67
|
end
|
25
68
|
end
|
26
69
|
end
|