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.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +42 -0
  3. data/.gitignore +4 -2
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +25 -1
  6. data/CHANGELOG.md +39 -1
  7. data/CODE_OF_CONDUCT.md +84 -0
  8. data/Gemfile +13 -6
  9. data/LICENSE.txt +21 -0
  10. data/README.md +13 -488
  11. data/Rakefile +8 -15
  12. data/bin/console +1 -0
  13. data/exe/hanami +10 -0
  14. data/hanami-cli.gemspec +24 -18
  15. data/lib/hanami/cli.rb +10 -121
  16. data/lib/hanami/cli/bundler.rb +73 -0
  17. data/lib/hanami/cli/command.rb +16 -355
  18. data/lib/hanami/cli/command_line.rb +17 -0
  19. data/lib/hanami/cli/commands.rb +26 -0
  20. data/lib/hanami/cli/commands/application.rb +63 -0
  21. data/lib/hanami/cli/commands/db/utils/database.rb +122 -0
  22. data/lib/hanami/cli/commands/db/utils/database_config.rb +48 -0
  23. data/lib/hanami/cli/commands/db/utils/mysql.rb +27 -0
  24. data/lib/hanami/cli/commands/db/utils/postgres.rb +49 -0
  25. data/lib/hanami/cli/commands/db/utils/sqlite.rb +37 -0
  26. data/lib/hanami/cli/commands/gem.rb +21 -0
  27. data/lib/hanami/cli/commands/gem/new.rb +77 -0
  28. data/lib/hanami/cli/commands/gem/version.rb +18 -0
  29. data/lib/hanami/cli/commands/monolith.rb +55 -0
  30. data/lib/hanami/cli/commands/monolith/console.rb +50 -0
  31. data/lib/hanami/cli/commands/monolith/db/create.rb +25 -0
  32. data/lib/hanami/cli/commands/monolith/db/create_migration.rb +29 -0
  33. data/lib/hanami/cli/commands/monolith/db/drop.rb +25 -0
  34. data/lib/hanami/cli/commands/monolith/db/migrate.rb +40 -0
  35. data/lib/hanami/cli/commands/monolith/db/reset.rb +26 -0
  36. data/lib/hanami/cli/commands/monolith/db/rollback.rb +55 -0
  37. data/lib/hanami/cli/commands/monolith/db/sample_data.rb +40 -0
  38. data/lib/hanami/cli/commands/monolith/db/seed.rb +40 -0
  39. data/lib/hanami/cli/commands/monolith/db/setup.rb +24 -0
  40. data/lib/hanami/cli/commands/monolith/db/structure/dump.rb +25 -0
  41. data/lib/hanami/cli/commands/monolith/db/version.rb +26 -0
  42. data/lib/hanami/cli/commands/monolith/generate.rb +14 -0
  43. data/lib/hanami/cli/commands/monolith/generate/action.rb +62 -0
  44. data/lib/hanami/cli/commands/monolith/generate/slice.rb +62 -0
  45. data/lib/hanami/cli/commands/monolith/install.rb +16 -0
  46. data/lib/hanami/cli/commands/monolith/version.rb +18 -0
  47. data/lib/hanami/cli/error.rb +8 -0
  48. data/lib/hanami/cli/generators/context.rb +38 -0
  49. data/lib/hanami/cli/generators/gem/application.rb +21 -0
  50. data/lib/hanami/cli/generators/gem/application/monolith.rb +83 -0
  51. data/lib/hanami/cli/generators/gem/application/monolith/action.erb +21 -0
  52. data/lib/hanami/cli/generators/gem/application/monolith/application.erb +8 -0
  53. data/lib/hanami/cli/generators/gem/application/monolith/config_ru.erb +5 -0
  54. data/lib/hanami/cli/generators/gem/application/monolith/entities.erb +9 -0
  55. data/lib/hanami/cli/generators/gem/application/monolith/env.erb +0 -0
  56. data/lib/hanami/cli/generators/gem/application/monolith/functions.erb +13 -0
  57. data/lib/hanami/cli/generators/gem/application/monolith/gemfile.erb +19 -0
  58. data/lib/hanami/cli/generators/gem/application/monolith/keep.erb +0 -0
  59. data/lib/hanami/cli/generators/gem/application/monolith/operation.erb +18 -0
  60. data/lib/hanami/cli/generators/gem/application/monolith/rakefile.erb +3 -0
  61. data/lib/hanami/cli/generators/gem/application/monolith/readme.erb +1 -0
  62. data/lib/hanami/cli/generators/gem/application/monolith/repository.erb +13 -0
  63. data/lib/hanami/cli/generators/gem/application/monolith/routes.erb +4 -0
  64. data/lib/hanami/cli/generators/gem/application/monolith/settings.erb +6 -0
  65. data/lib/hanami/cli/generators/gem/application/monolith/types.erb +10 -0
  66. data/lib/hanami/cli/generators/gem/application/monolith/validation_contract.erb +14 -0
  67. data/lib/hanami/cli/generators/gem/application/monolith/view_context.erb +15 -0
  68. data/lib/hanami/cli/generators/monolith/action.rb +123 -0
  69. data/lib/hanami/cli/generators/monolith/action/action.erb +13 -0
  70. data/lib/hanami/cli/generators/monolith/action/template.erb +0 -0
  71. data/lib/hanami/cli/generators/monolith/action/template.html.erb +2 -0
  72. data/lib/hanami/cli/generators/monolith/action/view.erb +13 -0
  73. data/lib/hanami/cli/generators/monolith/action_context.rb +76 -0
  74. data/lib/hanami/cli/generators/monolith/slice.rb +56 -0
  75. data/lib/hanami/cli/generators/monolith/slice/action.erb +9 -0
  76. data/lib/hanami/cli/generators/monolith/slice/entities.erb +9 -0
  77. data/lib/hanami/cli/generators/monolith/slice/keep.erb +0 -0
  78. data/lib/hanami/cli/generators/monolith/slice/repository.erb +10 -0
  79. data/lib/hanami/cli/generators/monolith/slice/routes.erb +2 -0
  80. data/lib/hanami/cli/generators/monolith/slice/view.erb +9 -0
  81. data/lib/hanami/cli/generators/monolith/slice_context.rb +33 -0
  82. data/lib/hanami/cli/repl/core.rb +55 -0
  83. data/lib/hanami/cli/repl/irb.rb +41 -0
  84. data/lib/hanami/cli/repl/pry.rb +29 -0
  85. data/lib/hanami/cli/system_call.rb +51 -0
  86. data/lib/hanami/cli/url.rb +34 -0
  87. data/lib/hanami/cli/version.rb +4 -3
  88. data/lib/hanami/console/context.rb +39 -0
  89. data/lib/hanami/console/plugins/slice_readers.rb +42 -0
  90. data/lib/hanami/rake_tasks.rb +52 -0
  91. metadata +138 -41
  92. data/.travis.yml +0 -16
  93. data/lib/hanami/cli/banner.rb +0 -126
  94. data/lib/hanami/cli/command_registry.rb +0 -213
  95. data/lib/hanami/cli/errors.rb +0 -32
  96. data/lib/hanami/cli/option.rb +0 -125
  97. data/lib/hanami/cli/parser.rb +0 -122
  98. data/lib/hanami/cli/program_name.rb +0 -19
  99. data/lib/hanami/cli/registry.rb +0 -328
  100. data/lib/hanami/cli/usage.rb +0 -88
  101. data/script/ci +0 -51
data/Rakefile CHANGED
@@ -1,19 +1,12 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
1
+ # frozen_string_literal: true
5
2
 
6
- namespace :spec do
7
- RSpec::Core::RakeTask.new(:unit) do |task|
8
- file_list = FileList['spec/**/*_spec.rb']
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
9
5
 
10
- task.pattern = file_list
11
- end
6
+ RSpec::Core::RakeTask.new(:spec)
12
7
 
13
- task :coverage do
14
- ENV['COVERAGE'] = 'true'
15
- Rake::Task['spec:unit'].invoke
16
- end
17
- end
8
+ require "rubocop/rake_task"
18
9
 
19
- task default: 'spec:unit'
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/bin/console CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "bundler/setup"
4
5
  require "hanami/cli"
data/exe/hanami ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "hanami/cli"
6
+
7
+ cli = Dry::CLI.new(Hanami::CLI)
8
+ Hanami::CLI::Bundler.require(:cli)
9
+
10
+ cli.call
data/hanami-cli.gemspec CHANGED
@@ -1,34 +1,40 @@
1
+ # frozen_string_literal: true
1
2
 
2
- lib = File.expand_path('../lib', __FILE__)
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 framework to build command line interfaces with Ruby"
15
- spec.homepage = "http://hanamirb.org"
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['allowed_push_host'] = "https://rubygems.org"
18
- spec.metadata['source_code_uri'] = "https://github.com/hanami/cli"
17
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
19
18
 
20
- spec.bindir = "exe"
21
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
- spec.require_paths = ["lib"]
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
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
25
- f.match(%r{^(test|spec|features)/})
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 "hanami-utils", "~> 1.2"
29
- spec.add_dependency "concurrent-ruby", "~> 1.0"
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 "bundler"
32
- spec.add_development_dependency "rake", "~> 12.0"
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
- # Hanami
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
- private
3
+ require "dry/cli"
65
4
 
66
- # @since 0.1.0
67
- # @api private
68
- attr_reader :commands
69
-
70
- # Parse arguments for a command.
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
- # Prints the command usage and exit.
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
- # Check if command
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
@@ -1,365 +1,26 @@
1
- require "forwardable"
2
- require "concurrent/array"
3
- require "hanami/cli/option"
1
+ # frozen_string_literal: true
4
2
 
5
- module Hanami
6
- class CLI
7
- # Base class for commands
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
- # Specify an argument
108
- #
109
- # @param name [Symbol] the argument name
110
- # @param options [Hash] a set of options
111
- #
112
- # @since 0.1.0
113
- #
114
- # @example Optional argument
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
- extend Forwardable
17
+ private
342
18
 
343
- delegate %i[
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
- # @since 0.1.0
355
- # @api private
356
- attr_reader :command_name
21
+ attr_reader :fs
357
22
 
358
- # @since 0.1.0
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