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