command_kit 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +15 -0
  3. data/.rubocop.yml +138 -0
  4. data/ChangeLog.md +29 -0
  5. data/Gemfile +3 -0
  6. data/README.md +141 -121
  7. data/Rakefile +3 -2
  8. data/command_kit.gemspec +4 -4
  9. data/examples/command.rb +1 -1
  10. data/gemspec.yml +7 -0
  11. data/lib/command_kit/arguments.rb +1 -1
  12. data/lib/command_kit/colors.rb +221 -45
  13. data/lib/command_kit/command.rb +1 -1
  14. data/lib/command_kit/commands.rb +4 -4
  15. data/lib/command_kit/help/man.rb +4 -25
  16. data/lib/command_kit/inflector.rb +47 -17
  17. data/lib/command_kit/main.rb +7 -9
  18. data/lib/command_kit/man.rb +44 -0
  19. data/lib/command_kit/open_app.rb +69 -0
  20. data/lib/command_kit/options/option.rb +1 -6
  21. data/lib/command_kit/options/parser.rb +15 -17
  22. data/lib/command_kit/options.rb +2 -2
  23. data/lib/command_kit/os/linux.rb +157 -0
  24. data/lib/command_kit/os.rb +159 -11
  25. data/lib/command_kit/package_manager.rb +200 -0
  26. data/lib/command_kit/pager.rb +46 -4
  27. data/lib/command_kit/printing/indent.rb +2 -2
  28. data/lib/command_kit/printing.rb +1 -1
  29. data/lib/command_kit/sudo.rb +40 -0
  30. data/lib/command_kit/terminal.rb +5 -0
  31. data/lib/command_kit/version.rb +1 -1
  32. data/spec/arguments/argument_spec.rb +1 -1
  33. data/spec/colors_spec.rb +256 -0
  34. data/spec/commands_spec.rb +1 -1
  35. data/spec/exception_handler_spec.rb +1 -1
  36. data/spec/help/man_spec.rb +0 -32
  37. data/spec/inflector_spec.rb +70 -8
  38. data/spec/man_spec.rb +46 -0
  39. data/spec/open_app_spec.rb +85 -0
  40. data/spec/options/option_spec.rb +2 -2
  41. data/spec/os/linux_spec.rb +154 -0
  42. data/spec/os_spec.rb +200 -13
  43. data/spec/package_manager_spec.rb +806 -0
  44. data/spec/pager_spec.rb +71 -6
  45. data/spec/sudo_spec.rb +51 -0
  46. data/spec/terminal_spec.rb +30 -0
  47. data/spec/usage_spec.rb +1 -1
  48. metadata +19 -4
data/spec/pager_spec.rb CHANGED
@@ -19,8 +19,8 @@ describe CommandKit::Pager do
19
19
 
20
20
  subject { command_class.new(env: {'PAGER' => pager}) }
21
21
 
22
- it "must set @pager to the PAGER env variable" do
23
- expect(subject.instance_variable_get('@pager')).to eq(pager)
22
+ it "must set @pager_command to the PAGER env variable" do
23
+ expect(subject.instance_variable_get('@pager_command')).to eq(pager)
24
24
  end
25
25
  end
26
26
 
@@ -29,7 +29,7 @@ describe CommandKit::Pager do
29
29
  subject { command_class.new(env: {'PATH' => ENV['PATH']}) }
30
30
 
31
31
  it "must search PATH for one of the pagers" do
32
- expect(subject.instance_variable_get('@pager')).to eq("less -r")
32
+ expect(subject.instance_variable_get('@pager_command')).to eq("less -r")
33
33
  end
34
34
  end
35
35
  end
@@ -46,9 +46,9 @@ describe CommandKit::Pager do
46
46
  end
47
47
  end
48
48
 
49
- context "when @pager isn't initialized" do
49
+ context "when @pager_command isn't initialized" do
50
50
  before do
51
- subject.instance_variable_set('@pager',nil)
51
+ subject.instance_variable_set('@pager_command',nil)
52
52
  end
53
53
 
54
54
  it "must yield stdout" do
@@ -58,7 +58,7 @@ describe CommandKit::Pager do
58
58
  end
59
59
  end
60
60
 
61
- context "when stdout is a TTY and @pager is initialized" do
61
+ context "when stdout is a TTY and @pager_command is initialized" do
62
62
  let(:pager) { 'less -r' }
63
63
 
64
64
  subject { command_class.new(env: {'PAGER' => pager}) }
@@ -149,4 +149,69 @@ describe CommandKit::Pager do
149
149
  end
150
150
  end
151
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) { %[. -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) { %[. -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
152
217
  end
data/spec/sudo_spec.rb ADDED
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require 'command_kit/sudo'
3
+
4
+ describe CommandKit::Sudo do
5
+ module TestSudo
6
+ class TestCommand
7
+ include CommandKit::Sudo
8
+ end
9
+ end
10
+
11
+ let(:command_class) { TestSudo::TestCommand }
12
+ subject { command_class.new }
13
+
14
+ describe "#sudo" do
15
+ let(:command) { "ls" }
16
+ let(:arguments) { ["-la", "~root"] }
17
+ let(:status) { double(:status) }
18
+
19
+ context "on UNIX" do
20
+ context "when the UID is 0" do
21
+ before { allow(Process).to receive(:uid).and_return(0) }
22
+
23
+ it "must execute the command without sudo" do
24
+ expect(subject).to receive(:system).with(command,*arguments).and_return(status)
25
+
26
+ expect(subject.sudo(command,*arguments)).to be(status)
27
+ end
28
+ end
29
+
30
+ context "when the UID is not 0" do
31
+ before { allow(Process).to receive(:uid).and_return(1000) }
32
+
33
+ it "must execute the command with 'sudo ...'" do
34
+ expect(subject).to receive(:system).with('sudo',command,*arguments).and_return(status)
35
+
36
+ expect(subject.sudo(command,*arguments)).to be(status)
37
+ end
38
+ end
39
+ end
40
+
41
+ context "on Windows" do
42
+ subject { command_class.new(os: :windows) }
43
+
44
+ it "must execute the command with 'runas /user:administrator ...'" do
45
+ expect(subject).to receive(:system).with('runas','/user:administrator',command,*arguments).and_return(status)
46
+
47
+ expect(subject.sudo(command,*arguments)).to be(status)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -43,6 +43,36 @@ describe CommandKit::Terminal do
43
43
  end
44
44
  end
45
45
 
46
+ describe "#tty?" do
47
+ context "when stdout is connected to a TTY" do
48
+ subject { command_class.new(stdout: STDOUT) }
49
+
50
+ it do
51
+ skip "STDOUT is not a TTY" unless STDOUT.tty?
52
+
53
+ expect(subject.tty?).to be(true)
54
+ end
55
+ end
56
+
57
+ context "when stdout is not connected to a TTY" do
58
+ subject { command_class.new(stdout: StringIO.new) }
59
+
60
+ it do
61
+ expect(subject.tty?).to be(false)
62
+ end
63
+ end
64
+
65
+ context "when IO.console is missing" do
66
+ before do
67
+ expect(IO).to receive(:respond_to?).with(:console).and_return(false)
68
+ end
69
+
70
+ it do
71
+ expect(subject.tty?).to be(false)
72
+ end
73
+ end
74
+ end
75
+
46
76
  describe "#terminal" do
47
77
  context "when stdout is connected to a TTY" do
48
78
  subject { command_class.new(stdout: STDOUT) }
data/spec/usage_spec.rb CHANGED
@@ -182,7 +182,7 @@ describe CommandKit::Usage do
182
182
  [
183
183
  "#{subject.command_name} #{command_class.usage[0]}",
184
184
  "#{subject.command_name} #{command_class.usage[1]}",
185
- "#{subject.command_name} #{command_class.usage[2]}",
185
+ "#{subject.command_name} #{command_class.usage[2]}"
186
186
  ]
187
187
  )
188
188
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: command_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Postmodern
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-17 00:00:00.000000000 Z
11
+ date: 2021-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,7 @@ files:
38
38
  - ".github/workflows/ruby.yml"
39
39
  - ".gitignore"
40
40
  - ".rspec"
41
+ - ".rubocop.yml"
41
42
  - ".yardopts"
42
43
  - ChangeLog.md
43
44
  - Gemfile
@@ -75,6 +76,8 @@ files:
75
76
  - lib/command_kit/inflector.rb
76
77
  - lib/command_kit/interactive.rb
77
78
  - lib/command_kit/main.rb
79
+ - lib/command_kit/man.rb
80
+ - lib/command_kit/open_app.rb
78
81
  - lib/command_kit/options.rb
79
82
  - lib/command_kit/options/option.rb
80
83
  - lib/command_kit/options/option_value.rb
@@ -83,11 +86,14 @@ files:
83
86
  - lib/command_kit/options/verbose.rb
84
87
  - lib/command_kit/options/version.rb
85
88
  - lib/command_kit/os.rb
89
+ - lib/command_kit/os/linux.rb
90
+ - lib/command_kit/package_manager.rb
86
91
  - lib/command_kit/pager.rb
87
92
  - lib/command_kit/printing.rb
88
93
  - lib/command_kit/printing/indent.rb
89
94
  - lib/command_kit/program_name.rb
90
95
  - lib/command_kit/stdio.rb
96
+ - lib/command_kit/sudo.rb
91
97
  - lib/command_kit/terminal.rb
92
98
  - lib/command_kit/usage.rb
93
99
  - lib/command_kit/version.rb
@@ -120,24 +126,33 @@ files:
120
126
  - spec/inflector_spec.rb
121
127
  - spec/interactive_spec.rb
122
128
  - spec/main_spec.rb
129
+ - spec/man_spec.rb
130
+ - spec/open_app_spec.rb
123
131
  - spec/options/option_spec.rb
124
132
  - spec/options/option_value_spec.rb
125
133
  - spec/options/parser_spec.rb
126
134
  - spec/options_spec.rb
135
+ - spec/os/linux_spec.rb
127
136
  - spec/os_spec.rb
137
+ - spec/package_manager_spec.rb
128
138
  - spec/pager_spec.rb
129
139
  - spec/printing/indent_spec.rb
130
140
  - spec/printing_spec.rb
131
141
  - spec/program_name_spec.rb
132
142
  - spec/spec_helper.rb
133
143
  - spec/stdio_spec.rb
144
+ - spec/sudo_spec.rb
134
145
  - spec/terminal_spec.rb
135
146
  - spec/usage_spec.rb
136
147
  - spec/xdg_spec.rb
137
148
  homepage: https://github.com/postmodern/command_kit.rb#readme
138
149
  licenses:
139
150
  - MIT
140
- metadata: {}
151
+ metadata:
152
+ documentation_uri: https://rubydoc.info/gems/command_kit
153
+ source_code_uri: https://github.com/postmodern/command_kit.rb
154
+ bug_tracker_uri: https://github.com/postmodern/command_kit.rb/issues
155
+ changelog_uri: https://github.com/postmodern/command_kit.rb/blob/main/ChangeLog.md
141
156
  post_install_message:
142
157
  rdoc_options: []
143
158
  require_paths:
@@ -153,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
168
  - !ruby/object:Gem::Version
154
169
  version: '0'
155
170
  requirements: []
156
- rubygems_version: 3.2.15
171
+ rubygems_version: 3.2.22
157
172
  signing_key:
158
173
  specification_version: 4
159
174
  summary: A toolkit for building Ruby CLI commands