Skip to content

Commit 0109f76

Browse files
committed
- Add stdin support for installer command
1 parent 7969ad3 commit 0109f76

File tree

7 files changed

+72
-8
lines changed

7 files changed

+72
-8
lines changed

lib/completely/commands/install.rb

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require 'tempfile'
12
require 'completely/commands/base'
23

34
module Completely
@@ -17,9 +18,19 @@ class Install < Base
1718
option '-d --dry', 'Show the installation command but do not run it'
1819

1920
param 'PROGRAM', 'Name of the program the completions are for.'
20-
param 'SCRIPT_PATH', 'Path to the source bash script [default: completely.bash].'
21+
param 'SCRIPT_PATH', <<~USAGE
22+
Path to the source bash script [default: completely.bash].
23+
Use '-' to provide the script via stdin.
24+
USAGE
2125

2226
def run
27+
if script_path == '-'
28+
raise InstallError, "Nothing is piped on stdin" if $stdin.tty?
29+
30+
@script_path = tempfile.path
31+
File.write script_path, $stdin.read
32+
end
33+
2334
if args['--dry']
2435
puts installer.install_command_string
2536
return
@@ -32,6 +43,10 @@ def run
3243
say 'You may need to restart your session to test it'
3344
end
3445

46+
def tempfile
47+
@tempfile ||= Tempfile.new('stdin-completely-')
48+
end
49+
3550
private
3651

3752
def installer

lib/completely/installer.rb

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,13 @@ def root_user?
7373
end
7474

7575
def completions_path
76-
@completions_path ||= completions_path!
77-
end
76+
@completions_path ||= begin
77+
target_directories.each do |target|
78+
return target if Dir.exist? target
79+
end
7880

79-
def completions_path!
80-
target_directories.each do |target|
81-
return target if Dir.exist? target
81+
nil
8282
end
83-
84-
nil
8583
end
8684
end
8785
end

spec/approvals/cli/install/help

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ Parameters:
2525

2626
SCRIPT_PATH
2727
Path to the source bash script [default: completely.bash].
28+
Use '-' to provide the script via stdin.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sudo cp <tmpfile-path> /usr/share/bash-completion/completions/completely-test
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Saved some-target-path
2+
You may need to restart your session to test it

spec/completely/commands/install_spec.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@
3434
end
3535
end
3636

37+
context 'with PROGRAM - (stdin)' do
38+
it 'invokes the Installer using a temp file' do
39+
allow(subject).to receive(:installer).and_return(mock_installer)
40+
allow($stdin).to receive_messages(tty?: false, read: 'dummy data')
41+
42+
expect(mock_installer).to receive(:install)
43+
44+
expect { subject.execute %w[install completely-test -] }
45+
.to output_approval('cli/install/stdin-install')
46+
47+
expect(File.read subject.tempfile.path).to eq 'dummy data'
48+
end
49+
end
50+
3751
context 'with PROGRAM --dry' do
3852
it 'shows the command and does not install anything' do
3953
expect(mock_installer).not_to receive(:install)
@@ -43,6 +57,29 @@
4357
end
4458
end
4559

60+
context 'with PROGRAM - --dry (stdin)' do
61+
it 'shows the command and does not install anything' do
62+
allow($stdin).to receive_messages(tty?: false, read: 'dummy data')
63+
64+
expect(mock_installer).not_to receive(:install)
65+
66+
expect { subject.execute %w[install completely-test - --dry] }
67+
.to output_approval('cli/install/stdin-dry')
68+
.except(/[^\s]*stdin-completely-[^\s]*/, '<tmpfile-path>')
69+
end
70+
71+
context 'when stdin is empty' do
72+
it 'raises InstallError' do
73+
allow($stdin).to receive_messages(tty?: true, read: nil)
74+
expect(mock_installer).not_to receive(:install)
75+
76+
expect { subject.execute %w[install completely-test - --dry] }
77+
.to raise_error(InstallError, 'Nothing is piped on stdin')
78+
end
79+
end
80+
end
81+
82+
4683
context 'when the installer fails' do
4784
it 'raises an error' do
4885
allow(subject).to receive(:installer).and_return(mock_installer)

spec/completely/installer_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@
2525
expect(subject.target_path)
2626
.to eq '/usr/share/bash-completion/completions/completely-test'
2727
end
28+
29+
# This method will not be called if there is no completions path
30+
# The test is here to cover the nil fallback
31+
context 'when no paths found' do
32+
it 'returns nil as the base path' do
33+
allow(subject).to receive(:target_directories).and_return([])
34+
35+
expect(subject.target_path).to eq '/completely-test'
36+
end
37+
end
2838
end
2939

3040
describe '#install_command' do

0 commit comments

Comments
 (0)