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
data/spec/pager_spec.rb DELETED
@@ -1,217 +0,0 @@
1
- require 'spec_helper'
2
- require 'command_kit/pager'
3
-
4
- require 'stringio'
5
-
6
- describe CommandKit::Pager do
7
- module TestPager
8
- class TestCommand
9
- include CommandKit::Pager
10
- end
11
- end
12
-
13
- let(:command_class) { TestPager::TestCommand }
14
- subject { command_class.new }
15
-
16
- describe "#initialize" do
17
- context "when the PAGER env variable is set" do
18
- let(:pager) { 'foo' }
19
-
20
- subject { command_class.new(env: {'PAGER' => pager}) }
21
-
22
- it "must set @pager_command to the PAGER env variable" do
23
- expect(subject.instance_variable_get('@pager_command')).to eq(pager)
24
- end
25
- end
26
-
27
- context "when the PAGER env variable is not set" do
28
- context "but the PATH env variable is" do
29
- subject { command_class.new(env: {'PATH' => ENV.fetch('PATH')}) }
30
-
31
- it "must search PATH for one of the pagers" do
32
- expect(subject.instance_variable_get('@pager_command')).to eq("less -r")
33
- end
34
- end
35
- end
36
- end
37
-
38
- describe "#pager" do
39
- context "when stdout is not a TTY" do
40
- subject { command_class.new(stdout: StringIO.new) }
41
-
42
- it "must yield stdout" do
43
- expect { |b|
44
- subject.pager(&b)
45
- }.to yield_with_args(subject.stdout)
46
- end
47
- end
48
-
49
- context "when @pager_command isn't initialized" do
50
- before do
51
- subject.instance_variable_set('@pager_command',nil)
52
- end
53
-
54
- it "must yield stdout" do
55
- expect { |b|
56
- subject.pager(&b)
57
- }.to yield_with_args(subject.stdout)
58
- end
59
- end
60
-
61
- context "when stdout is a TTY and @pager_command is initialized" do
62
- let(:pager) { 'less -r' }
63
-
64
- subject { command_class.new(env: {'PAGER' => pager}) }
65
-
66
- let(:pager_io) { double('less') }
67
- let(:pager_pid) { double('pid') }
68
-
69
- before do
70
- expect(subject.stdout).to receive(:tty?).and_return(true)
71
-
72
- expect(IO).to receive(:popen).with(pager,'w').and_return(pager_io)
73
- expect(pager_io).to receive(:pid).and_return(pager_pid)
74
-
75
- expect(pager_io).to receive(:close)
76
- expect(Process).to receive(:waitpid).with(pager_pid)
77
- end
78
-
79
- it "must spawn a new process and yield an IO object" do
80
- expect { |b|
81
- subject.pager(&b)
82
- }.to yield_with_args(pager_io)
83
- end
84
-
85
- context "when Errno::EPIPE is raised" do
86
- it "must return gracefully" do
87
- expect {
88
- subject.pager do
89
- raise(Errno::EPIPE,"pipe broken")
90
- end
91
- }.to_not raise_error
92
- end
93
- end
94
- end
95
- end
96
-
97
- describe "#print_or_page" do
98
- let(:terminal_height) { 10 }
99
-
100
- before do
101
- expect(subject).to receive(:terminal_height).and_return(terminal_height)
102
- end
103
-
104
- context "when given a String" do
105
- context "and the number of lines is less than the console's height" do
106
- let(:string) { "foo#{$/}bar#{$/}" }
107
-
108
- it "must puts the String to stdout" do
109
- expect(subject.stdout).to receive(:puts).with(string)
110
-
111
- subject.print_or_page(string)
112
- end
113
- end
114
-
115
- context "and the number of lines is greater than the console's height" do
116
- let(:string) { "foo#{$/}bar#{$/}" * terminal_height }
117
-
118
- it "must spawn a pager and puts the String to the pager" do
119
- pager = double('pager')
120
- expect(subject).to receive(:pager).and_yield(pager)
121
- expect(pager).to receive(:puts).with(string)
122
-
123
- subject.print_or_page(string)
124
- end
125
- end
126
- end
127
-
128
- context "when given an Array" do
129
- context "and the number of lines is less than the console's height" do
130
- let(:array) { ['foo', 'bar'] }
131
-
132
- it "must puts the Array of Strings to stdout" do
133
- expect(subject.stdout).to receive(:puts).with(array)
134
-
135
- subject.print_or_page(array)
136
- end
137
- end
138
-
139
- context "and the number of lines is greater than the console's height" do
140
- let(:array) { ['foo', 'bar'] * terminal_height }
141
-
142
- it "must spawn a pager and puts the Array of Strings to the pager" do
143
- pager = double('pager')
144
- expect(subject).to receive(:pager).and_yield(pager)
145
- expect(pager).to receive(:puts).with(array)
146
-
147
- subject.print_or_page(array)
148
- end
149
- end
150
- end
151
- end
152
-
153
- describe "#pipe_to_pager" do
154
- context "when @pager_command is initialized" do
155
- let(:pager) { 'less' }
156
-
157
- subject do
158
- command_class.new(env: {'PAGER' => pager})
159
- end
160
-
161
- context "and when given a single String" do
162
- let(:command) { "find ." }
163
-
164
- it "must run the command but piped into the pager" do
165
- expect(subject).to receive(:system).with("#{command} | #{pager}")
166
-
167
- subject.pipe_to_pager(command)
168
- end
169
- end
170
-
171
- context "and when given a String and additional arguments" do
172
- let(:command) { 'find' }
173
- let(:arguments) { %w[. -name *.md] }
174
-
175
- let(:escaped_command) do
176
- Shellwords.shelljoin([command,*arguments])
177
- end
178
-
179
- it "must shell escape the command and arguments" do
180
- expect(subject).to receive(:system).with(
181
- "#{escaped_command} | #{pager}"
182
- )
183
-
184
- subject.pipe_to_pager(command,*arguments)
185
- end
186
- end
187
- end
188
-
189
- context "when @pager_command is not initialized" do
190
- before do
191
- subject.instance_variable_set('@pager_command',nil)
192
- end
193
-
194
- let(:command) { 'find' }
195
- let(:arguments) { %w[. -name *.md] }
196
-
197
- it "must pass the command and any additional arguments to #system" do
198
- expect(subject).to receive(:system).with(command,*arguments)
199
-
200
- subject.pipe_to_pager(command,*arguments)
201
- end
202
-
203
- context "when one of the arguments is not a String" do
204
- let(:command) { :find }
205
- let(:arguments) { ['.', :"-name", "*.md"] }
206
-
207
- it "must convert the command to a String before calling #system" do
208
- expect(subject).to receive(:system).with(
209
- command.to_s, *arguments.map(&:to_s)
210
- )
211
-
212
- subject.pipe_to_pager(command,*arguments)
213
- end
214
- end
215
- end
216
- end
217
- end
@@ -1,167 +0,0 @@
1
- require 'spec_helper'
2
- require 'command_kit/printing/fields'
3
-
4
- describe CommandKit::Printing::Fields do
5
- module TestPrintingFields
6
- class TestCmd
7
-
8
- include CommandKit::Printing::Fields
9
-
10
- end
11
- end
12
-
13
- let(:command_class) { TestPrintingFields::TestCmd }
14
- subject { command_class.new }
15
-
16
- let(:nl) { $/ }
17
-
18
- describe "#print_fields" do
19
- context "when given a Hash" do
20
- context "and all key values are the same length" do
21
- let(:name1) { 'A' }
22
- let(:value1) { 'foo' }
23
- let(:name2) { 'B' }
24
- let(:value2) { 'bar' }
25
-
26
- let(:hash) do
27
- {
28
- name1 => value1,
29
- name2 => value2
30
- }
31
- end
32
-
33
- it "must not left-justify the Hash keys" do
34
- expect {
35
- subject.print_fields(hash)
36
- }.to output("#{name1}: #{value1}#{nl}#{name2}: #{value2}#{nl}").to_stdout
37
- end
38
- end
39
-
40
- context "but key values have different lengths" do
41
- let(:name1) { 'A' }
42
- let(:value1) { 'foo' }
43
- let(:name2) { 'Bar' }
44
- let(:value2) { 'bar' }
45
-
46
- let(:hash) do
47
- {
48
- name1 => value1,
49
- name2 => value2
50
- }
51
- end
52
-
53
- it "must left-justify the Hash keys" do
54
- expect {
55
- subject.print_fields(hash)
56
- }.to output("#{name1}: #{value1}#{nl}#{name2}: #{value2}#{nl}").to_stdout
57
- end
58
- end
59
-
60
- context "but the key values are not Strings" do
61
- let(:name1) { 1 }
62
- let(:value1) { 'foo' }
63
- let(:name2) { 100 }
64
- let(:value2) { 'bar' }
65
-
66
- let(:hash) do
67
- {
68
- name1 => value1,
69
- name2 => value2
70
- }
71
- end
72
-
73
- it "must convert them to Strings before calculating justification" do
74
- expect {
75
- subject.print_fields(hash)
76
- }.to output("#{name1}: #{value1}#{nl}#{name2}: #{value2}#{nl}").to_stdout
77
- end
78
- end
79
- end
80
-
81
- context "when given an Array of tuples" do
82
- context "and all first tuple values are the same length" do
83
- let(:name1) { 'A' }
84
- let(:value1) { 'foo' }
85
- let(:name2) { 'B' }
86
- let(:value2) { 'bar' }
87
-
88
- let(:array) do
89
- [
90
- [name1, value1],
91
- [name2, value2]
92
- ]
93
- end
94
-
95
- it "must not left-justify the tuples" do
96
- expect {
97
- subject.print_fields(array)
98
- }.to output("#{name1}: #{value1}#{nl}#{name2}: #{value2}#{nl}").to_stdout
99
- end
100
- end
101
-
102
- context "but first tuple values have different lengths" do
103
- let(:name1) { 'A' }
104
- let(:value1) { 'foo' }
105
- let(:name2) { 'Bar' }
106
- let(:value2) { 'bar' }
107
-
108
- let(:array) do
109
- [
110
- [name1, value1],
111
- [name2, value2]
112
- ]
113
- end
114
-
115
- it "must left-justify the tuples" do
116
- expect {
117
- subject.print_fields(array)
118
- }.to output("#{name1}: #{value1}#{nl}#{name2}: #{value2}#{nl}").to_stdout
119
- end
120
- end
121
-
122
- context "but the first tuple values are not Strings" do
123
- let(:name1) { 1 }
124
- let(:value1) { 'foo' }
125
- let(:name2) { 100 }
126
- let(:value2) { 'bar' }
127
-
128
- let(:array) do
129
- [
130
- [name1, value1],
131
- [name2, value2]
132
- ]
133
- end
134
-
135
- it "must convert them to Strings before calculating justification" do
136
- expect {
137
- subject.print_fields(array)
138
- }.to output("#{name1}: #{value1}#{nl}#{name2}: #{value2}#{nl}").to_stdout
139
- end
140
- end
141
- end
142
-
143
- context "but the values contain multiple lines" do
144
- let(:name1) { 'A' }
145
- let(:value1) { 'foo' }
146
- let(:name2) { 'Bar' }
147
- let(:line1) { 'bar' }
148
- let(:line2) { 'baz' }
149
- let(:value2) do
150
- [line1, line2].join($/)
151
- end
152
-
153
- let(:hash) do
154
- {
155
- name1 => value1,
156
- name2 => value2
157
- }
158
- end
159
-
160
- it "must print the header with the first line and then indent the other lines" do
161
- expect {
162
- subject.print_fields(hash)
163
- }.to output("#{name1}: #{value1}#{nl}#{name2}: #{line1}#{nl} #{line2}#{nl}").to_stdout
164
- end
165
- end
166
- end
167
- end
@@ -1,132 +0,0 @@
1
- require 'spec_helper'
2
- require 'command_kit/printing/indent'
3
-
4
- describe CommandKit::Printing::Indent do
5
- module TestIndent
6
- class TestCommand
7
- include CommandKit::Printing::Indent
8
- end
9
- end
10
-
11
- let(:command_class) { TestIndent::TestCommand }
12
- subject { command_class.new }
13
-
14
- describe "#initialize" do
15
- it "must initialize #indent to 0" do
16
- expect(subject.indent).to eq(0)
17
- end
18
-
19
- context "when the class has a superclass" do
20
- module TestIndent
21
- class TestSuperCommand
22
-
23
- attr_reader :var
24
-
25
- def initialize(var: 'default')
26
- @var = var
27
- end
28
-
29
- end
30
-
31
- class TestSubCommand < TestSuperCommand
32
-
33
- include CommandKit::Printing::Indent
34
-
35
- end
36
- end
37
-
38
- let(:command_class) { TestIndent::TestSubCommand }
39
-
40
- it "must initialize @indent to 0" do
41
- expect(subject.indent).to eq(0)
42
- end
43
-
44
- it "must call super()" do
45
- expect(subject.var).to eq('default')
46
- end
47
-
48
- context "and additional keyword arguments are given" do
49
- let(:var) { 'foo' }
50
-
51
- subject { command_class.new(var: var) }
52
-
53
- it "must call super() with the additional keyword arguments" do
54
- expect(subject.var).to eq(var)
55
- end
56
- end
57
- end
58
- end
59
-
60
- describe "#indent" do
61
- context "when no block is given" do
62
- it "must return the indentation level" do
63
- expect(subject.indent).to eq(0)
64
- end
65
- end
66
-
67
- context "when a block is given" do
68
- it do
69
- expect { |b| subject.indent(&b) }.to yield_control
70
- end
71
-
72
- it "must increase the indent level by 2 then yield" do
73
- expect(subject.indent).to eq(0)
74
-
75
- subject.indent do
76
- expect(subject.indent).to eq(2)
77
- end
78
- end
79
-
80
- it "must restore the indententation level to it's original value" do
81
- subject.indent do
82
- expect(subject.indent).to eq(2)
83
- end
84
-
85
- expect(subject.indent).to eq(0)
86
- end
87
-
88
- context "when an exception occurrs within the given block" do
89
- it "must not rescue the exception" do
90
- expect {
91
- subject.indent do
92
- raise("error")
93
- end
94
- }.to raise_error(RuntimeError,"error")
95
- end
96
-
97
- it "must restore the indententation level to it's original value" do
98
- begin
99
- subject.indent do
100
- expect(subject.indent).to eq(2)
101
- raise("error")
102
- end
103
- rescue
104
- end
105
-
106
- expect(subject.indent).to eq(0)
107
- end
108
- end
109
- end
110
- end
111
-
112
- describe "#puts" do
113
- let(:nl) { $/ }
114
- let(:text) { 'hello world' }
115
-
116
- context "when the indententation level is 0" do
117
- it "must not add leading indentation" do
118
- expect { subject.puts(text) }.to output("#{text}#{nl}").to_stdout
119
- end
120
- end
121
-
122
- context "when the indententation level is > 0" do
123
- it "must add a number of spaces to the text" do
124
- expect {
125
- subject.indent do
126
- subject.puts(text)
127
- end
128
- }.to output(" #{text}#{nl}").to_stdout
129
- end
130
- end
131
- end
132
- end
@@ -1,99 +0,0 @@
1
- require 'spec_helper'
2
- require 'command_kit/printing/lists'
3
-
4
- describe CommandKit::Printing::Lists do
5
- module TestPrintingLists
6
- class TestCmd
7
-
8
- include CommandKit::Printing::Lists
9
-
10
- end
11
- end
12
-
13
- let(:command_class) { TestPrintingLists::TestCmd }
14
- subject { command_class.new }
15
-
16
- describe "#print_list" do
17
- let(:list) { %w[foo bar baz] }
18
-
19
- it "must print each item in the list with a '*' bullet" do
20
- expect {
21
- subject.print_list(list)
22
- }.to output(
23
- list.map { |item| "* #{item}" }.join($/) + $/
24
- ).to_stdout
25
- end
26
-
27
- context "when the list contins multi-line Strings" do
28
- let(:item1) { "foo" }
29
- let(:item2) do
30
- [
31
- "line 1",
32
- "line 2",
33
- "line 3"
34
- ].join($/)
35
- end
36
- let(:item3) { "bar" }
37
- let(:list) { [item1, item2, item3] }
38
-
39
- it "must print the bullet with the first line and then indent the other lines" do
40
- expect {
41
- subject.print_list(list)
42
- }.to output(
43
- [
44
- "* #{item1}",
45
- "* #{item2.lines[0].chomp}",
46
- " #{item2.lines[1].chomp}",
47
- " #{item2.lines[2].chomp}",
48
- "* #{item3}",
49
- ''
50
- ].join($/)
51
- ).to_stdout
52
- end
53
- end
54
-
55
- context "when the list contains nested-lists" do
56
- let(:item1) { 'item 1' }
57
- let(:sub_item1) { 'sub-item 1' }
58
- let(:sub_item2) { 'sub-item 2' }
59
- let(:item2) { 'item 2' }
60
-
61
- let(:list) do
62
- [
63
- 'item 1',
64
- [
65
- 'sub-item 1',
66
- 'sub-item 2'
67
- ],
68
- 'item 2'
69
- ]
70
- end
71
-
72
- it "must indent and print each sub-list" do
73
- expect {
74
- subject.print_list(list)
75
- }.to output(
76
- [
77
- "* #{item1}",
78
- " * #{sub_item1}",
79
- " * #{sub_item2}",
80
- "* #{item2}",
81
- ''
82
- ].join($/)
83
- ).to_stdout
84
- end
85
- end
86
-
87
- context "when the bullet: keyowrd argument is given" do
88
- let(:bullet) { '-' }
89
-
90
- it "must print each item in the list with the bullet character" do
91
- expect {
92
- subject.print_list(list, bullet: bullet)
93
- }.to output(
94
- list.map { |item| "#{bullet} #{item}" }.join($/) + $/
95
- ).to_stdout
96
- end
97
- end
98
- end
99
- end
@@ -1,43 +0,0 @@
1
- require 'spec_helper'
2
- require 'command_kit/printing/tables/border_style'
3
-
4
- describe CommandKit::Printing::Tables::BorderStyle do
5
- describe "#initialize" do
6
- [
7
- :top_left_corner,
8
- :top_border,
9
- :top_joined_border,
10
- :top_right_corner,
11
- :left_border,
12
- :left_joined_border,
13
- :horizontal_separator,
14
- :vertical_separator,
15
- :inner_joined_border,
16
- :right_border,
17
- :right_joined_border,
18
- :bottom_border,
19
- :bottom_left_corner,
20
- :bottom_joined_border,
21
- :bottom_right_corner
22
- ].each do |keyword|
23
- context "when #{keyword}: keyword is given" do
24
- let(:keyword) { keyword }
25
- let(:value) { 'x' }
26
-
27
- subject { described_class.new(**{keyword => value}) }
28
-
29
- it "must set ##{keyword}" do
30
- expect(subject.send(keyword)).to eq(value)
31
- end
32
- end
33
-
34
- context "when #{keyword}: keyword is not given" do
35
- let(:keyword) { keyword }
36
-
37
- it "must default ##{keyword} to ' '" do
38
- expect(subject.send(keyword)).to eq(' ')
39
- end
40
- end
41
- end
42
- end
43
- end