Skip to content

fix(scp,rsync): fix misc bugs and refactor #1371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion bash_completion
Original file line number Diff line number Diff line change
Expand Up @@ -2856,7 +2856,7 @@ _comp_command_offset()
_comp_compgen_commands
else
_comp_dequote "${COMP_WORDS[0]}" || REPLY=${COMP_WORDS[0]}
local cmd=$REPLY compcmd=$REPLY
local cmd=${REPLY-} compcmd=${REPLY-}
local cspec=$(complete -p -- "$cmd" 2>/dev/null)

# If we have no completion for $cmd yet, see if we have for basename
Expand Down
28 changes: 13 additions & 15 deletions completions/ssh
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,6 @@ _comp_cmd_sftp()
shopt -u hostcomplete && complete -F _comp_cmd_sftp sftp

# things we want to backslash escape in scp paths
# shellcheck disable=SC2089
_comp_cmd_scp__path_esc='[][(){}<>"'"'"',:;^&!$=?`\\|[:space:]]'

# Complete remote files with ssh. Returns paths escaped with three backslashes
Expand Down Expand Up @@ -493,7 +492,6 @@ _comp_xfunc_scp_compgen_remote_files()
local _path=${cur#*:}

# unescape (3 backslashes to 1 for chars we escaped)
# shellcheck disable=SC2090
_path=$(command sed -e 's/\\\\\\\('"$_comp_cmd_scp__path_esc"'\)/\\\1/g' <<<"$_path")

# default to home dir of specified user on remote host
Expand All @@ -509,18 +507,17 @@ _comp_xfunc_scp_compgen_remote_files()
local _files
if [[ $_dirs_only ]]; then
# escape problematic characters; remove non-dirs
# shellcheck disable=SC2090
_files=$(ssh -o 'Batchmode yes' "$_userhost" \
command ls -aF1dL "$_path*" 2>/dev/null |
command sed -e 's/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/g' -e '/[^\/]$/d')
command sed -e 's/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/g' -e '/[^/]$/d')
else
# escape problematic characters; remove executables, aliases, pipes
# and sockets; add space at end of file names
# shellcheck disable=SC2090
_files=$(ssh -o 'Batchmode yes' "$_userhost" \
command ls -aF1dL "$_path*" 2>/dev/null |
command sed -e 's/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/g' -e 's/[*@|=]$//g' \
-e 's/[^\/]$/& /g')
command sed -e 's/[*@|=]$//g' \
-e 's/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/g' \
-e 's/[^/]$/& /g')
fi
_comp_compgen -R split -l -- "$_files"
}
Expand All @@ -538,25 +535,26 @@ _scp_remote_files()
# @since 2.12
_comp_xfunc_scp_compgen_local_files()
{
local _dirsonly=""
local _dirs_only=""
if [[ ${1-} == -d ]]; then
_dirsonly=set
_dirs_only=set
shift
fi

local files
_comp_expand_glob files '"$cur"*' || return 0
if [[ $_dirsonly ]]; then
_comp_compgen -U files split -l -- "$(
if [[ $_dirs_only ]]; then
_comp_compgen -RU files split -l ${1:+-P "$1"} -- "$(
command ls -aF1dL "${files[@]}" 2>/dev/null |
command sed -e "s/$_comp_cmd_scp__path_esc/\\\\&/g" \
-e '/[^\/]$/d' -e "s/^/${1-}/"
-e '/[^/]$/d'
)"
else
_comp_compgen -U files split -l -- "$(
_comp_compgen -RU files split -l ${1:+-P "$1"} -- "$(
command ls -aF1dL "${files[@]}" 2>/dev/null |
command sed -e "s/$_comp_cmd_scp__path_esc/\\\\&/g" \
-e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' -e "s/^/${1-}/"
command sed -e 's/[*@|=]$//g' \
-e "s/$_comp_cmd_scp__path_esc/\\\\&/g" \
-e 's/[^/]$/& /g'
)"
fi
}
Expand Down
Empty file.
Empty file.
2 changes: 1 addition & 1 deletion test/t/test_cancel.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def added_job(self, request, bash):
)
except AssertionError:
pytest.skip("Could not add test print job")
return

if len(got) > 3:
request.addfinalizer(
lambda: assert_bash_exec(bash, "cancel %s" % got[3])
Expand Down
2 changes: 1 addition & 1 deletion test/t/test_ls.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def test_3(self, bash):
part_full = find_unique_completion_pair(res)
if not part_full:
pytest.skip("No suitable test user found")
return

part, full = part_full
completion = assert_complete(bash, "ls ~%s" % part)
assert completion == full[len(part) :]
Expand Down
2 changes: 1 addition & 1 deletion test/t/test_man.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def colonpath(self, request, bash):
pass
else:
pytest.skip("Cygwin doesn't like paths with colons")
return

tmpdir, _, _ = prepare_fixture_dir(
request,
files=["man/man3/Bash::Completion.3pm.gz"],
Expand Down
34 changes: 33 additions & 1 deletion test/t/test_scp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

import pytest

from conftest import assert_bash_exec, assert_complete, bash_env_saved
from conftest import (
assert_bash_exec,
assert_complete,
bash_env_saved,
prepare_fixture_dir,
)

LIVE_HOST = "bash_completion"

Expand Down Expand Up @@ -55,6 +60,14 @@ def test_capital_f_without_space(self, completion):
"option requires an argument -- F" in x for x in completion
)

@pytest.mark.complete("scp -Fconf", cwd="scp")
def test_capital_f_without_space_2(self, completion):
assert completion == "ig"

@pytest.mark.complete("scp -Fbi", cwd="scp")
def test_capital_f_without_space_3(self, completion):
assert completion == "n/"

@pytest.fixture(scope="class")
def live_pwd(self, bash):
try:
Expand Down Expand Up @@ -141,3 +154,22 @@ def test_xfunc_remote_files(self, bash):
"shared/default/foo ",
"shared/default/foo.d/",
]

@pytest.fixture
def tmpdir_mkfifo(self, request, bash):
tmpdir, _, _ = prepare_fixture_dir(request, files=[], dirs=[])

try:
assert_bash_exec(bash, "mkfifo '%s/local_path_1-pipe'" % tmpdir)
except Exception:
pytest.skip(
"The present system does not allow creating a named pipe."
)

return tmpdir

def test_local_path_mark_1(self, bash, tmpdir_mkfifo):
completion = assert_complete(
bash, "scp local_path_1-", cwd=tmpdir_mkfifo
)
assert completion == "pipe"
4 changes: 4 additions & 0 deletions test/t/test_sshfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ class TestSshfs:
@pytest.mark.complete("sshfs ./")
def test_1(self, completion):
assert completion

@pytest.mark.complete("sshfs local_path", cwd="sshfs")
def test_local_path_suffix_1(self, completion):
assert completion == "-dir/"
Loading