completions: link official taps automatically

This commit is contained in:
Rylan Polster 2021-01-11 12:24:48 -05:00
parent bed16128cc
commit e7b369273a
7 changed files with 82 additions and 51 deletions

View File

@ -8,7 +8,6 @@ require "descriptions"
require "cleanup"
require "description_cache_store"
require "cli/parser"
require "completions"
module Homebrew
extend T::Sig
@ -151,15 +150,6 @@ module Homebrew
puts "Already up-to-date." unless args.quiet?
end
if Completions.read_completions_option.empty?
ohai "Homebrew completions are unlinked by default!"
puts <<~EOS
To opt-in to automatically linking Homebrew shell competion files, run:
brew completions link
Then, follow the directions at #{Formatter.url("https://docs.brew.sh/Shell-Completion")}
EOS
end
Commands.rebuild_commands_completion_list
link_completions_manpages_and_docs
Tap.each(&:link_completions_and_manpages)
@ -198,8 +188,7 @@ module Homebrew
def link_completions_manpages_and_docs(repository = HOMEBREW_REPOSITORY)
command = "brew update"
Completions.link_if_allowed! command: command
Utils::Link.link_completions(repository, command)
Utils::Link.link_manpages(repository, command)
Utils::Link.link_docs(repository, command)
rescue => e

View File

@ -11,25 +11,22 @@ module Completions
module_function
sig { params(command: String).void }
def link_if_allowed!(command: "brew completions link")
if link_completions?
link! command: command
else
unlink!
end
end
sig { params(command: String).void }
def link!(command: "brew completions link")
sig { void }
def link!
write_completions_option "yes"
Utils::Link.link_completions HOMEBREW_REPOSITORY, command
Tap.each do |tap|
Utils::Link.link_completions tap.path, "brew completions link"
end
end
sig { void }
def unlink!
write_completions_option "no"
Utils::Link.unlink_completions HOMEBREW_REPOSITORY
Tap.each do |tap|
next if tap.official?
Utils::Link.unlink_completions tap.path
end
end
sig { returns(T::Boolean) }
@ -37,17 +34,46 @@ module Completions
read_completions_option == "yes"
end
sig { returns(String) }
def read_completions_option
HOMEBREW_REPOSITORY.cd do
Utils.popen_read("git", "config", "--get", "homebrew.linkcompletions").chomp
sig { returns(T::Boolean) }
def completions_to_link?
shells = %w[bash fish zsh]
Tap.each do |tap|
next if tap.official?
shells.each do |shell|
return true if (tap.path/"completions/#{shell}").exist?
end
end
sig { params(state: String).void }
def write_completions_option(state)
HOMEBREW_REPOSITORY.cd do
T.unsafe(self).safe_system "git", "config", "--replace-all", "homebrew.linkcompletions", state.to_s
false
end
sig { params(option: String).returns(String) }
def read_completions_option(option: "linkcompletions")
HOMEBREW_REPOSITORY.cd do
Utils.popen_read("git", "config", "--get", "homebrew.#{option}").chomp
end
end
sig { params(state: String, option: String).void }
def write_completions_option(state, option: "linkcompletions")
HOMEBREW_REPOSITORY.cd do
T.unsafe(self).safe_system "git", "config", "--replace-all", "homebrew.#{option}", state.to_s
end
end
sig { void }
def show_completions_message_if_needed
return if read_completions_option(option: "completionsmessageshown") == "yes"
return unless completions_to_link?
T.unsafe(self).ohai "Homebrew completions for external commands are unlinked by default!"
T.unsafe(self).puts <<~EOS
To opt-in to automatically linking Homebrew shell competion files, run:
brew completions link
Then, follow the directions at #{Formatter.url("https://docs.brew.sh/Shell-Completion")}
EOS
write_completions_option("yes", option: "completionsmessageshown")
end
end

View File

@ -2,6 +2,7 @@
# frozen_string_literal: true
require "commands"
require "completions"
require "extend/cachable"
require "description_cache_store"
@ -340,7 +341,13 @@ class Tap
def link_completions_and_manpages
command = "brew tap --repair"
Utils::Link.link_manpages(path, command)
Completions.show_completions_message_if_needed
if official? || Completions.link_completions?
Utils::Link.link_completions(path, command)
else
Utils::Link.unlink_completions(path)
end
end
# Uninstall this {Tap}.

View File

@ -18,11 +18,5 @@ describe "brew completions", :integration_test do
.to output(/Completions are linked/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
brew "completions", "unlink"
expect { brew "completions" }
.to output(/Completions are not linked/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -88,6 +88,7 @@ describe Tap do
HOMEBREW_REPOSITORY.cd do
system "git", "init"
system "git", "config", "--replace-all", "homebrew.linkcompletions", link
system "git", "config", "--replace-all", "homebrew.completionsmessageshown", "yes"
end
end
@ -316,11 +317,11 @@ describe Tap do
(HOMEBREW_PREFIX/"share").rmtree if (HOMEBREW_PREFIX/"share").exist?
end
specify "#link_completions_and_manpages when completions are enabled" do
specify "#link_completions_and_manpages when completions are enabled for non-official tap" do
setup_tap_files
setup_git_repo
setup_completion link: "yes"
tap = described_class.new("Homebrew", "baz")
tap = described_class.new("NotHomebrew", "baz")
tap.install clone_target: subject.path/".git"
(HOMEBREW_PREFIX/"share/man/man1/brew-tap-cmd.1").delete
(HOMEBREW_PREFIX/"etc/bash_completion.d/brew-tap-cmd").delete
@ -337,11 +338,11 @@ describe Tap do
(HOMEBREW_PREFIX/"share").rmtree if (HOMEBREW_PREFIX/"share").exist?
end
specify "#link_completions_and_manpages when completions are disabled" do
specify "#link_completions_and_manpages when completions are disabled for non-official tap" do
setup_tap_files
setup_git_repo
setup_completion link: "no"
tap = described_class.new("Homebrew", "baz")
tap = described_class.new("NotHomebrew", "baz")
tap.install clone_target: subject.path/".git"
(HOMEBREW_PREFIX/"share/man/man1/brew-tap-cmd.1").delete
tap.link_completions_and_manpages
@ -355,6 +356,27 @@ describe Tap do
(HOMEBREW_PREFIX/"share").rmtree if (HOMEBREW_PREFIX/"share").exist?
end
specify "#link_completions_and_manpages when completions are enabled for official tap" do
setup_tap_files
setup_git_repo
setup_completion link: "no"
tap = described_class.new("Homebrew", "baz")
tap.install clone_target: subject.path/".git"
(HOMEBREW_PREFIX/"share/man/man1/brew-tap-cmd.1").delete
(HOMEBREW_PREFIX/"etc/bash_completion.d/brew-tap-cmd").delete
(HOMEBREW_PREFIX/"share/zsh/site-functions/_brew-tap-cmd").delete
(HOMEBREW_PREFIX/"share/fish/vendor_completions.d/brew-tap-cmd.fish").delete
tap.link_completions_and_manpages
expect(HOMEBREW_PREFIX/"share/man/man1/brew-tap-cmd.1").to be_a_file
expect(HOMEBREW_PREFIX/"etc/bash_completion.d/brew-tap-cmd").to be_a_file
expect(HOMEBREW_PREFIX/"share/zsh/site-functions/_brew-tap-cmd").to be_a_file
expect(HOMEBREW_PREFIX/"share/fish/vendor_completions.d/brew-tap-cmd.fish").to be_a_file
tap.uninstall
ensure
(HOMEBREW_PREFIX/"etc").rmtree if (HOMEBREW_PREFIX/"etc").exist?
(HOMEBREW_PREFIX/"share").rmtree if (HOMEBREW_PREFIX/"share").exist?
end
specify "#config" do
setup_git_repo

View File

@ -1,8 +1,6 @@
# typed: true
# frozen_string_literal: true
require "completions"
module Utils
# Helper functions for creating symlinks.
#
@ -66,11 +64,6 @@ module Utils
end
def link_completions(path, command)
unless Completions.link_completions?
unlink_completions path
return
end
link_src_dst_dirs(path/"completions/bash", HOMEBREW_PREFIX/"etc/bash_completion.d", command)
link_src_dst_dirs(path/"completions/zsh", HOMEBREW_PREFIX/"share/zsh/site-functions", command)
link_src_dst_dirs(path/"completions/fish", HOMEBREW_PREFIX/"share/fish/vendor_completions.d", command)

View File

@ -4,10 +4,10 @@ Homebrew comes with completion definitions for the `brew` command. Some packages
`zsh`, `bash` and `fish` are currently supported.
Shell completions for built-in Homebrew commands are not automatically installed. To opt-in to using our completions, they need to be linked to `HOMEBREW_PREFIX` by running `brew completions link`.
You must then configure your shell to enable its completion support. This is because the Homebrew-managed completions are stored under `HOMEBREW_PREFIX` which your system shell may not be aware of, and since it is difficult to automatically configure `bash` and `zsh` completions in a robust manner, the Homebrew installer does not do it for you.
Shell completions for external Homebrew commands are not automatically installed. To opt-in to using completions for external commands (if provided), they need to be linked to `HOMEBREW_PREFIX` by running `brew completions link`.
## Configuring Completions in `bash`
To make Homebrew's completions available in `bash`, you must source the definitions as part of your shell's startup. Add the following to your `~/.bash_profile` (or, if it doesn't exist, `~/.profile`):