command_kit 0.2.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +4 -5
  3. data/.rubocop.yml +14 -1
  4. data/ChangeLog.md +82 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE.txt +1 -1
  7. data/README.md +18 -9
  8. data/command_kit.gemspec +0 -1
  9. data/examples/printing/tables.rb +141 -0
  10. data/gemspec.yml +3 -3
  11. data/lib/command_kit/arguments/argument.rb +2 -2
  12. data/lib/command_kit/arguments.rb +27 -2
  13. data/lib/command_kit/bug_report.rb +105 -0
  14. data/lib/command_kit/colors.rb +488 -15
  15. data/lib/command_kit/command.rb +1 -2
  16. data/lib/command_kit/edit.rb +54 -0
  17. data/lib/command_kit/env.rb +1 -1
  18. data/lib/command_kit/file_utils.rb +46 -0
  19. data/lib/command_kit/options/option.rb +45 -22
  20. data/lib/command_kit/options/option_value.rb +2 -2
  21. data/lib/command_kit/options/parser.rb +1 -4
  22. data/lib/command_kit/options/quiet.rb +1 -1
  23. data/lib/command_kit/options/verbose.rb +2 -2
  24. data/lib/command_kit/options/version.rb +10 -0
  25. data/lib/command_kit/options.rb +89 -14
  26. data/lib/command_kit/os.rb +1 -1
  27. data/lib/command_kit/printing/fields.rb +56 -0
  28. data/lib/command_kit/printing/indent.rb +1 -1
  29. data/lib/command_kit/printing/lists.rb +91 -0
  30. data/lib/command_kit/printing/tables/border_style.rb +169 -0
  31. data/lib/command_kit/printing/tables/cell_builder.rb +93 -0
  32. data/lib/command_kit/printing/tables/row_builder.rb +111 -0
  33. data/lib/command_kit/printing/tables/style.rb +198 -0
  34. data/lib/command_kit/printing/tables/table_builder.rb +145 -0
  35. data/lib/command_kit/printing/tables/table_formatter.rb +254 -0
  36. data/lib/command_kit/printing/tables.rb +208 -0
  37. data/lib/command_kit/program_name.rb +9 -0
  38. data/lib/command_kit/stdio.rb +5 -1
  39. data/lib/command_kit/version.rb +1 -1
  40. data/spec/arguments_spec.rb +33 -0
  41. data/spec/bug_report_spec.rb +266 -0
  42. data/spec/colors_spec.rb +232 -195
  43. data/spec/command_name_spec.rb +1 -1
  44. data/spec/command_spec.rb +2 -2
  45. data/spec/edit_spec.rb +72 -0
  46. data/spec/file_utils_spec.rb +59 -0
  47. data/spec/fixtures/template.erb +5 -0
  48. data/spec/options/option_spec.rb +48 -2
  49. data/spec/options/parser_spec.rb +0 -10
  50. data/spec/options/quiet_spec.rb +51 -0
  51. data/spec/options/verbose_spec.rb +51 -0
  52. data/spec/options/version_spec.rb +146 -0
  53. data/spec/options_spec.rb +46 -0
  54. data/spec/pager_spec.rb +1 -1
  55. data/spec/printing/fields_spec.rb +167 -0
  56. data/spec/printing/lists_spec.rb +99 -0
  57. data/spec/printing/tables/border_style.rb +43 -0
  58. data/spec/printing/tables/cell_builer_spec.rb +135 -0
  59. data/spec/printing/tables/row_builder_spec.rb +165 -0
  60. data/spec/printing/tables/style_spec.rb +377 -0
  61. data/spec/printing/tables/table_builder_spec.rb +252 -0
  62. data/spec/printing/tables/table_formatter_spec.rb +1180 -0
  63. data/spec/printing/tables_spec.rb +1069 -0
  64. data/spec/program_name_spec.rb +8 -0
  65. metadata +36 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d04119403fa9585e0258d2b20bb7c307d124aafb70c88e03749395c7b4eedb97
4
- data.tar.gz: 3ec992adf12bbc98313bb6ff8f3038091b50b31abbf8950765a71edd771378fb
3
+ metadata.gz: 72a3fdeb65d9eb4c4e996aa95ea7e8131e220c2cb24be8b17d56e1742a156d35
4
+ data.tar.gz: d05b75366f58c219c9680d07571a171239f0ab8f77580cb1c2d47c6322d7e74c
5
5
  SHA512:
6
- metadata.gz: faeeaa08921ab315a825d4b1ff69f6b254c53b6675dd4278478b77200d6d2afb688d110757685ed33d74b90a6b1e9394c12135c3ab5f08e2ca3ca5834ead248d
7
- data.tar.gz: 6b4ba3da0434c9fbd93d92a4c9d91e8eb53f1185df15edb21283c09b2ddf9ec4dc9fcb3708bdf83a1158cef92c988ccb5133ec5664ac9dcb213bdcde45aacf3d
6
+ metadata.gz: 1cc85835b40fded3170ee21619620dbb988dd3427fa8cb48456f09a7991b6eed72299a81ba19be543c260557504d5636237993f33360d463d72a87600ca14441
7
+ data.tar.gz: 9d57ec57d540547d2fa664faf8e3bb1e0c0aa06929162d3dac849f858911aa5e7610e8294b2189927d8633de8e9784079df548a3e900fd73c57f76e72c87ad9d
@@ -10,12 +10,11 @@ jobs:
10
10
  fail-fast: false
11
11
  matrix:
12
12
  ruby:
13
- - 2.7
14
- - 3.0
13
+ - '3.0'
14
+ - '3.1'
15
15
  # TODO: uncomment when jruby supports ruby >= 2.7
16
16
  # - jruby
17
- # TODO: uncomment when truffleruby supports splatting empty kwargs
18
- # - truffleruby
17
+ - truffleruby
19
18
  name: Ruby ${{ matrix.ruby }}
20
19
  steps:
21
20
  - uses: actions/checkout@v2
@@ -36,7 +35,7 @@ jobs:
36
35
  - name: Set up Ruby
37
36
  uses: ruby/setup-ruby@v1
38
37
  with:
39
- ruby-version: 2.7
38
+ ruby-version: 3.0
40
39
  - name: Install dependencies
41
40
  run: bundle install --jobs 4 --retry 3
42
41
  - name: Run rubocop
data/.rubocop.yml CHANGED
@@ -7,7 +7,7 @@ AllCops:
7
7
  # our rules
8
8
  #
9
9
 
10
- Layout/FirstArrayElementIndentation: { EnforcedStyle: consistent }
10
+ Layout/FirstArrayElementIndentation: { Exclude: ['spec/**/*'] }
11
11
  Layout/LineLength: { Enabled: false }
12
12
  Layout/SpaceAroundEqualsInParameterDefault: { EnforcedStyle: no_space }
13
13
  Lint/ConstantDefinitionInBlock: { Exclude: ['spec/**/*'] }
@@ -22,6 +22,7 @@ Style/PercentLiteralDelimiters:
22
22
  '%I': '[]'
23
23
  '%w': '[]'
24
24
  '%W': '[]'
25
+ Style/UnlessElse: { Enabled: false }
25
26
 
26
27
  #
27
28
  # rules that are in flux
@@ -139,3 +140,15 @@ Style/TrailingCommaInHashLiteral: { Enabled: false } # Offense count: 2
139
140
 
140
141
  # rubocop cannot tell that rubygems_mfa_required is enabled in gemspec.yml
141
142
  Gemspec/RequireMFA: { Enabled: false }
143
+
144
+ # make an exception for our gemspec code
145
+ Gemspec/DuplicatedAssignment:
146
+ Exclude:
147
+ - 'command_kit.gemspec'
148
+
149
+ Bundler/OrderedGems: { Enabled: false }
150
+
151
+ # rubocup is not aware of vertical alignment of matrixes (Array of Arrays).
152
+ Layout/SpaceInsideArrayLiteralBrackets: { Enabled: false }
153
+
154
+ Naming/HeredocDelimiterNaming: { Enabled: false }
data/ChangeLog.md CHANGED
@@ -1,3 +1,85 @@
1
+ ### 0.4.0 / 2022-11-11
2
+
3
+ * Added {CommandKit::BugReport}.
4
+ * Added {CommandKit::Edit}.
5
+ * Added {CommandKit::Printing::Fields}.
6
+ * Added {CommandKit::Printing::Lists}.
7
+ * Added {CommandKit::Printing::Tables}.
8
+
9
+ #### CommandKit::Colors
10
+
11
+ * Support disabling ANSI color output if the `NO_COLOR` environment variable is
12
+ set.
13
+
14
+ #### CommandKit::Options
15
+
16
+ * Correct the option usage for long option flags that have optional values
17
+ (ex: `--longopt[=VALUE]`).
18
+
19
+ ### 0.3.0 / 2021-12-26
20
+
21
+ * Added {CommandKit::FileUtils}.
22
+
23
+ #### CommandKit::FileUtils
24
+
25
+ * Added {CommandKit::FileUtils#erb #erb}.
26
+
27
+ #### CommandKit::Colors
28
+
29
+ * Added {CommandKit::Colors::ANSI::RESET_FG RESET_FG}.
30
+ * Added {CommandKit::Colors::ANSI.bright_black bright_black}.
31
+ * Added {CommandKit::Colors::ANSI.gray gray}.
32
+ * Added {CommandKit::Colors::ANSI.bright_red bright_red}.
33
+ * Added {CommandKit::Colors::ANSI.bright_green bright_green}.
34
+ * Added {CommandKit::Colors::ANSI.bright_yellow bright_yellow}.
35
+ * Added {CommandKit::Colors::ANSI.bright_blue bright_blue}.
36
+ * Added {CommandKit::Colors::ANSI.bright_magenta bright_magenta}.
37
+ * Added {CommandKit::Colors::ANSI.bright_cyan bright_cyan}.
38
+ * Added {CommandKit::Colors::ANSI.bright_white bright_white}.
39
+ * Added {CommandKit::Colors::ANSI.on_bright_black on_bright_black}.
40
+ * Added {CommandKit::Colors::ANSI.on_gray on_gray}.
41
+ * Added {CommandKit::Colors::ANSI.on_bright_red on_bright_red}.
42
+ * Added {CommandKit::Colors::ANSI.on_bright_green on_bright_green}.
43
+ * Added {CommandKit::Colors::ANSI.on_bright_yellow on_bright_yellow}.
44
+ * Added {CommandKit::Colors::ANSI.on_bright_blue on_bright_blue}.
45
+ * Added {CommandKit::Colors::ANSI.on_bright_magenta on_bright_magenta}.
46
+ * Added {CommandKit::Colors::ANSI.on_bright_cyan on_bright_cyan}.
47
+ * Added {CommandKit::Colors::ANSI.on_bright_white on_bright_white}.
48
+
49
+ #### ComandKit::Options
50
+
51
+ * Allow grouping options into categories:
52
+
53
+ option :opt1, category: 'Foo Options',
54
+ desc: 'Option 1'
55
+
56
+ option :opt2, category: 'Foo Options',
57
+ desc: 'Option 1'
58
+
59
+ * Allow options to have multi-line descriptions:
60
+
61
+ option :opt1, short: '-o',
62
+ desc: [
63
+ 'line1',
64
+ 'line2',
65
+ '...'
66
+ ]
67
+
68
+ #### CommandKit::Arguments
69
+
70
+ * Allow arguments to have multi-line descriptions:
71
+
72
+ argument :arg1, desc: [
73
+ 'line1',
74
+ 'line2',
75
+ '...'
76
+ ]
77
+
78
+
79
+ #### CommandKit::ProgramName
80
+
81
+ * Added {CommandKit::ProgramName#command_name}.
82
+
1
83
  ### 0.2.2 / 2021-12-26
2
84
 
3
85
  #### CommandKit::Help::Man
data/Gemfile CHANGED
@@ -12,6 +12,8 @@ group :development do
12
12
  gem 'simplecov', '~> 0.20', require: false
13
13
 
14
14
  gem 'kramdown'
15
+ gem 'redcarpet', platform: :mri
15
16
  gem 'yard', '~> 0.9'
16
17
  gem 'yard-spellcheck', require: false
18
+ gem 'dead_end'
17
19
  end
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2021 Hal Brodigan
1
+ Copyright (c) 2021-2022 Hal Brodigan
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -11,30 +11,33 @@
11
11
 
12
12
  ## Description
13
13
 
14
- A Ruby toolkit for building clean, correct, and robust CLI commands as
14
+ A modular Ruby toolkit for building clean, correct, and robust CLI commands as
15
15
  plain-old Ruby classes.
16
16
 
17
17
  ## Features
18
18
 
19
19
  * **Simple** - Commands are plain-old ruby classes, with options and
20
- arguments declared as attributes. All features are ruby modules that can be
20
+ arguments declared as attributes. All features are Ruby modules that can be
21
21
  included into command classes.
22
22
  * **Correct** - CommandKit behaves like a standard UNIX command.
23
23
  * Safely handles Ctrl^C / SIGINT interrupts and [exits with 130](https://tldp.org/LDP/abs/html/exitcodes.html).
24
24
  * Safely handles broken pipes (aka `mycmd | head`).
25
- * Respects common environment variables (ex: `TERM=dumb`).
25
+ * Respects common environment variables (ex: `TERM=dumb` and `NO_COLOR`).
26
26
  * Uses [OptionParser][optparse] for POSIX option parsing.
27
- * Disables ANSI color when output is redirected to a file.
27
+ * Disables ANSI color when output is redirected to a file or when `NO_COLOR`
28
+ is set.
28
29
  * **Complete** - Provides many additional CLI features.
29
30
  * OS detection.
30
31
  * Terminal size detection.
31
32
  * ANSI coloring support.
32
33
  * Interactive input.
34
+ * Rich text printing support (fields, lists, and tables).
33
35
  * Subcommands (explicit or lazy-loaded) and command aliases.
34
36
  * Displaying man pages for `--help`/`help`.
35
37
  * Using the pager (aka `less`).
36
38
  * [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
39
+ * Exception handling / Bug reporting.
40
+ * **Testable** - Since commands are plain-old Ruby classes, it's easy to
38
41
  initialize them and call `#main` or `#run`.
39
42
 
40
43
  ## Anti-Features
@@ -45,7 +48,7 @@ plain-old Ruby classes.
45
48
 
46
49
  ## Requirements
47
50
 
48
- * [ruby] >= 2.7.0
51
+ * [ruby] >= 3.0.0
49
52
 
50
53
  ## Install
51
54
 
@@ -56,13 +59,13 @@ $ gem install command_kit
56
59
  ### gemspec
57
60
 
58
61
  ```ruby
59
- gem.add_dependency 'command_kit', '~> 0.2'
62
+ gem.add_dependency 'command_kit', '~> 0.3'
60
63
  ```
61
64
 
62
65
  ### Gemfile
63
66
 
64
67
  ```ruby
65
- gem 'command_kit', '~> 0.2'
68
+ gem 'command_kit', '~> 0.3'
66
69
  ```
67
70
 
68
71
  ## Examples
@@ -204,6 +207,7 @@ end
204
207
  ### Reference
205
208
 
206
209
  * [CommandKit::Arguments](https://rubydoc.info/gems/command_kit/CommandKit/Arguments)
210
+ * [CommandKit::BugReport](https://rubydoc.info/gems/command_kit/CommandKit/BugReport)
207
211
  * [CommandKit::Colors](https://rubydoc.info/gems/command_kit/CommandKit/Colors)
208
212
  * [CommandKit::Command](https://rubydoc.info/gems/command_kit/CommandKit/Command)
209
213
  * [CommandKit::CommandName](https://rubydoc.info/gems/command_kit/CommandKit/CommandName)
@@ -211,11 +215,13 @@ end
211
215
  * [CommandKit::Commands::AutoLoad](https://rubydoc.info/gems/command_kit/CommandKit/Commands/AutoLoad)
212
216
  * [CommandKit::Commands::AutoRequire](https://rubydoc.info/gems/command_kit/CommandKit/Commands/AutoRequire)
213
217
  * [CommandKit::Description](https://rubydoc.info/gems/command_kit/CommandKit/Description)
218
+ * [CommandKit::Edit](https://rubydoc.info/gems/command_kit/CommandKit/Edit)
214
219
  * [CommandKit::Env](https://rubydoc.info/gems/command_kit/CommandKit/Env)
215
220
  * [CommandKit::Env::Home](https://rubydoc.info/gems/command_kit/CommandKit/Env/Home)
216
221
  * [CommandKit::Env::Path](https://rubydoc.info/gems/command_kit/CommandKit/Env/Path)
217
222
  * [CommandKit::Examples](https://rubydoc.info/gems/command_kit/CommandKit/Examples)
218
223
  * [CommandKit::ExceptionHandler](https://rubydoc.info/gems/command_kit/CommandKit/ExceptionHandler)
224
+ * [CommandKit::FileUtils](https://rubydoc.info/gems/command_kit/CommandKit/FileUtils)
219
225
  * [CommandKit::Help](https://rubydoc.info/gems/command_kit/CommandKit/Help)
220
226
  * [CommandKit::Help::Man](https://rubydoc.info/gems/command_kit/CommandKit/Help/Man)
221
227
  * [CommandKit::Interactive](https://rubydoc.info/gems/command_kit/CommandKit/Interactive)
@@ -225,7 +231,10 @@ end
225
231
  * [CommandKit::Options::Verbose](https://rubydoc.info/gems/command_kit/CommandKit/Options/Verbose)
226
232
  * [CommandKit::Pager](https://rubydoc.info/gems/command_kit/CommandKit/Pager)
227
233
  * [CommandKit::Printing](https://rubydoc.info/gems/command_kit/CommandKit/Printing)
234
+ * [CommandKit::Printing::Fields](https://rubydoc.info/gems/command_kit/CommandKit/Printing/Fields)
228
235
  * [CommandKit::Printing::Indent](https://rubydoc.info/gems/command_kit/CommandKit/Printing/Indent)
236
+ * [CommandKit::Printing::Lists](https://rubydoc.info/gems/command_kit/CommandKit/Printing/Lists)
237
+ * [CommandKit::Printing::Tables](https://rubydoc.info/gems/command_kit/CommandKit/Printing/Tables)
229
238
  * [CommandKit::ProgramName](https://rubydoc.info/gems/command_kit/CommandKit/ProgramName)
230
239
  * [CommandKit::Stdio](https://rubydoc.info/gems/command_kit/CommandKit/Stdio)
231
240
  * [CommandKit::Terminal](https://rubydoc.info/gems/command_kit/CommandKit/Terminal)
@@ -244,7 +253,7 @@ Twitter.
244
253
 
245
254
  ## Copyright
246
255
 
247
- Copyright (c) 2021 Hal Brodigan
256
+ Copyright (c) 2021-2022 Hal Brodigan
248
257
 
249
258
  See {file:LICENSE.txt} for details.
250
259
 
data/command_kit.gemspec CHANGED
@@ -32,7 +32,6 @@ Gem::Specification.new do |gem|
32
32
  gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
33
33
 
34
34
  gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
35
- gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
36
35
  gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
37
36
 
38
37
  gem.require_paths = Array(gemspec.fetch('require_paths') {
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../../../lib',__FILE__))
4
+ require 'command_kit/command'
5
+ require 'command_kit/printing/tables'
6
+
7
+ class TablesCmd < CommandKit::Command
8
+
9
+ include CommandKit::Printing::Tables
10
+
11
+ def run
12
+ header = ['A', 'B', 'C']
13
+ table = [
14
+ ['AAAA', 'BBBB', 'CCCC'],
15
+ ['AAAA', 'BBBB', 'CCCC'],
16
+ ['AAAA', 'BBBB', 'CCCC']
17
+ ]
18
+
19
+ puts
20
+ puts "Table:"
21
+ puts
22
+ print_table table
23
+
24
+ puts
25
+ puts "Table with header:"
26
+ puts
27
+ print_table table, header: header
28
+
29
+ puts
30
+ puts "ASCII border:"
31
+ puts
32
+
33
+ print_table table, header: header,
34
+ border: :ascii
35
+
36
+ puts
37
+ puts "Border + Separated rows:"
38
+ puts
39
+
40
+ print_table table, header: header,
41
+ border: :ascii,
42
+ separate_rows: true
43
+
44
+ puts
45
+ puts "Lined border:"
46
+ puts
47
+
48
+ print_table table, header: header,
49
+ border: :line
50
+
51
+ puts
52
+ puts "Double line border:"
53
+ puts
54
+
55
+ print_table table, header: header,
56
+ border: :double_line
57
+
58
+ uneven_table = [
59
+ ['AAAAAA', 'B', 'CCCCCCC'],
60
+ ['AAA', 'BBBB', 'CCC' ],
61
+ ['A', 'BBBBBBB', 'C' ]
62
+ ]
63
+
64
+ puts
65
+ puts "Left-justified:"
66
+ puts
67
+
68
+ print_table uneven_table, header: header,
69
+ justify: :left,
70
+ justify_header: :left,
71
+ border: :line
72
+
73
+ puts
74
+ puts "Right-justified:"
75
+ puts
76
+
77
+ print_table uneven_table, header: header,
78
+ justify: :right,
79
+ justify_header: :right,
80
+ border: :line
81
+
82
+ puts
83
+ puts "Center-justified:"
84
+ puts
85
+
86
+ print_table uneven_table, header: header,
87
+ justify: :center,
88
+ justify_header: :center,
89
+ border: :line
90
+
91
+ puts
92
+ puts "Table with empty cells:"
93
+ puts
94
+
95
+ table_with_empty_cells = [
96
+ ['AAAA', 'BBBB', 'CCCC'],
97
+ ['AAAA', nil, 'CCCC'],
98
+ ['AAAA', 'BBBB']
99
+ ]
100
+
101
+ print_table table_with_empty_cells, header: header,
102
+ justify: :left,
103
+ border: :line
104
+
105
+ puts
106
+ puts "Multi-line table:"
107
+ puts
108
+
109
+ multi_line_table = [
110
+ ['AAAA', 'BBBB', "CCCC\nCC"],
111
+ ['AAAA', "BBBB\nB", 'CCCC'],
112
+ ["AAAA\nAA\nA", "BBBB", "CCCC"]
113
+ ]
114
+
115
+ print_table multi_line_table, header: header,
116
+ justify: :left,
117
+ border: :line
118
+
119
+ puts
120
+ puts "Indent aware:"
121
+ puts
122
+
123
+ puts "* Item 1"
124
+ indent do
125
+ puts "* Item 2"
126
+ puts
127
+
128
+ indent do
129
+ print_table table, header: header,
130
+ border: :line
131
+ end
132
+ end
133
+
134
+ puts
135
+ end
136
+
137
+ end
138
+
139
+ if __FILE__ == $0
140
+ TablesCmd.start
141
+ end
data/gemspec.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  name: command_kit
2
- summary: A toolkit for building Ruby CLI commands
2
+ summary: An all-in-one modular Ruby CLI toolkit
3
3
  description:
4
- A Ruby toolkit for building clean, correct, and robust CLI commands as
4
+ A modular Ruby toolkit for building clean, correct, and robust CLI commands as
5
5
  plain-old Ruby classes.
6
6
 
7
7
  license: MIT
@@ -16,7 +16,7 @@ metadata:
16
16
  changelog_uri: https://github.com/postmodern/command_kit.rb/blob/main/ChangeLog.md
17
17
  rubygems_mfa_required: 'true'
18
18
 
19
- required_ruby_version: ">= 2.7.0"
19
+ required_ruby_version: ">= 3.0.0"
20
20
 
21
21
  development_dependencies:
22
22
  bundler: ~> 2.0
@@ -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)]
@@ -46,6 +46,14 @@ module CommandKit
46
46
  # def run(*files)
47
47
  # end
48
48
  #
49
+ # ### Multi-line descriptions
50
+ #
51
+ # argument :arg, desc: [
52
+ # 'line1',
53
+ # 'line2',
54
+ # '...'
55
+ # ]
56
+ #
49
57
  module Arguments
50
58
  include Usage
51
59
  include Main
@@ -114,7 +122,7 @@ module CommandKit
114
122
  # @option kwargs [Boolean] repeats
115
123
  # Specifies whether the argument can be repeated multiple times.
116
124
  #
117
- # @option kwargs [String] desc
125
+ # @option kwargs [String, Array<String>] desc
118
126
  # The description for the argument.
119
127
  #
120
128
  # @return [Argument]
@@ -123,6 +131,12 @@ module CommandKit
123
131
  # @example Define an argument:
124
132
  # argument :bar, desc: "Bar argument"
125
133
  #
134
+ # @example Defines an argument with a multi-line description:
135
+ # argument :bar, desc: [
136
+ # "Line 1 ...",
137
+ # "Line 2 ..."
138
+ # ]
139
+ #
126
140
  # @example With a custom usage string:
127
141
  # argument :bar, usage: 'BAR',
128
142
  # desc: "Bar argument"
@@ -191,7 +205,18 @@ module CommandKit
191
205
  puts 'Arguments:'
192
206
 
193
207
  arguments.each_value do |arg|
194
- puts " #{arg.usage.ljust(33)}#{arg.desc}"
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
195
220
  end
196
221
  end
197
222
  end
@@ -0,0 +1,105 @@
1
+ require 'command_kit/exception_handler'
2
+ require 'command_kit/printing'
3
+
4
+ module CommandKit
5
+ #
6
+ # Adds an exception handler to print a bug report when an unhandled exception
7
+ # is raised by `run`.
8
+ #
9
+ # @since 0.4.0
10
+ #
11
+ module BugReport
12
+ include ExceptionHandler
13
+ include Printing
14
+
15
+ #
16
+ # @api private
17
+ #
18
+ module ModuleMethods
19
+ #
20
+ # Extends {ClassMethods} or {ModuleMethods}, depending on whether
21
+ # {Options} is being included into a class or a module.
22
+ #
23
+ # @param [Class, Module] context
24
+ # The class or module which is including {Options}.
25
+ #
26
+ def included(context)
27
+ super(context)
28
+
29
+ if context.class == Module
30
+ context.extend ModuleMethods
31
+ else
32
+ context.extend ClassMethods
33
+ end
34
+ end
35
+ end
36
+
37
+ extend ModuleMethods
38
+
39
+ #
40
+ # Defines class-level methods.
41
+ #
42
+ module ClassMethods
43
+ #
44
+ # Gets or sets the bug report URL.
45
+ #
46
+ # @param [String, nil] new_url
47
+ # The new bug report URL.
48
+ #
49
+ # @return [String, nil]
50
+ # The bug report URL.
51
+ #
52
+ # @example
53
+ # bug_report_url 'https://github.com/user/repo/issues/new'
54
+ #
55
+ def bug_report_url(new_url=nil)
56
+ if new_url
57
+ @bug_report_url = new_url
58
+ else
59
+ @bug_report_url || if superclass.kind_of?(ClassMethods)
60
+ superclass.bug_report_url
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ #
67
+ # The bug report URL.
68
+ #
69
+ # @return [String, nil]
70
+ #
71
+ def bug_report_url
72
+ self.class.bug_report_url
73
+ end
74
+
75
+ #
76
+ # Overrides {#on_exception} to print a bug report for unhandled exceptions
77
+ # and then exit with `-1`.
78
+ #
79
+ # @param [Exception] error
80
+ # The unhandled exception.
81
+ #
82
+ def on_exception(error)
83
+ print_bug_report(error)
84
+ exit(-1)
85
+ end
86
+
87
+ #
88
+ # Prints a bug report for the unhandled exception.
89
+ #
90
+ # @param [Exception] error
91
+ # The unhandled exception.
92
+ #
93
+ def print_bug_report(error)
94
+ url = bug_report_url
95
+
96
+ stderr.puts
97
+ stderr.puts "Oops! Looks like you have found a bug. Please report it!"
98
+ stderr.puts url if url
99
+ stderr.puts
100
+ stderr.puts '```'
101
+ print_exception(error)
102
+ stderr.puts '```'
103
+ end
104
+ end
105
+ end