hanami-cli 0.2.0 → 2.0.0.alpha2
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 +42 -0
- data/.gitignore +4 -2
- data/.rspec +1 -0
- data/.rubocop.yml +25 -1
- data/CHANGELOG.md +39 -1
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +13 -6
- data/LICENSE.txt +21 -0
- data/README.md +13 -488
- data/Rakefile +8 -15
- data/bin/console +1 -0
- data/exe/hanami +10 -0
- data/hanami-cli.gemspec +24 -18
- data/lib/hanami/cli.rb +10 -121
- data/lib/hanami/cli/bundler.rb +73 -0
- data/lib/hanami/cli/command.rb +16 -355
- data/lib/hanami/cli/command_line.rb +17 -0
- data/lib/hanami/cli/commands.rb +26 -0
- data/lib/hanami/cli/commands/application.rb +63 -0
- data/lib/hanami/cli/commands/db/utils/database.rb +122 -0
- data/lib/hanami/cli/commands/db/utils/database_config.rb +48 -0
- data/lib/hanami/cli/commands/db/utils/mysql.rb +27 -0
- data/lib/hanami/cli/commands/db/utils/postgres.rb +49 -0
- data/lib/hanami/cli/commands/db/utils/sqlite.rb +37 -0
- data/lib/hanami/cli/commands/gem.rb +21 -0
- data/lib/hanami/cli/commands/gem/new.rb +77 -0
- data/lib/hanami/cli/commands/gem/version.rb +18 -0
- data/lib/hanami/cli/commands/monolith.rb +55 -0
- data/lib/hanami/cli/commands/monolith/console.rb +50 -0
- data/lib/hanami/cli/commands/monolith/db/create.rb +25 -0
- data/lib/hanami/cli/commands/monolith/db/create_migration.rb +29 -0
- data/lib/hanami/cli/commands/monolith/db/drop.rb +25 -0
- data/lib/hanami/cli/commands/monolith/db/migrate.rb +40 -0
- data/lib/hanami/cli/commands/monolith/db/reset.rb +26 -0
- data/lib/hanami/cli/commands/monolith/db/rollback.rb +55 -0
- data/lib/hanami/cli/commands/monolith/db/sample_data.rb +40 -0
- data/lib/hanami/cli/commands/monolith/db/seed.rb +40 -0
- data/lib/hanami/cli/commands/monolith/db/setup.rb +24 -0
- data/lib/hanami/cli/commands/monolith/db/structure/dump.rb +25 -0
- data/lib/hanami/cli/commands/monolith/db/version.rb +26 -0
- data/lib/hanami/cli/commands/monolith/generate.rb +14 -0
- data/lib/hanami/cli/commands/monolith/generate/action.rb +62 -0
- data/lib/hanami/cli/commands/monolith/generate/slice.rb +62 -0
- data/lib/hanami/cli/commands/monolith/install.rb +16 -0
- data/lib/hanami/cli/commands/monolith/version.rb +18 -0
- data/lib/hanami/cli/error.rb +8 -0
- data/lib/hanami/cli/generators/context.rb +38 -0
- data/lib/hanami/cli/generators/gem/application.rb +21 -0
- data/lib/hanami/cli/generators/gem/application/monolith.rb +83 -0
- data/lib/hanami/cli/generators/gem/application/monolith/action.erb +21 -0
- data/lib/hanami/cli/generators/gem/application/monolith/application.erb +8 -0
- data/lib/hanami/cli/generators/gem/application/monolith/config_ru.erb +5 -0
- data/lib/hanami/cli/generators/gem/application/monolith/entities.erb +9 -0
- data/lib/hanami/cli/generators/gem/application/monolith/env.erb +0 -0
- data/lib/hanami/cli/generators/gem/application/monolith/functions.erb +13 -0
- data/lib/hanami/cli/generators/gem/application/monolith/gemfile.erb +19 -0
- data/lib/hanami/cli/generators/gem/application/monolith/keep.erb +0 -0
- data/lib/hanami/cli/generators/gem/application/monolith/operation.erb +18 -0
- data/lib/hanami/cli/generators/gem/application/monolith/rakefile.erb +3 -0
- data/lib/hanami/cli/generators/gem/application/monolith/readme.erb +1 -0
- data/lib/hanami/cli/generators/gem/application/monolith/repository.erb +13 -0
- data/lib/hanami/cli/generators/gem/application/monolith/routes.erb +4 -0
- data/lib/hanami/cli/generators/gem/application/monolith/settings.erb +6 -0
- data/lib/hanami/cli/generators/gem/application/monolith/types.erb +10 -0
- data/lib/hanami/cli/generators/gem/application/monolith/validation_contract.erb +14 -0
- data/lib/hanami/cli/generators/gem/application/monolith/view_context.erb +15 -0
- data/lib/hanami/cli/generators/monolith/action.rb +123 -0
- data/lib/hanami/cli/generators/monolith/action/action.erb +13 -0
- data/lib/hanami/cli/generators/monolith/action/template.erb +0 -0
- data/lib/hanami/cli/generators/monolith/action/template.html.erb +2 -0
- data/lib/hanami/cli/generators/monolith/action/view.erb +13 -0
- data/lib/hanami/cli/generators/monolith/action_context.rb +76 -0
- data/lib/hanami/cli/generators/monolith/slice.rb +56 -0
- data/lib/hanami/cli/generators/monolith/slice/action.erb +9 -0
- data/lib/hanami/cli/generators/monolith/slice/entities.erb +9 -0
- data/lib/hanami/cli/generators/monolith/slice/keep.erb +0 -0
- data/lib/hanami/cli/generators/monolith/slice/repository.erb +10 -0
- data/lib/hanami/cli/generators/monolith/slice/routes.erb +2 -0
- data/lib/hanami/cli/generators/monolith/slice/view.erb +9 -0
- data/lib/hanami/cli/generators/monolith/slice_context.rb +33 -0
- data/lib/hanami/cli/repl/core.rb +55 -0
- data/lib/hanami/cli/repl/irb.rb +41 -0
- data/lib/hanami/cli/repl/pry.rb +29 -0
- data/lib/hanami/cli/system_call.rb +51 -0
- data/lib/hanami/cli/url.rb +34 -0
- data/lib/hanami/cli/version.rb +4 -3
- data/lib/hanami/console/context.rb +39 -0
- data/lib/hanami/console/plugins/slice_readers.rb +42 -0
- data/lib/hanami/rake_tasks.rb +52 -0
- metadata +138 -41
- data/.travis.yml +0 -16
- data/lib/hanami/cli/banner.rb +0 -126
- data/lib/hanami/cli/command_registry.rb +0 -213
- data/lib/hanami/cli/errors.rb +0 -32
- data/lib/hanami/cli/option.rb +0 -125
- data/lib/hanami/cli/parser.rb +0 -122
- data/lib/hanami/cli/program_name.rb +0 -19
- data/lib/hanami/cli/registry.rb +0 -328
- data/lib/hanami/cli/usage.rb +0 -88
- data/script/ci +0 -51
data/Rakefile
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
require 'rake/testtask'
|
|
3
|
-
require 'bundler/gem_tasks'
|
|
4
|
-
require 'rspec/core/rake_task'
|
|
1
|
+
# frozen_string_literal: true
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
file_list = FileList['spec/**/*_spec.rb']
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "rspec/core/rake_task"
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
end
|
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
12
7
|
|
|
13
|
-
|
|
14
|
-
ENV['COVERAGE'] = 'true'
|
|
15
|
-
Rake::Task['spec:unit'].invoke
|
|
16
|
-
end
|
|
17
|
-
end
|
|
8
|
+
require "rubocop/rake_task"
|
|
18
9
|
|
|
19
|
-
|
|
10
|
+
RuboCop::RakeTask.new
|
|
11
|
+
|
|
12
|
+
task default: %i[spec rubocop]
|
data/bin/console
CHANGED
data/exe/hanami
ADDED
data/hanami-cli.gemspec
CHANGED
|
@@ -1,34 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
|
|
2
|
-
|
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require 'hanami/cli/version'
|
|
3
|
+
require_relative "lib/hanami/cli/version"
|
|
5
4
|
|
|
6
5
|
Gem::Specification.new do |spec|
|
|
7
6
|
spec.name = "hanami-cli"
|
|
8
7
|
spec.version = Hanami::CLI::VERSION
|
|
9
8
|
spec.authors = ["Luca Guidi"]
|
|
10
9
|
spec.email = ["me@lucaguidi.com"]
|
|
11
|
-
spec.licenses = ["MIT"]
|
|
12
10
|
|
|
13
11
|
spec.summary = "Hanami CLI"
|
|
14
|
-
spec.description = "Hanami
|
|
15
|
-
spec.homepage = "
|
|
12
|
+
spec.description = "Hanami command line"
|
|
13
|
+
spec.homepage = "https://hanamirb.org"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
|
|
16
16
|
|
|
17
|
-
spec.metadata[
|
|
18
|
-
spec.metadata['source_code_uri'] = "https://github.com/hanami/cli"
|
|
17
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
19
18
|
|
|
20
|
-
spec.
|
|
21
|
-
spec.
|
|
22
|
-
spec.
|
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/hanami/cli"
|
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/hanami/cli/blob/master/CHANGELOG.md"
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
25
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
26
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
|
26
27
|
end
|
|
28
|
+
spec.bindir = "exe"
|
|
29
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
30
|
+
spec.require_paths = ["lib"]
|
|
27
31
|
|
|
28
|
-
spec.add_dependency "
|
|
29
|
-
spec.add_dependency "
|
|
32
|
+
spec.add_dependency "bundler", "~> 2.1"
|
|
33
|
+
spec.add_dependency "rake", "~> 13.0"
|
|
34
|
+
spec.add_dependency "dry-cli", "~> 0.6"
|
|
35
|
+
spec.add_dependency "dry-files", "~> 0.1"
|
|
36
|
+
spec.add_dependency "dry-inflector", "~> 0.2"
|
|
30
37
|
|
|
31
|
-
spec.add_development_dependency "
|
|
32
|
-
spec.add_development_dependency "
|
|
33
|
-
spec.add_development_dependency "rspec", "~> 3.7"
|
|
38
|
+
spec.add_development_dependency "rspec", "~> 3.9"
|
|
39
|
+
spec.add_development_dependency "rubocop", "~> 1.11"
|
|
34
40
|
end
|
data/lib/hanami/cli.rb
CHANGED
|
@@ -1,127 +1,16 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
# @since 0.1.0
|
|
4
|
-
module Hanami
|
|
5
|
-
# General purpose Command Line Interface (CLI) framework for Ruby
|
|
6
|
-
#
|
|
7
|
-
# @since 0.1.0
|
|
8
|
-
class CLI
|
|
9
|
-
require "hanami/cli/version"
|
|
10
|
-
require "hanami/cli/errors"
|
|
11
|
-
require "hanami/cli/command"
|
|
12
|
-
require "hanami/cli/registry"
|
|
13
|
-
require "hanami/cli/parser"
|
|
14
|
-
require "hanami/cli/usage"
|
|
15
|
-
require "hanami/cli/banner"
|
|
16
|
-
|
|
17
|
-
# Check if command
|
|
18
|
-
#
|
|
19
|
-
# @param command [Object] the command to check
|
|
20
|
-
#
|
|
21
|
-
# @return [TrueClass,FalseClass] true if instance of `Hanami::CLI::Command`
|
|
22
|
-
#
|
|
23
|
-
# @since 0.1.0
|
|
24
|
-
# @api private
|
|
25
|
-
def self.command?(command)
|
|
26
|
-
case command
|
|
27
|
-
when Class
|
|
28
|
-
command.ancestors.include?(Command)
|
|
29
|
-
else
|
|
30
|
-
command.is_a?(Command)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Create a new instance
|
|
35
|
-
#
|
|
36
|
-
# @param registry [Hanami::CLI::Registry] a registry
|
|
37
|
-
#
|
|
38
|
-
# @return [Hanami::CLI] the new instance
|
|
39
|
-
# @since 0.1.0
|
|
40
|
-
def initialize(registry)
|
|
41
|
-
@commands = registry
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# Invoke the CLI
|
|
45
|
-
#
|
|
46
|
-
# @param arguments [Array<string>] the command line arguments (defaults to `ARGV`)
|
|
47
|
-
# @param out [IO] the standard output (defaults to `$stdout`)
|
|
48
|
-
#
|
|
49
|
-
# @since 0.1.0
|
|
50
|
-
def call(arguments: ARGV, out: $stdout)
|
|
51
|
-
result = commands.get(arguments)
|
|
52
|
-
|
|
53
|
-
if result.found?
|
|
54
|
-
command, args = parse(result, out)
|
|
55
|
-
|
|
56
|
-
result.before_callbacks.run(command, args)
|
|
57
|
-
command.call(args)
|
|
58
|
-
result.after_callbacks.run(command, args)
|
|
59
|
-
else
|
|
60
|
-
usage(result, out)
|
|
61
|
-
end
|
|
62
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
63
2
|
|
|
64
|
-
|
|
3
|
+
require "dry/cli"
|
|
65
4
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
# It may exit in case of error, or in case of help.
|
|
73
|
-
#
|
|
74
|
-
# @param result [Hanami::CLI::CommandRegistry::LookupResult]
|
|
75
|
-
# @param out [IO] sta output
|
|
76
|
-
#
|
|
77
|
-
# @return [Array<Hanami:CLI::Command, Array>] returns an array where the
|
|
78
|
-
# first element is a command and the second one is the list of arguments
|
|
79
|
-
#
|
|
80
|
-
# @since 0.1.0
|
|
81
|
-
# @api private
|
|
82
|
-
def parse(result, out) # rubocop:disable Metrics/MethodLength
|
|
83
|
-
command = result.command
|
|
84
|
-
return [command, result.arguments] unless command?(command)
|
|
85
|
-
|
|
86
|
-
result = Parser.call(command, result.arguments, result.names)
|
|
87
|
-
|
|
88
|
-
if result.help?
|
|
89
|
-
Banner.call(command, out)
|
|
90
|
-
exit(0)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
if result.error?
|
|
94
|
-
out.puts(result.error)
|
|
95
|
-
exit(1)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
[command, result.arguments]
|
|
99
|
-
end
|
|
5
|
+
module Hanami
|
|
6
|
+
module CLI
|
|
7
|
+
require_relative "cli/version"
|
|
8
|
+
require_relative "cli/error"
|
|
9
|
+
require_relative "cli/bundler"
|
|
10
|
+
require_relative "cli/commands"
|
|
100
11
|
|
|
101
|
-
|
|
102
|
-
#
|
|
103
|
-
# @param result [Hanami::CLI::CommandRegistry::LookupResult]
|
|
104
|
-
# @param out [IO] sta output
|
|
105
|
-
#
|
|
106
|
-
# @since 0.1.0
|
|
107
|
-
# @api private
|
|
108
|
-
def usage(result, out)
|
|
109
|
-
Usage.call(result, out)
|
|
110
|
-
exit(1)
|
|
111
|
-
end
|
|
12
|
+
extend Dry::CLI::Registry
|
|
112
13
|
|
|
113
|
-
|
|
114
|
-
#
|
|
115
|
-
# @param command [Object] the command to check
|
|
116
|
-
#
|
|
117
|
-
# @return [TrueClass,FalseClass] true if instance of `Hanami::CLI::Command`
|
|
118
|
-
#
|
|
119
|
-
# @since 0.1.0
|
|
120
|
-
# @api private
|
|
121
|
-
#
|
|
122
|
-
# @see .command?
|
|
123
|
-
def command?(command)
|
|
124
|
-
CLI.command?(command)
|
|
125
|
-
end
|
|
14
|
+
register_commands!
|
|
126
15
|
end
|
|
127
16
|
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler"
|
|
4
|
+
require "open3"
|
|
5
|
+
require "etc"
|
|
6
|
+
require "dry/files"
|
|
7
|
+
require_relative "./system_call"
|
|
8
|
+
|
|
9
|
+
module Hanami
|
|
10
|
+
module CLI
|
|
11
|
+
class Bundler
|
|
12
|
+
BUNDLE_GEMFILE = "BUNDLE_GEMFILE"
|
|
13
|
+
private_constant :BUNDLE_GEMFILE
|
|
14
|
+
|
|
15
|
+
DEFAULT_GEMFILE_PATH = "Gemfile"
|
|
16
|
+
private_constant :DEFAULT_GEMFILE_PATH
|
|
17
|
+
|
|
18
|
+
def self.require(*groups)
|
|
19
|
+
return unless File.exist?(ENV[BUNDLE_GEMFILE] || DEFAULT_GEMFILE_PATH)
|
|
20
|
+
|
|
21
|
+
::Bundler.require(*groups)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(fs: Dry::Files.new, system_call: SystemCall.new)
|
|
25
|
+
@fs = fs
|
|
26
|
+
@system_call = system_call
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def install
|
|
30
|
+
parallelism_level = Etc.nprocessors
|
|
31
|
+
bundle "install --jobs=#{parallelism_level} --quiet --no-color"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def install!
|
|
35
|
+
install.tap do |result|
|
|
36
|
+
raise "Bundle install failed\n\n\n#{result.err.inspect}" unless result.successful?
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def exec(cmd, env: nil, &blk)
|
|
41
|
+
bundle("exec #{cmd}", env: env, &blk)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def bundle(cmd, env: nil, &blk)
|
|
45
|
+
bundle_bin = which("bundle")
|
|
46
|
+
hanami_env = "HANAMI_ENV=#{env} " unless env.nil?
|
|
47
|
+
|
|
48
|
+
system_call.call("#{hanami_env}#{bundle_bin} #{cmd}",
|
|
49
|
+
env: {BUNDLE_GEMFILE => fs.expand_path(DEFAULT_GEMFILE_PATH)}, &blk)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
attr_reader :fs
|
|
55
|
+
|
|
56
|
+
attr_reader :system_call
|
|
57
|
+
|
|
58
|
+
# Adapted from https://stackoverflow.com/a/5471032/498386
|
|
59
|
+
def which(cmd)
|
|
60
|
+
exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
|
|
61
|
+
|
|
62
|
+
ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
|
|
63
|
+
exts.each do |ext|
|
|
64
|
+
exe = fs.join(path, "#{cmd}#{ext}")
|
|
65
|
+
return exe if fs.executable?(exe) && !fs.directory?(exe)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
nil
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
data/lib/hanami/cli/command.rb
CHANGED
|
@@ -1,365 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
require "concurrent/array"
|
|
3
|
-
require "hanami/cli/option"
|
|
1
|
+
# frozen_string_literal: true
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
#
|
|
9
|
-
# @since 0.1.0
|
|
10
|
-
class Command
|
|
11
|
-
# @since 0.1.0
|
|
12
|
-
# @api private
|
|
13
|
-
def self.inherited(base)
|
|
14
|
-
super
|
|
15
|
-
base.extend ClassMethods
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# @since 0.1.0
|
|
19
|
-
# @api private
|
|
20
|
-
module ClassMethods
|
|
21
|
-
# @since 0.1.0
|
|
22
|
-
# @api private
|
|
23
|
-
def self.extended(base)
|
|
24
|
-
super
|
|
25
|
-
|
|
26
|
-
base.class_eval do
|
|
27
|
-
@description = nil
|
|
28
|
-
@examples = Concurrent::Array.new
|
|
29
|
-
@arguments = Concurrent::Array.new
|
|
30
|
-
@options = Concurrent::Array.new
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# @since 0.1.0
|
|
35
|
-
# @api private
|
|
36
|
-
attr_reader :description
|
|
37
|
-
|
|
38
|
-
# @since 0.1.0
|
|
39
|
-
# @api private
|
|
40
|
-
attr_reader :examples
|
|
41
|
-
|
|
42
|
-
# @since 0.1.0
|
|
43
|
-
# @api private
|
|
44
|
-
attr_reader :arguments
|
|
45
|
-
|
|
46
|
-
# @since 0.1.0
|
|
47
|
-
# @api private
|
|
48
|
-
attr_reader :options
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Set the description of the command
|
|
52
|
-
#
|
|
53
|
-
# @param description [String] the description
|
|
54
|
-
#
|
|
55
|
-
# @since 0.1.0
|
|
56
|
-
#
|
|
57
|
-
# @example
|
|
58
|
-
# require "hanami/cli"
|
|
59
|
-
#
|
|
60
|
-
# class Echo < Hanami::CLI::Command
|
|
61
|
-
# desc "Prints given input"
|
|
62
|
-
#
|
|
63
|
-
# def call(*)
|
|
64
|
-
# # ...
|
|
65
|
-
# end
|
|
66
|
-
# end
|
|
67
|
-
def self.desc(description)
|
|
68
|
-
@description = description
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# Describe the usage of the command
|
|
72
|
-
#
|
|
73
|
-
# @param examples [Array<String>] one or more examples
|
|
74
|
-
#
|
|
75
|
-
# @since 0.1.0
|
|
76
|
-
#
|
|
77
|
-
# @example
|
|
78
|
-
# require "hanami/cli"
|
|
79
|
-
#
|
|
80
|
-
# class Server < Hanami::CLI::Command
|
|
81
|
-
# example [
|
|
82
|
-
# " # Basic usage (it uses the bundled server engine)",
|
|
83
|
-
# "--server=webrick # Force `webrick` server engine",
|
|
84
|
-
# "--host=0.0.0.0 # Bind to a host",
|
|
85
|
-
# "--port=2306 # Bind to a port",
|
|
86
|
-
# "--no-code-reloading # Disable code reloading"
|
|
87
|
-
# ]
|
|
88
|
-
#
|
|
89
|
-
# def call(*)
|
|
90
|
-
# # ...
|
|
91
|
-
# end
|
|
92
|
-
# end
|
|
93
|
-
#
|
|
94
|
-
# # $ foo server --help
|
|
95
|
-
# # # ...
|
|
96
|
-
# #
|
|
97
|
-
# # Examples:
|
|
98
|
-
# # foo server # Basic usage (it uses the bundled server engine)
|
|
99
|
-
# # foo server --server=webrick # Force `webrick` server engine
|
|
100
|
-
# # foo server --host=0.0.0.0 # Bind to a host
|
|
101
|
-
# # foo server --port=2306 # Bind to a port
|
|
102
|
-
# # foo server --no-code-reloading # Disable code reloading
|
|
103
|
-
def self.example(*examples)
|
|
104
|
-
@examples += examples.flatten
|
|
105
|
-
end
|
|
3
|
+
require "dry/cli"
|
|
4
|
+
require "dry/files"
|
|
5
|
+
require "dry/inflector"
|
|
106
6
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
# require "hanami/cli"
|
|
116
|
-
#
|
|
117
|
-
# class Hello < Hanami::CLI::Command
|
|
118
|
-
# argument :name
|
|
119
|
-
#
|
|
120
|
-
# def call(name: nil, **)
|
|
121
|
-
# if name.nil?
|
|
122
|
-
# puts "Hello, stranger"
|
|
123
|
-
# else
|
|
124
|
-
# puts "Hello, #{name}"
|
|
125
|
-
# end
|
|
126
|
-
# end
|
|
127
|
-
# end
|
|
128
|
-
#
|
|
129
|
-
# # $ foo hello
|
|
130
|
-
# # Hello, stranger
|
|
131
|
-
#
|
|
132
|
-
# # $ foo hello Luca
|
|
133
|
-
# # Hello, Luca
|
|
134
|
-
#
|
|
135
|
-
# @example Required argument
|
|
136
|
-
# require "hanami/cli"
|
|
137
|
-
#
|
|
138
|
-
# class Hello < Hanami::CLI::Command
|
|
139
|
-
# argument :name, required: true
|
|
140
|
-
#
|
|
141
|
-
# def call(name:, **)
|
|
142
|
-
# puts "Hello, #{name}"
|
|
143
|
-
# end
|
|
144
|
-
# end
|
|
145
|
-
#
|
|
146
|
-
# # $ foo hello Luca
|
|
147
|
-
# # Hello, Luca
|
|
148
|
-
#
|
|
149
|
-
# # $ foo hello
|
|
150
|
-
# # ERROR: "foo hello" was called with no arguments
|
|
151
|
-
# # Usage: "foo hello NAME"
|
|
152
|
-
#
|
|
153
|
-
# @example Multiple arguments
|
|
154
|
-
# require "hanami/cli"
|
|
155
|
-
#
|
|
156
|
-
# module Generate
|
|
157
|
-
# class Action < Hanami::CLI::Command
|
|
158
|
-
# argument :app, required: true
|
|
159
|
-
# argument :action, required: true
|
|
160
|
-
#
|
|
161
|
-
# def call(app:, action:, **)
|
|
162
|
-
# puts "Generating action: #{action} for app: #{app}"
|
|
163
|
-
# end
|
|
164
|
-
# end
|
|
165
|
-
# end
|
|
166
|
-
#
|
|
167
|
-
# # $ foo generate action web home
|
|
168
|
-
# # Generating action: home for app: web
|
|
169
|
-
#
|
|
170
|
-
# # $ foo generate action
|
|
171
|
-
# # ERROR: "foo generate action" was called with no arguments
|
|
172
|
-
# # Usage: "foo generate action APP ACTION"
|
|
173
|
-
#
|
|
174
|
-
# @example Description
|
|
175
|
-
# require "hanami/cli"
|
|
176
|
-
#
|
|
177
|
-
# class Hello < Hanami::CLI::Command
|
|
178
|
-
# argument :name, desc: "The name of the person to greet"
|
|
179
|
-
#
|
|
180
|
-
# def call(name: nil, **)
|
|
181
|
-
# # ...
|
|
182
|
-
# end
|
|
183
|
-
# end
|
|
184
|
-
#
|
|
185
|
-
# # $ foo hello --help
|
|
186
|
-
# # Command:
|
|
187
|
-
# # foo hello
|
|
188
|
-
# #
|
|
189
|
-
# # Usage:
|
|
190
|
-
# # foo hello [NAME]
|
|
191
|
-
# #
|
|
192
|
-
# # Arguments:
|
|
193
|
-
# # NAME # The name of the person to greet
|
|
194
|
-
# #
|
|
195
|
-
# # Options:
|
|
196
|
-
# # --help, -h # Print this help
|
|
197
|
-
def self.argument(name, options = {})
|
|
198
|
-
@arguments << Argument.new(name, options)
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
# Command line option (aka optional argument)
|
|
202
|
-
#
|
|
203
|
-
# @param name [Symbol] the param name
|
|
204
|
-
# @param options [Hash] a set of options
|
|
205
|
-
#
|
|
206
|
-
# @since 0.1.0
|
|
207
|
-
#
|
|
208
|
-
# @example Basic usage
|
|
209
|
-
# require "hanami/cli"
|
|
210
|
-
#
|
|
211
|
-
# class Console < Hanami::CLI::Command
|
|
212
|
-
# param :engine
|
|
213
|
-
#
|
|
214
|
-
# def call(engine: nil, **)
|
|
215
|
-
# puts "starting console (engine: #{engine || :irb})"
|
|
216
|
-
# end
|
|
217
|
-
# end
|
|
218
|
-
#
|
|
219
|
-
# # $ foo console
|
|
220
|
-
# # starting console (engine: irb)
|
|
221
|
-
#
|
|
222
|
-
# # $ foo console --engine=pry
|
|
223
|
-
# # starting console (engine: pry)
|
|
224
|
-
#
|
|
225
|
-
# @example List values
|
|
226
|
-
# require "hanami/cli"
|
|
227
|
-
#
|
|
228
|
-
# class Console < Hanami::CLI::Command
|
|
229
|
-
# param :engine, values: %w(irb pry ripl)
|
|
230
|
-
#
|
|
231
|
-
# def call(engine: nil, **)
|
|
232
|
-
# puts "starting console (engine: #{engine || :irb})"
|
|
233
|
-
# end
|
|
234
|
-
# end
|
|
235
|
-
#
|
|
236
|
-
# # $ foo console
|
|
237
|
-
# # starting console (engine: irb)
|
|
238
|
-
#
|
|
239
|
-
# # $ foo console --engine=pry
|
|
240
|
-
# # starting console (engine: pry)
|
|
241
|
-
#
|
|
242
|
-
# # $ foo console --engine=foo
|
|
243
|
-
# # Error: Invalid param provided
|
|
244
|
-
#
|
|
245
|
-
# @example Description
|
|
246
|
-
# require "hanami/cli"
|
|
247
|
-
#
|
|
248
|
-
# class Console < Hanami::CLI::Command
|
|
249
|
-
# param :engine, desc: "Force a console engine"
|
|
250
|
-
#
|
|
251
|
-
# def call(engine: nil, **)
|
|
252
|
-
# # ...
|
|
253
|
-
# end
|
|
254
|
-
# end
|
|
255
|
-
#
|
|
256
|
-
# # $ foo console --help
|
|
257
|
-
# # # ...
|
|
258
|
-
# #
|
|
259
|
-
# # Options:
|
|
260
|
-
# # --engine=VALUE # Force a console engine: (irb/pry/ripl)
|
|
261
|
-
# # --help, -h # Print this help
|
|
262
|
-
#
|
|
263
|
-
# @example Boolean
|
|
264
|
-
# require "hanami/cli"
|
|
265
|
-
#
|
|
266
|
-
# class Server < Hanami::CLI::Command
|
|
267
|
-
# param :code_reloading, type: :boolean, default: true
|
|
268
|
-
#
|
|
269
|
-
# def call(code_reloading:, **)
|
|
270
|
-
# puts "staring server (code reloading: #{code_reloading})"
|
|
271
|
-
# end
|
|
272
|
-
# end
|
|
273
|
-
#
|
|
274
|
-
# # $ foo server
|
|
275
|
-
# # starting server (code reloading: true)
|
|
276
|
-
#
|
|
277
|
-
# # $ foo server --no-code-reloading
|
|
278
|
-
# # starting server (code reloading: false)
|
|
279
|
-
#
|
|
280
|
-
# # $ foo server --help
|
|
281
|
-
# # # ...
|
|
282
|
-
# #
|
|
283
|
-
# # Options:
|
|
284
|
-
# # --[no]-code-reloading
|
|
285
|
-
#
|
|
286
|
-
# @example Aliases
|
|
287
|
-
# require "hanami/cli"
|
|
288
|
-
#
|
|
289
|
-
# class Server < Hanami::CLI::Command
|
|
290
|
-
# param :port, aliases: ["-p"]
|
|
291
|
-
#
|
|
292
|
-
# def call(options)
|
|
293
|
-
# puts "staring server (port: #{options.fetch(:port, 2300)})"
|
|
294
|
-
# end
|
|
295
|
-
# end
|
|
296
|
-
#
|
|
297
|
-
# # $ foo server
|
|
298
|
-
# # starting server (port: 2300)
|
|
299
|
-
#
|
|
300
|
-
# # $ foo server --port=2306
|
|
301
|
-
# # starting server (port: 2306)
|
|
302
|
-
#
|
|
303
|
-
# # $ foo server -p 2306
|
|
304
|
-
# # starting server (port: 2306)
|
|
305
|
-
#
|
|
306
|
-
# # $ foo server --help
|
|
307
|
-
# # # ...
|
|
308
|
-
# #
|
|
309
|
-
# # Options:
|
|
310
|
-
# # --port=VALUE, -p VALUE
|
|
311
|
-
def self.option(name, options = {})
|
|
312
|
-
@options << Option.new(name, options)
|
|
313
|
-
end
|
|
314
|
-
|
|
315
|
-
# @since 0.1.0
|
|
316
|
-
# @api private
|
|
317
|
-
def self.params
|
|
318
|
-
(@arguments + @options).uniq
|
|
319
|
-
end
|
|
320
|
-
|
|
321
|
-
# @since 0.1.0
|
|
322
|
-
# @api private
|
|
323
|
-
def self.default_params
|
|
324
|
-
params.each_with_object({}) do |param, result|
|
|
325
|
-
result[param.name] = param.default unless param.default.nil?
|
|
326
|
-
end
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
# @since 0.1.0
|
|
330
|
-
# @api private
|
|
331
|
-
def self.required_arguments
|
|
332
|
-
arguments.select(&:required?)
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
# @since 0.1.0
|
|
336
|
-
# @api private
|
|
337
|
-
def self.optional_arguments
|
|
338
|
-
arguments.reject(&:required?)
|
|
7
|
+
module Hanami
|
|
8
|
+
module CLI
|
|
9
|
+
class Command < Dry::CLI::Command
|
|
10
|
+
def initialize(out: $stdout, fs: Dry::Files.new, inflector: Dry::Inflector.new)
|
|
11
|
+
super()
|
|
12
|
+
@out = out
|
|
13
|
+
@fs = fs
|
|
14
|
+
@inflector = inflector
|
|
339
15
|
end
|
|
340
16
|
|
|
341
|
-
|
|
17
|
+
private
|
|
342
18
|
|
|
343
|
-
|
|
344
|
-
description
|
|
345
|
-
examples
|
|
346
|
-
arguments
|
|
347
|
-
options
|
|
348
|
-
params
|
|
349
|
-
default_params
|
|
350
|
-
required_arguments
|
|
351
|
-
optional_arguments
|
|
352
|
-
] => "self.class"
|
|
19
|
+
attr_reader :out
|
|
353
20
|
|
|
354
|
-
|
|
355
|
-
# @api private
|
|
356
|
-
attr_reader :command_name
|
|
21
|
+
attr_reader :fs
|
|
357
22
|
|
|
358
|
-
|
|
359
|
-
# @api private
|
|
360
|
-
def initialize(command_name:, **)
|
|
361
|
-
@command_name = command_name
|
|
362
|
-
end
|
|
23
|
+
attr_reader :inflector
|
|
363
24
|
end
|
|
364
25
|
end
|
|
365
26
|
end
|