command_kit 0.4.0 → 0.5.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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +2 -0
  3. data/.rubocop.yml +3 -0
  4. data/ChangeLog.md +18 -0
  5. data/LICENSE.txt +1 -1
  6. data/README.md +4 -1
  7. data/command_kit.gemspec +7 -2
  8. data/examples/subcommands/cli/config/get.rb +47 -0
  9. data/examples/subcommands/cli/config/set.rb +44 -0
  10. data/examples/subcommands/cli/config.rb +23 -0
  11. data/examples/subcommands/cli/list.rb +35 -0
  12. data/examples/subcommands/cli/update.rb +47 -0
  13. data/examples/subcommands/cli.rb +55 -0
  14. data/lib/command_kit/completion/install.rb +276 -0
  15. data/lib/command_kit/env/home.rb +1 -1
  16. data/lib/command_kit/env/prefix.rb +41 -0
  17. data/lib/command_kit/env/shell.rb +58 -0
  18. data/lib/command_kit/inflector.rb +1 -1
  19. data/lib/command_kit/options/parser.rb +1 -1
  20. data/lib/command_kit/os/linux.rb +1 -1
  21. data/lib/command_kit/os.rb +1 -1
  22. data/lib/command_kit/printing/tables/table_formatter.rb +2 -2
  23. data/lib/command_kit/version.rb +1 -1
  24. data/lib/command_kit/xdg.rb +1 -1
  25. metadata +12 -66
  26. data/spec/arguments/argument_spec.rb +0 -133
  27. data/spec/arguments/argument_value_spec.rb +0 -66
  28. data/spec/arguments_spec.rb +0 -279
  29. data/spec/bug_report_spec.rb +0 -266
  30. data/spec/colors_spec.rb +0 -771
  31. data/spec/command_kit_spec.rb +0 -8
  32. data/spec/command_name_spec.rb +0 -130
  33. data/spec/command_spec.rb +0 -123
  34. data/spec/commands/auto_load/subcommand_spec.rb +0 -82
  35. data/spec/commands/auto_load_spec.rb +0 -159
  36. data/spec/commands/auto_require_spec.rb +0 -142
  37. data/spec/commands/fixtures/test_auto_load/cli/commands/test1.rb +0 -10
  38. data/spec/commands/fixtures/test_auto_load/cli/commands/test2.rb +0 -10
  39. data/spec/commands/fixtures/test_auto_require/lib/test_auto_require/cli/commands/test1.rb +0 -10
  40. data/spec/commands/help_spec.rb +0 -66
  41. data/spec/commands/parent_command_spec.rb +0 -40
  42. data/spec/commands/subcommand_spec.rb +0 -99
  43. data/spec/commands_spec.rb +0 -839
  44. data/spec/description_spec.rb +0 -179
  45. data/spec/edit_spec.rb +0 -72
  46. data/spec/env/home_spec.rb +0 -46
  47. data/spec/env/path_spec.rb +0 -84
  48. data/spec/env_spec.rb +0 -123
  49. data/spec/examples_spec.rb +0 -211
  50. data/spec/exception_handler_spec.rb +0 -103
  51. data/spec/file_utils_spec.rb +0 -59
  52. data/spec/fixtures/template.erb +0 -5
  53. data/spec/help/man_spec.rb +0 -345
  54. data/spec/help_spec.rb +0 -94
  55. data/spec/inflector_spec.rb +0 -166
  56. data/spec/interactive_spec.rb +0 -415
  57. data/spec/main_spec.rb +0 -179
  58. data/spec/man_spec.rb +0 -46
  59. data/spec/open_app_spec.rb +0 -85
  60. data/spec/options/option_spec.rb +0 -343
  61. data/spec/options/option_value_spec.rb +0 -171
  62. data/spec/options/parser_spec.rb +0 -255
  63. data/spec/options/quiet_spec.rb +0 -51
  64. data/spec/options/verbose_spec.rb +0 -51
  65. data/spec/options/version_spec.rb +0 -146
  66. data/spec/options_spec.rb +0 -465
  67. data/spec/os/linux_spec.rb +0 -164
  68. data/spec/os_spec.rb +0 -233
  69. data/spec/package_manager_spec.rb +0 -806
  70. data/spec/pager_spec.rb +0 -217
  71. data/spec/printing/fields_spec.rb +0 -167
  72. data/spec/printing/indent_spec.rb +0 -132
  73. data/spec/printing/lists_spec.rb +0 -99
  74. data/spec/printing/tables/border_style.rb +0 -43
  75. data/spec/printing/tables/cell_builer_spec.rb +0 -135
  76. data/spec/printing/tables/row_builder_spec.rb +0 -165
  77. data/spec/printing/tables/style_spec.rb +0 -377
  78. data/spec/printing/tables/table_builder_spec.rb +0 -252
  79. data/spec/printing/tables/table_formatter_spec.rb +0 -1180
  80. data/spec/printing/tables_spec.rb +0 -1069
  81. data/spec/printing_spec.rb +0 -106
  82. data/spec/program_name_spec.rb +0 -70
  83. data/spec/spec_helper.rb +0 -3
  84. data/spec/stdio_spec.rb +0 -264
  85. data/spec/sudo_spec.rb +0 -51
  86. data/spec/terminal_spec.rb +0 -231
  87. data/spec/usage_spec.rb +0 -237
  88. data/spec/xdg_spec.rb +0 -191
@@ -1,279 +0,0 @@
1
- require 'spec_helper'
2
- require 'command_kit/arguments'
3
-
4
- describe CommandKit::Arguments do
5
- module TestArguments
6
- class ImplicitCmd
7
- include CommandKit::Arguments
8
- end
9
- end
10
-
11
- let(:command_class) { TestArguments::ImplicitCmd }
12
-
13
- describe ".included" do
14
- subject { command_class }
15
-
16
- it { expect(subject).to include(CommandKit::Main) }
17
- it { expect(subject).to include(CommandKit::Help) }
18
- end
19
-
20
- describe ".arguments" do
21
- subject { TestArguments::ImplicitCmd }
22
-
23
- context "when no arguments have been defined" do
24
- it "should default to {}" do
25
- expect(subject.arguments).to eq({})
26
- end
27
- end
28
-
29
- context "when a arguments is explicitly set" do
30
- module TestArguments
31
- class ExplicitCmd
32
- include CommandKit::Arguments
33
- argument :foo, desc: 'Foo option'
34
- argument :bar, desc: 'Bar option'
35
- end
36
- end
37
-
38
- subject { TestArguments::ExplicitCmd }
39
-
40
- it "must return the explicitly set arguments" do
41
- expect(subject.arguments.keys).to eq([:foo, :bar])
42
- end
43
- end
44
-
45
- context "when the command class inherites from another class" do
46
- context "but no arguments are defined" do
47
- module TestArguments
48
- class BaseCmd
49
- include CommandKit::Arguments
50
- end
51
-
52
- class InheritedCmd < BaseCmd
53
- end
54
- end
55
-
56
- subject { TestArguments::InheritedCmd }
57
-
58
- it "must search each class then return {}"do
59
- expect(subject.arguments).to eq({})
60
- end
61
- end
62
-
63
- module TestArguments
64
- class ExplicitBaseCmd
65
- include CommandKit::Arguments
66
- argument :foo, desc: 'Foo option'
67
- argument :bar, desc: 'Bar option'
68
- end
69
- end
70
-
71
- context "when the superclass defines arguments" do
72
- module TestArguments
73
- class ImplicitInheritedCmd < ExplicitBaseCmd
74
- end
75
- end
76
-
77
- let(:super_subject) { TestArguments::ExplicitBaseCmd }
78
- subject { TestArguments::ImplicitInheritedCmd }
79
-
80
- it "must inherit the superclass'es arguments" do
81
- expect(subject.arguments).to eq(super_subject.arguments)
82
- end
83
-
84
- it "must not change the superclass'es arguments" do
85
- expect(super_subject.arguments.keys).to eq([:foo, :bar])
86
- end
87
- end
88
-
89
- context "when the subclass defines arguments" do
90
- module TestArguments
91
- class ImplicitBaseCmd
92
- include CommandKit::Arguments
93
- end
94
-
95
- class ExplicitInheritedCmd < ImplicitBaseCmd
96
- argument :baz, desc: 'Baz option'
97
- argument :qux, desc: 'Qux option'
98
- end
99
- end
100
-
101
- let(:super_subject) { TestArguments::ImplicitBaseCmd }
102
- subject { TestArguments::ExplicitInheritedCmd }
103
-
104
- it "must return the subclass'es arguments" do
105
- expect(subject.arguments.keys).to eq([:baz, :qux])
106
- end
107
-
108
- it "must not change the superclass'es arguments" do
109
- expect(super_subject.arguments).to eq({})
110
- end
111
- end
112
-
113
- context "when subclass overrides the superclass's argumentss" do
114
- module TestArguments
115
- class ExplicitOverridingInheritedCmd < ExplicitBaseCmd
116
- argument :foo, desc: "Overriden foo option"
117
- end
118
- end
119
-
120
- let(:super_subject) { TestArguments::ExplicitBaseCmd }
121
- subject { TestArguments::ExplicitOverridingInheritedCmd }
122
-
123
- it "must combine the superclass'es arguments with the subclass'es" do
124
- expect(subject.arguments.keys).to eq([:foo, :bar])
125
- expect(subject.arguments[:foo].desc).to eq("Overriden foo option")
126
- expect(subject.arguments[:bar].desc).to eq("Bar option")
127
- end
128
-
129
- it "must not change the superclass'es arguments" do
130
- expect(super_subject.arguments.keys).to eq([:foo, :bar])
131
- expect(super_subject.arguments[:foo].desc).to eq("Foo option")
132
- expect(super_subject.arguments[:bar].desc).to eq("Bar option")
133
- end
134
- end
135
- end
136
- end
137
-
138
- subject { command_class.new }
139
-
140
- describe "#main" do
141
- module TestArguments
142
- class TestCommand
143
-
144
- include CommandKit::Arguments
145
-
146
- argument :argument1, required: true,
147
- usage: 'ARG1',
148
- desc: "Argument 1"
149
-
150
- argument :argument2, required: false,
151
- usage: 'ARG2',
152
- desc: "Argument 2"
153
-
154
- end
155
- end
156
-
157
- let(:command_class) { TestArguments::TestCommand }
158
-
159
- context "when given the correct number of arguments" do
160
- let(:argv) { %w[arg1 arg2] }
161
-
162
- it "must parse options before validating the number of arguments" do
163
- expect {
164
- expect(subject.main(argv)).to eq(0)
165
- }.to_not output.to_stderr
166
- end
167
- end
168
-
169
- context "when given fewer than the required number of arguments" do
170
- let(:argv) { %w[] }
171
-
172
- it "must print an error message and return 1" do
173
- expect {
174
- expect(subject.main(argv)).to eq(1)
175
- }.to output("#{subject.command_name}: insufficient number of arguments.#{$/}").to_stderr
176
- end
177
- end
178
-
179
- context "when given more than the total number of arguments" do
180
- let(:argv) { %w[foo bar baz] }
181
-
182
- it "must print an error message and return 1" do
183
- expect {
184
- expect(subject.main(argv)).to eq(1)
185
- }.to output("#{subject.command_name}: too many arguments given.#{$/}").to_stderr
186
- end
187
- end
188
- end
189
-
190
- describe "#help_arguments" do
191
- context "when #arguments returns {}" do
192
- module TestArguments
193
- class NoArguments
194
- include CommandKit::Arguments
195
- end
196
- end
197
-
198
- let(:command_class) { TestArguments::NoArguments }
199
- subject { command_class.new }
200
-
201
- it "must print out the arguments" do
202
- expect { subject.help_arguments }.to_not output.to_stdout
203
- end
204
- end
205
-
206
- context "when #arguments returns a Hash" do
207
- module TestArguments
208
- class MultipleArguments
209
- include CommandKit::Arguments
210
-
211
- argument :foo, desc: "Foo option"
212
- argument :bar, desc: "Bar option"
213
- argument :baz, desc: "Baz option"
214
- end
215
- end
216
-
217
- let(:command_class) { TestArguments::MultipleArguments }
218
- subject { command_class.new }
219
-
220
- let(:foo_argument) { command_class.arguments[:foo] }
221
- let(:bar_argument) { command_class.arguments[:bar] }
222
- let(:baz_argument) { command_class.arguments[:baz] }
223
-
224
- it "must print out the 'Arguments:' section header and the arguments" do
225
- expect { subject.help_arguments }.to output(
226
- [
227
- '',
228
- "Arguments:",
229
- " #{foo_argument.usage.ljust(33)}#{foo_argument.desc}",
230
- " #{bar_argument.usage.ljust(33)}#{bar_argument.desc}",
231
- " #{baz_argument.usage.ljust(33)}#{baz_argument.desc}",
232
- ''
233
- ].join($/)
234
- ).to_stdout
235
- end
236
-
237
- context "when one the argument has an Array for a description" do
238
- module TestArguments
239
- class MultiLineArgumentDescription
240
- include CommandKit::Arguments
241
-
242
- argument :foo, desc: "Foo option"
243
- argument :bar, desc: [
244
- "Bar option",
245
- "Line 2",
246
- "Line 3"
247
- ]
248
- argument :baz, desc: "Baz option"
249
- end
250
- end
251
-
252
- let(:command_class) { TestArguments::MultiLineArgumentDescription }
253
-
254
- it "must print out each line of a multi-line argument description" do
255
- expect { subject.help_arguments }.to output(
256
- [
257
- '',
258
- "Arguments:",
259
- " #{foo_argument.usage.ljust(33)}#{foo_argument.desc}",
260
- " #{bar_argument.usage.ljust(33)}#{bar_argument.desc[0]}",
261
- " #{' '.ljust(33)}#{bar_argument.desc[1]}",
262
- " #{' '.ljust(33)}#{bar_argument.desc[2]}",
263
- " #{baz_argument.usage.ljust(33)}#{baz_argument.desc}",
264
- ''
265
- ].join($/)
266
- ).to_stdout
267
- end
268
- end
269
- end
270
- end
271
-
272
- describe "#help" do
273
- it "must call #help_arguments" do
274
- expect(subject).to receive(:help_arguments)
275
-
276
- subject.help
277
- end
278
- end
279
- end
@@ -1,266 +0,0 @@
1
- require 'spec_helper'
2
- require 'command_kit/bug_report'
3
-
4
- describe CommandKit::BugReport do
5
- module TestBugReport
6
- class CommandWithoutBugReportURLSet
7
- include CommandKit::BugReport
8
- end
9
-
10
- class CommandWithBugReportURLSet
11
- include CommandKit::BugReport
12
-
13
- bug_report_url 'https://github.com/org/repo/issues/new'
14
- end
15
-
16
- class CommandWithInheritedBugReportURL < CommandWithBugReportURLSet
17
- end
18
- end
19
-
20
- let(:command_class) { TestBugReport::CommandWithBugReportURLSet }
21
-
22
- describe ".included" do
23
- it { expect(command_class).to include(CommandKit::ExceptionHandler) }
24
- it { expect(command_class).to include(CommandKit::Printing) }
25
- end
26
-
27
- describe ".bug_report_url" do
28
- subject { TestBugReport::CommandWithoutBugReportURLSet }
29
-
30
- context "when no bug_report_url has been set" do
31
- it "should default to nil" do
32
- expect(subject.bug_report_url).to be_nil
33
- end
34
- end
35
-
36
- context "when a bug_report_url is explicitly set" do
37
- subject { TestBugReport::CommandWithBugReportURLSet }
38
-
39
- it "must return the explicitly set bug_report_url" do
40
- expect(subject.bug_report_url).to eq("https://github.com/org/repo/issues/new")
41
- end
42
- end
43
-
44
- context "when the command class inherites from another class" do
45
- context "but no bug_report_url is set" do
46
- module TestBugReport
47
- class BaseCmd
48
- include CommandKit::BugReport
49
- end
50
-
51
- class InheritedCmd < BaseCmd
52
- end
53
- end
54
-
55
- subject { TestBugReport::InheritedCmd }
56
-
57
- it "must search each class then return nil "do
58
- expect(subject.bug_report_url).to be_nil
59
- end
60
- end
61
-
62
- module TestBugReport
63
- class ExplicitBaseCmd
64
- include CommandKit::BugReport
65
- bug_report_url 'https://github.com/org/repo/issues/new'
66
- end
67
- end
68
-
69
- context "when the superclass defines an explicit bug_report_url" do
70
- module TestBugReport
71
- class ImplicitInheritedCmd < ExplicitBaseCmd
72
- end
73
- end
74
-
75
- let(:super_subject) { TestBugReport::ExplicitBaseCmd }
76
- subject { TestBugReport::ImplicitInheritedCmd }
77
-
78
- it "must inherit the superclass'es bug_report_url" do
79
- expect(subject.bug_report_url).to eq(super_subject.bug_report_url)
80
- end
81
-
82
- it "must not change the superclass'es bug_report_url" do
83
- expect(super_subject.bug_report_url).to eq('https://github.com/org/repo/issues/new')
84
- end
85
- end
86
-
87
- context "when the subclass defines an explicit bug_report_url" do
88
- module TestBugReport
89
- class ImplicitBaseCmd
90
- include CommandKit::BugReport
91
- end
92
-
93
- class ExplicitInheritedCmd < ImplicitBaseCmd
94
- bug_report_url 'https://github.com/other_org/other_repo/issues/new'
95
- end
96
- end
97
-
98
- let(:super_subject) { TestBugReport::ImplicitBaseCmd }
99
- subject { TestBugReport::ExplicitInheritedCmd }
100
-
101
- it "must return the subclass'es bug_report_url" do
102
- expect(subject.bug_report_url).to eq('https://github.com/other_org/other_repo/issues/new')
103
- end
104
-
105
- it "must not change the superclass'es bug_report_url" do
106
- expect(super_subject.bug_report_url).to be_nil
107
- end
108
- end
109
-
110
- context "when both the subclass overrides the superclass's bug_report_urls" do
111
- module TestBugReport
112
- class ExplicitOverridingInheritedCmd < ExplicitBaseCmd
113
- bug_report_url 'https://github.com/other_org/other_repo/issues/new'
114
- end
115
- end
116
-
117
- let(:super_subject) { TestBugReport::ExplicitBaseCmd }
118
- subject { TestBugReport::ExplicitOverridingInheritedCmd }
119
-
120
- it "must return the subclass'es bug_report_url" do
121
- expect(subject.bug_report_url).to eq("https://github.com/other_org/other_repo/issues/new")
122
- end
123
-
124
- it "must not change the superclass'es bug_report_url" do
125
- expect(super_subject.bug_report_url).to eq("https://github.com/org/repo/issues/new")
126
- end
127
- end
128
- end
129
- end
130
-
131
- subject { command_class.new }
132
-
133
- describe "#bug_report_url" do
134
- context "when the command has bug_report_url set" do
135
- let(:command_class) { TestBugReport::CommandWithBugReportURLSet }
136
-
137
- it "must return the bug_report_url" do
138
- expect(subject.bug_report_url).to eq(command_class.bug_report_url)
139
- end
140
- end
141
-
142
- context "when the command does not have bug_report_url set" do
143
- let(:command_class) { TestBugReport::CommandWithoutBugReportURLSet }
144
-
145
- it "must return nil" do
146
- expect(subject.bug_report_url).to be(nil)
147
- end
148
- end
149
- end
150
-
151
- describe "#print_bug_report" do
152
- let(:message) { "error!" }
153
- let(:backtrace) do
154
- [
155
- "/path/to/test1.rb:1 in `test1'",
156
- "/path/to/test2.rb:2 in `test2'",
157
- "/path/to/test3.rb:3 in `test3'",
158
- "/path/to/test4.rb:4 in `test4'"
159
- ]
160
- end
161
- let(:exception) do
162
- error = RuntimeError.new(message)
163
- error.set_backtrace(backtrace)
164
- error
165
- end
166
-
167
- subject { command_class.new(stderr: StringIO.new) }
168
-
169
- context "when the command has bug_report_url set" do
170
- let(:command_class) { TestBugReport::CommandWithBugReportURLSet }
171
-
172
- context "when stderr is a TTY" do
173
- before { expect(subject.stderr).to receive(:tty?).and_return(true) }
174
-
175
- it "must print a message, bug_report_url, and a highlighted exception" do
176
- subject.print_bug_report(exception)
177
-
178
- expect(subject.stderr.string).to eq(
179
- [
180
- '',
181
- 'Oops! Looks like you have found a bug. Please report it!',
182
- command_class.bug_report_url,
183
- '',
184
- '```',
185
- exception.full_message(highlight: true).chomp,
186
- '```',
187
- ''
188
- ].join($/)
189
- )
190
- end
191
- end
192
-
193
- context "when stderr is not a TTY" do
194
- it "must print a message, bug_report_url, and print an unhighlighted exception" do
195
- subject.print_bug_report(exception)
196
-
197
- expect(subject.stderr.string).to eq(
198
- [
199
- '',
200
- 'Oops! Looks like you have found a bug. Please report it!',
201
- command_class.bug_report_url,
202
- '',
203
- '```',
204
- exception.full_message(highlight: false).chomp,
205
- '```',
206
- ''
207
- ].join($/)
208
- )
209
- end
210
- end
211
- end
212
-
213
- context "when the command does not have bug_report_url set" do
214
- let(:command_class) { TestBugReport::CommandWithoutBugReportURLSet }
215
-
216
- context "when stderr is a TTY" do
217
- before { expect(subject.stderr).to receive(:tty?).and_return(true) }
218
-
219
- it "must print a message and a highlighted exception" do
220
- subject.print_bug_report(exception)
221
-
222
- expect(subject.stderr.string).to eq(
223
- [
224
- '',
225
- 'Oops! Looks like you have found a bug. Please report it!',
226
- '',
227
- '```',
228
- exception.full_message(highlight: true).chomp,
229
- '```',
230
- ''
231
- ].join($/)
232
- )
233
- end
234
- end
235
-
236
- context "when stderr is not a TTY" do
237
- it "must print a message and print an unhighlighted exception" do
238
- subject.print_bug_report(exception)
239
-
240
- expect(subject.stderr.string).to eq(
241
- [
242
- '',
243
- 'Oops! Looks like you have found a bug. Please report it!',
244
- '',
245
- '```',
246
- exception.full_message(highlight: false).chomp,
247
- '```',
248
- ''
249
- ].join($/)
250
- )
251
- end
252
- end
253
- end
254
- end
255
-
256
- describe "#on_exception" do
257
- let(:exception) { RuntimeError.new('error!') }
258
-
259
- it "must call print_bug_report with the exception and then exit(-1)" do
260
- expect(subject).to receive(:print_bug_report).with(exception)
261
- expect(subject).to receive(:exit).with(-1)
262
-
263
- subject.on_exception(exception)
264
- end
265
- end
266
- end