Skip to content

Commit be750a6

Browse files
committed
refactor completions installer
1 parent 3c90db0 commit be750a6

File tree

5 files changed

+49
-57
lines changed

5 files changed

+49
-57
lines changed

lib/bashly/commands/completions.rb

Lines changed: 14 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,55 +13,32 @@ def run
1313
if args['--install']
1414
install_completions
1515
else
16-
show_completions
16+
puts script
1717
end
1818
end
1919

20+
def installer
21+
@installer ||= Completely::Installer.new program: 'bashly', script_path: script_path
22+
end
23+
2024
private
2125

2226
def install_completions
23-
raise Error, 'Cannot find completions directory' unless compdir
24-
25-
target = "#{compdir}/bashly"
26-
27-
say "Installing completions to m`#{target}`"
28-
command = %[cp "#{completions_path}" "#{target}"]
29-
command = "sudo #{command}" unless root_user?
30-
system command
27+
success = installer.install force: true
28+
raise Error, "Failed running command:\nnb`#{installer.command_string}`" unless success
3129

30+
say 'Completions installed.'
31+
say "Source: m`#{installer.script_path}`"
32+
say "Target: m`#{installer.target_path}`"
3233
say 'Restart your session for the changes to take effect'
3334
end
3435

35-
def show_completions
36-
puts completions_script
37-
end
38-
39-
def completions_path
40-
@completions_path ||= asset('completions/bashly-completions.bash')
41-
end
42-
43-
def completions_script
44-
@completions_script ||= asset_content('completions/bashly-completions.bash')
45-
end
46-
47-
def compdir
48-
@compdir ||= compdir!
49-
end
50-
51-
def compdir!
52-
compdir_candidates.each { |dir| return dir if Dir.exist? dir }
53-
nil
54-
end
55-
56-
def compdir_candidates
57-
@compdir_candidates ||= [
58-
'/usr/share/bash-completion/completions',
59-
'/usr/local/etc/bash_completion.d',
60-
]
36+
def script_path
37+
@script_path ||= asset('completions/bashly-completions.bash')
6138
end
6239

63-
def root_user?
64-
Process.uid.zero?
40+
def script
41+
@script ||= asset_content('completions/bashly-completions.bash')
6542
end
6643
end
6744
end
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
Installing completions to /tmp/bashly
1+
Completions installed.
2+
Source: some-script-path
3+
Target: some-target-path
24
Restart your session for the changes to take effect
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
#<Bashly::Error: Cannot find completions directory>
1+
#<Bashly::Error: Failed running command:
2+
nb`cp source target`>

spec/approvals/cli/completions/install-root

Lines changed: 0 additions & 2 deletions
This file was deleted.

spec/bashly/commands/completions_spec.rb

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,55 @@
33
describe Commands::Completions do
44
subject { described_class.new }
55

6+
let(:leeway) { RUBY_VERSION < '3.2.0' ? 0 : 5 }
67
let(:completions_path) { File.expand_path 'lib/bashly/completions/bashly-completions.bash' }
78
let(:completions_script) { File.read completions_path }
9+
let :mock_installer do
10+
instance_double Completely::Installer,
11+
install: true,
12+
target_path: 'some-target-path',
13+
script_path: 'some-script-path',
14+
command_string: 'cp source target'
15+
end
16+
17+
describe '#installer' do
18+
it 'returns a properly configured Completely::Installer instance' do
19+
expect(subject.installer).to be_a Completely::Installer
20+
expect(subject.installer.program).to eq 'bashly'
21+
expect(subject.installer.script_path).to end_with '/bashly-completions.bash'
22+
end
23+
end
824

925
context 'with --help' do
1026
it 'shows long usage' do
11-
expect { subject.execute %w[completions --help] }.to output_approval('cli/completions/help')
27+
expect { subject.execute %w[completions --help] }
28+
.to output_approval('cli/completions/help')
1229
end
1330
end
1431

1532
context 'without arguments' do
1633
it 'shows the completions script' do
17-
expect { subject.execute %w[completions] }.to output(completions_script).to_stdout
34+
expect { subject.execute %w[completions] }
35+
.to output(completions_script).to_stdout
1836
end
1937
end
2038

2139
context 'with --install' do
2240
it 'installs the completions script to the completions directory' do
23-
allow(subject).to receive(:compdir_candidates).and_return ['/tmp']
24-
expect(subject).to receive(:system).with(%[sudo cp "#{completions_path}" "/tmp/bashly"])
25-
expect { subject.execute %w[completions --install] }.to output_approval('cli/completions/install')
41+
allow(subject).to receive(:installer).and_return mock_installer
42+
43+
expect { subject.execute %w[completions --install] }
44+
.to output_approval('cli/completions/install')
2645
end
2746

28-
context 'when the completions directory is not found' do
47+
context 'when the installer fails' do
2948
it 'raises an error' do
30-
allow(Dir).to receive(:exist?).twice.and_return(false)
31-
expect { subject.execute %w[completions --install] }.to raise_approval('cli/completions/install-error')
32-
end
33-
end
49+
allow(subject).to receive(:installer).and_return mock_installer
50+
allow(mock_installer).to receive(:install).and_return(false)
3451

35-
context 'when running as root' do
36-
it 'installs the completions script to the completions directory without sudo' do
37-
allow(subject).to receive(:compdir_candidates).and_return ['/tmp']
38-
allow(subject).to receive(:root_user?).and_return true
39-
expect(subject).to receive(:system).with(%[cp "#{completions_path}" "/tmp/bashly"])
40-
expect { subject.execute %w[completions --install] }.to output_approval('cli/completions/install-root')
52+
expect { subject.execute %w[completions --install] }
53+
.to raise_approval('cli/completions/install-error')
54+
.diff(leeway)
4155
end
4256
end
4357
end

0 commit comments

Comments
 (0)