command_kit 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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?