Skip to content

Commit

Permalink
Added additional output messages for Fish and Zsh users.
Browse files Browse the repository at this point in the history
* Allow `print_completion_file`, `install_completion_file`, and
  `uninstall_completion_file` to be overridden.
  • Loading branch information
postmodern committed Jan 3, 2024
1 parent b1065f4 commit 365fb20
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 9 deletions.
58 changes: 55 additions & 3 deletions lib/ronin/core/cli/completion_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,18 +134,70 @@ def completion_file
# Runs the `completion` command.
#
def run
if shell_type == :fish
print_error "shell completions for the fish shell are not currently supported"
exit(-1)
end

case @mode
when :print
print_completion_file(completion_file)
print_completion_file
when :install
install_completion_file(completion_file)
install_completion_file

if shell_type == :zsh
puts "Ensure that you have the following lines added to your ~/.zshrc:"
puts
puts " autoload -Uz +X compinit && compinit"
puts " autoload -Uz +X bashcompinit && bashcompinit"
puts
end
when :uninstall
uninstall_completion_file_for(File.basename(completion_file))
uninstall_completion_file

puts "Completion rules successfully uninstalled. Please restart your shell."
else
raise(NotImplementedError,"mode not implemented: #{@mode.inspect}")
end
end

#
# Prints the `completion` command's {completion_file} to stdout.
#
# @param [String] completion_file
# The path to the completion file to print.
#
# @api private
#
def print_completion_file(completion_file=self.completion_file)
super(completion_file)
end

#
# Installs the `completion` command's {completion_file} for the current
# `SHELL`.
#
# @param [String] completion_file
# The path to the completion file to install.
#
# @api private
#
def install_completion_file(completion_file=self.completion_file)
super(completion_file)
end

#
# Uninstalls the `completion` command's {completion_file}.
#
# @param [String] completion_file
# The path to the completion file to uninstall.
#
# @api private
#
def uninstall_completion_file(completion_file=self.completion_file)
uninstall_completion_file_for(File.basename(completion_file))
end

end
end
end
Expand Down
58 changes: 52 additions & 6 deletions spec/cli/completion_command_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class CommandWithCompletionFile < Ronin::Core::CLI::CompletionCommand
describe "#run" do
context "when no options are given" do
it "must call #print_completion_file with #completion_file" do
expect(subject).to receive(:print_completion_file).with(subject.completion_file)
expect(subject).to receive(:print_completion_file).with(no_args)

subject.run
end
Expand All @@ -130,7 +130,7 @@ class CommandWithCompletionFile < Ronin::Core::CLI::CompletionCommand
before { subject.option_parser.parse(%w[--print]) }

it "must call #print_completion_file with #completion_file" do
expect(subject).to receive(:print_completion_file).with(subject.completion_file)
expect(subject).to receive(:print_completion_file).with(no_args)

subject.run
end
Expand All @@ -140,24 +140,70 @@ class CommandWithCompletionFile < Ronin::Core::CLI::CompletionCommand
before { subject.option_parser.parse(%w[--install]) }

it "must call #install_completion_file with #completion_file" do
expect(subject).to receive(:install_completion_file).with(subject.completion_file)
expect(subject).to receive(:install_completion_file).with(no_args)

subject.run
end

context "and the 'SHELL' is a zsh shell" do
let(:shell) { '/bin/zsh' }

subject do
command_class.new(env: {'SHELL' => shell})
end

it "must also print a message instructing the user to add additional configuration to their ~/.zshrc file to enable the installed bash completions" do
expect(subject).to receive(:install_completion_file).with(no_args)
expect(subject).to receive(:puts).with(
"Ensure that you have the following lines added to your ~/.zshrc:"
)
expect(subject).to receive(:puts).with(no_args)
expect(subject).to receive(:puts).with(
" autoload -Uz +X compinit && compinit"
)
expect(subject).to receive(:puts).with(
" autoload -Uz +X bashcompinit && bashcompinit"
)
expect(subject).to receive(:puts).with(no_args)

subject.run
end
end
end

context "when the --uninstall option is given" do
before { subject.option_parser.parse(%w[--uninstall]) }

it "must call #uninstall_completion_file with the basename of the #completion_file" do
expect(subject).to receive(:uninstall_completion_file_for).with(
File.basename(subject.completion_file)
it "must call #uninstall_completion_file with the basename of the #completion_file and print a message instructing the user to restart their shell" do
expect(subject).to receive(:uninstall_completion_file).with(no_args)
expect(subject).to receive(:puts).with(
"Completion rules successfully uninstalled. Please restart your shell."
)

subject.run
end
end

context "when the 'SHELL' is a fish shell" do
let(:shell) { '/bin/fish' }

subject do
command_class.new(env: {'SHELL' => shell})
end

it "must print an error message about fish completions not being supported and exit with -1" do
expect(subject).to receive(:print_error).with(
"shell completions for the fish shell are not currently supported"
)

expect {
subject.run
}.to raise_error(SystemExit) { |error|
expect(error.status).to eq(-1)
}
end
end

context "when #mode is neither :print, :install, or :uninstall" do
let(:mode) { :foo }

Expand Down

0 comments on commit 365fb20

Please sign in to comment.