command_kit 0.1.0.pre2 → 0.2.1
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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +15 -0
- data/.rubocop.yml +141 -0
- data/ChangeLog.md +98 -2
- data/Gemfile +3 -0
- data/README.md +189 -117
- data/Rakefile +3 -2
- data/command_kit.gemspec +4 -4
- data/examples/command.rb +1 -1
- data/gemspec.yml +10 -2
- data/lib/command_kit/arguments/argument.rb +2 -0
- data/lib/command_kit/arguments/argument_value.rb +2 -0
- data/lib/command_kit/arguments.rb +23 -4
- data/lib/command_kit/colors.rb +253 -45
- data/lib/command_kit/command.rb +6 -1
- data/lib/command_kit/command_name.rb +9 -0
- data/lib/command_kit/commands/auto_load.rb +24 -1
- data/lib/command_kit/commands/auto_require.rb +16 -0
- data/lib/command_kit/commands/command.rb +3 -0
- data/lib/command_kit/commands/help.rb +5 -2
- data/lib/command_kit/commands/parent_command.rb +7 -0
- data/lib/command_kit/commands/subcommand.rb +13 -1
- data/lib/command_kit/commands.rb +54 -9
- data/lib/command_kit/description.rb +12 -1
- data/lib/command_kit/env/home.rb +9 -0
- data/lib/command_kit/env/path.rb +16 -1
- data/lib/command_kit/env.rb +4 -0
- data/lib/command_kit/examples.rb +12 -1
- data/lib/command_kit/exception_handler.rb +4 -0
- data/lib/command_kit/help/man.rb +26 -30
- data/lib/command_kit/help.rb +7 -1
- data/lib/command_kit/inflector.rb +49 -17
- data/lib/command_kit/interactive.rb +248 -0
- data/lib/command_kit/main.rb +18 -9
- data/lib/command_kit/man.rb +44 -0
- data/lib/command_kit/open_app.rb +69 -0
- data/lib/command_kit/options/option.rb +3 -6
- data/lib/command_kit/options/option_value.rb +5 -2
- data/lib/command_kit/options/parser.rb +46 -19
- data/lib/command_kit/options/quiet.rb +3 -0
- data/lib/command_kit/options/verbose.rb +5 -0
- data/lib/command_kit/options/version.rb +6 -0
- data/lib/command_kit/options.rb +32 -7
- data/lib/command_kit/os/linux.rb +157 -0
- data/lib/command_kit/os.rb +165 -11
- data/lib/command_kit/package_manager.rb +200 -0
- data/lib/command_kit/pager.rb +80 -11
- data/lib/command_kit/printing/indent.rb +27 -4
- data/lib/command_kit/printing.rb +35 -1
- data/lib/command_kit/program_name.rb +7 -0
- data/lib/command_kit/stdio.rb +24 -0
- data/lib/command_kit/sudo.rb +40 -0
- data/lib/command_kit/terminal.rb +159 -0
- data/lib/command_kit/usage.rb +14 -0
- data/lib/command_kit/version.rb +1 -1
- data/lib/command_kit/xdg.rb +13 -0
- data/lib/command_kit.rb +1 -0
- data/spec/arguments/argument_spec.rb +2 -2
- data/spec/arguments_spec.rb +53 -27
- data/spec/colors_spec.rb +277 -13
- data/spec/command_name_spec.rb +1 -1
- data/spec/command_spec.rb +79 -5
- data/spec/commands/auto_load/subcommand_spec.rb +1 -1
- data/spec/commands/auto_load_spec.rb +34 -3
- data/spec/commands/auto_require_spec.rb +2 -2
- data/spec/commands/help_spec.rb +1 -1
- data/spec/commands/parent_command_spec.rb +1 -1
- data/spec/commands/subcommand_spec.rb +1 -1
- data/spec/commands_spec.rb +103 -29
- data/spec/description_spec.rb +1 -25
- data/spec/env/home_spec.rb +1 -1
- data/spec/env/path_spec.rb +7 -1
- data/spec/examples_spec.rb +1 -25
- data/spec/exception_handler_spec.rb +1 -1
- data/spec/help/man_spec.rb +45 -58
- data/spec/help_spec.rb +0 -25
- data/spec/inflector_spec.rb +71 -9
- data/spec/interactive_spec.rb +415 -0
- data/spec/main_spec.rb +7 -7
- data/spec/man_spec.rb +46 -0
- data/spec/open_app_spec.rb +85 -0
- data/spec/options/option_spec.rb +5 -5
- data/spec/options/option_value_spec.rb +56 -1
- data/spec/options_spec.rb +283 -1
- data/spec/os/linux_spec.rb +164 -0
- data/spec/os_spec.rb +201 -14
- data/spec/package_manager_spec.rb +806 -0
- data/spec/pager_spec.rb +76 -11
- data/spec/printing/indent_spec.rb +8 -6
- data/spec/printing_spec.rb +33 -3
- data/spec/program_name_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -3
- data/spec/sudo_spec.rb +51 -0
- data/spec/{console_spec.rb → terminal_spec.rb} +65 -35
- data/spec/usage_spec.rb +2 -2
- data/spec/xdg_spec.rb +1 -1
- metadata +26 -8
- data/lib/command_kit/console.rb +0 -141
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a218265a42b8b11c95888d07a3dcc3817d534adf830f8e7b1f1790bae73f05d6
|
4
|
+
data.tar.gz: c11cf5b2179d0701d5164b5ffcc07f2040cf8c813ea68caafdd7602e8603b754
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7bd20d0e6b33b1d84933ea246c51b552c8652e3f59c8ec3fe32bf1944148377799b20b8177f0025114689ff5f73a88d08fe14171bdbd48189ab4123ba9129113
|
7
|
+
data.tar.gz: 617efce051bc51bbb88ada26a83ded0e158b8e0af28ab2bad8af1478aac05a156833aa3bfd95b59e7b07daf1075c08e60f7f6165cc28b76908cb13eb694c4f4b
|
data/.github/workflows/ruby.yml
CHANGED
@@ -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,141 @@
|
|
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
|
+
Lint/ElseLayout: { Enabled: false } # Offense count: 22
|
89
|
+
|
90
|
+
# < 10 violations
|
91
|
+
Layout/EmptyLinesAroundModuleBody: { Enabled: false } # Offense count: 5
|
92
|
+
Layout/ExtraSpacing: { Enabled: false } # Offense count: 6
|
93
|
+
Layout/FirstHashElementIndentation: { Enabled: false } # Offense count: 4
|
94
|
+
Layout/ParameterAlignment: { Enabled: false } # Offense count: 9
|
95
|
+
Layout/SpaceAroundKeyword: { Enabled: false } # Offense count: 7
|
96
|
+
Layout/SpaceBeforeComma: { Enabled: false } # Offense count: 4
|
97
|
+
Layout/SpaceInsideParens: { Enabled: false } # Offense count: 4
|
98
|
+
Lint/EmptyClass: { Enabled: false } # Offense count: 3
|
99
|
+
Lint/SuppressedException: { Enabled: false } # Offense count: 4
|
100
|
+
Lint/UnusedMethodArgument: { Enabled: false } # Offense count: 5
|
101
|
+
Style/AccessorGrouping: { Enabled: false } # Offense count: 7
|
102
|
+
Style/Documentation: { Enabled: false } # Offense count: 3
|
103
|
+
Style/ExpandPathArguments: { Enabled: false } # Offense count: 8
|
104
|
+
Style/HashSyntax: { Exclude: ['Rakefile'] } # Offense count: 3
|
105
|
+
Style/KeywordParametersOrder: { Enabled: false } # Offense count: 8
|
106
|
+
Style/Lambda: { Enabled: false } # Offense count: 3
|
107
|
+
Style/MutableConstant: { Enabled: false } # Offense count: 4
|
108
|
+
Style/RaiseArgs: { Enabled: false } # Offense count: 4
|
109
|
+
Style/RedundantReturn: { Enabled: false } # Offense count: 7
|
110
|
+
Style/SafeNavigation: { Enabled: false } # Offense count: 5
|
111
|
+
Style/StringConcatenation: { Enabled: false } # Offense count: 8
|
112
|
+
Style/WordArray: { Enabled: false } # Offense count: 4
|
113
|
+
|
114
|
+
# 1 or 2 violations
|
115
|
+
Layout/ArgumentAlignment: { Enabled: false } # Offense count: 1
|
116
|
+
Layout/BlockAlignment: { Enabled: false } # Offense count: 1
|
117
|
+
Layout/IndentationWidth: { Enabled: false } # Offense count: 2
|
118
|
+
Layout/SpaceAroundOperators: { Enabled: false } # Offense count: 1
|
119
|
+
Layout/SpaceBeforeBlockBraces: { Enabled: false } # Offense count: 1
|
120
|
+
Lint/MissingSuper: { Enabled: false } # Offense count: 2
|
121
|
+
Lint/RescueException: { Enabled: false } # Offense count: 1
|
122
|
+
Lint/UnreachableLoop: { Enabled: false } # Offense count: 1
|
123
|
+
Lint/UnusedBlockArgument: { Enabled: false } # Offense count: 1
|
124
|
+
Naming/MethodParameterName: { Enabled: false } # Offense count: 1
|
125
|
+
Style/EmptyMethod: { Enabled: false } # Offense count: 2
|
126
|
+
Style/HashConversion: { Enabled: false } # Offense count: 1
|
127
|
+
Style/MultilineMemoization: { Enabled: false } # Offense count: 1
|
128
|
+
Style/NumericPredicate: { Enabled: false } # Offense count: 1
|
129
|
+
Style/OptionalArguments: { Enabled: false } # Offense count: 1
|
130
|
+
Style/ParenthesesAroundCondition: { Enabled: false } # Offense count: 1
|
131
|
+
Style/PreferredHashMethods: { Enabled: false } # Offense count: 1
|
132
|
+
Style/QuotedSymbols: { Enabled: false } # Offense count: 1
|
133
|
+
Style/RedundantException: { Enabled: false } # Offense count: 1
|
134
|
+
Style/RedundantRegexpEscape: { Enabled: false } # Offense count: 1
|
135
|
+
Style/RegexpLiteral: { Enabled: false } # Offense count: 1
|
136
|
+
Style/RescueStandardError: { Enabled: false } # Offense count: 1
|
137
|
+
Style/SoleNestedConditional: { Enabled: false } # Offense count: 1
|
138
|
+
Style/TrailingCommaInHashLiteral: { Enabled: false } # Offense count: 2
|
139
|
+
|
140
|
+
# rubocop cannot tell that rubygems_mfa_required is enabled in gemspec.yml
|
141
|
+
Gemspec/RequireMFA: { Enabled: false }
|
data/ChangeLog.md
CHANGED
@@ -1,13 +1,105 @@
|
|
1
|
-
### 0.1
|
1
|
+
### 0.2.1 / 2021-11-16
|
2
|
+
|
3
|
+
* Ensure that all error messages end with a period.
|
4
|
+
* Documentation fixes.
|
5
|
+
* Opt-in to [rubygem.org MFA requirement](https://guides.rubygems.org/mfa-requirement-opt-in/).
|
6
|
+
|
7
|
+
#### CommandKit::Printing
|
8
|
+
|
9
|
+
* Auto-detect whether {CommandKit::CommandName#command_name #command_name} is
|
10
|
+
available, and if so, prepend the command name to all error messages.
|
11
|
+
|
12
|
+
#### CommandKit::Help::Man
|
13
|
+
|
14
|
+
* Expand the path given to
|
15
|
+
{CommandKit::Help::Man::ClassMethods#man_dir man_dir}.
|
16
|
+
* If {CommandKit::Help::Man::ClassMethods#man_dir man_dir} is not set, fallback
|
17
|
+
to regular `--help` output.
|
18
|
+
|
19
|
+
#### CommandKit::Arguments
|
20
|
+
|
21
|
+
* Include {CommandKit::Usage} and {CommandKit::Printing} into
|
22
|
+
{CommandKit::Arguments}.
|
23
|
+
|
24
|
+
#### CommandKit::Options
|
25
|
+
|
26
|
+
* Include {CommandKit::Arguments} into {CommandKit::Options}.
|
27
|
+
* Ensure that {CommandKit::Options::Parser#main} runs before
|
28
|
+
{CommandKit::Arguments#main}.
|
29
|
+
* Ensure that {CommandKit::Options#help} also calls
|
30
|
+
{CommandKit::Arguments#help_arguments}.
|
31
|
+
* Always prepopulate {CommandKit::Options#options #options} with option's
|
32
|
+
default values.
|
33
|
+
* Note: if an option has a default value but the option's value is not
|
34
|
+
required (ex: `value: {required: false, default: "foo"}`), and the option's
|
35
|
+
flag is given but no value is given (ex: `--option-flag --some-other-flag`),
|
36
|
+
the option's value in {CommandKit::Options#options #options} will be `nil`
|
37
|
+
_not_ the option's default value (`"foo"`). This helps indicate that the
|
38
|
+
option's flag was given but no value was given with it.
|
39
|
+
|
40
|
+
#### CommandKit::Options::OptionValue
|
41
|
+
|
42
|
+
* When a `Class` is passed to {CommandKit::Options::OptionValue.default_usage},
|
43
|
+
demodularize the class name before converting it to underscored/uppercase.
|
44
|
+
|
45
|
+
#### CommandKit::Command
|
46
|
+
|
47
|
+
* Fixed the inclusion order of {CommandKit::Options} and
|
48
|
+
{CommandKit::Arguments}.
|
49
|
+
|
50
|
+
#### CommandKit::Commands
|
51
|
+
|
52
|
+
* Define the `COMMAND` and `ARGS` arguments.
|
53
|
+
* Correctly duplicate the {CommandKit::Env#env env} (which can be either `ENV`
|
54
|
+
or a `Hash`) to work on ruby-3.1.0-preview1.
|
55
|
+
* Print command aliases that were set explicitly
|
56
|
+
(ex: `command_aliases['rm'] = 'remove'`) in {CommandKit::Commands#help}.
|
57
|
+
* Print help and exit with status `1` if no command is given. This matches the
|
58
|
+
behavior of the `git` command.
|
59
|
+
|
60
|
+
#### CommandKit::Commands::AutoLoad
|
61
|
+
|
62
|
+
* Ensure that any explicit command aliases are added to the command's
|
63
|
+
{CommandKit::Commands::ClassMethods#command_aliases command_aliases}.
|
64
|
+
|
65
|
+
### 0.2.0 / 2021-08-31
|
66
|
+
|
67
|
+
* Added {CommandKit::Colors::ANSI#on_black}.
|
68
|
+
* Added {CommandKit::Colors::ANSI#on_red}.
|
69
|
+
* Added {CommandKit::Colors::ANSI#on_green}.
|
70
|
+
* Added {CommandKit::Colors::ANSI#on_yellow}.
|
71
|
+
* Added {CommandKit::Colors::ANSI#on_blue}.
|
72
|
+
* Added {CommandKit::Colors::ANSI#on_magenta}.
|
73
|
+
* Added {CommandKit::Colors::ANSI#on_cyan}.
|
74
|
+
* Added {CommandKit::Colors::ANSI#on_white}.
|
75
|
+
* Added {CommandKit::Man}.
|
76
|
+
* Added {CommandKit::OS#bsd?}.
|
77
|
+
* Added {CommandKit::OS#freebsd?}.
|
78
|
+
* Added {CommandKit::OS#netbsd?}.
|
79
|
+
* Added {CommandKit::OS#openbsd?}.
|
80
|
+
* Added {CommandKit::OS#os}.
|
81
|
+
* Added {CommandKit::OS#unix?}.
|
82
|
+
* Added {CommandKit::OS::Linux}.
|
83
|
+
* Added {CommandKit::OpenApp}.
|
84
|
+
* Added {CommandKit::PackageManager}.
|
85
|
+
* Added {CommandKit::Pager#pipe_to_pager}.
|
86
|
+
* Added {CommandKit::Sudo}.
|
87
|
+
* Added {CommandKit::Terminal#tty?}.
|
88
|
+
* Refactor {CommandKit::Inflector.camelize} and
|
89
|
+
{CommandKit::Inflector.underscore} to use StringScanner.
|
90
|
+
* Allow {CommandKit::OS#initialize} to accept an `os:` keyword to override the
|
91
|
+
detected OS.
|
92
|
+
|
93
|
+
### 0.1.0 / 2021-07-16
|
2
94
|
|
3
95
|
* Initial release:
|
4
96
|
* {CommandKit::Arguments}
|
5
97
|
* {CommandKit::Colors}
|
98
|
+
* {CommandKit::Command}
|
6
99
|
* {CommandKit::CommandName}
|
7
100
|
* {CommandKit::Commands}
|
8
101
|
* {CommandKit::Commands::AutoLoad}
|
9
102
|
* {CommandKit::Commands::AutoRequire}
|
10
|
-
* {CommandKit::Console}
|
11
103
|
* {CommandKit::Description}
|
12
104
|
* {CommandKit::Env}
|
13
105
|
* {CommandKit::Env::Home}
|
@@ -16,14 +108,18 @@
|
|
16
108
|
* {CommandKit::ExceptionHandler}
|
17
109
|
* {CommandKit::Help}
|
18
110
|
* {CommandKit::Help::Man}
|
111
|
+
* {CommandKit::Interactive}
|
19
112
|
* {CommandKit::Main}
|
20
113
|
* {CommandKit::Options}
|
21
114
|
* {CommandKit::Options::Quiet}
|
22
115
|
* {CommandKit::Options::Verbose}
|
116
|
+
* {CommandKit::OS}
|
23
117
|
* {CommandKit::Pager}
|
24
118
|
* {CommandKit::Printing}
|
119
|
+
* {CommandKit::Printing::Indent}
|
25
120
|
* {CommandKit::ProgramName}
|
26
121
|
* {CommandKit::Stdio}
|
122
|
+
* {CommandKit::Terminal}
|
27
123
|
* {CommandKit::Usage}
|
28
124
|
* {CommandKit::XDG}
|
29
125
|
|
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,60 +1,41 @@
|
|
1
1
|
# command_kit
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
[](https://github.com/postmodern/command_kit.rb/actions)
|
4
|
+
[](https://codeclimate.com/github/postmodern/command_kit.rb)
|
5
|
+
[](https://badge.fury.io/rb/command_kit)
|
6
|
+
|
7
|
+
* [Homepage](https://github.com/postmodern/command_kit.rb#readme)
|
8
|
+
* [Forum](https://github.com/postmodern/command_kit.rb/discussions) |
|
9
|
+
[Issues](https://github.com/postmodern/command_kit.rb/issues)
|
5
10
|
* [Documentation](http://rubydoc.info/gems/command_kit/frames)
|
6
|
-
* [Email](mailto:postmodern.mod3 at gmail.com)
|
7
11
|
|
8
12
|
## Description
|
9
13
|
|
10
|
-
A Ruby toolkit for building clean, correct, and robust CLI commands as
|
11
|
-
classes.
|
14
|
+
A Ruby toolkit for building clean, correct, and robust CLI commands as
|
15
|
+
plain-old Ruby classes.
|
12
16
|
|
13
17
|
## Features
|
14
18
|
|
15
|
-
*
|
16
|
-
|
17
|
-
|
18
|
-
*
|
19
|
-
*
|
20
|
-
*
|
21
|
-
*
|
22
|
-
*
|
23
|
-
*
|
24
|
-
|
25
|
-
*
|
26
|
-
*
|
27
|
-
*
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
*
|
32
|
-
* [
|
33
|
-
*
|
34
|
-
|
35
|
-
* [CommandKit::Commands](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Commands)
|
36
|
-
* [CommandKit::Commands::AutoLoad](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Commands/AutoLoad)
|
37
|
-
* [CommandKit::Commands::AutoRequire](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Commands/AutoRequire)
|
38
|
-
* [CommandKit::Console](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Console)
|
39
|
-
* [CommandKit::Description](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Description)
|
40
|
-
* [CommandKit::Env](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Env)
|
41
|
-
* [CommandKit::Env::Home](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Env/Home)
|
42
|
-
* [CommandKit::Env::Path](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Env/Path)
|
43
|
-
* [CommandKit::Examples](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Examples)
|
44
|
-
* [CommandKit::ExceptionHandler](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/ExceptionHandler)
|
45
|
-
* [CommandKit::Help](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Help)
|
46
|
-
* [CommandKit::Help::Man](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Help/Man)
|
47
|
-
* [CommandKit::Main](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Main)
|
48
|
-
* [CommandKit::Options](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Options)
|
49
|
-
* [CommandKit::Options::Quiet](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Options/Quiet)
|
50
|
-
* [CommandKit::Options::Verbose](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Options/Verbose)
|
51
|
-
* [CommandKit::Pager](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Pager)
|
52
|
-
* [CommandKit::Printing](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Printing)
|
53
|
-
* [CommandKit::Printing::Indent](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Printing/Indent)
|
54
|
-
* [CommandKit::ProgramName](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/ProgramName)
|
55
|
-
* [CommandKit::Stdio](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Stdio)
|
56
|
-
* [CommandKit::Usage](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/Usage)
|
57
|
-
* [CommandKit::XDG](https://rubydoc.info/github/postmodern/command_kit/main/CommandKit/XDG)
|
19
|
+
* **Simple** - Commands are plain-old ruby classes, with options and
|
20
|
+
arguments declared as attributes. All features are ruby modules that can be
|
21
|
+
included into command classes.
|
22
|
+
* **Correct** - CommandKit behaves like a standard UNIX command.
|
23
|
+
* Safely handles Ctrl^C / SIGINT interrupts and [exits with 130](https://tldp.org/LDP/abs/html/exitcodes.html).
|
24
|
+
* Safely handles broken pipes (aka `mycmd | head`).
|
25
|
+
* Respects common environment variables (ex: `TERM=dumb`).
|
26
|
+
* Uses [OptionParser][optparse] for POSIX option parsing.
|
27
|
+
* Disables ANSI color when output is redirected to a file.
|
28
|
+
* **Complete** - Provides many additional CLI features.
|
29
|
+
* OS detection.
|
30
|
+
* Terminal size detection.
|
31
|
+
* ANSI coloring support.
|
32
|
+
* Interactive input.
|
33
|
+
* Subcommands (explicit or lazy-loaded) and command aliases.
|
34
|
+
* Displaying man pages for `--help`/`help`.
|
35
|
+
* Using the pager (aka `less`).
|
36
|
+
* [XDG directories](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) (aka `~/.config/`, `~/.local/share/`, `~/.cache/`).
|
37
|
+
* **Testable** - Since commands are plain-old ruby classes, it's easy to
|
38
|
+
initialize them and call `#main` or `#run`.
|
58
39
|
|
59
40
|
## Anti-Features
|
60
41
|
|
@@ -62,103 +43,194 @@ classes.
|
|
62
43
|
* Does not implement it's own option parser.
|
63
44
|
* Not named after a comic-book Superhero.
|
64
45
|
|
46
|
+
## Requirements
|
47
|
+
|
48
|
+
* [ruby] >= 2.7.0
|
49
|
+
|
50
|
+
## Install
|
51
|
+
|
52
|
+
```sh
|
53
|
+
$ gem install command_kit
|
54
|
+
```
|
55
|
+
|
56
|
+
### gemspec
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
gem.add_dependency 'command_kit', '~> 0.2'
|
60
|
+
```
|
61
|
+
|
62
|
+
### Gemfile
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
gem 'command_kit', '~> 0.2'
|
66
|
+
```
|
67
|
+
|
65
68
|
## Examples
|
66
69
|
|
67
70
|
### lib/foo/cli/my_cmd.rb
|
68
71
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
argument :file, 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
|
72
|
+
```ruby
|
73
|
+
require 'command_kit'
|
74
|
+
|
75
|
+
module Foo
|
76
|
+
module CLI
|
77
|
+
class MyCmd < CommandKit::Command
|
78
|
+
|
79
|
+
usage '[OPTIONS] [-o OUTPUT] FILE'
|
80
|
+
|
81
|
+
option :count, short: '-c',
|
82
|
+
value: {
|
83
|
+
type: Integer,
|
84
|
+
default: 1
|
85
|
+
},
|
86
|
+
desc: "Number of times"
|
87
|
+
|
88
|
+
option :output, short: '-o',
|
89
|
+
value: {
|
90
|
+
type: String,
|
91
|
+
usage: 'FILE'
|
92
|
+
},
|
93
|
+
desc: "Optional output file"
|
94
|
+
|
95
|
+
option :verbose, short: '-v', desc: "Increase verbose level" do
|
96
|
+
@verbose += 1
|
120
97
|
end
|
98
|
+
|
99
|
+
argument :file, required: true,
|
100
|
+
usage: 'FILE',
|
101
|
+
desc: "Input file"
|
102
|
+
|
103
|
+
examples [
|
104
|
+
'-o path/to/output.txt path/to/input.txt',
|
105
|
+
'-v -c 2 -o path/to/output.txt path/to/input.txt',
|
106
|
+
]
|
107
|
+
|
108
|
+
description 'Example command'
|
109
|
+
|
110
|
+
def initialize(**kwargs)
|
111
|
+
super(**kwargs)
|
112
|
+
|
113
|
+
@verbose = 0
|
114
|
+
end
|
115
|
+
|
116
|
+
def run(file)
|
117
|
+
puts "count=#{options[:count].inspect}"
|
118
|
+
puts "output=#{options[:output].inspect}"
|
119
|
+
puts "file=#{file.inspect}"
|
120
|
+
puts "verbose=#{@verbose.inspect}"
|
121
|
+
end
|
122
|
+
|
121
123
|
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
```
|
122
127
|
|
123
128
|
### bin/my_cmd
|
124
129
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
130
|
+
```ruby
|
131
|
+
#!/usr/bin/env ruby
|
132
|
+
|
133
|
+
$LOAD_PATH.unshift(File.expand_path('../../lib',__FILE__))
|
134
|
+
require 'foo/cli/my_cmd'
|
135
|
+
|
136
|
+
Foo::CLI::MyCmd.start
|
137
|
+
```
|
131
138
|
|
132
139
|
### --help
|
133
140
|
|
134
141
|
Usage: my_cmd [OPTIONS] [-o OUTPUT] FILE
|
135
|
-
|
142
|
+
|
136
143
|
Options:
|
137
144
|
-c, --count INT Number of times (Default: 1)
|
138
145
|
-o, --output FILE Optional output file
|
139
146
|
-v, --verbose Increase verbose level
|
140
147
|
-h, --help Print help information
|
141
|
-
|
148
|
+
|
142
149
|
Arguments:
|
143
150
|
FILE Input file
|
144
|
-
|
151
|
+
|
145
152
|
Examples:
|
146
153
|
my_cmd -o path/to/output.txt path/to/input.txt
|
147
154
|
my_cmd -v -c 2 -o path/to/output.txt path/to/input.txt
|
148
|
-
|
149
|
-
Example command
|
150
155
|
|
151
|
-
|
152
|
-
|
153
|
-
* [ruby] >= 2.7.0
|
156
|
+
Example command
|
154
157
|
|
155
|
-
##
|
158
|
+
## Testing
|
159
|
+
|
160
|
+
### RSpec
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
require 'spec_helper'
|
164
|
+
require 'stringio'
|
165
|
+
require 'foo/cli/my_cmd'
|
166
|
+
|
167
|
+
describe Foo::CLI::MyCmd do
|
168
|
+
let(:stdin) { StringIO.new }
|
169
|
+
let(:stdout) { StringIO.new }
|
170
|
+
let(:stderr) { StringIO.new }
|
171
|
+
let(:env) { ENV }
|
172
|
+
|
173
|
+
subject do
|
174
|
+
described_class.new(
|
175
|
+
stdin: stdin,
|
176
|
+
stdout: stdout,
|
177
|
+
stderr: stderr,
|
178
|
+
env: env
|
179
|
+
)
|
180
|
+
end
|
181
|
+
|
182
|
+
# testing with raw options/arguments
|
183
|
+
describe "#main" do
|
184
|
+
context "when executed with no arguments" do
|
185
|
+
it "must exit with -1" do
|
186
|
+
expect(subject.main([])).to eq(-1)
|
187
|
+
end
|
188
|
+
end
|
156
189
|
|
157
|
-
|
190
|
+
context "when executed with -o OUTPUT" do
|
191
|
+
let(:file) { ... }
|
192
|
+
let(:output) { ... }
|
158
193
|
|
159
|
-
|
194
|
+
before { subject.main(["-o", output, file]) }
|
160
195
|
|
161
|
-
|
196
|
+
it "must create the output file" do
|
197
|
+
...
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
```
|
203
|
+
|
204
|
+
### Reference
|
205
|
+
|
206
|
+
* [CommandKit::Arguments](https://rubydoc.info/gems/command_kit/CommandKit/Arguments)
|
207
|
+
* [CommandKit::Colors](https://rubydoc.info/gems/command_kit/CommandKit/Colors)
|
208
|
+
* [CommandKit::Command](https://rubydoc.info/gems/command_kit/CommandKit/Command)
|
209
|
+
* [CommandKit::CommandName](https://rubydoc.info/gems/command_kit/CommandKit/CommandName)
|
210
|
+
* [CommandKit::Commands](https://rubydoc.info/gems/command_kit/CommandKit/Commands)
|
211
|
+
* [CommandKit::Commands::AutoLoad](https://rubydoc.info/gems/command_kit/CommandKit/Commands/AutoLoad)
|
212
|
+
* [CommandKit::Commands::AutoRequire](https://rubydoc.info/gems/command_kit/CommandKit/Commands/AutoRequire)
|
213
|
+
* [CommandKit::Description](https://rubydoc.info/gems/command_kit/CommandKit/Description)
|
214
|
+
* [CommandKit::Env](https://rubydoc.info/gems/command_kit/CommandKit/Env)
|
215
|
+
* [CommandKit::Env::Home](https://rubydoc.info/gems/command_kit/CommandKit/Env/Home)
|
216
|
+
* [CommandKit::Env::Path](https://rubydoc.info/gems/command_kit/CommandKit/Env/Path)
|
217
|
+
* [CommandKit::Examples](https://rubydoc.info/gems/command_kit/CommandKit/Examples)
|
218
|
+
* [CommandKit::ExceptionHandler](https://rubydoc.info/gems/command_kit/CommandKit/ExceptionHandler)
|
219
|
+
* [CommandKit::Help](https://rubydoc.info/gems/command_kit/CommandKit/Help)
|
220
|
+
* [CommandKit::Help::Man](https://rubydoc.info/gems/command_kit/CommandKit/Help/Man)
|
221
|
+
* [CommandKit::Interactive](https://rubydoc.info/gems/command_kit/CommandKit/Interactive)
|
222
|
+
* [CommandKit::Main](https://rubydoc.info/gems/command_kit/CommandKit/Main)
|
223
|
+
* [CommandKit::Options](https://rubydoc.info/gems/command_kit/CommandKit/Options)
|
224
|
+
* [CommandKit::Options::Quiet](https://rubydoc.info/gems/command_kit/CommandKit/Options/Quiet)
|
225
|
+
* [CommandKit::Options::Verbose](https://rubydoc.info/gems/command_kit/CommandKit/Options/Verbose)
|
226
|
+
* [CommandKit::Pager](https://rubydoc.info/gems/command_kit/CommandKit/Pager)
|
227
|
+
* [CommandKit::Printing](https://rubydoc.info/gems/command_kit/CommandKit/Printing)
|
228
|
+
* [CommandKit::Printing::Indent](https://rubydoc.info/gems/command_kit/CommandKit/Printing/Indent)
|
229
|
+
* [CommandKit::ProgramName](https://rubydoc.info/gems/command_kit/CommandKit/ProgramName)
|
230
|
+
* [CommandKit::Stdio](https://rubydoc.info/gems/command_kit/CommandKit/Stdio)
|
231
|
+
* [CommandKit::Terminal](https://rubydoc.info/gems/command_kit/CommandKit/Terminal)
|
232
|
+
* [CommandKit::Usage](https://rubydoc.info/gems/command_kit/CommandKit/Usage)
|
233
|
+
* [CommandKit::XDG](https://rubydoc.info/gems/command_kit/CommandKit/XDG)
|
162
234
|
|
163
235
|
## Alternatives
|
164
236
|
|