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
data/.travis.yml DELETED
@@ -1,16 +0,0 @@
1
- language: ruby
2
- sudo: false
3
- cache: bundler
4
- script: ./script/ci
5
- rvm:
6
- - 2.3.6
7
- - 2.4.2
8
- - 2.5.0
9
- - ruby-head
10
- - jruby-9.1.13.0
11
- - jruby-head
12
-
13
- matrix:
14
- allow_failures:
15
- - rvm: ruby-head
16
- - rvm: jruby-head
@@ -1,126 +0,0 @@
1
- require "hanami/cli/program_name"
2
-
3
- module Hanami
4
- class CLI
5
- # Command banner
6
- #
7
- # @since 0.1.0
8
- # @api private
9
- module Banner
10
- # Prints command banner
11
- #
12
- # @param command [Hanami::CLI::Command] the command
13
- # @param out [IO] standard output
14
- #
15
- # @since 0.1.0
16
- # @api private
17
- def self.call(command, out)
18
- output = [
19
- command_name(command),
20
- command_name_and_arguments(command),
21
- command_description(command),
22
- command_arguments(command),
23
- command_options(command),
24
- command_examples(command)
25
- ].compact.join("\n")
26
-
27
- out.puts output
28
- end
29
-
30
- # @since 0.1.0
31
- # @api private
32
- def self.command_name(command)
33
- "Command:\n #{full_command_name(command)}"
34
- end
35
-
36
- # @since 0.1.0
37
- # @api private
38
- def self.command_name_and_arguments(command)
39
- "\nUsage:\n #{full_command_name(command)}#{arguments(command)}"
40
- end
41
-
42
- # @since 0.1.0
43
- # @api private
44
- def self.command_examples(command)
45
- return if command.examples.empty?
46
-
47
- "\nExamples:\n#{command.examples.map { |example| " #{full_command_name(command)} #{example}" }.join("\n")}"
48
- end
49
-
50
- # @since 0.1.0
51
- # @api private
52
- def self.command_description(command)
53
- return if command.description.nil?
54
-
55
- "\nDescription:\n #{command.description}"
56
- end
57
-
58
- # @since 0.1.0
59
- # @api private
60
- def self.command_arguments(command)
61
- return if command.arguments.empty?
62
- "\nArguments:\n#{extended_command_arguments(command)}"
63
- end
64
-
65
- # @since 0.1.0
66
- # @api private
67
- def self.command_options(command)
68
- "\nOptions:\n#{extended_command_options(command)}"
69
- end
70
-
71
- # @since 0.1.0
72
- # @api private
73
- def self.full_command_name(command)
74
- ProgramName.call(command.command_name)
75
- end
76
-
77
- # @since 0.1.0
78
- # @api private
79
- def self.arguments(command) # rubocop:disable Metrics/AbcSize
80
- required_arguments = command.required_arguments
81
- optional_arguments = command.optional_arguments
82
-
83
- required = required_arguments.map { |arg| arg.name.upcase }.join(' ') if required_arguments.any?
84
- optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(' ') if optional_arguments.any?
85
- result = [required, optional].compact
86
-
87
- " #{result.join(' ')}" unless result.empty?
88
- end
89
-
90
- # @since 0.1.0
91
- # @api private
92
- def self.extended_command_arguments(command)
93
- command.arguments.map do |argument|
94
- " #{argument.name.to_s.upcase.ljust(20)}\t# #{'REQUIRED ' if argument.required?}#{argument.desc}"
95
- end.join("\n")
96
- end
97
-
98
- # @since 0.1.0
99
- # @api private
100
- #
101
- # rubocop:disable Metrics/AbcSize
102
- # rubocop:disable Metrics/MethodLength
103
- def self.extended_command_options(command)
104
- result = command.options.map do |option|
105
- name = Utils::String.dasherize(option.name)
106
- name = if option.boolean?
107
- "[no-]#{name}"
108
- else
109
- "#{name}=VALUE"
110
- end
111
-
112
- name = "#{name}, #{option.aliases.map { |a| a.start_with?('--') ? "#{a}=VALUE" : "#{a} VALUE" }.join(', ')}" unless option.aliases.empty?
113
- name = " --#{name.ljust(30)}"
114
- name = "#{name}\t# #{option.desc}"
115
- name = "#{name}, default: #{option.default.inspect}" unless option.default.nil?
116
- name
117
- end
118
-
119
- result << " --#{'help, -h'.ljust(30)}\t# Print this help"
120
- result.join("\n")
121
- end
122
- # rubocop:enable Metrics/MethodLength
123
- # rubocop:enable Metrics/AbcSize
124
- end
125
- end
126
- end
@@ -1,213 +0,0 @@
1
- require "concurrent/hash"
2
- require 'hanami/utils/callbacks'
3
-
4
- module Hanami
5
- class CLI
6
- # Command registry
7
- #
8
- # @since 0.1.0
9
- # @api private
10
- class CommandRegistry
11
- # @since 0.1.0
12
- # @api private
13
- def initialize
14
- @root = Node.new
15
- end
16
-
17
- # @since 0.1.0
18
- # @api private
19
- def set(name, command, aliases, **options)
20
- node = @root
21
- command = command_for(name, command, **options)
22
- name.split(/[[:space:]]/).each do |token|
23
- node = node.put(node, token)
24
- end
25
-
26
- node.aliases!(aliases)
27
- node.leaf!(command) unless command.nil?
28
-
29
- nil
30
- end
31
-
32
- # @since 0.1.0
33
- # @api private
34
- #
35
- # rubocop:disable Metrics/AbcSize
36
- # rubocop:disable Metrics/MethodLength
37
- def get(arguments)
38
- node = @root
39
- args = []
40
- names = []
41
- result = LookupResult.new(node, args, names, node.leaf?)
42
-
43
- arguments.each_with_index do |token, i|
44
- tmp = node.lookup(token)
45
-
46
- if tmp.nil?
47
- result = LookupResult.new(node, args, names, false)
48
- break
49
- elsif tmp.leaf?
50
- args = arguments[i + 1..-1]
51
- names = arguments[0..i]
52
- node = tmp
53
- result = LookupResult.new(node, args, names, true)
54
- break
55
- else
56
- names = arguments[0..i]
57
- node = tmp
58
- result = LookupResult.new(node, args, names, node.leaf?)
59
- end
60
- end
61
-
62
- result
63
- end
64
- # rubocop:enable Metrics/MethodLength
65
- # rubocop:enable Metrics/AbcSize
66
-
67
- private
68
-
69
- # @since 0.1.0
70
- # @api private
71
- def command_for(name, command, **options)
72
- if command.nil?
73
- command
74
- else
75
- command.new(command_name: name, **options)
76
- end
77
- end
78
-
79
- # Node of the registry
80
- #
81
- # @since 0.1.0
82
- # @api private
83
- class Node
84
- # @since 0.1.0
85
- # @api private
86
- attr_reader :parent
87
-
88
- # @since 0.1.0
89
- # @api private
90
- attr_reader :children
91
-
92
- # @since 0.1.0
93
- # @api private
94
- attr_reader :aliases
95
-
96
- # @since 0.1.0
97
- # @api private
98
- attr_reader :command
99
-
100
- # @since 0.1.0
101
- # @api private
102
- attr_reader :before_callbacks
103
-
104
- # @since 0.1.0
105
- # @api private
106
- attr_reader :after_callbacks
107
-
108
- # @since 0.1.0
109
- # @api private
110
- def initialize(parent = nil)
111
- @parent = parent
112
- @children = Concurrent::Hash.new
113
- @aliases = Concurrent::Hash.new
114
- @command = nil
115
-
116
- @before_callbacks = Utils::Callbacks::Chain.new
117
- @after_callbacks = Utils::Callbacks::Chain.new
118
- end
119
-
120
- # @since 0.1.0
121
- # @api private
122
- def put(parent, key)
123
- children[key] ||= self.class.new(parent)
124
- end
125
-
126
- # @since 0.1.0
127
- # @api private
128
- def lookup(token)
129
- children[token] || aliases[token]
130
- end
131
-
132
- # @since 0.1.0
133
- # @api private
134
- def leaf!(command)
135
- @command = command
136
- end
137
-
138
- # @since 0.1.0
139
- # @api private
140
- def alias!(key, child)
141
- @aliases[key] = child
142
- end
143
-
144
- # @since 0.1.0
145
- # @api private
146
- def aliases!(aliases)
147
- aliases.each do |a|
148
- parent.alias!(a, self)
149
- end
150
- end
151
-
152
- # @since 0.1.0
153
- # @api private
154
- def leaf?
155
- !command.nil?
156
- end
157
- end
158
-
159
- # Result of a registry lookup
160
- #
161
- # @since 0.1.0
162
- # @api private
163
- class LookupResult
164
- # @since 0.1.0
165
- # @api private
166
- attr_reader :names
167
-
168
- # @since 0.1.0
169
- # @api private
170
- attr_reader :arguments
171
-
172
- # @since 0.1.0
173
- # @api private
174
- def initialize(node, arguments, names, found)
175
- @node = node
176
- @arguments = arguments
177
- @names = names
178
- @found = found
179
- end
180
-
181
- # @since 0.1.0
182
- # @api private
183
- def found?
184
- @found
185
- end
186
-
187
- # @since 0.1.0
188
- # @api private
189
- def children
190
- @node.children
191
- end
192
-
193
- # @since 0.1.0
194
- # @api private
195
- def command
196
- @node.command
197
- end
198
-
199
- # @since 0.2.0
200
- # @api private
201
- def before_callbacks
202
- @node.before_callbacks
203
- end
204
-
205
- # @since 0.2.0
206
- # @api private
207
- def after_callbacks
208
- @node.after_callbacks
209
- end
210
- end
211
- end
212
- end
213
- end
@@ -1,32 +0,0 @@
1
- module Hanami
2
- class CLI
3
- # @since 0.2.0
4
- class Error < StandardError
5
- end
6
-
7
- # @since 0.2.0
8
- class UnkwnownCommandError < Error
9
- # @since 0.2.0
10
- # @api private
11
- def initialize(command_name)
12
- super("unknown command: `#{command_name}'")
13
- end
14
- end
15
-
16
- # @since 0.2.0
17
- class InvalidCallbackError < Error
18
- # @since 0.2.0
19
- # @api private
20
- def initialize(callback)
21
- message = case callback
22
- when Class
23
- "expected `#{callback.inspect}' to respond to `#initialize' with arity 0"
24
- else
25
- "expected `#{callback.inspect}' to respond to `#call'"
26
- end
27
-
28
- super(message)
29
- end
30
- end
31
- end
32
- end
@@ -1,125 +0,0 @@
1
- require "hanami/utils/string"
2
-
3
- module Hanami
4
- class CLI
5
- # Command line option
6
- #
7
- # @since 0.1.0
8
- # @api private
9
- class Option
10
- # @since 0.1.0
11
- # @api private
12
- attr_reader :name
13
-
14
- # @since 0.1.0
15
- # @api private
16
- attr_reader :options
17
-
18
- # @since 0.1.0
19
- # @api private
20
- def initialize(name, options = {})
21
- @name = name
22
- @options = options
23
- end
24
-
25
- # @since 0.1.0
26
- # @api private
27
- def aliases
28
- options[:aliases] || []
29
- end
30
-
31
- # @since 0.1.0
32
- # @api private
33
- def desc
34
- desc = options[:desc]
35
- values ? "#{desc}: (#{values.join('/')})" : desc
36
- end
37
-
38
- # @since 0.1.0
39
- # @api private
40
- def required?
41
- options[:required]
42
- end
43
-
44
- # @since 0.1.0
45
- # @api private
46
- def type
47
- options[:type]
48
- end
49
-
50
- # @since 0.1.0
51
- # @api private
52
- def values
53
- options[:values]
54
- end
55
-
56
- # @since 0.1.0
57
- # @api private
58
- def boolean?
59
- type == :boolean
60
- end
61
-
62
- # @since 0.1.0
63
- # @api private
64
- def default
65
- options[:default]
66
- end
67
-
68
- # @since 0.1.0
69
- # @api private
70
- def description_name
71
- options[:label] || name.upcase
72
- end
73
-
74
- # @since 0.1.0
75
- # @api private
76
- def argument?
77
- false
78
- end
79
-
80
- # @since 0.1.0
81
- # @api private
82
- #
83
- # rubocop:disable Metrics/AbcSize
84
- # rubocop:disable Metrics/MethodLength
85
- def parser_options
86
- dasherized_name = Hanami::Utils::String.dasherize(name)
87
- parser_options = []
88
-
89
- if type == :boolean
90
- parser_options << "--[no-]#{dasherized_name}"
91
- else
92
- parser_options << "--#{dasherized_name}=#{name}"
93
- parser_options << "--#{dasherized_name} #{name}"
94
- end
95
-
96
- parser_options << values if values
97
- parser_options.unshift(alias_name) unless alias_name.nil?
98
- parser_options << desc if desc
99
- parser_options
100
- end
101
- # rubocop:enable Metrics/MethodLength
102
- # rubocop:enable Metrics/AbcSize
103
-
104
- private
105
-
106
- # @since 0.1.0
107
- # @api private
108
- def alias_name
109
- aliases.join(" ") if aliases.any?
110
- end
111
- end
112
-
113
- # Command line argument
114
- #
115
- # @since 0.1.0
116
- # @api private
117
- class Argument < Option
118
- # @since 0.1.0
119
- # @api private
120
- def argument?
121
- true
122
- end
123
- end
124
- end
125
- end