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/.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