command_kit 0.1.0.pre1 → 0.2.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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +15 -0
  3. data/.rubocop.yml +138 -0
  4. data/ChangeLog.md +34 -2
  5. data/Gemfile +3 -0
  6. data/README.md +135 -214
  7. data/Rakefile +3 -2
  8. data/command_kit.gemspec +4 -4
  9. data/examples/colors.rb +30 -0
  10. data/examples/command.rb +65 -0
  11. data/examples/pager.rb +30 -0
  12. data/gemspec.yml +10 -2
  13. data/lib/command_kit/arguments/argument.rb +16 -44
  14. data/lib/command_kit/arguments/argument_value.rb +3 -30
  15. data/lib/command_kit/arguments.rb +66 -20
  16. data/lib/command_kit/colors.rb +253 -45
  17. data/lib/command_kit/command.rb +50 -3
  18. data/lib/command_kit/command_name.rb +9 -0
  19. data/lib/command_kit/commands/auto_load/subcommand.rb +3 -0
  20. data/lib/command_kit/commands/auto_load.rb +16 -0
  21. data/lib/command_kit/commands/auto_require.rb +16 -0
  22. data/lib/command_kit/commands/command.rb +3 -0
  23. data/lib/command_kit/commands/help.rb +2 -0
  24. data/lib/command_kit/commands/parent_command.rb +7 -0
  25. data/lib/command_kit/commands/subcommand.rb +15 -0
  26. data/lib/command_kit/commands.rb +40 -4
  27. data/lib/command_kit/description.rb +15 -2
  28. data/lib/command_kit/env/home.rb +9 -0
  29. data/lib/command_kit/env/path.rb +15 -0
  30. data/lib/command_kit/env.rb +4 -0
  31. data/lib/command_kit/examples.rb +15 -2
  32. data/lib/command_kit/exception_handler.rb +4 -0
  33. data/lib/command_kit/help/man.rb +74 -47
  34. data/lib/command_kit/help.rb +10 -1
  35. data/lib/command_kit/inflector.rb +49 -17
  36. data/lib/command_kit/interactive.rb +239 -0
  37. data/lib/command_kit/main.rb +20 -9
  38. data/lib/command_kit/man.rb +44 -0
  39. data/lib/command_kit/open_app.rb +69 -0
  40. data/lib/command_kit/options/option.rb +36 -9
  41. data/lib/command_kit/options/option_value.rb +42 -3
  42. data/lib/command_kit/options/parser.rb +44 -17
  43. data/lib/command_kit/options/quiet.rb +3 -0
  44. data/lib/command_kit/options/verbose.rb +5 -0
  45. data/lib/command_kit/options/version.rb +6 -0
  46. data/lib/command_kit/options.rb +59 -10
  47. data/lib/command_kit/os/linux.rb +157 -0
  48. data/lib/command_kit/os.rb +165 -11
  49. data/lib/command_kit/package_manager.rb +200 -0
  50. data/lib/command_kit/pager.rb +84 -9
  51. data/lib/command_kit/printing/indent.rb +25 -2
  52. data/lib/command_kit/printing.rb +23 -0
  53. data/lib/command_kit/program_name.rb +7 -0
  54. data/lib/command_kit/stdio.rb +24 -0
  55. data/lib/command_kit/sudo.rb +40 -0
  56. data/lib/command_kit/terminal.rb +159 -0
  57. data/lib/command_kit/usage.rb +14 -0
  58. data/lib/command_kit/version.rb +1 -1
  59. data/lib/command_kit/xdg.rb +21 -1
  60. data/lib/command_kit.rb +1 -0
  61. data/spec/arguments/argument_spec.rb +5 -41
  62. data/spec/arguments/argument_value_spec.rb +1 -61
  63. data/spec/arguments_spec.rb +8 -25
  64. data/spec/colors_spec.rb +277 -13
  65. data/spec/command_name_spec.rb +1 -1
  66. data/spec/command_spec.rb +4 -1
  67. data/spec/commands/auto_load/subcommand_spec.rb +1 -1
  68. data/spec/commands/auto_load_spec.rb +1 -1
  69. data/spec/commands/auto_require_spec.rb +2 -2
  70. data/spec/commands/help_spec.rb +1 -1
  71. data/spec/commands/parent_command_spec.rb +1 -1
  72. data/spec/commands/subcommand_spec.rb +1 -1
  73. data/spec/commands_spec.rb +2 -2
  74. data/spec/description_spec.rb +1 -25
  75. data/spec/env/home_spec.rb +1 -1
  76. data/spec/env/path_spec.rb +1 -1
  77. data/spec/examples_spec.rb +1 -25
  78. data/spec/exception_handler_spec.rb +1 -1
  79. data/spec/help/man_spec.rb +316 -0
  80. data/spec/help_spec.rb +0 -25
  81. data/spec/inflector_spec.rb +71 -9
  82. data/spec/interactive_spec.rb +415 -0
  83. data/spec/main_spec.rb +7 -7
  84. data/spec/man_spec.rb +46 -0
  85. data/spec/open_app_spec.rb +85 -0
  86. data/spec/options/option_spec.rb +48 -9
  87. data/spec/options/option_value_spec.rb +53 -4
  88. data/spec/options_spec.rb +1 -1
  89. data/spec/os/linux_spec.rb +154 -0
  90. data/spec/os_spec.rb +201 -14
  91. data/spec/package_manager_spec.rb +806 -0
  92. data/spec/pager_spec.rb +78 -15
  93. data/spec/printing/indent_spec.rb +1 -1
  94. data/spec/printing_spec.rb +10 -2
  95. data/spec/program_name_spec.rb +1 -1
  96. data/spec/spec_helper.rb +0 -3
  97. data/spec/sudo_spec.rb +51 -0
  98. data/spec/{console_spec.rb → terminal_spec.rb} +65 -35
  99. data/spec/usage_spec.rb +2 -2
  100. data/spec/xdg_spec.rb +1 -1
  101. metadata +32 -13
  102. data/lib/command_kit/arguments/usage.rb +0 -6
  103. data/lib/command_kit/console.rb +0 -141
  104. data/lib/command_kit/options/usage.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa6096447b8ddf59149147d020c3fe6f5fcf6de1c167f749692fc1b50dec1b8a
4
- data.tar.gz: c4c0a58596e92563f9f69a7fd151a7b7dd9121c8083ca104a21dd3ce53ef2fc5
3
+ metadata.gz: 5dc00be598fd9cee093dbfaf32a03118897179587d4dc17c97fdde2b020d3ac7
4
+ data.tar.gz: 88e498fa844b4db50dc194f6ec474d7c85bbea1619bf1340e6d2abfc4c13c0b3
5
5
  SHA512:
6
- metadata.gz: a777422cddc17a986940b7cd902ac43c01765b6ef98efe717307f545a29dfe975579bb8eacdce9647cd2ccbd0f210b7a8b0ab3ffac026d8341f2c9669ef56a18
7
- data.tar.gz: 7b768f74911ac136b24f755534d31844febb92b5b034e672b4b93c3a45083b4731d9658830b6f700bc8b70106b772f253291ed15fcd36f5f709351808910c93b
6
+ metadata.gz: 5fd2683d7d3fb3f4c1258019d209b9f8ca348b0fc71c21c9f292b6799502dcfbc39d8f5ff8e50d54b822aaf229eedd85c3e151bea0f9c92d13dc08bb5b6d947e
7
+ data.tar.gz: 4276756c0495b2583303c9db090cd0e1221681d7eb357b34d4078a7e59167695f3250552c58ff0be24ee27535fb49ab2ce15d8e0711ee44cebbb93a52f6dfac0
@@ -3,6 +3,7 @@ name: CI
3
3
  on: [ push, pull_request ]
4
4
 
5
5
  jobs:
6
+ # run tests
6
7
  tests:
7
8
  runs-on: ubuntu-latest
8
9
  strategy:
@@ -27,3 +28,17 @@ jobs:
27
28
  run: bundle install --jobs 4 --retry 3
28
29
  - name: Run tests
29
30
  run: bundle exec rake test
31
+
32
+ # rubocop linting
33
+ rubocop:
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@v2
37
+ - name: Set up Ruby
38
+ uses: ruby/setup-ruby@v1
39
+ with:
40
+ ruby-version: 2.7
41
+ - name: Install dependencies
42
+ run: bundle install --jobs 4 --retry 3
43
+ - name: Run rubocop
44
+ run: bundle exec rubocop --parallel
data/.rubocop.yml ADDED
@@ -0,0 +1,138 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ SuggestExtensions: false
4
+ TargetRubyVersion: 2.7
5
+
6
+ #
7
+ # our rules
8
+ #
9
+
10
+ Layout/FirstArrayElementIndentation: { EnforcedStyle: consistent }
11
+ Layout/LineLength: { Enabled: false }
12
+ Layout/SpaceAroundEqualsInParameterDefault: { EnforcedStyle: no_space }
13
+ Lint/ConstantDefinitionInBlock: { Exclude: ['spec/**/*'] }
14
+ Metrics: { Enabled: false }
15
+ Style/SymbolArray: { EnforcedStyle: brackets }
16
+ Style/IfInsideElse: { Enabled: false } # Offense count: 1
17
+ Style/PercentLiteralDelimiters:
18
+ Enabled: true
19
+ PreferredDelimiters:
20
+ default: '{}'
21
+ '%i': '[]'
22
+ '%I': '[]'
23
+ '%w': '[]'
24
+ '%W': '[]'
25
+
26
+ #
27
+ # rules that are in flux
28
+ #
29
+
30
+ # consider enabling these and autocorrecting?
31
+ # Layout/SpaceAfterComma
32
+ # Layout/SpaceAroundKeyword
33
+ # Layout/SpaceBeforeComma
34
+ # Layout/SpaceInsideHashLiteralBraces
35
+ # Layout/SpaceInsideParens
36
+ # Layout/TrailingWhitespace
37
+ # Lint/UnreachableLoop
38
+ # Lint/UnusedBlockArgument
39
+ # Style/ClassCheck
40
+ # Style/Documentation
41
+ # Style/ExpandPathArguments
42
+ # Style/GlobalStdStream
43
+ # Style/HashSyntax
44
+ # Style/KeywordParametersOrder
45
+ # Style/MethodCallWithoutArgsParentheses
46
+ # Style/MutableConstant
47
+ # Style/QuotedSymbols: { EnforcedStyle: double_quotes }
48
+ # Style/RedundantReturn
49
+ # Style/SafeNavigation
50
+ # Style/SpecialGlobalVars
51
+ # Style/StringLiterals: { EnforcedStyle: double_quotes }
52
+ # Style/WordArray
53
+
54
+ # these have been fixed
55
+ # Gemspec/DuplicatedAssignment: { Enabled: false } # Offense count: 1
56
+ # Layout/ElseAlignment: { Enabled: false } # Offense count: 1
57
+ # Layout/EndAlignment: { Enabled: false } # Offense count: 1
58
+ # Lint/DuplicateMethods: { Enabled: false } # Offense count: 1
59
+ # Lint/UselessAssignment: { Enabled: false } # Offense count: 1
60
+ # Style/Encoding: { Enabled: false } # Offense count: 2
61
+ # Style/RedundantBegin: { Enabled: false } # Offense count: 2
62
+ # Style/RedundantInterpolation: { Enabled: false } # Offense count: 1
63
+ # Style/TrailingCommaInArrayLiteral: { Enabled: false } # Offense count: 1
64
+
65
+ #
66
+ # This list was generated with:
67
+ # bundle exec rubocop --auto-gen-config --exclude-limit 1
68
+ #
69
+
70
+ # > 10 violations
71
+ Layout/AssignmentIndentation: { Enabled: false } # Offense count: 11
72
+ Layout/EmptyLinesAroundClassBody: { Enabled: false } # Offense count: 76
73
+ Layout/HashAlignment: { Enabled: false } # Offense count: 28
74
+ Layout/SpaceAfterComma: { Enabled: false } # Offense count: 141
75
+ Layout/SpaceInsideHashLiteralBraces: { Enabled: false } # Offense count: 57
76
+ Layout/TrailingWhitespace: { Enabled: false } # Offense count: 50
77
+ Naming/RescuedExceptionsVariableName: { Enabled: false } # Offense count: 11
78
+ Style/BlockDelimiters: { Enabled: false } # Offense count: 17
79
+ Style/ClassCheck: { Enabled: false } # Offense count: 10
80
+ Style/ClassEqualityComparison: { Enabled: false } # Offense count: 16
81
+ Style/FrozenStringLiteralComment: { Enabled: false } # Offense count: 77
82
+ Style/GlobalStdStream: { Enabled: false } # Offense count: 13
83
+ Style/GuardClause: { Enabled: false } # Offense count: 10
84
+ Style/IfUnlessModifier: { Enabled: false } # Offense count: 13
85
+ Style/MethodCallWithoutArgsParentheses: { Enabled: false } # Offense count: 10
86
+ Style/SpecialGlobalVars: { Enabled: false } # Offense count: 28
87
+ Style/StringLiterals: { Enabled: false } # Offense count: 774
88
+
89
+ # < 10 violations
90
+ Layout/EmptyLinesAroundModuleBody: { Enabled: false } # Offense count: 5
91
+ Layout/ExtraSpacing: { Enabled: false } # Offense count: 6
92
+ Layout/FirstHashElementIndentation: { Enabled: false } # Offense count: 4
93
+ Layout/ParameterAlignment: { Enabled: false } # Offense count: 9
94
+ Layout/SpaceAroundKeyword: { Enabled: false } # Offense count: 7
95
+ Layout/SpaceBeforeComma: { Enabled: false } # Offense count: 4
96
+ Layout/SpaceInsideParens: { Enabled: false } # Offense count: 4
97
+ Lint/EmptyClass: { Enabled: false } # Offense count: 3
98
+ Lint/SuppressedException: { Enabled: false } # Offense count: 4
99
+ Lint/UnusedMethodArgument: { Enabled: false } # Offense count: 5
100
+ Style/AccessorGrouping: { Enabled: false } # Offense count: 7
101
+ Style/Documentation: { Enabled: false } # Offense count: 3
102
+ Style/ExpandPathArguments: { Enabled: false } # Offense count: 8
103
+ Style/HashSyntax: { Exclude: ['Rakefile'] } # Offense count: 3
104
+ Style/KeywordParametersOrder: { Enabled: false } # Offense count: 8
105
+ Style/Lambda: { Enabled: false } # Offense count: 3
106
+ Style/MutableConstant: { Enabled: false } # Offense count: 4
107
+ Style/RaiseArgs: { Enabled: false } # Offense count: 4
108
+ Style/RedundantReturn: { Enabled: false } # Offense count: 7
109
+ Style/SafeNavigation: { Enabled: false } # Offense count: 5
110
+ Style/StringConcatenation: { Enabled: false } # Offense count: 8
111
+ Style/WordArray: { Enabled: false } # Offense count: 4
112
+
113
+ # 1 or 2 violations
114
+ Layout/ArgumentAlignment: { Enabled: false } # Offense count: 1
115
+ Layout/BlockAlignment: { Enabled: false } # Offense count: 1
116
+ Layout/IndentationWidth: { Enabled: false } # Offense count: 2
117
+ Layout/SpaceAroundOperators: { Enabled: false } # Offense count: 1
118
+ Layout/SpaceBeforeBlockBraces: { Enabled: false } # Offense count: 1
119
+ Lint/MissingSuper: { Enabled: false } # Offense count: 2
120
+ Lint/RescueException: { Enabled: false } # Offense count: 1
121
+ Lint/UnreachableLoop: { Enabled: false } # Offense count: 1
122
+ Lint/UnusedBlockArgument: { Enabled: false } # Offense count: 1
123
+ Naming/MethodParameterName: { Enabled: false } # Offense count: 1
124
+ Style/EmptyMethod: { Enabled: false } # Offense count: 2
125
+ Style/HashConversion: { Enabled: false } # Offense count: 1
126
+ Style/MultilineMemoization: { Enabled: false } # Offense count: 1
127
+ Style/NumericPredicate: { Enabled: false } # Offense count: 1
128
+ Style/OptionalArguments: { Enabled: false } # Offense count: 1
129
+ Style/ParenthesesAroundCondition: { Enabled: false } # Offense count: 1
130
+ Style/PreferredHashMethods: { Enabled: false } # Offense count: 1
131
+ Style/QuotedSymbols: { Enabled: false } # Offense count: 1
132
+ Style/RedundantException: { Enabled: false } # Offense count: 1
133
+ Style/RedundantRegexpEscape: { Enabled: false } # Offense count: 1
134
+ Style/RegexpLiteral: { Enabled: false } # Offense count: 1
135
+ Style/RescueStandardError: { Enabled: false } # Offense count: 1
136
+ Style/SoleNestedConditional: { Enabled: false } # Offense count: 1
137
+ Style/TrailingCommaInHashLiteral: { Enabled: false } # Offense count: 2
138
+ Style/PercentLiteralDelimiters: { Enabled: false } # Offense count: 2
data/ChangeLog.md CHANGED
@@ -1,13 +1,41 @@
1
- ### 0.1.0 / 2021-05-XX
1
+ ### 0.2.0 / 2021-08-31
2
+
3
+ * Added {CommandKit::Colors::ANSI#on_black}.
4
+ * Added {CommandKit::Colors::ANSI#on_red}.
5
+ * Added {CommandKit::Colors::ANSI#on_green}.
6
+ * Added {CommandKit::Colors::ANSI#on_yellow}.
7
+ * Added {CommandKit::Colors::ANSI#on_blue}.
8
+ * Added {CommandKit::Colors::ANSI#on_magenta}.
9
+ * Added {CommandKit::Colors::ANSI#on_cyan}.
10
+ * Added {CommandKit::Colors::ANSI#on_white}.
11
+ * Added {CommandKit::Man}.
12
+ * Added {CommandKit::OS#bsd?}.
13
+ * Added {CommandKit::OS#freebsd?}.
14
+ * Added {CommandKit::OS#netbsd?}.
15
+ * Added {CommandKit::OS#openbsd?}.
16
+ * Added {CommandKit::OS#os}.
17
+ * Added {CommandKit::OS#unix?}.
18
+ * Added {CommandKit::OS::Linux}.
19
+ * Added {CommandKit::OpenApp}.
20
+ * Added {CommandKit::PackageManager}.
21
+ * Added {CommandKit::Pager#pipe_to_pager}.
22
+ * Added {CommandKit::Sudo}.
23
+ * Added {CommandKit::Terminal#tty?}.
24
+ * Refactor {CommandKit::Inflector.camelize} and
25
+ {CommandKit::Inflector.underscore} to use StringScanner.
26
+ * Allow {CommandKit::OS#initialize} to accept an `os:` keyword to override the
27
+ detected OS.
28
+
29
+ ### 0.1.0 / 2021-07-16
2
30
 
3
31
  * Initial release:
4
32
  * {CommandKit::Arguments}
5
33
  * {CommandKit::Colors}
34
+ * {CommandKit::Command}
6
35
  * {CommandKit::CommandName}
7
36
  * {CommandKit::Commands}
8
37
  * {CommandKit::Commands::AutoLoad}
9
38
  * {CommandKit::Commands::AutoRequire}
10
- * {CommandKit::Console}
11
39
  * {CommandKit::Description}
12
40
  * {CommandKit::Env}
13
41
  * {CommandKit::Env::Home}
@@ -16,14 +44,18 @@
16
44
  * {CommandKit::ExceptionHandler}
17
45
  * {CommandKit::Help}
18
46
  * {CommandKit::Help::Man}
47
+ * {CommandKit::Interactive}
19
48
  * {CommandKit::Main}
20
49
  * {CommandKit::Options}
21
50
  * {CommandKit::Options::Quiet}
22
51
  * {CommandKit::Options::Verbose}
52
+ * {CommandKit::OS}
23
53
  * {CommandKit::Pager}
24
54
  * {CommandKit::Printing}
55
+ * {CommandKit::Printing::Indent}
25
56
  * {CommandKit::ProgramName}
26
57
  * {CommandKit::Stdio}
58
+ * {CommandKit::Terminal}
27
59
  * {CommandKit::Usage}
28
60
  * {CommandKit::XDG}
29
61
 
data/Gemfile CHANGED
@@ -6,9 +6,12 @@ group :development do
6
6
  gem 'rake'
7
7
  gem 'rubygems-tasks', '~> 0.2'
8
8
 
9
+ gem 'rubocop', '~> 1.18'
10
+
9
11
  gem 'rspec', '~> 3.0'
10
12
  gem 'simplecov', '~> 0.20', require: false
11
13
 
12
14
  gem 'kramdown'
13
15
  gem 'yard', '~> 0.9'
16
+ gem 'yard-spellcheck', require: false
14
17
  end
data/README.md CHANGED
@@ -1,57 +1,39 @@
1
1
  # command_kit
2
2
 
3
- * [Homepage](https://github.com/postmodern/command_kit#readme)
4
- * [Issues](https://github.com/postmodern/command_kit/issues)
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
+
5
+ * [Homepage](https://github.com/postmodern/command_kit.rb#readme)
6
+ * [Forum](https://github.com/postmodern/command_kit.rb/discussions) |
7
+ [Issues](https://github.com/postmodern/command_kit.rb/issues)
5
8
  * [Documentation](http://rubydoc.info/gems/command_kit/frames)
6
- * [Email](mailto:postmodern.mod3 at gmail.com)
7
9
 
8
10
  ## Description
9
11
 
10
- A Ruby toolkit for building clean, correct, and robust CLI commands as Ruby
11
- classes.
12
+ A Ruby toolkit for building clean, correct, and robust CLI commands as
13
+ plain-old Ruby classes.
12
14
 
13
15
  ## Features
14
16
 
15
- * Supports defining commands as Classes.
16
- * Supports defining options and arguments as attributes.
17
- * Supports subcommands (explicit or lazy-loaded) and command aliases.
18
- * Correctly handles Ctrl^C and SIGINT interrupts (aka exit 130).
19
- * Correctly handles broken pipes (aka `mycmd | head`).
20
- * Uses [OptionParser][optparse] for option parsing.
21
- * Provides ANSI coloring support.
22
- * Supports optionally displaying a man-page instead of `--help`
23
- (see {CommandKit::Help::Man}).
24
- * Supports XDG directories (`~/.config/`, `~/.local/share/`, `~/.cache/`).
25
- * Easy to test:
26
- * `MyCmd.main(arg1, arg2, options: {foo: foo}) # => 0`
27
-
28
- ### Modules
29
-
30
- * {CommandKit::Arguments}
31
- * {CommandKit::Colors}
32
- * {CommandKit::CommandName}
33
- * {CommandKit::Commands}
34
- * {CommandKit::Commands::AutoLoad}
35
- * {CommandKit::Commands::AutoRequire}
36
- * {CommandKit::Console}
37
- * {CommandKit::Description}
38
- * {CommandKit::Env}
39
- * {CommandKit::Env::Home}
40
- * {CommandKit::Env::Path}
41
- * {CommandKit::Examples}
42
- * {CommandKit::ExceptionHandler}
43
- * {CommandKit::Help}
44
- * {CommandKit::Help::Man}
45
- * {CommandKit::Main}
46
- * {CommandKit::Options}
47
- * {CommandKit::Options::Quiet}
48
- * {CommandKit::Options::Verbose}
49
- * {CommandKit::Pager}
50
- * {CommandKit::Printing}
51
- * {CommandKit::ProgramName}
52
- * {CommandKit::Stdio}
53
- * {CommandKit::Usage}
54
- * {CommandKit::XDG}
17
+ * **Simple** - Commands are plain-old ruby classes, with options and
18
+ arguments declared as attributes. All features are ruby modules that can be
19
+ included into command classes.
20
+ * **Correct** - CommandKit behaves like a standard UNIX command.
21
+ * Safely handles Ctrl^C / SIGINT interrupts and [exits with 130](https://tldp.org/LDP/abs/html/exitcodes.html).
22
+ * Safely handles broken pipes (aka `mycmd | head`).
23
+ * Respects common environment variables (ex: `TERM=dumb`).
24
+ * Uses [OptionParser][optparse] for POSIX option parsing.
25
+ * Disables ANSI color when output is redirected to a file.
26
+ * **Complete** - Provides many additional CLI features.
27
+ * OS detection.
28
+ * Terminal size detection.
29
+ * ANSI coloring support.
30
+ * Interactive input.
31
+ * Subcommands (explicit or lazy-loaded) and command aliases.
32
+ * Displaying man pages for `--help`/`help`.
33
+ * Using the pager (aka `less`).
34
+ * [XDG directories](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) (aka `~/.config/`, `~/.local/share/`, `~/.cache/`).
35
+ * **Testable** - Since commands are plain-old ruby classes, it's easy to
36
+ initialize them and call `#main` or `#run`.
55
37
 
56
38
  ## Anti-Features
57
39
 
@@ -59,209 +41,148 @@ classes.
59
41
  * Does not implement it's own option parser.
60
42
  * Not named after a comic-book Superhero.
61
43
 
62
- ## Examples
63
-
64
- ### Command
65
-
66
- #### lib/foo/cli/my_cmd.rb
67
-
68
- require 'command_kit'
69
-
70
- module Foo
71
- module CLI
72
- class MyCmd < CommandKit::Command
73
-
74
- usage '[OPTIONS] [-o OUTPUT] FILE'
75
-
76
- option :count, short: '-c',
77
- value: {
78
- type: Integer,
79
- default: 1
80
- },
81
- desc: "Number of times"
82
-
83
- option :output, short: '-o',
84
- value: {
85
- type: String,
86
- usage: 'FILE'
87
- },
88
- desc: "Optional output file"
89
-
90
- option :verbose, short: '-v', desc: "Increase verbose level" do
91
- @verbose += 1
92
- end
93
-
94
- argument :file, type: String,
95
- required: true,
96
- usage: 'FILE',
97
- desc: "Input file"
98
-
99
- examples [
100
- '-o path/to/output.txt path/to/input.txt',
101
- '-v -c 2 -o path/to/output.txt path/to/input.txt',
102
- ]
103
-
104
- description 'Example command'
105
-
106
- def initialize(**kwargs)
107
- super(**kwargs)
108
-
109
- @verbose = 0
110
- end
111
-
112
- def run(file)
113
- puts "count=#{options[:count].inspect}"
114
- puts "output=#{options[:output].inspect}"
115
- puts "file=#{file.inspect}"
116
- puts "verbose=#{@verbose.inspect}"
117
- end
118
-
119
- end
120
- end
121
- end
122
-
123
- #### bin/my_cmd
124
-
125
- #!/usr/bin/env ruby
126
-
127
- $LOAD_PATH.unshift(File.expand_path('../../lib',__FILE__))
128
- require 'foo/cli/my_cmd'
129
-
130
- Foo::CLI::MyCmd.start
131
-
132
- #### --help
133
-
134
- Usage: my_cmd [OPTIONS] [-o OUTPUT] FILE
135
-
136
- Options:
137
- -c, --count INT Number of times (Default: 1)
138
- -o, --output FILE Optional output file
139
- -v, --verbose Increase verbose level
140
- -h, --help Print help information
141
-
142
- Arguments:
143
- FILE Input file
144
-
145
- Examples:
146
- my_cmd -o path/to/output.txt path/to/input.txt
147
- my_cmd -v -c 2 -o path/to/output.txt path/to/input.txt
148
-
149
- Example command
150
-
151
- ### Options
152
-
153
- Define an option:
154
-
155
- option :foo, desc: "Foo option"
156
-
157
- With a custom short option:
158
-
159
- option :foo, short: '-f',
160
- desc: "Foo option"
161
-
162
- With a custom long option:
163
-
164
- option :foo, short: '--foo-opt',
165
- desc: "Foo option"
166
-
167
- With a custom usage string:
44
+ ## Requirements
168
45
 
169
- option :foo, value: {usage: 'FOO'},
170
- desc: "Foo option"
46
+ * [ruby] >= 2.7.0
171
47
 
172
- With a custom block:
48
+ ## Install
173
49
 
174
- option :foo, desc: "Foo option" do |value|
175
- @foo = Foo.new(value)
176
- end
50
+ ```sh
51
+ $ gem install command_kit
52
+ ```
177
53
 
178
- With a custom type:
54
+ ### gemspec
179
55
 
180
- option :foo, value: {type: Integer},
181
- desc: "Foo option"
56
+ ```ruby
57
+ gem.add_dependency 'command_kit', '~> 0.2'
58
+ ```
182
59
 
183
- With a default value:
60
+ ### Gemfile
184
61
 
185
- option :foo, value: {type: Integer, default: 1},
186
- desc: "Foo option"
62
+ ```ruby
63
+ gem 'command_kit', '~> 0.2'
64
+ ```
187
65
 
188
- With a required value:
66
+ ## Examples
189
67
 
190
- option :foo, value: {type: String, required: true},
191
- desc: "Foo option"
68
+ ### lib/foo/cli/my_cmd.rb
192
69
 
193
- With a custom option value Hash map:
70
+ ```ruby
71
+ require 'command_kit'
194
72
 
195
- option :flag, value: {
196
- type: {
197
- 'enabled' => :enabled,
198
- 'yes' => :enabled,
199
- 'disabled' => :disabled,
200
- 'no' => :disabled
201
- }
202
- },
203
- desc: "Flag option"
73
+ module Foo
74
+ module CLI
75
+ class MyCmd < CommandKit::Command
204
76
 
205
- With a custom option value Array enum:
77
+ usage '[OPTIONS] [-o OUTPUT] FILE'
206
78
 
207
- option :enum, value: {type: %w[yes no]},
208
- desc: "Enum option"
79
+ option :count, short: '-c',
80
+ value: {
81
+ type: Integer,
82
+ default: 1
83
+ },
84
+ desc: "Number of times"
209
85
 
210
- With a custom option value Regexp:
86
+ option :output, short: '-o',
87
+ value: {
88
+ type: String,
89
+ usage: 'FILE'
90
+ },
91
+ desc: "Optional output file"
211
92
 
212
- option :date, value: {type: /(\d+)-(\d+)-(\d{2,4})/},
213
- desc: "Regexp optin" do |date,d,m,y|
214
- # ...
215
- end
93
+ option :verbose, short: '-v', desc: "Increase verbose level" do
94
+ @verbose += 1
95
+ end
216
96
 
217
- ### Arguments
97
+ argument :file, required: true,
98
+ usage: 'FILE',
99
+ desc: "Input file"
218
100
 
219
- Define an argument:
101
+ examples [
102
+ '-o path/to/output.txt path/to/input.txt',
103
+ '-v -c 2 -o path/to/output.txt path/to/input.txt',
104
+ ]
220
105
 
221
- argument :bar, desc: "Bar argument"
106
+ description 'Example command'
222
107
 
223
- With a custom usage string:
108
+ def initialize(**kwargs)
109
+ super(**kwargs)
224
110
 
225
- option :bar, usage: 'BAR',
226
- desc: "Bar argument"
111
+ @verbose = 0
112
+ end
227
113
 
228
- With a custom block:
114
+ def run(file)
115
+ puts "count=#{options[:count].inspect}"
116
+ puts "output=#{options[:output].inspect}"
117
+ puts "file=#{file.inspect}"
118
+ puts "verbose=#{@verbose.inspect}"
119
+ end
229
120
 
230
- argument :bar, desc: "Bar argument" do |bar|
231
- # ...
232
121
  end
122
+ end
123
+ end
124
+ ```
233
125
 
234
- With a custom type:
235
-
236
- argument :bar, type: Integer,
237
- desc: "Bar argument"
238
-
239
- With a default value:
126
+ ### bin/my_cmd
240
127
 
241
- argument :bar, default: "bar.txt",
242
- desc: "Bar argument"
128
+ ```ruby
129
+ #!/usr/bin/env ruby
243
130
 
244
- An optional argument:
131
+ $LOAD_PATH.unshift(File.expand_path('../../lib',__FILE__))
132
+ require 'foo/cli/my_cmd'
245
133
 
246
- argument :bar, required: true,
247
- desc: "Bar argument"
134
+ Foo::CLI::MyCmd.start
135
+ ```
248
136
 
249
- A repeating argument:
137
+ ### --help
250
138
 
251
- argument :bar, repeats: true,
252
- desc: "Bar argument"
253
-
254
- ## Requirements
139
+ Usage: my_cmd [OPTIONS] [-o OUTPUT] FILE
255
140
 
256
- * [ruby] >= 2.7.0
141
+ Options:
142
+ -c, --count INT Number of times (Default: 1)
143
+ -o, --output FILE Optional output file
144
+ -v, --verbose Increase verbose level
145
+ -h, --help Print help information
257
146
 
258
- ## Install
147
+ Arguments:
148
+ FILE Input file
259
149
 
260
- $ gem install command_kit
150
+ Examples:
151
+ my_cmd -o path/to/output.txt path/to/input.txt
152
+ my_cmd -v -c 2 -o path/to/output.txt path/to/input.txt
261
153
 
262
- ### Gemfile
154
+ Example command
263
155
 
264
- gem 'command_kit', '~> 0.1'
156
+ ### Reference
157
+
158
+ * [CommandKit::Arguments](https://rubydoc.info/gems/command_kit/CommandKit/Arguments)
159
+ * [CommandKit::Colors](https://rubydoc.info/gems/command_kit/CommandKit/Colors)
160
+ * [CommandKit::Command](https://rubydoc.info/gems/command_kit/CommandKit/Command)
161
+ * [CommandKit::CommandName](https://rubydoc.info/gems/command_kit/CommandKit/CommandName)
162
+ * [CommandKit::Commands](https://rubydoc.info/gems/command_kit/CommandKit/Commands)
163
+ * [CommandKit::Commands::AutoLoad](https://rubydoc.info/gems/command_kit/CommandKit/Commands/AutoLoad)
164
+ * [CommandKit::Commands::AutoRequire](https://rubydoc.info/gems/command_kit/CommandKit/Commands/AutoRequire)
165
+ * [CommandKit::Description](https://rubydoc.info/gems/command_kit/CommandKit/Description)
166
+ * [CommandKit::Env](https://rubydoc.info/gems/command_kit/CommandKit/Env)
167
+ * [CommandKit::Env::Home](https://rubydoc.info/gems/command_kit/CommandKit/Env/Home)
168
+ * [CommandKit::Env::Path](https://rubydoc.info/gems/command_kit/CommandKit/Env/Path)
169
+ * [CommandKit::Examples](https://rubydoc.info/gems/command_kit/CommandKit/Examples)
170
+ * [CommandKit::ExceptionHandler](https://rubydoc.info/gems/command_kit/CommandKit/ExceptionHandler)
171
+ * [CommandKit::Help](https://rubydoc.info/gems/command_kit/CommandKit/Help)
172
+ * [CommandKit::Help::Man](https://rubydoc.info/gems/command_kit/CommandKit/Help/Man)
173
+ * [CommandKit::Interactive](https://rubydoc.info/gems/command_kit/CommandKit/Interactive)
174
+ * [CommandKit::Main](https://rubydoc.info/gems/command_kit/CommandKit/Main)
175
+ * [CommandKit::Options](https://rubydoc.info/gems/command_kit/CommandKit/Options)
176
+ * [CommandKit::Options::Quiet](https://rubydoc.info/gems/command_kit/CommandKit/Options/Quiet)
177
+ * [CommandKit::Options::Verbose](https://rubydoc.info/gems/command_kit/CommandKit/Options/Verbose)
178
+ * [CommandKit::Pager](https://rubydoc.info/gems/command_kit/CommandKit/Pager)
179
+ * [CommandKit::Printing](https://rubydoc.info/gems/command_kit/CommandKit/Printing)
180
+ * [CommandKit::Printing::Indent](https://rubydoc.info/gems/command_kit/CommandKit/Printing/Indent)
181
+ * [CommandKit::ProgramName](https://rubydoc.info/gems/command_kit/CommandKit/ProgramName)
182
+ * [CommandKit::Stdio](https://rubydoc.info/gems/command_kit/CommandKit/Stdio)
183
+ * [CommandKit::Terminal](https://rubydoc.info/gems/command_kit/CommandKit/Terminal)
184
+ * [CommandKit::Usage](https://rubydoc.info/gems/command_kit/CommandKit/Usage)
185
+ * [CommandKit::XDG](https://rubydoc.info/gems/command_kit/CommandKit/XDG)
265
186
 
266
187
  ## Alternatives
267
188