command_kit 0.4.1 → 0.5.0

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