command_kit 0.4.1 → 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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +6 -0
  3. data/README.md +3 -0
  4. data/command_kit.gemspec +7 -2
  5. data/lib/command_kit/completion/install.rb +276 -0
  6. data/lib/command_kit/env/prefix.rb +41 -0
  7. data/lib/command_kit/env/shell.rb +58 -0
  8. data/lib/command_kit/version.rb +1 -1
  9. metadata +4 -64
  10. data/spec/arguments/argument_spec.rb +0 -133
  11. data/spec/arguments/argument_value_spec.rb +0 -66
  12. data/spec/arguments_spec.rb +0 -279
  13. data/spec/bug_report_spec.rb +0 -266
  14. data/spec/colors_spec.rb +0 -771
  15. data/spec/command_kit_spec.rb +0 -8
  16. data/spec/command_name_spec.rb +0 -130
  17. data/spec/command_spec.rb +0 -123
  18. data/spec/commands/auto_load/subcommand_spec.rb +0 -82
  19. data/spec/commands/auto_load_spec.rb +0 -159
  20. data/spec/commands/auto_require_spec.rb +0 -142
  21. data/spec/commands/fixtures/test_auto_load/cli/commands/test1.rb +0 -10
  22. data/spec/commands/fixtures/test_auto_load/cli/commands/test2.rb +0 -10
  23. data/spec/commands/fixtures/test_auto_require/lib/test_auto_require/cli/commands/test1.rb +0 -10
  24. data/spec/commands/help_spec.rb +0 -66
  25. data/spec/commands/parent_command_spec.rb +0 -40
  26. data/spec/commands/subcommand_spec.rb +0 -99
  27. data/spec/commands_spec.rb +0 -865
  28. data/spec/description_spec.rb +0 -179
  29. data/spec/edit_spec.rb +0 -72
  30. data/spec/env/home_spec.rb +0 -46
  31. data/spec/env/path_spec.rb +0 -84
  32. data/spec/env_spec.rb +0 -123
  33. data/spec/examples_spec.rb +0 -211
  34. data/spec/exception_handler_spec.rb +0 -103
  35. data/spec/file_utils_spec.rb +0 -59
  36. data/spec/fixtures/template.erb +0 -5
  37. data/spec/help/man_spec.rb +0 -345
  38. data/spec/help_spec.rb +0 -94
  39. data/spec/inflector_spec.rb +0 -166
  40. data/spec/interactive_spec.rb +0 -415
  41. data/spec/main_spec.rb +0 -179
  42. data/spec/man_spec.rb +0 -46
  43. data/spec/open_app_spec.rb +0 -85
  44. data/spec/options/option_spec.rb +0 -343
  45. data/spec/options/option_value_spec.rb +0 -171
  46. data/spec/options/parser_spec.rb +0 -274
  47. data/spec/options/quiet_spec.rb +0 -51
  48. data/spec/options/verbose_spec.rb +0 -51
  49. data/spec/options/version_spec.rb +0 -146
  50. data/spec/options_spec.rb +0 -465
  51. data/spec/os/linux_spec.rb +0 -164
  52. data/spec/os_spec.rb +0 -233
  53. data/spec/package_manager_spec.rb +0 -806
  54. data/spec/pager_spec.rb +0 -217
  55. data/spec/printing/fields_spec.rb +0 -167
  56. data/spec/printing/indent_spec.rb +0 -132
  57. data/spec/printing/lists_spec.rb +0 -99
  58. data/spec/printing/tables/border_style.rb +0 -43
  59. data/spec/printing/tables/cell_builer_spec.rb +0 -135
  60. data/spec/printing/tables/row_builder_spec.rb +0 -165
  61. data/spec/printing/tables/style_spec.rb +0 -377
  62. data/spec/printing/tables/table_builder_spec.rb +0 -252
  63. data/spec/printing/tables/table_formatter_spec.rb +0 -1190
  64. data/spec/printing/tables_spec.rb +0 -1069
  65. data/spec/printing_spec.rb +0 -106
  66. data/spec/program_name_spec.rb +0 -70
  67. data/spec/spec_helper.rb +0 -3
  68. data/spec/stdio_spec.rb +0 -264
  69. data/spec/sudo_spec.rb +0 -51
  70. data/spec/terminal_spec.rb +0 -231
  71. data/spec/usage_spec.rb +0 -237
  72. data/spec/xdg_spec.rb +0 -191
@@ -1,66 +0,0 @@
1
- require 'spec_helper'
2
- require 'command_kit/arguments/argument_value'
3
-
4
- describe CommandKit::Arguments::ArgumentValue do
5
- let(:required) { false }
6
- let(:usage) { 'FOO' }
7
-
8
- subject do
9
- described_class.new(
10
- required: required,
11
- usage: usage
12
- )
13
- end
14
-
15
- describe "#initialize" do
16
- it "must require a usage: keyword"do
17
- expect {
18
- described_class.new(required: required)
19
- }.to raise_error(ArgumentError)
20
- end
21
-
22
- context "when required: is given" do
23
- subject { described_class.new(required: required, usage: usage) }
24
-
25
- it "must set #required" do
26
- expect(subject.required).to eq(required)
27
- end
28
- end
29
-
30
- context "when required: is not given" do
31
- subject { described_class.new(usage: usage) }
32
-
33
- it "must default to true" do
34
- expect(subject.required).to be(true)
35
- end
36
- end
37
- end
38
-
39
- describe "#required?" do
40
- context "when required: is initialized with true" do
41
- let(:required) { true }
42
-
43
- it { expect(subject.required?).to be(true) }
44
- end
45
-
46
- context "when required: is initialized with false" do
47
- let(:required) { false }
48
-
49
- it { expect(subject.required?).to be(false) }
50
- end
51
- end
52
-
53
- describe "#optional?" do
54
- context "when required: is initialized with true" do
55
- let(:required) { true }
56
-
57
- it { expect(subject.optional?).to be(false) }
58
- end
59
-
60
- context "when required: is initialized with false" do
61
- let(:required) { false }
62
-
63
- it { expect(subject.optional?).to be(true) }
64
- end
65
- end
66
- end
@@ -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