-
Notifications
You must be signed in to change notification settings - Fork 382
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
fix(rsync,ssh): do not overescape spaces in remote filenames #910
Conversation
Can we detect the |
Sure, but that'll require an extra call to |
Do you have a better solution? |
I've added a commit with the rsync version check. However, if I were a maintainer, I'd much prefer the simpler solution of just working with the latest version. By the time bash-completion 2.12 is released and propagates to the distributions, it is likely that rsync will also be updated in those distributions. It would be strange if bash-completion were updated while rsync remained on an older version. I've done a quick check on the distributions:
Arch Linux, of course, has the latest version. I was actually quite surprised to find out that Arch still uses bash-completion from 2020. From a maintenance perspective, I believe it would be much better not to check the rsync version, as this significantly complicates the code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for updating the PR.
I have a question. The function _comp_xfunc_ssh_scp_remote_files
seems to be also called from the completions for other commands ssh and sshfs. I guess we want to keep the original behavior for these commands. Or did these commands also change its interpretation of the escapes?
The others are cosmetic.
It was my understanding that they accept both versions of these arguments (tested on my versions), but I'm not sure for how long they had this behavior. I'll invert the check so that we only change the behavior for the newer rsyncs. |
Users are allowed to anytime download the latest version of bash-completion from GitHub independently of the OS distributions.
Ubuntu LTS 18.04 will soon expire, but LTS 20.04 (with rsync 3.1.3) will still continue to be maintained until 2025-04. That's the idea of LTS. Also, we perform CI tests under Debian 10 (w/ rsync 3.1.3), CentOS 7 (w/ rsync 3.1.2), and Ubuntu 14.04 (w/ rsync ???). We actually support as old Bash as 4.2, (which is the reason that we have tests in Ubuntu 14.04). |
Thank you. I think that's safer for now. |
c944277
to
1d72577
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for addressing all the points. Two points are raised by shfmt of the CI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are additional suggestions/comments.
1d72577
to
e02ff4e
Compare
e02ff4e
to
03eb3ab
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments.
Also, I think at least _comp_cmd_rsync__vercomp
would deserve some tests.
completions/ssh
Outdated
@@ -434,8 +434,11 @@ _comp_cmd_scp__path_esc='[][(){}<>"'"'"',:;^&!$=?`\\|[:space:]]' | |||
# Complete remote files with ssh. If the first arg is -d, complete on dirs | |||
# only. Returns paths escaped with three backslashes. | |||
# shellcheck disable=SC2120 | |||
# @param $1 `no-overescape` if we should use 1 backslash for escaping instead of 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though I agree that the original escape seems a bit overdoing it, it is the traditional/standard one that's been there for a long time, and it is still the say ssh does it -- rsync is kind of a "guest" here. In that sense I'd prefer a more neutral variable name here.
Also, requiring a positional boolean-like parameter to have a specific value like here feels somewhat unconventional. Making it an option (i.e. dash prefixed, no value required as it's a boolean) would be more in line with rest of the codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I overlooked the fact that $1
is already used for -d
.
edit:
I think the added documentation line of @param
should be put before the shellcheck
line.
I think we should test the new behavior of scp_remote_files
too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that sense I'd prefer a more neutral variable name here.
What name would you suggest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should test the new behavior of scp_remote_files too.
How shall I approach that? It calls ssh inside to fetch completions, so simply calling the function as it is now won't work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see there's a mechanism with LIVE_HOST in test_scp, however to test remote escaping I need to know list of filenames that are present on the remote machine, and at least one of the files needs to have a space in it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should test the new behavior of scp_remote_files too.
How shall I approach that? It calls ssh inside to fetch completions, so simply calling the function as it is now won't work.
This is a good question. I confess that I haven't thought about it deeply.
Also, I haven't recognized the LIVE_HOST
approach used by test_scp.py
until now. Hmm, I'm not sure how LIVE_HOST
is set up in the repository. There doesn't seem to be a ssh config file that contains bash_completion
as a hostname:
(venv) [murase@chatoyancy 1 bash-completion]$ grep bash_completion $(git ls-files | grep config)
.pre-commit-config.yaml: files: ^(bash_completion(\.d/[^/]+\.bash)?|completions/.+|test/(config/bashrc|update-test-cmd-list)|.+\.sh(\.in)?)$
.pre-commit-config.yaml: files: ^(bash_completion(\.d/[^/]+\.bash)?|completions/.+|test/(config/bashrc|update-test-cmd-list)|.+\.sh(\.in)?)$
bash-completion-config.cmake.in:set (BASH_COMPLETION_COMPATDIR "@sysconfdir@/bash_completion.d")
doc/configuration.md:Sourced late by `bash_completion`, pretty much after everything else.
doc/configuration.md:and override ones installed by bash_completion. Defaults to
doc/configuration.md:`~/.bash_completion` if unset or null.
doc/configuration.md:### `$XDG_CONFIG_HOME/bash_completion`
doc/configuration.md:Sourced by the `bash_completion.sh` `profile.d` script. This file is
doc/configuration.md:compatibility completion files that are loaded eagerly from `bash_completion`
doc/configuration.md:use are `/etc/bash_completion.d`, and `bash_completion.d` relative to
doc/configuration.md:`bash_completion` location.
doc/configuration.md:with this pattern will not be sourced by `bash_completion` at its load time.
test/config/bashrc:# installed via the same PATH expansion in `bash_completion.have()'
test/config/bashrc:# For clean test state, avoid sourcing user's ~/.bash_completion
test/config/bashrc:export BASH_COMPLETION_COMPAT_DIR="$SRCDIRABS/../bash_completion.d"
Another way is to prepare a mock command/function named ssh
, which mimics the command results (as discussed in #573). This can be an option if we actually do not have the working LIVE_HOST
.
@scop Are there any references on what is LIVE_HOST
used in test_scp.py
and how to set it up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@scop I realise this is the current comment requested that's still blocking. However, now that the latest rsync has a bigger install base, the problem (that this PR would fix) is spreading. Would you consider merging it even without this test, to pull users out of their misery, please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@scop To summarize the conversation, the initial test followed the LIVE_HOST
approach that one of the scp
tests used. The problem was that it was non-trivial how to properly set the host for the continuous integration (CI). This has been blocking this PR for a long time. However, the existing test case turned out to be skipped in the CI. We decided to use an approach that does not require LIVE_HOST
: the one using mock functions that reproduces the fixed output of the command ssh
or rsync
.
03eb3ab
to
9022d56
Compare
Applied changes according to comments. Regarding scp_remote_files test - added tests that expect LIVE_HOST remote files to include file |
9708e3a
to
87f3e60
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for updating the PR. Here are the comments on the new part.
87f3e60
to
9fb38ca
Compare
9fb38ca
to
f1155c4
Compare
I got bitten by this problem today. Would it be possible to get this merged, please? |
f1155c4
to
a60f0b4
Compare
rebased. The test using LIVE_HOST is not fixed. |
Would it be fair to suggest that we split that specific problem with LIVE_HOST into a separate issue, as it requires a different skillset and was not introduced here? Yes it does need sorting, but since (again if I understand correctly) the LIVE_HOST was already used before, maybe it shouldn't block this PR, should it? We could skip the new test like the old one was. We could then merge this PR. |
Existing tab completions are tested using real commands. We currently do not use any mock commands for tests. See #573. |
Nice, thanks for the pointer. So introducing a mock would be a completely new approach here, bit of a scope creep 😅 How do you currently (before this PR) test the tab completion of paths? |
We can skip the new test, but that is not the problem. As I mentioned, the new behavior needs to be tested in the CI. The existing test using |
OK, now I see where you're coming from, thanks for taking the time to explain. Let me check what's the current tests are for the tab complete for paths. Do we agree that, as long as this PR does the same level of tests for tab complete of paths as there was for the old behaviour, this can be merged? |
In general, new features and behaviors should come with new tests. Speficailly for the present case, we haven't tested anything about the path completion of |
@Rogach Could you convert the test or add a new one so that it doesn't depend on edit: If you take the mock approach, for example, you can run tests in a local environment to collect pairs of a set of arguments and the corresponding output, and mock a command that reproduces the output using the recorded mapping. |
I hear you. I'm trying to be pragmatic and avoid users doing the kind of tricks referred there: https://www.reddit.com/r/pop_os/comments/124jmp1/comment/js1mdp8/ I wholeheartedly agree that more code should mean more tests. Of course, it's your project, your call, I can only advocate :) |
Fixes scop#848. If a remote machine contains a file named `a b`, completing rsync command results in `rsync remote:a\\\ b`, which results in rsync failing to find the file. This commit removes the extra slashes, and now completion results in `rsync remote:a\ b`. scp somehow accepts both variants, so this change won't break it.
c46234a
to
0abe57a
Compare
Here you go, I've figured out how to make a test with a mock function. |
I'm open to suggestions for a better commit title. How you are supposed to fit anything useful into 72 characters, anyway? |
Something like this? I'd use
edit: I changed "filenames" to "path" because it matches the name of the test function
By giving up something that is not so important. If you want to include details, you can do it in the second (or a later) paragraph (separated by an empty line). |
0abe57a
to
4da52c2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to the fix for CI, I'd suggest changing the quoting of the string literal. The current quoted string is not so special that it requires triple quotations, and we haven't used triple quotations for anything other than docstrings.
4da52c2
to
0dc2c37
Compare
0dc2c37
to
1da052f
Compare
@yedayak Could you also quickly review this PR if there aren't obvious problems you notice or points to improve? |
Thank you! |
Woot woot, thanks everyone! |
Fixes #848.
If a remote machine contains a file named
a b
, completing rsync command results inrsync remote:a\\\ b
, which results in rsync failing to find the file.This commit removes the extra slashes, and now completion results in
rsync remote:a\ b
.scp somehow accepts both variants, so this change won't break it.