command_kit 0.1.0 → 0.3.0

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +18 -3
  3. data/.rubocop.yml +141 -0
  4. data/ChangeLog.md +165 -0
  5. data/Gemfile +3 -0
  6. data/README.md +186 -118
  7. data/Rakefile +3 -2
  8. data/command_kit.gemspec +4 -4
  9. data/examples/command.rb +1 -1
  10. data/gemspec.yml +7 -0
  11. data/lib/command_kit/arguments/argument.rb +2 -2
  12. data/lib/command_kit/arguments.rb +36 -7
  13. data/lib/command_kit/colors.rb +702 -53
  14. data/lib/command_kit/command.rb +2 -3
  15. data/lib/command_kit/commands/auto_load.rb +8 -1
  16. data/lib/command_kit/commands/help.rb +3 -2
  17. data/lib/command_kit/commands/subcommand.rb +1 -1
  18. data/lib/command_kit/commands.rb +24 -9
  19. data/lib/command_kit/env/path.rb +1 -1
  20. data/lib/command_kit/file_utils.rb +46 -0
  21. data/lib/command_kit/help/man.rb +17 -33
  22. data/lib/command_kit/inflector.rb +47 -17
  23. data/lib/command_kit/interactive.rb +9 -0
  24. data/lib/command_kit/main.rb +7 -9
  25. data/lib/command_kit/man.rb +44 -0
  26. data/lib/command_kit/open_app.rb +69 -0
  27. data/lib/command_kit/options/option.rb +41 -27
  28. data/lib/command_kit/options/option_value.rb +3 -2
  29. data/lib/command_kit/options/parser.rb +17 -22
  30. data/lib/command_kit/options.rb +102 -14
  31. data/lib/command_kit/os/linux.rb +157 -0
  32. data/lib/command_kit/os.rb +159 -11
  33. data/lib/command_kit/package_manager.rb +200 -0
  34. data/lib/command_kit/pager.rb +46 -4
  35. data/lib/command_kit/printing/indent.rb +4 -4
  36. data/lib/command_kit/printing.rb +14 -3
  37. data/lib/command_kit/program_name.rb +9 -0
  38. data/lib/command_kit/sudo.rb +40 -0
  39. data/lib/command_kit/terminal.rb +5 -0
  40. data/lib/command_kit/version.rb +1 -1
  41. data/spec/arguments/argument_spec.rb +1 -1
  42. data/spec/arguments_spec.rb +84 -1
  43. data/spec/colors_spec.rb +357 -70
  44. data/spec/command_spec.rb +77 -6
  45. data/spec/commands/auto_load_spec.rb +33 -2
  46. data/spec/commands_spec.rb +101 -29
  47. data/spec/env/path_spec.rb +6 -0
  48. data/spec/exception_handler_spec.rb +1 -1
  49. data/spec/file_utils_spec.rb +59 -0
  50. data/spec/fixtures/template.erb +5 -0
  51. data/spec/help/man_spec.rb +54 -57
  52. data/spec/inflector_spec.rb +70 -8
  53. data/spec/man_spec.rb +46 -0
  54. data/spec/open_app_spec.rb +85 -0
  55. data/spec/options/option_spec.rb +38 -2
  56. data/spec/options/option_value_spec.rb +55 -0
  57. data/spec/options/parser_spec.rb +0 -10
  58. data/spec/options_spec.rb +328 -0
  59. data/spec/os/linux_spec.rb +164 -0
  60. data/spec/os_spec.rb +200 -13
  61. data/spec/package_manager_spec.rb +806 -0
  62. data/spec/pager_spec.rb +71 -6
  63. data/spec/printing/indent_spec.rb +7 -5
  64. data/spec/printing_spec.rb +23 -1
  65. data/spec/program_name_spec.rb +8 -0
  66. data/spec/sudo_spec.rb +51 -0
  67. data/spec/terminal_spec.rb +30 -0
  68. data/spec/usage_spec.rb +1 -1
  69. metadata +23 -4
data/README.md CHANGED
@@ -1,8 +1,12 @@
1
1
  # command_kit
2
2
 
3
+ [![Build Status](https://github.com/postmodern/command_kit.rb/workflows/CI/badge.svg?branch=main)](https://github.com/postmodern/command_kit.rb/actions)
4
+ [![Code Climate](https://codeclimate.com/github/postmodern/command_kit.rb.svg)](https://codeclimate.com/github/postmodern/command_kit.rb)
5
+ [![Gem Version](https://badge.fury.io/rb/command_kit.svg)](https://badge.fury.io/rb/command_kit)
6
+
3
7
  * [Homepage](https://github.com/postmodern/command_kit.rb#readme)
4
- * [Forum](https://github.com/postmodern/command_kit.rb/discussions)
5
- * [Issues](https://github.com/postmodern/command_kit.rb/issues)
8
+ * [Forum](https://github.com/postmodern/command_kit.rb/discussions) |
9
+ [Issues](https://github.com/postmodern/command_kit.rb/issues)
6
10
  * [Documentation](http://rubydoc.info/gems/command_kit/frames)
7
11
 
8
12
  ## Description
@@ -12,53 +16,26 @@ plain-old Ruby classes.
12
16
 
13
17
  ## Features
14
18
 
15
- * Supports defining commands as Classes.
16
- * Supports defining options and arguments as attributes.
17
- * Supports extending commands via inheritance.
18
- * Supports subcommands (explicit or lazy-loaded) and command aliases.
19
- * Correctly handles Ctrl^C and SIGINT interrupts (aka exit 130).
20
- * Correctly handles broken pipes (aka `mycmd | head`).
21
- * Correctly handles when stdout or stdin is redirected to a file.
22
- * Uses [OptionParser][optparse] for POSIX option parsing.
23
- * Supports optionally displaying a man-page instead of `--help`
24
- (see {CommandKit::Help::Man}).
25
- * Supports optional ANSI coloring.
26
- * Supports interactively prompting for user input.
27
- * Supports easily detecting the terminal size.
28
- * Supports paging output with `less` or `more`.
29
- * Supports XDG directories (`~/.config/`, `~/.local/share/`, `~/.cache/`).
30
- * Easy to test (ex: `MyCmd.main(arg1, arg2, options: {foo: foo}) # => 0`)
31
-
32
- ### API
33
-
34
- * [CommandKit::Arguments](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Arguments)
35
- * [CommandKit::Colors](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Colors)
36
- * [CommandKit::Command](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Command)
37
- * [CommandKit::CommandName](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/CommandName)
38
- * [CommandKit::Commands](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Commands)
39
- * [CommandKit::Commands::AutoLoad](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Commands/AutoLoad)
40
- * [CommandKit::Commands::AutoRequire](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Commands/AutoRequire)
41
- * [CommandKit::Description](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Description)
42
- * [CommandKit::Env](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Env)
43
- * [CommandKit::Env::Home](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Env/Home)
44
- * [CommandKit::Env::Path](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Env/Path)
45
- * [CommandKit::Examples](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Examples)
46
- * [CommandKit::ExceptionHandler](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/ExceptionHandler)
47
- * [CommandKit::Help](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Help)
48
- * [CommandKit::Help::Man](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Help/Man)
49
- * [CommandKit::Interactive](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Interactive)
50
- * [CommandKit::Main](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Main)
51
- * [CommandKit::Options](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Options)
52
- * [CommandKit::Options::Quiet](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Options/Quiet)
53
- * [CommandKit::Options::Verbose](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Options/Verbose)
54
- * [CommandKit::Pager](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Pager)
55
- * [CommandKit::Printing](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Printing)
56
- * [CommandKit::Printing::Indent](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Printing/Indent)
57
- * [CommandKit::ProgramName](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/ProgramName)
58
- * [CommandKit::Stdio](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Stdio)
59
- * [CommandKit::Terminal](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Terminal)
60
- * [CommandKit::Usage](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Usage)
61
- * [CommandKit::XDG](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/XDG)
19
+ * **Simple** - Commands are plain-old ruby classes, with options and
20
+ arguments declared as attributes. All features are ruby modules that can be
21
+ included into command classes.
22
+ * **Correct** - CommandKit behaves like a standard UNIX command.
23
+ * Safely handles Ctrl^C / SIGINT interrupts and [exits with 130](https://tldp.org/LDP/abs/html/exitcodes.html).
24
+ * Safely handles broken pipes (aka `mycmd | head`).
25
+ * Respects common environment variables (ex: `TERM=dumb`).
26
+ * Uses [OptionParser][optparse] for POSIX option parsing.
27
+ * Disables ANSI color when output is redirected to a file.
28
+ * **Complete** - Provides many additional CLI features.
29
+ * OS detection.
30
+ * Terminal size detection.
31
+ * ANSI coloring support.
32
+ * Interactive input.
33
+ * Subcommands (explicit or lazy-loaded) and command aliases.
34
+ * Displaying man pages for `--help`/`help`.
35
+ * Using the pager (aka `less`).
36
+ * [XDG directories](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) (aka `~/.config/`, `~/.local/share/`, `~/.cache/`).
37
+ * **Testable** - Since commands are plain-old ruby classes, it's easy to
38
+ initialize them and call `#main` or `#run`.
62
39
 
63
40
  ## Anti-Features
64
41
 
@@ -66,103 +43,194 @@ plain-old Ruby classes.
66
43
  * Does not implement it's own option parser.
67
44
  * Not named after a comic-book Superhero.
68
45
 
46
+ ## Requirements
47
+
48
+ * [ruby] >= 2.7.0
49
+
50
+ ## Install
51
+
52
+ ```sh
53
+ $ gem install command_kit
54
+ ```
55
+
56
+ ### gemspec
57
+
58
+ ```ruby
59
+ gem.add_dependency 'command_kit', '~> 0.2'
60
+ ```
61
+
62
+ ### Gemfile
63
+
64
+ ```ruby
65
+ gem 'command_kit', '~> 0.2'
66
+ ```
67
+
69
68
  ## Examples
70
69
 
71
70
  ### lib/foo/cli/my_cmd.rb
72
71
 
73
- require 'command_kit'
74
-
75
- module Foo
76
- module CLI
77
- class MyCmd < CommandKit::Command
78
-
79
- usage '[OPTIONS] [-o OUTPUT] FILE'
80
-
81
- option :count, short: '-c',
82
- value: {
83
- type: Integer,
84
- default: 1
85
- },
86
- desc: "Number of times"
87
-
88
- option :output, short: '-o',
89
- value: {
90
- type: String,
91
- usage: 'FILE'
92
- },
93
- desc: "Optional output file"
94
-
95
- option :verbose, short: '-v', desc: "Increase verbose level" do
96
- @verbose += 1
97
- end
98
-
99
- argument :file, required: true,
100
- usage: 'FILE',
101
- desc: "Input file"
102
-
103
- examples [
104
- '-o path/to/output.txt path/to/input.txt',
105
- '-v -c 2 -o path/to/output.txt path/to/input.txt',
106
- ]
107
-
108
- description 'Example command'
109
-
110
- def initialize(**kwargs)
111
- super(**kwargs)
112
-
113
- @verbose = 0
114
- end
115
-
116
- def run(file)
117
- puts "count=#{options[:count].inspect}"
118
- puts "output=#{options[:output].inspect}"
119
- puts "file=#{file.inspect}"
120
- puts "verbose=#{@verbose.inspect}"
121
- end
122
-
123
- end
72
+ ```ruby
73
+ require 'command_kit'
74
+
75
+ module Foo
76
+ module CLI
77
+ class MyCmd < CommandKit::Command
78
+
79
+ usage '[OPTIONS] [-o OUTPUT] FILE'
80
+
81
+ option :count, short: '-c',
82
+ value: {
83
+ type: Integer,
84
+ default: 1
85
+ },
86
+ desc: "Number of times"
87
+
88
+ option :output, short: '-o',
89
+ value: {
90
+ type: String,
91
+ usage: 'FILE'
92
+ },
93
+ desc: "Optional output file"
94
+
95
+ option :verbose, short: '-v', desc: "Increase verbose level" do
96
+ @verbose += 1
124
97
  end
98
+
99
+ argument :file, required: true,
100
+ usage: 'FILE',
101
+ desc: "Input file"
102
+
103
+ examples [
104
+ '-o path/to/output.txt path/to/input.txt',
105
+ '-v -c 2 -o path/to/output.txt path/to/input.txt',
106
+ ]
107
+
108
+ description 'Example command'
109
+
110
+ def initialize(**kwargs)
111
+ super(**kwargs)
112
+
113
+ @verbose = 0
114
+ end
115
+
116
+ def run(file)
117
+ puts "count=#{options[:count].inspect}"
118
+ puts "output=#{options[:output].inspect}"
119
+ puts "file=#{file.inspect}"
120
+ puts "verbose=#{@verbose.inspect}"
121
+ end
122
+
125
123
  end
124
+ end
125
+ end
126
+ ```
126
127
 
127
128
  ### bin/my_cmd
128
129
 
129
- #!/usr/bin/env ruby
130
-
131
- $LOAD_PATH.unshift(File.expand_path('../../lib',__FILE__))
132
- require 'foo/cli/my_cmd'
133
-
134
- Foo::CLI::MyCmd.start
130
+ ```ruby
131
+ #!/usr/bin/env ruby
132
+
133
+ $LOAD_PATH.unshift(File.expand_path('../../lib',__FILE__))
134
+ require 'foo/cli/my_cmd'
135
+
136
+ Foo::CLI::MyCmd.start
137
+ ```
135
138
 
136
139
  ### --help
137
140
 
138
141
  Usage: my_cmd [OPTIONS] [-o OUTPUT] FILE
139
-
142
+
140
143
  Options:
141
144
  -c, --count INT Number of times (Default: 1)
142
145
  -o, --output FILE Optional output file
143
146
  -v, --verbose Increase verbose level
144
147
  -h, --help Print help information
145
-
148
+
146
149
  Arguments:
147
150
  FILE Input file
148
-
151
+
149
152
  Examples:
150
153
  my_cmd -o path/to/output.txt path/to/input.txt
151
154
  my_cmd -v -c 2 -o path/to/output.txt path/to/input.txt
152
-
153
- Example command
154
155
 
155
- ## Requirements
156
-
157
- * [ruby] >= 2.7.0
156
+ Example command
158
157
 
159
- ## Install
158
+ ## Testing
159
+
160
+ ### RSpec
161
+
162
+ ```ruby
163
+ require 'spec_helper'
164
+ require 'stringio'
165
+ require 'foo/cli/my_cmd'
166
+
167
+ describe Foo::CLI::MyCmd do
168
+ let(:stdin) { StringIO.new }
169
+ let(:stdout) { StringIO.new }
170
+ let(:stderr) { StringIO.new }
171
+ let(:env) { ENV }
172
+
173
+ subject do
174
+ described_class.new(
175
+ stdin: stdin,
176
+ stdout: stdout,
177
+ stderr: stderr,
178
+ env: env
179
+ )
180
+ end
181
+
182
+ # testing with raw options/arguments
183
+ describe "#main" do
184
+ context "when executed with no arguments" do
185
+ it "must exit with -1" do
186
+ expect(subject.main([])).to eq(-1)
187
+ end
188
+ end
160
189
 
161
- $ gem install command_kit
190
+ context "when executed with -o OUTPUT" do
191
+ let(:file) { ... }
192
+ let(:output) { ... }
162
193
 
163
- ### Gemfile
194
+ before { subject.main(["-o", output, file]) }
164
195
 
165
- gem 'command_kit', '~> 0.1'
196
+ it "must create the output file" do
197
+ ...
198
+ end
199
+ end
200
+ end
201
+ end
202
+ ```
203
+
204
+ ### Reference
205
+
206
+ * [CommandKit::Arguments](https://rubydoc.info/gems/command_kit/CommandKit/Arguments)
207
+ * [CommandKit::Colors](https://rubydoc.info/gems/command_kit/CommandKit/Colors)
208
+ * [CommandKit::Command](https://rubydoc.info/gems/command_kit/CommandKit/Command)
209
+ * [CommandKit::CommandName](https://rubydoc.info/gems/command_kit/CommandKit/CommandName)
210
+ * [CommandKit::Commands](https://rubydoc.info/gems/command_kit/CommandKit/Commands)
211
+ * [CommandKit::Commands::AutoLoad](https://rubydoc.info/gems/command_kit/CommandKit/Commands/AutoLoad)
212
+ * [CommandKit::Commands::AutoRequire](https://rubydoc.info/gems/command_kit/CommandKit/Commands/AutoRequire)
213
+ * [CommandKit::Description](https://rubydoc.info/gems/command_kit/CommandKit/Description)
214
+ * [CommandKit::Env](https://rubydoc.info/gems/command_kit/CommandKit/Env)
215
+ * [CommandKit::Env::Home](https://rubydoc.info/gems/command_kit/CommandKit/Env/Home)
216
+ * [CommandKit::Env::Path](https://rubydoc.info/gems/command_kit/CommandKit/Env/Path)
217
+ * [CommandKit::Examples](https://rubydoc.info/gems/command_kit/CommandKit/Examples)
218
+ * [CommandKit::ExceptionHandler](https://rubydoc.info/gems/command_kit/CommandKit/ExceptionHandler)
219
+ * [CommandKit::Help](https://rubydoc.info/gems/command_kit/CommandKit/Help)
220
+ * [CommandKit::Help::Man](https://rubydoc.info/gems/command_kit/CommandKit/Help/Man)
221
+ * [CommandKit::Interactive](https://rubydoc.info/gems/command_kit/CommandKit/Interactive)
222
+ * [CommandKit::Main](https://rubydoc.info/gems/command_kit/CommandKit/Main)
223
+ * [CommandKit::Options](https://rubydoc.info/gems/command_kit/CommandKit/Options)
224
+ * [CommandKit::Options::Quiet](https://rubydoc.info/gems/command_kit/CommandKit/Options/Quiet)
225
+ * [CommandKit::Options::Verbose](https://rubydoc.info/gems/command_kit/CommandKit/Options/Verbose)
226
+ * [CommandKit::Pager](https://rubydoc.info/gems/command_kit/CommandKit/Pager)
227
+ * [CommandKit::Printing](https://rubydoc.info/gems/command_kit/CommandKit/Printing)
228
+ * [CommandKit::Printing::Indent](https://rubydoc.info/gems/command_kit/CommandKit/Printing/Indent)
229
+ * [CommandKit::ProgramName](https://rubydoc.info/gems/command_kit/CommandKit/ProgramName)
230
+ * [CommandKit::Stdio](https://rubydoc.info/gems/command_kit/CommandKit/Stdio)
231
+ * [CommandKit::Terminal](https://rubydoc.info/gems/command_kit/CommandKit/Terminal)
232
+ * [CommandKit::Usage](https://rubydoc.info/gems/command_kit/CommandKit/Usage)
233
+ * [CommandKit::XDG](https://rubydoc.info/gems/command_kit/CommandKit/XDG)
166
234
 
167
235
  ## Alternatives
168
236
 
data/Rakefile CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  require 'rubygems'
4
2
 
5
3
  begin
@@ -21,3 +19,6 @@ task :default => :spec
21
19
  require 'yard'
22
20
  YARD::Rake::YardocTask.new
23
21
  task :doc => :yard
22
+
23
+ require 'rubocop/rake_task'
24
+ RuboCop::RakeTask.new
data/command_kit.gemspec CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  require 'yaml'
4
2
 
5
3
  Gem::Specification.new do |gem|
@@ -20,11 +18,13 @@ Gem::Specification.new do |gem|
20
18
  gem.authors = Array(gemspec['authors'])
21
19
  gem.email = gemspec['email']
22
20
  gem.homepage = gemspec['homepage']
21
+ gem.metadata = gemspec['metadata'] if gemspec['metadata']
23
22
 
24
23
  glob = lambda { |patterns| gem.files & Dir[*patterns] }
25
24
 
26
- gem.files = `git ls-files`.split($/)
27
- gem.files = glob[gemspec['files']] if gemspec['files']
25
+ gem.files = if gemspec['files'] then glob[gemspec['files']]
26
+ else `git ls-files`.split($/)
27
+ end
28
28
 
29
29
  gem.executables = gemspec.fetch('executables') do
30
30
  glob['bin/*'].map { |path| File.basename(path) }
data/examples/command.rb CHANGED
@@ -16,7 +16,7 @@ class Command < CommandKit::Command
16
16
 
17
17
  option :output, value: {
18
18
  type: String,
19
- usage: 'FILE',
19
+ usage: 'FILE'
20
20
  },
21
21
  short: '-o',
22
22
  desc: "Optional output file"
data/gemspec.yml CHANGED
@@ -9,6 +9,13 @@ authors: Postmodern
9
9
  email: postmodern.mod3@gmail.com
10
10
  homepage: https://github.com/postmodern/command_kit.rb#readme
11
11
 
12
+ metadata:
13
+ documentation_uri: https://rubydoc.info/gems/command_kit
14
+ source_code_uri: https://github.com/postmodern/command_kit.rb
15
+ bug_tracker_uri: https://github.com/postmodern/command_kit.rb/issues
16
+ changelog_uri: https://github.com/postmodern/command_kit.rb/blob/main/ChangeLog.md
17
+ rubygems_mfa_required: 'true'
18
+
12
19
  required_ruby_version: ">= 2.7.0"
13
20
 
14
21
  development_dependencies:
@@ -16,7 +16,7 @@ module CommandKit
16
16
 
17
17
  # The argument's description.
18
18
  #
19
- # @return [String]
19
+ # @return [String, Array<String>]
20
20
  attr_reader :desc
21
21
 
22
22
  #
@@ -34,7 +34,7 @@ module CommandKit
34
34
  # @param [Boolean] repeats
35
35
  # Specifies whether the argument can be repeated multiple times.
36
36
  #
37
- # @param [String] desc
37
+ # @param [String, Array<String>] desc
38
38
  # The description for the argument.
39
39
  #
40
40
  # @yield [(value)]
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'command_kit/arguments/argument'
4
+ require 'command_kit/usage'
3
5
  require 'command_kit/main'
4
6
  require 'command_kit/help'
5
- require 'command_kit/arguments/argument'
7
+ require 'command_kit/printing'
6
8
 
7
9
  module CommandKit
8
10
  #
@@ -44,9 +46,19 @@ module CommandKit
44
46
  # def run(*files)
45
47
  # end
46
48
  #
49
+ # ### Multi-line descriptions
50
+ #
51
+ # argument :arg, desc: [
52
+ # 'line1',
53
+ # 'line2',
54
+ # '...'
55
+ # ]
56
+ #
47
57
  module Arguments
58
+ include Usage
48
59
  include Main
49
60
  include Help
61
+ include Printing
50
62
 
51
63
  #
52
64
  # @api private
@@ -110,7 +122,7 @@ module CommandKit
110
122
  # @option kwargs [Boolean] repeats
111
123
  # Specifies whether the argument can be repeated multiple times.
112
124
  #
113
- # @option kwargs [String] desc
125
+ # @option kwargs [String, Array<String>] desc
114
126
  # The description for the argument.
115
127
  #
116
128
  # @return [Argument]
@@ -119,9 +131,15 @@ module CommandKit
119
131
  # @example Define an argument:
120
132
  # argument :bar, desc: "Bar argument"
121
133
  #
134
+ # @example Defines an argument with a multi-line description:
135
+ # argument :bar, desc: [
136
+ # "Line 1 ...",
137
+ # "Line 2 ..."
138
+ # ]
139
+ #
122
140
  # @example With a custom usage string:
123
- # option :bar, usage: 'BAR',
124
- # desc: "Bar argument"
141
+ # argument :bar, usage: 'BAR',
142
+ # desc: "Bar argument"
125
143
  #
126
144
  # @example With a custom type:
127
145
  # argument :bar, desc: "Bar argument"
@@ -168,7 +186,7 @@ module CommandKit
168
186
  help_usage
169
187
  return 1
170
188
  elsif argv.length > (required_args + optional_args) && !has_repeats_arg
171
- print_error("too many arguments given")
189
+ print_error("too many arguments given.")
172
190
  help_usage
173
191
  return 1
174
192
  end
@@ -186,8 +204,19 @@ module CommandKit
186
204
  puts
187
205
  puts 'Arguments:'
188
206
 
189
- self.class.arguments.each_value do |arg|
190
- puts " #{arg.usage.ljust(33)}#{arg.desc}"
207
+ arguments.each_value do |arg|
208
+ case arg.desc
209
+ when Array
210
+ arg.desc.each_with_index do |line,index|
211
+ if index == 0
212
+ puts " #{arg.usage.ljust(33)}#{line}"
213
+ else
214
+ puts " #{' '.ljust(33)}#{line}"
215
+ end
216
+ end
217
+ else
218
+ puts " #{arg.usage.ljust(33)}#{arg.desc}"
219
+ end
191
220
  end
192
221
  end
193
222
  end