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