Merge pull request #13536 from max-ae/generate-completions-dsl

Formula: add DSL to generate completions
This commit is contained in:
Rylan Polster 2022-08-12 10:39:37 -04:00 committed by GitHub
commit dac54fbbfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 116 additions and 0 deletions

View File

@ -1622,6 +1622,98 @@ class Formula
end
private :extract_macho_slice_from
# Generate shell completions for a formula for bash, zsh, and fish, using the formula's executable.
#
# @param commands [Pathname, String] the path to the executable and any passed subcommand(s)
# to use for generating the completion scripts.
# @param base_name [String] the base name of the generated completion script. Defaults to the formula name.
# @param shells [Array<Symbol>] the shells to generate completion scripts for. Defaults to `[:bash, :zsh, :fish]`.
# @param shell_parameter_format [String, Symbol] specify how `shells` should each be passed
# to the `executable`. Takes either a String representing a prefix, or one of [:flag, :arg, :none].
# Defaults to plainly passing the shell.
#
# @example Using default values for optional arguments
# generate_completions_from_executable(bin/"foo", "completions")
# translates to
#
# (bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo", "completions", "bash")
#
# (zsh_completion/"_foo").write Utils.safe_popen_read({ "SHELL" => "zsh" }, bin/"foo", "completions", "zsh")
#
# (fish_completion/"foo.fish").write Utils.safe_popen_read({ "SHELL" => "fish" }, bin/"foo", "completions", "fish")
#
# @example Selecting shells and using a different base_name
# generate_completions_from_executable(bin/"foo", "completions", shells: [:bash, :zsh], base_name: "bar")
# translates to
#
# (bash_completion/"bar").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo", "completions", "bash")
#
# (zsh_completion/"_bar").write Utils.safe_popen_read({ "SHELL" => "zsh" }, bin/"foo", "completions", "zsh")
#
# @example Using predefined shell_parameter_format :flag
# generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: :flag, shells: [:bash])
# translates to
#
# (bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo", "completions", "--bash")
#
# @example Using predefined shell_parameter_format :arg
# generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: :arg, shells: [:bash])
# translates to
#
# (bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo",
# "completions", "--shell=bash")
#
# @example Using predefined shell_parameter_format :none
# generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: :none, shells: [:bash])
# translates to
#
# (bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo", "completions")
#
# @example Using custom shell_parameter_format
# generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: "--selected-shell=",
# shells: [:bash])
# translates to
#
# (bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo",
# "completions", "--selected-shell=bash")
sig {
params(commands: T.any(Pathname, String), base_name: String, shells: T::Array[Symbol],
shell_parameter_format: T.nilable(T.any(Symbol, String))).void
}
def generate_completions_from_executable(*commands,
base_name: name,
shells: [:bash, :zsh, :fish],
shell_parameter_format: nil)
completion_script_path_map = {
bash: bash_completion/base_name,
zsh: zsh_completion/"_#{base_name}",
fish: fish_completion/"#{base_name}.fish",
}
shells.each do |shell|
script_path = completion_script_path_map[shell]
shell_parameter = if shell_parameter_format.nil?
shell.to_s
elsif shell_parameter_format == :flag
"--#{shell}"
elsif shell_parameter_format == :arg
"--shell=#{shell}"
elsif shell_parameter_format == :none
""
else
"#{shell_parameter_format}#{shell}"
end
popen_read_args = %w[]
popen_read_args << commands
popen_read_args << shell_parameter
popen_read_args.flatten!
script_path.dirname.mkpath
script_path.write Utils.safe_popen_read({ "SHELL" => shell.to_s }, *popen_read_args)
end
end
# an array of all core {Formula} names
# @private
def self.core_names

View File

@ -1996,4 +1996,28 @@ describe Formula do
}.to raise_error("ignore_missing_libraries is available on Linux only")
end
end
describe "#generate_completions_from_executable" do
let(:f) do
Class.new(Testball) do
def install
bin.mkpath
(bin/"foo").write <<-EOF
echo completion
EOF
FileUtils.chmod "+x", bin/"foo"
generate_completions_from_executable(bin/"foo", "test")
end
end.new
end
it "generates completion scripts" do
f.brew { f.install }
expect(f.bash_completion/"testball").to be_a_file
expect(f.zsh_completion/"_testball").to be_a_file
expect(f.fish_completion/"testball.fish").to be_a_file
end
end
end