hanami-cli 1.0.0.alpha1 → 2.0.0.alpha6

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 +50 -0
  3. data/.gitignore +4 -2
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +28 -1
  6. data/CHANGELOG.md +32 -1
  7. data/CODE_OF_CONDUCT.md +84 -0
  8. data/Gemfile +9 -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 +22 -17
  14. data/lib/hanami/cli/bundler.rb +73 -0
  15. data/lib/hanami/cli/command.rb +14 -386
  16. data/lib/hanami/cli/command_line.rb +17 -0
  17. data/lib/hanami/cli/commands/application.rb +63 -0
  18. data/lib/hanami/cli/commands/db/utils/database.rb +122 -0
  19. data/lib/hanami/cli/commands/db/utils/database_config.rb +48 -0
  20. data/lib/hanami/cli/commands/db/utils/mysql.rb +27 -0
  21. data/lib/hanami/cli/commands/db/utils/postgres.rb +49 -0
  22. data/lib/hanami/cli/commands/db/utils/sqlite.rb +37 -0
  23. data/lib/hanami/cli/commands/gem/new.rb +77 -0
  24. data/lib/hanami/cli/commands/gem/version.rb +18 -0
  25. data/lib/hanami/cli/commands/gem.rb +21 -0
  26. data/lib/hanami/cli/commands/monolith/console.rb +49 -0
  27. data/lib/hanami/cli/commands/monolith/db/create.rb +25 -0
  28. data/lib/hanami/cli/commands/monolith/db/create_migration.rb +29 -0
  29. data/lib/hanami/cli/commands/monolith/db/drop.rb +25 -0
  30. data/lib/hanami/cli/commands/monolith/db/migrate.rb +40 -0
  31. data/lib/hanami/cli/commands/monolith/db/reset.rb +26 -0
  32. data/lib/hanami/cli/commands/monolith/db/rollback.rb +55 -0
  33. data/lib/hanami/cli/commands/monolith/db/sample_data.rb +40 -0
  34. data/lib/hanami/cli/commands/monolith/db/seed.rb +40 -0
  35. data/lib/hanami/cli/commands/monolith/db/setup.rb +24 -0
  36. data/lib/hanami/cli/commands/monolith/db/structure/dump.rb +25 -0
  37. data/lib/hanami/cli/commands/monolith/db/version.rb +26 -0
  38. data/lib/hanami/cli/commands/monolith/generate/action.rb +62 -0
  39. data/lib/hanami/cli/commands/monolith/generate/slice.rb +62 -0
  40. data/lib/hanami/cli/commands/monolith/generate.rb +14 -0
  41. data/lib/hanami/cli/commands/monolith/install.rb +16 -0
  42. data/lib/hanami/cli/commands/monolith/version.rb +18 -0
  43. data/lib/hanami/cli/commands/monolith.rb +55 -0
  44. data/lib/hanami/cli/commands.rb +26 -0
  45. data/lib/hanami/cli/error.rb +8 -0
  46. data/lib/hanami/cli/generators/context.rb +38 -0
  47. data/lib/hanami/cli/generators/gem/application/monolith/action.erb +21 -0
  48. data/lib/hanami/cli/generators/gem/application/monolith/application.erb +8 -0
  49. data/lib/hanami/cli/generators/gem/application/monolith/config_ru.erb +5 -0
  50. data/lib/hanami/cli/generators/gem/application/monolith/entities.erb +9 -0
  51. data/lib/hanami/cli/generators/gem/application/monolith/env.erb +0 -0
  52. data/lib/hanami/cli/generators/gem/application/monolith/functions.erb +13 -0
  53. data/lib/hanami/cli/generators/gem/application/monolith/gemfile.erb +19 -0
  54. data/lib/hanami/cli/generators/gem/application/monolith/keep.erb +0 -0
  55. data/lib/hanami/cli/generators/gem/application/monolith/operation.erb +18 -0
  56. data/lib/hanami/cli/generators/gem/application/monolith/rakefile.erb +3 -0
  57. data/lib/hanami/cli/generators/gem/application/monolith/readme.erb +1 -0
  58. data/lib/hanami/cli/generators/gem/application/monolith/repository.erb +13 -0
  59. data/lib/hanami/cli/generators/gem/application/monolith/routes.erb +4 -0
  60. data/lib/hanami/cli/generators/gem/application/monolith/settings.erb +6 -0
  61. data/lib/hanami/cli/generators/gem/application/monolith/types.erb +10 -0
  62. data/lib/hanami/cli/generators/gem/application/monolith/validation_contract.erb +14 -0
  63. data/lib/hanami/cli/generators/gem/application/monolith/view_context.erb +15 -0
  64. data/lib/hanami/cli/generators/gem/application/monolith.rb +83 -0
  65. data/lib/hanami/cli/generators/gem/application.rb +21 -0
  66. data/lib/hanami/cli/generators/monolith/action/action.erb +13 -0
  67. data/lib/hanami/cli/generators/monolith/action/template.erb +0 -0
  68. data/lib/hanami/cli/generators/monolith/action/template.html.erb +2 -0
  69. data/lib/hanami/cli/generators/monolith/action/view.erb +13 -0
  70. data/lib/hanami/cli/generators/monolith/action.rb +123 -0
  71. data/lib/hanami/cli/generators/monolith/action_context.rb +76 -0
  72. data/lib/hanami/cli/generators/monolith/slice/action.erb +9 -0
  73. data/lib/hanami/cli/generators/monolith/slice/entities.erb +9 -0
  74. data/lib/hanami/cli/generators/monolith/slice/keep.erb +0 -0
  75. data/lib/hanami/cli/generators/monolith/slice/repository.erb +10 -0
  76. data/lib/hanami/cli/generators/monolith/slice/routes.erb +2 -0
  77. data/lib/hanami/cli/generators/monolith/slice/view.erb +9 -0
  78. data/lib/hanami/cli/generators/monolith/slice.rb +56 -0
  79. data/lib/hanami/cli/generators/monolith/slice_context.rb +33 -0
  80. data/lib/hanami/cli/repl/core.rb +55 -0
  81. data/lib/hanami/cli/repl/irb.rb +38 -0
  82. data/lib/hanami/cli/repl/pry.rb +29 -0
  83. data/lib/hanami/cli/system_call.rb +51 -0
  84. data/lib/hanami/cli/url.rb +34 -0
  85. data/lib/hanami/cli/version.rb +2 -3
  86. data/lib/hanami/cli.rb +9 -122
  87. data/lib/hanami/console/context.rb +53 -0
  88. data/lib/hanami/console/plugins/slice_readers.rb +24 -0
  89. data/lib/hanami/rake_tasks.rb +52 -0
  90. metadata +135 -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
@@ -1,330 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "hanami/cli/command_registry"
4
-
5
- module Hanami
6
- class CLI
7
- # Registry mixin
8
- #
9
- # @since 0.1.0
10
- module Registry
11
- # @since 0.1.0
12
- # @api private
13
- def self.extended(base)
14
- base.class_eval do
15
- @commands = CommandRegistry.new
16
- end
17
- end
18
-
19
- # Register a command
20
- #
21
- # @param name [String] the command name
22
- # @param command [NilClass,Hanami::CLI::Command] the optional command
23
- # @param aliases [Array<String>] an optional list of aliases
24
- # @param options [Hash] a set of options
25
- #
26
- # @since 0.1.0
27
- #
28
- # @example Register a command
29
- # require "hanami/cli"
30
- #
31
- # module Foo
32
- # module Commands
33
- # extend Hanami::CLI::Registry
34
- #
35
- # class Hello < Hanami::CLI::Command
36
- # end
37
- #
38
- # register "hi", Hello
39
- # end
40
- # end
41
- #
42
- # @example Register a command with aliases
43
- # require "hanami/cli"
44
- #
45
- # module Foo
46
- # module Commands
47
- # extend Hanami::CLI::Registry
48
- #
49
- # class Hello < Hanami::CLI::Command
50
- # end
51
- #
52
- # register "hello", Hello, aliases: ["hi", "ciao"]
53
- # end
54
- # end
55
- #
56
- # @example Register a group of commands
57
- # require "hanami/cli"
58
- #
59
- # module Foo
60
- # module Commands
61
- # extend Hanami::CLI::Registry
62
- #
63
- # module Generate
64
- # class App < Hanami::CLI::Command
65
- # end
66
- #
67
- # class Action < Hanami::CLI::Command
68
- # end
69
- # end
70
- #
71
- # register "generate", aliases: ["g"] do |prefix|
72
- # prefix.register "app", Generate::App
73
- # prefix.register "action", Generate::Action
74
- # end
75
- # end
76
- # end
77
- def register(name, command = nil, aliases: [], **options)
78
- if block_given?
79
- yield Prefix.new(@commands, name, aliases)
80
- else
81
- @commands.set(name, command, aliases, **options)
82
- end
83
- end
84
-
85
- # Register a before callback.
86
- #
87
- # @param command_name [String] the name used for command registration
88
- # @param callback [Class, #call] the callback object. If a class is given,
89
- # it MUST respond to `#call`.
90
- # @param blk [Proc] the callback espressed as a block
91
- #
92
- # @raise [Hanami::CLI::UnknownCommandError] if the command isn't registered
93
- # @raise [Hanami::CLI::InvalidCallbackError] if the given callback doesn't
94
- # implement the required interface
95
- #
96
- # @since 0.2.0
97
- #
98
- # @example
99
- # require "hanami/cli"
100
- #
101
- # module Foo
102
- # module Commands
103
- # extend Hanami::CLI::Registry
104
- #
105
- # class Hello < Hanami::CLI::Command
106
- # def call(*)
107
- # puts "hello"
108
- # end
109
- # end
110
- #
111
- # register "hello", Hello
112
- # before "hello", -> { puts "I'm about to say.." }
113
- # end
114
- # end
115
- #
116
- # @example Register an object as callback
117
- # require "hanami/cli"
118
- #
119
- # module Callbacks
120
- # class Hello
121
- # def call(*)
122
- # puts "world"
123
- # end
124
- # end
125
- # end
126
- #
127
- # module Foo
128
- # module Commands
129
- # extend Hanami::CLI::Registry
130
- #
131
- # class Hello < Hanami::CLI::Command
132
- # def call(*)
133
- # puts "I'm about to say.."
134
- # end
135
- # end
136
- #
137
- # register "hello", Hello
138
- # before "hello", Callbacks::Hello.new
139
- # end
140
- # end
141
- #
142
- # @example Register a class as callback
143
- # require "hanami/cli"
144
- #
145
- # module Callbacks
146
- # class Hello
147
- # def call(*)
148
- # puts "world"
149
- # end
150
- # end
151
- # end
152
- #
153
- # module Foo
154
- # module Commands
155
- # extend Hanami::CLI::Registry
156
- #
157
- # class Hello < Hanami::CLI::Command
158
- # def call(*)
159
- # puts "I'm about to say.."
160
- # end
161
- # end
162
- #
163
- # register "hello", Hello
164
- # before "hello", Callbacks::Hello
165
- # end
166
- # end
167
- def before(command_name, callback = nil, &blk)
168
- command(command_name).before_callbacks.append(&_callback(callback, blk))
169
- end
170
-
171
- # Register an after callback.
172
- #
173
- # @param command_name [String] the name used for command registration
174
- # @param callback [Class, #call] the callback object. If a class is given,
175
- # it MUST respond to `#call`.
176
- # @param blk [Proc] the callback espressed as a block
177
- #
178
- # @raise [Hanami::CLI::UnknownCommandError] if the command isn't registered
179
- # @raise [Hanami::CLI::InvalidCallbackError] if the given callback doesn't
180
- # implement the required interface
181
- #
182
- # @since 0.2.0
183
- #
184
- # @example
185
- # require "hanami/cli"
186
- #
187
- # module Foo
188
- # module Commands
189
- # extend Hanami::CLI::Registry
190
- #
191
- # class Hello < Hanami::CLI::Command
192
- # def call(*)
193
- # puts "hello"
194
- # end
195
- # end
196
- #
197
- # register "hello", Hello
198
- # after "hello", -> { puts "world" }
199
- # end
200
- # end
201
- #
202
- # @example Register an object as callback
203
- # require "hanami/cli"
204
- #
205
- # module Callbacks
206
- # class World
207
- # def call(*)
208
- # puts "world"
209
- # end
210
- # end
211
- # end
212
- #
213
- # module Foo
214
- # module Commands
215
- # extend Hanami::CLI::Registry
216
- #
217
- # class Hello < Hanami::CLI::Command
218
- # def call(*)
219
- # puts "hello"
220
- # end
221
- # end
222
- #
223
- # register "hello", Hello
224
- # after "hello", Callbacks::World.new
225
- # end
226
- # end
227
- #
228
- # @example Register a class as callback
229
- # require "hanami/cli"
230
- #
231
- # module Callbacks
232
- # class World
233
- # def call(*)
234
- # puts "world"
235
- # end
236
- # end
237
- # end
238
- #
239
- # module Foo
240
- # module Commands
241
- # extend Hanami::CLI::Registry
242
- #
243
- # class Hello < Hanami::CLI::Command
244
- # def call(*)
245
- # puts "hello"
246
- # end
247
- # end
248
- #
249
- # register "hello", Hello
250
- # after "hello", Callbacks::World
251
- # end
252
- # end
253
- def after(command_name, callback = nil, &blk)
254
- command(command_name).after_callbacks.append(&_callback(callback, blk))
255
- end
256
-
257
- # @since 0.1.0
258
- # @api private
259
- def get(arguments)
260
- @commands.get(arguments)
261
- end
262
-
263
- private
264
-
265
- COMMAND_NAME_SEPARATOR = " "
266
-
267
- # @since 0.2.0
268
- # @api private
269
- def command(command_name)
270
- get(command_name.split(COMMAND_NAME_SEPARATOR)).tap do |result|
271
- raise UnknownCommandError.new(command_name) unless result.found?
272
- end
273
- end
274
-
275
- # @since 0.2.0
276
- # @api private
277
- #
278
- # rubocop:disable Metrics/MethodLength
279
- def _callback(callback, blk)
280
- return blk if blk.respond_to?(:to_proc)
281
-
282
- case callback
283
- when ->(c) { c.respond_to?(:call) }
284
- callback.method(:call)
285
- when Class
286
- begin
287
- _callback(callback.new, blk)
288
- rescue ArgumentError
289
- raise InvalidCallbackError.new(callback)
290
- end
291
- else
292
- raise InvalidCallbackError.new(callback)
293
- end
294
- end
295
- # rubocop:enable Metrics/MethodLength
296
-
297
- # Command name prefix
298
- #
299
- # @since 0.1.0
300
- class Prefix
301
- # @since 0.1.0
302
- # @api private
303
- def initialize(registry, prefix, aliases)
304
- @registry = registry
305
- @prefix = prefix
306
-
307
- registry.set(prefix, nil, aliases)
308
- end
309
-
310
- # @since 0.1.0
311
- #
312
- # @see Hanami::CLI::Registry#register
313
- def register(name, command, aliases: [], **options)
314
- command_name = "#{prefix} #{name}"
315
- registry.set(command_name, command, aliases, **options)
316
- end
317
-
318
- private
319
-
320
- # @since 0.1.0
321
- # @api private
322
- attr_reader :registry
323
-
324
- # @since 0.1.0
325
- # @api private
326
- attr_reader :prefix
327
- end
328
- end
329
- end
330
- end
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "hanami/cli/program_name"
4
-
5
- module Hanami
6
- class CLI
7
- # Command(s) usage
8
- #
9
- # @since 0.1.0
10
- # @api private
11
- module Usage
12
- # @since 0.1.0
13
- # @api private
14
- SUBCOMMAND_BANNER = " [SUBCOMMAND]"
15
-
16
- # @since 0.1.0
17
- # @api private
18
- def self.call(result, out)
19
- out.puts "Commands:"
20
- max_length, commands = commands_and_arguments(result)
21
-
22
- commands.each do |banner, node|
23
- usage = description(node.command) if node.leaf?
24
- out.puts "#{justify(banner, max_length, usage)}#{usage}"
25
- end
26
- end
27
-
28
- # @since 0.1.0
29
- # @api private
30
- def self.commands_and_arguments(result) # rubocop:disable Metrics/MethodLength
31
- max_length = 0
32
- ret = commands(result).each_with_object({}) do |(name, node), memo|
33
- args = if node.leaf?
34
- arguments(node.command)
35
- else
36
- SUBCOMMAND_BANNER
37
- end
38
-
39
- partial = " #{command_name(result, name)}#{args}"
40
- max_length = partial.bytesize if max_length < partial.bytesize
41
- memo[partial] = node
42
- end
43
-
44
- [max_length, ret]
45
- end
46
-
47
- # @since 0.1.0
48
- # @api private
49
- def self.arguments(command) # rubocop:disable Metrics/AbcSize
50
- return unless CLI.command?(command)
51
-
52
- required_arguments = command.required_arguments
53
- optional_arguments = command.optional_arguments
54
-
55
- required = required_arguments.map { |arg| arg.name.upcase }.join(" ") if required_arguments.any?
56
- optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(" ") if optional_arguments.any?
57
- result = [required, optional].compact
58
-
59
- " #{result.join(' ')}" unless result.empty?
60
- end
61
-
62
- # @since 0.1.0
63
- # @api private
64
- def self.description(command)
65
- return unless CLI.command?(command)
66
-
67
- " # #{command.description}" unless command.description.nil?
68
- end
69
-
70
- # @since 0.1.0
71
- # @api private
72
- def self.justify(string, padding, usage)
73
- return string.chomp(" ") if usage.nil?
74
-
75
- string.ljust(padding + padding / 2)
76
- end
77
-
78
- # @since 0.1.0
79
- # @api private
80
- def self.commands(result)
81
- result.children.sort_by { |name, _| name }
82
- end
83
-
84
- # @since 0.1.0
85
- # @api private
86
- def self.command_name(result, name)
87
- ProgramName.call([result.names, name])
88
- end
89
- end
90
- end
91
- end
data/script/ci DELETED
@@ -1,61 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
-
5
- prepare_build() {
6
- if [ -d coverage ]; then
7
- rm -rf coverage
8
- fi
9
- }
10
-
11
- print_ruby_version() {
12
- echo "Using $(ruby -v)"
13
- echo
14
- }
15
-
16
- run_code_quality_checks() {
17
- bundle exec rubocop .
18
- }
19
-
20
- run_unit_tests() {
21
- bundle exec rake spec:unit
22
- }
23
-
24
- run_integration_tests() {
25
- local pwd=$PWD
26
- local root="$pwd/spec/integration"
27
-
28
- for test in $(find $root -name '*_spec.rb')
29
- do
30
- run_test $test
31
-
32
- if [ $? -ne 0 ]; then
33
- local exit_code=$?
34
- echo "Failing test: $test"
35
- exit $exit_code
36
- fi
37
- done
38
- }
39
-
40
- run_test() {
41
- local test=$1
42
- local hash="$(shasum "$test" | cut -b 1-40)"
43
-
44
- printf "\n\n\nRunning: $test\n"
45
- SIMPLECOV_COMMAND_NAME=$hash bundle exec rspec $test
46
- }
47
-
48
- upload_code_coverage() {
49
- bundle exec rake codecov:upload
50
- }
51
-
52
- main() {
53
- prepare_build &&
54
- print_ruby_version &&
55
- run_code_quality_checks &&
56
- run_unit_tests &&
57
- run_integration_tests &&
58
- upload_code_coverage
59
- }
60
-
61
- main