command_kit 0.3.0 → 0.4.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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +4 -6
  3. data/.rubocop.yml +13 -0
  4. data/ChangeLog.md +18 -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/bug_report.rb +105 -0
  12. data/lib/command_kit/colors.rb +4 -4
  13. data/lib/command_kit/edit.rb +54 -0
  14. data/lib/command_kit/env.rb +1 -1
  15. data/lib/command_kit/options/option.rb +5 -1
  16. data/lib/command_kit/options/option_value.rb +2 -2
  17. data/lib/command_kit/options/parser.rb +1 -1
  18. data/lib/command_kit/options/quiet.rb +1 -1
  19. data/lib/command_kit/options/verbose.rb +2 -2
  20. data/lib/command_kit/options/version.rb +10 -0
  21. data/lib/command_kit/options.rb +1 -1
  22. data/lib/command_kit/os.rb +1 -1
  23. data/lib/command_kit/printing/fields.rb +56 -0
  24. data/lib/command_kit/printing/indent.rb +1 -1
  25. data/lib/command_kit/printing/lists.rb +91 -0
  26. data/lib/command_kit/printing/tables/border_style.rb +169 -0
  27. data/lib/command_kit/printing/tables/cell_builder.rb +93 -0
  28. data/lib/command_kit/printing/tables/row_builder.rb +111 -0
  29. data/lib/command_kit/printing/tables/style.rb +198 -0
  30. data/lib/command_kit/printing/tables/table_builder.rb +145 -0
  31. data/lib/command_kit/printing/tables/table_formatter.rb +254 -0
  32. data/lib/command_kit/printing/tables.rb +208 -0
  33. data/lib/command_kit/stdio.rb +5 -1
  34. data/lib/command_kit/version.rb +1 -1
  35. data/spec/bug_report_spec.rb +266 -0
  36. data/spec/colors_spec.rb +6 -0
  37. data/spec/command_name_spec.rb +1 -1
  38. data/spec/edit_spec.rb +72 -0
  39. data/spec/options/option_spec.rb +12 -2
  40. data/spec/options/quiet_spec.rb +51 -0
  41. data/spec/options/verbose_spec.rb +51 -0
  42. data/spec/options/version_spec.rb +146 -0
  43. data/spec/pager_spec.rb +1 -1
  44. data/spec/printing/fields_spec.rb +167 -0
  45. data/spec/printing/lists_spec.rb +99 -0
  46. data/spec/printing/tables/border_style.rb +43 -0
  47. data/spec/printing/tables/cell_builer_spec.rb +135 -0
  48. data/spec/printing/tables/row_builder_spec.rb +165 -0
  49. data/spec/printing/tables/style_spec.rb +377 -0
  50. data/spec/printing/tables/table_builder_spec.rb +252 -0
  51. data/spec/printing/tables/table_formatter_spec.rb +1180 -0
  52. data/spec/printing/tables_spec.rb +1069 -0
  53. metadata +33 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 306f055fa898d4d82c14ba8e79b397ae413280bb7144ce69e1787081620827e9
4
- data.tar.gz: e79e640f7d4ae566401e7543d3ba98aa42b1e2396657734e29ab3cd3b383b41c
3
+ metadata.gz: 72a3fdeb65d9eb4c4e996aa95ea7e8131e220c2cb24be8b17d56e1742a156d35
4
+ data.tar.gz: d05b75366f58c219c9680d07571a171239f0ab8f77580cb1c2d47c6322d7e74c
5
5
  SHA512:
6
- metadata.gz: ee4268377db8c2398b5157feda9fa106a0b156537c6085b71fcfd8c7710f898c3bc0ef5d4408d9c6cbcae932e4f4ee4dd49070003e6c5734da06da33fbbace9a
7
- data.tar.gz: 03b6a48369bea030002f9432d0d8645d8c0f5cdefba81778922e73a54f267611419bdb63e5033e98b09aa1c6ae97af1e8c3b8135cb7ed4b807fce666c6c379b8
6
+ metadata.gz: 1cc85835b40fded3170ee21619620dbb988dd3427fa8cb48456f09a7991b6eed72299a81ba19be543c260557504d5636237993f33360d463d72a87600ca14441
7
+ data.tar.gz: 9d57ec57d540547d2fa664faf8e3bb1e0c0aa06929162d3dac849f858911aa5e7610e8294b2189927d8633de8e9784079df548a3e900fd73c57f76e72c87ad9d
@@ -10,13 +10,11 @@ jobs:
10
10
  fail-fast: false
11
11
  matrix:
12
12
  ruby:
13
- - 2.7
14
- - 3.0
15
- - 3.1
13
+ - '3.0'
14
+ - '3.1'
16
15
  # TODO: uncomment when jruby supports ruby >= 2.7
17
16
  # - jruby
18
- # TODO: uncomment when truffleruby supports splatting empty kwargs
19
- # - truffleruby
17
+ - truffleruby
20
18
  name: Ruby ${{ matrix.ruby }}
21
19
  steps:
22
20
  - uses: actions/checkout@v2
@@ -37,7 +35,7 @@ jobs:
37
35
  - name: Set up Ruby
38
36
  uses: ruby/setup-ruby@v1
39
37
  with:
40
- ruby-version: 2.7
38
+ ruby-version: 3.0
41
39
  - name: Install dependencies
42
40
  run: bundle install --jobs 4 --retry 3
43
41
  - name: Run rubocop
data/.rubocop.yml CHANGED
@@ -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,21 @@
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
+
1
19
  ### 0.3.0 / 2021-12-26
2
20
 
3
21
  * Added {CommandKit::FileUtils}.
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
@@ -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
@@ -998,14 +998,14 @@ module CommandKit
998
998
  # @return [Boolean]
999
999
  #
1000
1000
  # @note
1001
- # When the env variable `TERM` is set to `dumb`, it will disable color
1002
- # output. Color output will also be disabled if the given stream is not
1003
- # a TTY.
1001
+ # When the env variable `TERM` is set to `dumb` or when the `NO_COLOR`
1002
+ # env variable is set, it will disable color output. Color output will
1003
+ # also be disabled if the given stream is not a TTY.
1004
1004
  #
1005
1005
  # @api public
1006
1006
  #
1007
1007
  def ansi?(stream=stdout)
1008
- env['TERM'] != 'dumb' && stream.tty?
1008
+ env['TERM'] != 'dumb' && !env['NO_COLOR'] && stream.tty?
1009
1009
  end
1010
1010
 
1011
1011
  #
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'command_kit/env'
4
+
5
+ module CommandKit
6
+ #
7
+ # Allows invoking the `EDITOR` environment variable.
8
+ #
9
+ # ## Environment Variables
10
+ #
11
+ # * `EDITOR` - The preferred editor command.
12
+ #
13
+ # ## Example
14
+ #
15
+ # if options[:edit]
16
+ # edit CONFIG_FILE
17
+ # end
18
+ #
19
+ # @since 0.4.0
20
+ #
21
+ module Edit
22
+ include Env
23
+
24
+ #
25
+ # The `EDITOR` environment variable.
26
+ #
27
+ # @return [String]
28
+ # The `EDITOR` environment variable, or `"nano"` if `EDITOR` was not set.
29
+ #
30
+ # @api semipublic
31
+ #
32
+ def editor
33
+ env['EDITOR'] || 'nano'
34
+ end
35
+
36
+ #
37
+ # Invokes the preferred editor with the additional arguments.
38
+ #
39
+ # @param [Array] arguments
40
+ # The additional arguments to pass to the editor command.
41
+ #
42
+ # @return [Boolean, nil]
43
+ # Indicates whether the editor successfully launched and exited.
44
+ # If the {#editor} command was not installed, `nil` will be returned.
45
+ #
46
+ # @api public
47
+ #
48
+ def edit(*arguments)
49
+ if editor
50
+ system(editor,*arguments.map(&:to_s))
51
+ end
52
+ end
53
+ end
54
+ end
@@ -7,7 +7,7 @@ module CommandKit
7
7
  # class MyCmd
8
8
  # include CommandKit::Env
9
9
  #
10
- # def main
10
+ # def run
11
11
  # home = env['HOME']
12
12
  # # ...
13
13
  # end
@@ -154,7 +154,11 @@ module CommandKit
154
154
  # The usage strings.
155
155
  #
156
156
  def usage
157
- [*@short, "#{@long}#{separator}#{@value && @value.usage}"]
157
+ if equals? && (@value && @value.optional?)
158
+ [*@short, "#{@long}[#{separator}#{@value && @value.usage}]"]
159
+ else
160
+ [*@short, "#{@long}#{separator}#{@value && @value.usage}"]
161
+ end
158
162
  end
159
163
 
160
164
  #
@@ -19,7 +19,7 @@ module CommandKit
19
19
  class OptionValue < Arguments::ArgumentValue
20
20
 
21
21
  # Maps OptionParser types to USAGE strings.
22
- USAGES = {
22
+ DEFAULT_USAGES = {
23
23
  # NOTE: NilClass and Object are intentionally omitted
24
24
  Date => 'DATE',
25
25
  DateTime => 'DATE_TIME',
@@ -90,7 +90,7 @@ module CommandKit
90
90
  # The given type was not a Class, Hash, Array, or Regexp.
91
91
  #
92
92
  def self.default_usage(type)
93
- USAGES.fetch(type) do
93
+ DEFAULT_USAGES.fetch(type) do
94
94
  case type
95
95
  when Hash then type.keys.join('|')
96
96
  when Array then type.join('|')
@@ -22,7 +22,7 @@ module CommandKit
22
22
  # end
23
23
  # end
24
24
  #
25
- # def main(*argv)
25
+ # def run(*argv)
26
26
  # if @custom
27
27
  # puts "Custom mode enabled"
28
28
  # end
@@ -9,7 +9,7 @@ module CommandKit
9
9
  #
10
10
  # include CommandKit::Options::Quiet
11
11
  #
12
- # def main(*argv)
12
+ # def run(*argv)
13
13
  # # ...
14
14
  # puts "verbose output" unless quiet?
15
15
  # # ...
@@ -7,9 +7,9 @@ module CommandKit
7
7
  #
8
8
  # ## Examples
9
9
  #
10
- # include Options::Verbose
10
+ # include CommandKit::Options::Verbose
11
11
  #
12
- # def main(*argv)
12
+ # def run(*argv)
13
13
  # # ...
14
14
  # puts "verbose output" if verbose?
15
15
  # # ...
@@ -5,6 +5,16 @@ module CommandKit
5
5
  #
6
6
  # Defines a version option.
7
7
  #
8
+ # ## Examples
9
+ #
10
+ # include CommandKit::Options::Version
11
+ #
12
+ # version '0.1.0'
13
+ #
14
+ # def run(*argv)
15
+ # # ...
16
+ # end
17
+ #
8
18
  module Version
9
19
  #
10
20
  # Includes {Options}, extends {Version::ClassMethods}, and defines a
@@ -247,7 +247,7 @@ module CommandKit
247
247
 
248
248
  super(**kwargs)
249
249
 
250
- define_option_categories
250
+ define_option_categories()
251
251
  end
252
252
 
253
253
  #
@@ -11,7 +11,7 @@ module CommandKit
11
11
  #
12
12
  # include CommandKit::OS
13
13
  #
14
- # def main(*argv)
14
+ # def run(*argv)
15
15
  # if linux?
16
16
  # # ...
17
17
  # elsif macos?