hanami-cli 0.2.0 → 2.0.0.alpha2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,122 +0,0 @@
1
- require "optparse"
2
- require "hanami/cli/program_name"
3
-
4
- module Hanami
5
- class CLI
6
- # Parse command line arguments and options
7
- #
8
- # @since 0.1.0
9
- # @api private
10
- module Parser
11
- # @since 0.1.0
12
- # @api private
13
- #
14
- # rubocop:disable Metrics/MethodLength
15
- def self.call(command, arguments, names)
16
- parsed_options = {}
17
-
18
- OptionParser.new do |opts|
19
- command.options.each do |option|
20
- opts.on(*option.parser_options) do |value|
21
- parsed_options[option.name.to_sym] = value
22
- end
23
- end
24
-
25
- opts.on_tail("-h", "--help") do
26
- return Result.help
27
- end
28
- end.parse!(arguments)
29
-
30
- parsed_options = command.default_params.merge(parsed_options)
31
- parse_required_params(command, arguments, names, parsed_options)
32
- rescue ::OptionParser::ParseError
33
- Result.failure
34
- end
35
- # rubocop:enable Metrics/MethodLength
36
-
37
- # @since 0.1.0
38
- # @api private
39
- def self.full_command_name(names)
40
- ProgramName.call(names)
41
- end
42
-
43
- # @since 0.1.0
44
- # @api private
45
- #
46
- # rubocop:disable Metrics/AbcSize
47
- # rubocop:disable Metrics/MethodLength
48
- def self.parse_required_params(command, arguments, names, parsed_options)
49
- parse_params = Hash[command.arguments.map(&:name).zip(arguments)]
50
- parse_required_params = Hash[command.required_arguments.map(&:name).zip(arguments)]
51
- all_required_params_satisfied = command.required_arguments.all? { |param| !parse_required_params[param.name].nil? }
52
-
53
- unless all_required_params_satisfied
54
- parse_required_params_values = parse_required_params.values.compact
55
-
56
- usage = "\nUsage: \"#{full_command_name(names)} #{command.required_arguments.map(&:description_name).join(' ')}\""
57
-
58
- if parse_required_params_values.empty? # rubocop:disable Style/GuardClause
59
- return Result.failure("ERROR: \"#{full_command_name(names)}\" was called with no arguments#{usage}")
60
- else
61
- return Result.failure("ERROR: \"#{full_command_name(names)}\" was called with arguments #{parse_required_params_values}#{usage}")
62
- end
63
- end
64
-
65
- parse_params.reject! { |_key, value| value.nil? }
66
- Result.success(parsed_options.merge(parse_params))
67
- end
68
- # rubocop:enable Metrics/MethodLength
69
- # rubocop:enable Metrics/AbcSize
70
-
71
- # @since 0.1.0
72
- # @api private
73
- class Result
74
- # @since 0.1.0
75
- # @api private
76
- def self.help
77
- new(help: true)
78
- end
79
-
80
- # @since 0.1.0
81
- # @api private
82
- def self.success(arguments = {})
83
- new(arguments: arguments)
84
- end
85
-
86
- # @since 0.1.0
87
- # @api private
88
- def self.failure(error = "Error: Invalid param provided")
89
- new(error: error)
90
- end
91
-
92
- # @since 0.1.0
93
- # @api private
94
- attr_reader :arguments
95
-
96
- # @since 0.1.0
97
- # @api private
98
- attr_reader :error
99
-
100
- # @since 0.1.0
101
- # @api private
102
- def initialize(arguments: {}, error: nil, help: false)
103
- @arguments = arguments
104
- @error = error
105
- @help = help
106
- end
107
-
108
- # @since 0.1.0
109
- # @api private
110
- def error?
111
- !error.nil?
112
- end
113
-
114
- # @since 0.1.0
115
- # @api private
116
- def help?
117
- @help
118
- end
119
- end
120
- end
121
- end
122
- end
@@ -1,19 +0,0 @@
1
- module Hanami
2
- class CLI
3
- # Program name
4
- #
5
- # @since 0.1.0
6
- # @api private
7
- module ProgramName
8
- # @since 0.1.0
9
- # @api private
10
- SEPARATOR = " ".freeze
11
-
12
- # @since 0.1.0
13
- # @api private
14
- def self.call(names = [], program_name: $PROGRAM_NAME)
15
- [File.basename(program_name), names].flatten.join(SEPARATOR)
16
- end
17
- end
18
- end
19
- end
@@ -1,328 +0,0 @@
1
- require "hanami/cli/command_registry"
2
-
3
- module Hanami
4
- class CLI
5
- # Registry mixin
6
- #
7
- # @since 0.1.0
8
- module Registry
9
- # @since 0.1.0
10
- # @api private
11
- def self.extended(base)
12
- base.class_eval do
13
- @commands = CommandRegistry.new
14
- end
15
- end
16
-
17
- # Register a command
18
- #
19
- # @param name [String] the command name
20
- # @param command [NilClass,Hanami::CLI::Command] the optional command
21
- # @param aliases [Array<String>] an optional list of aliases
22
- # @param options [Hash] a set of options
23
- #
24
- # @since 0.1.0
25
- #
26
- # @example Register a command
27
- # require "hanami/cli"
28
- #
29
- # module Foo
30
- # module Commands
31
- # extend Hanami::CLI::Registry
32
- #
33
- # class Hello < Hanami::CLI::Command
34
- # end
35
- #
36
- # register "hi", Hello
37
- # end
38
- # end
39
- #
40
- # @example Register a command with aliases
41
- # require "hanami/cli"
42
- #
43
- # module Foo
44
- # module Commands
45
- # extend Hanami::CLI::Registry
46
- #
47
- # class Hello < Hanami::CLI::Command
48
- # end
49
- #
50
- # register "hello", Hello, aliases: ["hi", "ciao"]
51
- # end
52
- # end
53
- #
54
- # @example Register a group of commands
55
- # require "hanami/cli"
56
- #
57
- # module Foo
58
- # module Commands
59
- # extend Hanami::CLI::Registry
60
- #
61
- # module Generate
62
- # class App < Hanami::CLI::Command
63
- # end
64
- #
65
- # class Action < Hanami::CLI::Command
66
- # end
67
- # end
68
- #
69
- # register "generate", aliases: ["g"] do |prefix|
70
- # prefix.register "app", Generate::App
71
- # prefix.register "action", Generate::Action
72
- # end
73
- # end
74
- # end
75
- def register(name, command = nil, aliases: [], **options)
76
- if block_given?
77
- yield Prefix.new(@commands, name, aliases)
78
- else
79
- @commands.set(name, command, aliases, **options)
80
- end
81
- end
82
-
83
- # Register a before callback.
84
- #
85
- # @param command_name [String] the name used for command registration
86
- # @param callback [Class, #call] the callback object. If a class is given,
87
- # it MUST respond to `#call`.
88
- # @param blk [Proc] the callback espressed as a block
89
- #
90
- # @raise [Hanami::CLI::UnkwnownCommandError] if the command isn't registered
91
- # @raise [Hanami::CLI::InvalidCallbackError] if the given callback doesn't
92
- # implement the required interface
93
- #
94
- # @since 0.2.0
95
- #
96
- # @example
97
- # require "hanami/cli"
98
- #
99
- # module Foo
100
- # module Commands
101
- # extend Hanami::CLI::Registry
102
- #
103
- # class Hello < Hanami::CLI::Command
104
- # def call(*)
105
- # puts "hello"
106
- # end
107
- # end
108
- #
109
- # register "hello", Hello
110
- # before "hello", -> { puts "I'm about to say.." }
111
- # end
112
- # end
113
- #
114
- # @example Register an object as callback
115
- # require "hanami/cli"
116
- #
117
- # module Callbacks
118
- # class Hello
119
- # def call(*)
120
- # puts "world"
121
- # end
122
- # end
123
- # end
124
- #
125
- # module Foo
126
- # module Commands
127
- # extend Hanami::CLI::Registry
128
- #
129
- # class Hello < Hanami::CLI::Command
130
- # def call(*)
131
- # puts "I'm about to say.."
132
- # end
133
- # end
134
- #
135
- # register "hello", Hello
136
- # before "hello", Callbacks::Hello.new
137
- # end
138
- # end
139
- #
140
- # @example Register a class as callback
141
- # require "hanami/cli"
142
- #
143
- # module Callbacks
144
- # class Hello
145
- # def call(*)
146
- # puts "world"
147
- # end
148
- # end
149
- # end
150
- #
151
- # module Foo
152
- # module Commands
153
- # extend Hanami::CLI::Registry
154
- #
155
- # class Hello < Hanami::CLI::Command
156
- # def call(*)
157
- # puts "I'm about to say.."
158
- # end
159
- # end
160
- #
161
- # register "hello", Hello
162
- # before "hello", Callbacks::Hello
163
- # end
164
- # end
165
- def before(command_name, callback = nil, &blk)
166
- command(command_name).before_callbacks.append(&_callback(callback, blk))
167
- end
168
-
169
- # Register an after callback.
170
- #
171
- # @param command_name [String] the name used for command registration
172
- # @param callback [Class, #call] the callback object. If a class is given,
173
- # it MUST respond to `#call`.
174
- # @param blk [Proc] the callback espressed as a block
175
- #
176
- # @raise [Hanami::CLI::UnkwnownCommandError] if the command isn't registered
177
- # @raise [Hanami::CLI::InvalidCallbackError] if the given callback doesn't
178
- # implement the required interface
179
- #
180
- # @since 0.2.0
181
- #
182
- # @example
183
- # require "hanami/cli"
184
- #
185
- # module Foo
186
- # module Commands
187
- # extend Hanami::CLI::Registry
188
- #
189
- # class Hello < Hanami::CLI::Command
190
- # def call(*)
191
- # puts "hello"
192
- # end
193
- # end
194
- #
195
- # register "hello", Hello
196
- # after "hello", -> { puts "world" }
197
- # end
198
- # end
199
- #
200
- # @example Register an object as callback
201
- # require "hanami/cli"
202
- #
203
- # module Callbacks
204
- # class World
205
- # def call(*)
206
- # puts "world"
207
- # end
208
- # end
209
- # end
210
- #
211
- # module Foo
212
- # module Commands
213
- # extend Hanami::CLI::Registry
214
- #
215
- # class Hello < Hanami::CLI::Command
216
- # def call(*)
217
- # puts "hello"
218
- # end
219
- # end
220
- #
221
- # register "hello", Hello
222
- # after "hello", Callbacks::World.new
223
- # end
224
- # end
225
- #
226
- # @example Register a class as callback
227
- # require "hanami/cli"
228
- #
229
- # module Callbacks
230
- # class World
231
- # def call(*)
232
- # puts "world"
233
- # end
234
- # end
235
- # end
236
- #
237
- # module Foo
238
- # module Commands
239
- # extend Hanami::CLI::Registry
240
- #
241
- # class Hello < Hanami::CLI::Command
242
- # def call(*)
243
- # puts "hello"
244
- # end
245
- # end
246
- #
247
- # register "hello", Hello
248
- # after "hello", Callbacks::World
249
- # end
250
- # end
251
- def after(command_name, callback = nil, &blk)
252
- command(command_name).after_callbacks.append(&_callback(callback, blk))
253
- end
254
-
255
- # @since 0.1.0
256
- # @api private
257
- def get(arguments)
258
- @commands.get(arguments)
259
- end
260
-
261
- private
262
-
263
- COMMAND_NAME_SEPARATOR = " ".freeze
264
-
265
- # @since 0.2.0
266
- # @api private
267
- def command(command_name)
268
- get(command_name.split(COMMAND_NAME_SEPARATOR)).tap do |result|
269
- raise UnkwnownCommandError.new(command_name) unless result.found?
270
- end
271
- end
272
-
273
- # @since 0.2.0
274
- # @api private
275
- #
276
- # rubocop:disable Metrics/MethodLength
277
- def _callback(callback, blk)
278
- return blk if blk.respond_to?(:to_proc)
279
-
280
- case callback
281
- when ->(c) { c.respond_to?(:call) }
282
- callback.method(:call)
283
- when Class
284
- begin
285
- _callback(callback.new, blk)
286
- rescue ArgumentError
287
- raise InvalidCallbackError.new(callback)
288
- end
289
- else
290
- raise InvalidCallbackError.new(callback)
291
- end
292
- end
293
- # rubocop:enable Metrics/MethodLength
294
-
295
- # Command name prefix
296
- #
297
- # @since 0.1.0
298
- class Prefix
299
- # @since 0.1.0
300
- # @api private
301
- def initialize(registry, prefix, aliases)
302
- @registry = registry
303
- @prefix = prefix
304
-
305
- registry.set(prefix, nil, aliases)
306
- end
307
-
308
- # @since 0.1.0
309
- #
310
- # @see Hanami::CLI::Registry#register
311
- def register(name, command, aliases: [], **options)
312
- command_name = "#{prefix} #{name}"
313
- registry.set(command_name, command, aliases, **options)
314
- end
315
-
316
- private
317
-
318
- # @since 0.1.0
319
- # @api private
320
- attr_reader :registry
321
-
322
- # @since 0.1.0
323
- # @api private
324
- attr_reader :prefix
325
- end
326
- end
327
- end
328
- end