From 986f4d1eb8652061e23e8c73301989b021c53482 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Thu, 19 May 2022 15:55:13 +0000 Subject: [PATCH 1/4] - Add Tester class for testing any completions script --- lib/completely.rb | 1 + lib/completely/completions.rb | 4 +++ lib/completely/tester-template.erb | 13 ++++++++ lib/completely/tester.rb | 48 +++++++++++++++++++++++++++++ spec/approvals/tester/script | 13 ++++++++ spec/approvals/tester/script_path | 13 ++++++++ spec/completely/completions_spec.rb | 10 ++++++ spec/completely/tester_spec.rb | 38 +++++++++++++++++++++++ spec/fixtures/tester/default.bash | 22 +++++++++++++ spec/fixtures/tester/default.yaml | 19 ++++++++++++ 10 files changed, 181 insertions(+) create mode 100644 lib/completely/tester-template.erb create mode 100644 lib/completely/tester.rb create mode 100644 spec/approvals/tester/script create mode 100644 spec/approvals/tester/script_path create mode 100644 spec/completely/tester_spec.rb create mode 100644 spec/fixtures/tester/default.bash create mode 100644 spec/fixtures/tester/default.yaml diff --git a/lib/completely.rb b/lib/completely.rb index d054a04..8bb09c7 100644 --- a/lib/completely.rb +++ b/lib/completely.rb @@ -5,3 +5,4 @@ require 'completely/pattern' require 'completely/completions' +require 'completely/tester' diff --git a/lib/completely/completions.rb b/lib/completely/completions.rb index acb4435..a29fee7 100644 --- a/lib/completely/completions.rb +++ b/lib/completely/completions.rb @@ -46,6 +46,10 @@ def wrapper_function(name = nil) "#{name}() {\n#{script_lines}\n}" end + def tester + @tester ||= Tester.new script: script, function_name: function_name + end + private def patterns! diff --git a/lib/completely/tester-template.erb b/lib/completely/tester-template.erb new file mode 100644 index 0000000..805efcf --- /dev/null +++ b/lib/completely/tester-template.erb @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +<%= script || %Q[source "#{absolute_script_path}"] %> + +# END OF COMPLETION SCRIPT + +source /usr/share/bash-completion/bash_completion +COMP_WORDS=( <%= compline %> ) +COMP_LINE="<%= compline %>" +COMP_POINT=${#COMP_LINE} +COMP_CWORD=<%= cword %> + +<%= function_name %> +echo "${COMPREPLY[*]}" diff --git a/lib/completely/tester.rb b/lib/completely/tester.rb new file mode 100644 index 0000000..05eec2e --- /dev/null +++ b/lib/completely/tester.rb @@ -0,0 +1,48 @@ +require 'erb' +require 'tempfile' + +module Completely + class Tester + attr_reader :script, :script_path, :function_name, :cword, :compline + + def initialize(script: nil, script_path: nil, function_name: ) + @script, @script_path, @function_name = script, script_path, function_name + end + + def test(compline) + Tempfile.create "completely-tester" do |f| + f << tester_script(compline) + f.flush + `bash #{f.path}` + end.split " " + end + + def tester_script(compline) + set_compline_vars compline + ERB.new(template, trim_mode: '%-').result(binding) + end + + protected + + def set_compline_vars(compline) + @compline = compline + @cword = compline.split(' ').size - 1 + @cword += 1 if compline.end_with? ' ' + end + + def absolute_script_path + @absolute_script_path ||= begin + script_path ? File.expand_path(script_path) : nil + end + end + + def template_path + @template_path ||= File.expand_path "tester-template.erb", __dir__ + end + + def template + @template ||= File.read template_path + end + + end +end \ No newline at end of file diff --git a/spec/approvals/tester/script b/spec/approvals/tester/script new file mode 100644 index 0000000..15f445b --- /dev/null +++ b/spec/approvals/tester/script @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# some completion script + +# END OF COMPLETION SCRIPT + +source /usr/share/bash-completion/bash_completion +COMP_WORDS=( cli co ) +COMP_LINE="cli co" +COMP_POINT=${#COMP_LINE} +COMP_CWORD=1 + +_cli_completions +echo "${COMPREPLY[*]}" diff --git a/spec/approvals/tester/script_path b/spec/approvals/tester/script_path new file mode 100644 index 0000000..79e257e --- /dev/null +++ b/spec/approvals/tester/script_path @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +source "" + +# END OF COMPLETION SCRIPT + +source /usr/share/bash-completion/bash_completion +COMP_WORDS=( cli co ) +COMP_LINE="cli co" +COMP_POINT=${#COMP_LINE} +COMP_CWORD=1 + +_cli_completions +echo "${COMPREPLY[*]}" diff --git a/spec/completely/completions_spec.rb b/spec/completely/completions_spec.rb index df31674..95dee20 100644 --- a/spec/completely/completions_spec.rb +++ b/spec/completely/completions_spec.rb @@ -47,4 +47,14 @@ expect(subject.wrapper_function).to match_approval "completions/function" end end + + describe '#tester', :focus do + it "returns a Tester object" do + expect(subject.tester).to be_a Tester + end + + it "assigns self.script to tester.script" do + expect(subject.tester.script).to eq subject.script + end + end end diff --git a/spec/completely/tester_spec.rb b/spec/completely/tester_spec.rb new file mode 100644 index 0000000..9e532f4 --- /dev/null +++ b/spec/completely/tester_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +describe Tester do + subject { described_class.new script_path: script_path, function_name: function_name } + let(:function_name) { '_cli_completions' } + let(:script_path) { "spec/fixtures/tester/#{fixture}.bash" } + let(:fixture) { 'default' } + let(:compline) { "cli co" } + + describe "#tester_script" do + it "sources the script using its absolute path" do + expect(subject.tester_script compline).to match %r[source "/.*spec/fixtures/tester/default.bash"] + end + + it "returns a valid testing script" do + expect(subject.tester_script compline).to match_approval("tester/script_path") + .except(/source "(.*)"/, 'source ""') + end + end + + describe '#test' do + it "returns an array with completions" do + expect(subject.test compline).to eq ["command", "conquer"] + end + end + + context "with script instead of script_path" do + subject { described_class.new script: script, function_name: function_name } + let(:script) { "# some completion script" } + + describe '#tester_script' do + it "includes the embedded script" do + expect(subject.tester_script compline).to match_approval("tester/script") + end + end + end + +end diff --git a/spec/fixtures/tester/default.bash b/spec/fixtures/tester/default.bash new file mode 100644 index 0000000..02e3186 --- /dev/null +++ b/spec/fixtures/tester/default.bash @@ -0,0 +1,22 @@ +# cli completion -*- shell-script -*- + +# This bash completions script was generated by +# completely (https://github.com/dannyben/completely) +# Modifying it manually is not recommended + +_cli_completions() { + local cur comp_line + _init_completion -s || return + cur=${COMP_WORDS[COMP_CWORD]} + comp_line="${COMP_WORDS[@]:1}" + + case "$comp_line" in + 'command childcommand'*) COMPREPLY=($(compgen -W "--quiet --verbose -q -v" -- "$cur")) ;; + 'command subcommand'*) COMPREPLY=($(compgen -W "--force --quiet" -- "$cur")) ;; + 'command'*) COMPREPLY=($(compgen -W "subcommand childcommand" -- "$cur")) ;; + ''*) COMPREPLY=($(compgen -W "--help --version command conquer" -- "$cur")) ;; + esac +} && +complete -F _cli_completions cli + +# ex: filetype=sh diff --git a/spec/fixtures/tester/default.yaml b/spec/fixtures/tester/default.yaml new file mode 100644 index 0000000..0208091 --- /dev/null +++ b/spec/fixtures/tester/default.yaml @@ -0,0 +1,19 @@ +cli: +- --help +- --version +- command +- conquer + +cli command: +- subcommand +- childcommand + +cli command subcommand: +- --force +- --quiet + +cli command childcommand: +- --quiet +- --verbose +- -q +- -v \ No newline at end of file From 09e91ee73c27640e2051abe54e03ab7744faa9ff Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Thu, 19 May 2022 17:18:15 +0000 Subject: [PATCH 2/4] - Add tester CLI command --- lib/completely/cli.rb | 2 + lib/completely/commands/preview.rb | 2 +- lib/completely/commands/test.rb | 69 +++++++++++++++++++++ spec/approvals/cli/commands | 1 + spec/approvals/cli/test/comps-custom-config | 2 + spec/approvals/cli/test/comps-default | 2 + spec/approvals/cli/test/comps-git | 2 + spec/approvals/cli/test/error | 1 + spec/approvals/cli/test/help | 43 +++++++++++++ spec/approvals/cli/test/usage | 3 + spec/completely/commands/test_spec.rb | 69 +++++++++++++++++++++ 11 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 lib/completely/commands/test.rb create mode 100644 spec/approvals/cli/test/comps-custom-config create mode 100644 spec/approvals/cli/test/comps-default create mode 100644 spec/approvals/cli/test/comps-git create mode 100644 spec/approvals/cli/test/error create mode 100644 spec/approvals/cli/test/help create mode 100644 spec/approvals/cli/test/usage create mode 100644 spec/completely/commands/test_spec.rb diff --git a/lib/completely/cli.rb b/lib/completely/cli.rb index d5638b3..79ca3e9 100644 --- a/lib/completely/cli.rb +++ b/lib/completely/cli.rb @@ -2,6 +2,7 @@ require 'completely/commands/init' require 'completely/commands/preview' require 'completely/commands/generate' +require 'completely/commands/test' module Completely class CLI @@ -13,6 +14,7 @@ def self.runner runner.route 'init', to: Commands::Init runner.route 'preview', to: Commands::Preview runner.route 'generate', to: Commands::Generate + runner.route 'test', to: Commands::Test runner end diff --git a/lib/completely/commands/preview.rb b/lib/completely/commands/preview.rb index d1f9c08..390f66c 100644 --- a/lib/completely/commands/preview.rb +++ b/lib/completely/commands/preview.rb @@ -8,7 +8,7 @@ class Preview < Base usage "completely preview [CONFIG_PATH --function NAME]" usage "completely preview (-h|--help)" - function_usage + function_usage config_path_usage def run diff --git a/lib/completely/commands/test.rb b/lib/completely/commands/test.rb new file mode 100644 index 0000000..0b82ccc --- /dev/null +++ b/lib/completely/commands/test.rb @@ -0,0 +1,69 @@ +require 'completely/commands/base' + +module Completely + module Commands + class Test < Base + summary "Test completions" + + help <<~EOF + This command can be used to test that any completion script (either generated by compeltely or not) responds with the right completions. + + In order to test on a completely configuration file other than 'completely.yaml', set the COMPLETELY_CONFIG_PATH environemnt variable. + + In order to test on an arbitrary completions script, set the COMPLETELY_SCRIPT_PATH and COMPLETELY_SCRIPT_FUNCTION environment variables. + EOF + + usage "completely test COMPLINE" + usage "completely test (-h|--help)" + + param "COMPLINE", "The command to test completions for. This will be handled as if a TAB was pressed immediately at the end of it, so the last word is considered the active cursor. If you wish to complete for the next word instead, end your command with a space." + + environment "COMPLETELY_CONFIG_PATH", "Path to a completely configuration file [default: completely.yaml]" + environment "COMPLETELY_SCRIPT_PATH", "Path to a completions script. When set, this script will be tested instead of the completely configuration file" + environment "COMPLETELY_SCRIPT_FUNCTION", "The main completion function to call when using a custom script" + + example %q[completely test "mygit pu"] + example %q[completely test "mygit pull "] + example <<~EOF + COMPLETELY_SCRIPT_PATH=/usr/share/bash-completion/completions/git \\ + COMPLETELY_SCRIPT_FUNCTION=_git \\ + completely test "git pu" + EOF + + attr_reader :config, :script_path, :script_function + + def run + set_vars + puts tester.test(compline).join "\n" + end + + private + + def compline + args['COMPLINE'] + end + + def tester + if config + completions = Completions.load config + completions.tester + else + Tester.new script: File.read(script_path), function_name: ENV['COMPLETELY_SCRIPT_FUNCTION'] + end + end + + def set_vars + if ENV['COMPLETELY_CONFIG_PATH'] + @config = ENV['COMPLETELY_CONFIG_PATH'] + elsif ENV['COMPLETELY_SCRIPT_PATH'] and ENV['COMPLETELY_SCRIPT_FUNCTION'] + @script_path = ENV['COMPLETELY_SCRIPT_PATH'] + @script_function = ENV['COMPLETELY_SCRIPT_FUNCTION'] + elsif File.exist? 'completely.yaml' + @config = 'completely.yaml' + else + raise "Please set the proper environment variables or run in a folder with completely.yaml" + end + end + end + end +end diff --git a/spec/approvals/cli/commands b/spec/approvals/cli/commands index ddc8aa3..0664eb2 100644 --- a/spec/approvals/cli/commands +++ b/spec/approvals/cli/commands @@ -4,5 +4,6 @@ Commands: init Create a new sample YAML configuration file preview Generate the bash completion script to STDOUT generate Generate the bash completion script to a file + test Test completions Run completely COMMAND --help for more information diff --git a/spec/approvals/cli/test/comps-custom-config b/spec/approvals/cli/test/comps-custom-config new file mode 100644 index 0000000..f22b05f --- /dev/null +++ b/spec/approvals/cli/test/comps-custom-config @@ -0,0 +1,2 @@ +command +conquer diff --git a/spec/approvals/cli/test/comps-default b/spec/approvals/cli/test/comps-default new file mode 100644 index 0000000..c5738cd --- /dev/null +++ b/spec/approvals/cli/test/comps-default @@ -0,0 +1,2 @@ +--help +--version diff --git a/spec/approvals/cli/test/comps-git b/spec/approvals/cli/test/comps-git new file mode 100644 index 0000000..f838f44 --- /dev/null +++ b/spec/approvals/cli/test/comps-git @@ -0,0 +1,2 @@ +pull +push diff --git a/spec/approvals/cli/test/error b/spec/approvals/cli/test/error new file mode 100644 index 0000000..96dc780 --- /dev/null +++ b/spec/approvals/cli/test/error @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/spec/approvals/cli/test/help b/spec/approvals/cli/test/help new file mode 100644 index 0000000..e779660 --- /dev/null +++ b/spec/approvals/cli/test/help @@ -0,0 +1,43 @@ +Test completions + +This command can be used to test that any completion script (either generated by +compeltely or not) responds with the right completions. + +In order to test on a completely configuration file other than +'completely.yaml', set the COMPLETELY_CONFIG_PATH environemnt variable. + +In order to test on an arbitrary completions script, set the +COMPLETELY_SCRIPT_PATH and COMPLETELY_SCRIPT_FUNCTION environment variables. + +Usage: + completely test COMPLINE + completely test (-h|--help) + +Options: + -h --help + Show this help + +Parameters: + COMPLINE + The command to test completions for. This will be handled as if a TAB was + pressed immediately at the end of it, so the last word is considered the + active cursor. If you wish to complete for the next word instead, end your + command with a space. + +Environment Variables: + COMPLETELY_CONFIG_PATH + Path to a completely configuration file [default: completely.yaml] + + COMPLETELY_SCRIPT_PATH + Path to a completions script. When set, this script will be tested instead + of the completely configuration file + + COMPLETELY_SCRIPT_FUNCTION + The main completion function to call when using a custom script + +Examples: + completely test "mygit pu" + completely test "mygit pull " + COMPLETELY_SCRIPT_PATH=/usr/share/bash-completion/completions/git \ + COMPLETELY_SCRIPT_FUNCTION=_git \ + completely test "git pu" diff --git a/spec/approvals/cli/test/usage b/spec/approvals/cli/test/usage new file mode 100644 index 0000000..c13cce1 --- /dev/null +++ b/spec/approvals/cli/test/usage @@ -0,0 +1,3 @@ +Usage: + completely test COMPLINE + completely test (-h|--help) diff --git a/spec/completely/commands/test_spec.rb b/spec/completely/commands/test_spec.rb new file mode 100644 index 0000000..09c7924 --- /dev/null +++ b/spec/completely/commands/test_spec.rb @@ -0,0 +1,69 @@ +require 'spec_helper' + +describe Commands::Test do + subject { CLI.runner } + + before do + system "cp lib/completely/sample.yaml completely.yaml" + ENV['COMPLETELY_CONFIG_PATH'] = nil + ENV['COMPLETELY_SCRIPT_PATH'] = nil + ENV['COMPLETELY_SCRIPT_FUNCTION'] = nil + end + + after { system "rm -f completely.yaml" } + + context "with --help" do + it "shows long usage" do + expect{ subject.run %w[test --help] }.to output_approval('cli/test/help') + end + end + + context "without arguments" do + it "shows a short usage" do + expect { subject.run %w[test] } + .to output_approval('cli/test/usage') + end + end + + context "with COMPLINE" do + it "prints completions" do + expect { subject.run ["test", "mygit --"] } + .to output_approval('cli/test/comps-default') + end + end + + context "when COMPLETELY_CONFIG_PATH is set" do + before do + reset_tmp_dir + File.write "spec/tmp/in.yaml", { "play" => ["command", "conquer"] }.to_yaml + ENV['COMPLETELY_CONFIG_PATH'] = "spec/tmp/in.yaml" + end + + it "tests against this completely file" do + expect { subject.run ["test", "play co"] } + .to output_approval('cli/test/comps-custom-config') + end + end + + context "when COMPLETELY_SCRIPT_PATH and COMPLETELY_SCRIPT_FUNCTION are set" do + before do + ENV['COMPLETELY_SCRIPT_PATH'] = "/usr/share/bash-completion/completions/git" + ENV['COMPLETELY_SCRIPT_FUNCTION'] = "_git" + end + + it "tests against this script" do + expect { subject.run ["test", "git pu"] } + .to output_approval('cli/test/comps-git') + end + end + + context "when there is no compeltely.yaml or any environment instructions" do + before { system "rm -f completely.yaml" } + + it "fails gracefully" do + expect { subject.run ["test", "mygit --"] } + .to raise_approval('cli/test/error') + end + end + +end From e2513fcd5f4a1c73e70414081c49c961aa6237f9 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Thu, 19 May 2022 17:24:21 +0000 Subject: [PATCH 3/4] test with apt instead of git --- spec/approvals/cli/test/comps-apt | 2 ++ spec/approvals/cli/test/comps-git | 2 -- spec/completely/commands/test_spec.rb | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 spec/approvals/cli/test/comps-apt delete mode 100644 spec/approvals/cli/test/comps-git diff --git a/spec/approvals/cli/test/comps-apt b/spec/approvals/cli/test/comps-apt new file mode 100644 index 0000000..7bc8233 --- /dev/null +++ b/spec/approvals/cli/test/comps-apt @@ -0,0 +1,2 @@ +update +upgrade diff --git a/spec/approvals/cli/test/comps-git b/spec/approvals/cli/test/comps-git deleted file mode 100644 index f838f44..0000000 --- a/spec/approvals/cli/test/comps-git +++ /dev/null @@ -1,2 +0,0 @@ -pull -push diff --git a/spec/completely/commands/test_spec.rb b/spec/completely/commands/test_spec.rb index 09c7924..e574f44 100644 --- a/spec/completely/commands/test_spec.rb +++ b/spec/completely/commands/test_spec.rb @@ -47,13 +47,13 @@ context "when COMPLETELY_SCRIPT_PATH and COMPLETELY_SCRIPT_FUNCTION are set" do before do - ENV['COMPLETELY_SCRIPT_PATH'] = "/usr/share/bash-completion/completions/git" - ENV['COMPLETELY_SCRIPT_FUNCTION'] = "_git" + ENV['COMPLETELY_SCRIPT_PATH'] = "/usr/share/bash-completion/completions/apt" + ENV['COMPLETELY_SCRIPT_FUNCTION'] = "_apt" end it "tests against this script" do - expect { subject.run ["test", "git pu"] } - .to output_approval('cli/test/comps-git') + expect { subject.run ["test", "apt up"] } + .to output_approval('cli/test/comps-apt') end end From 609030eca74be8b0011d2e9dd72e407da7a144f7 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Thu, 19 May 2022 17:59:57 +0000 Subject: [PATCH 4/4] make COMPLETELY_SCRIPT_FUNCTION optional --- lib/completely/commands/test.rb | 15 +++++++-------- spec/approvals/cli/test/help | 11 ++++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/completely/commands/test.rb b/lib/completely/commands/test.rb index 0b82ccc..72132a2 100644 --- a/lib/completely/commands/test.rb +++ b/lib/completely/commands/test.rb @@ -10,7 +10,7 @@ class Test < Base In order to test on a completely configuration file other than 'completely.yaml', set the COMPLETELY_CONFIG_PATH environemnt variable. - In order to test on an arbitrary completions script, set the COMPLETELY_SCRIPT_PATH and COMPLETELY_SCRIPT_FUNCTION environment variables. + In order to test on an arbitrary completions script, set the COMPLETELY_SCRIPT_PATH and optionally the COMPLETELY_SCRIPT_FUNCTION environment variables. EOF usage "completely test COMPLINE" @@ -20,14 +20,13 @@ class Test < Base environment "COMPLETELY_CONFIG_PATH", "Path to a completely configuration file [default: completely.yaml]" environment "COMPLETELY_SCRIPT_PATH", "Path to a completions script. When set, this script will be tested instead of the completely configuration file" - environment "COMPLETELY_SCRIPT_FUNCTION", "The main completion function to call when using a custom script" + environment "COMPLETELY_SCRIPT_FUNCTION", "The main completion function to call when using a custom script. If not set, the basename of the script path will be used, prefixed by an underscore" example %q[completely test "mygit pu"] example %q[completely test "mygit pull "] example <<~EOF - COMPLETELY_SCRIPT_PATH=/usr/share/bash-completion/completions/git \\ - COMPLETELY_SCRIPT_FUNCTION=_git \\ - completely test "git pu" + COMPLETELY_SCRIPT_PATH=/usr/share/bash-completion/completions/chown \\ + completely test "chown --" EOF attr_reader :config, :script_path, :script_function @@ -48,16 +47,16 @@ def tester completions = Completions.load config completions.tester else - Tester.new script: File.read(script_path), function_name: ENV['COMPLETELY_SCRIPT_FUNCTION'] + Tester.new script_path: script_path, function_name: script_function end end def set_vars if ENV['COMPLETELY_CONFIG_PATH'] @config = ENV['COMPLETELY_CONFIG_PATH'] - elsif ENV['COMPLETELY_SCRIPT_PATH'] and ENV['COMPLETELY_SCRIPT_FUNCTION'] + elsif ENV['COMPLETELY_SCRIPT_PATH'] @script_path = ENV['COMPLETELY_SCRIPT_PATH'] - @script_function = ENV['COMPLETELY_SCRIPT_FUNCTION'] + @script_function = ENV['COMPLETELY_SCRIPT_FUNCTION'] || "_#{File.basename(script_path)}" elsif File.exist? 'completely.yaml' @config = 'completely.yaml' else diff --git a/spec/approvals/cli/test/help b/spec/approvals/cli/test/help index e779660..c26aef9 100644 --- a/spec/approvals/cli/test/help +++ b/spec/approvals/cli/test/help @@ -7,7 +7,8 @@ In order to test on a completely configuration file other than 'completely.yaml', set the COMPLETELY_CONFIG_PATH environemnt variable. In order to test on an arbitrary completions script, set the -COMPLETELY_SCRIPT_PATH and COMPLETELY_SCRIPT_FUNCTION environment variables. +COMPLETELY_SCRIPT_PATH and optionally the COMPLETELY_SCRIPT_FUNCTION environment +variables. Usage: completely test COMPLINE @@ -33,11 +34,11 @@ Environment Variables: of the completely configuration file COMPLETELY_SCRIPT_FUNCTION - The main completion function to call when using a custom script + The main completion function to call when using a custom script. If not set, + the basename of the script path will be used, prefixed by an underscore Examples: completely test "mygit pu" completely test "mygit pull " - COMPLETELY_SCRIPT_PATH=/usr/share/bash-completion/completions/git \ - COMPLETELY_SCRIPT_FUNCTION=_git \ - completely test "git pu" + COMPLETELY_SCRIPT_PATH=/usr/share/bash-completion/completions/chown \ + completely test "chown --"