Skip to content

path fixing when copying folders from windows #88

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

Merged
merged 6 commits into from
Sep 27, 2017

Conversation

moscoquera
Copy link
Contributor

as window's file separator is '', when copying folders from windows the destination path get malformed, replacing '' with '/' is enough to solve it.

as window's file separator is '\', when copying folders from windows the destination path get malformed, replacing '\' with '/' is enough to solve it.
@pkittenis
Copy link
Member

Hi there, thanks for the PR.

If I understand correctly, os.path.sep is \ on Windows but SFTP file paths always use /, therefore file copy with directory paths breaks on Windows?

In that case it would be more appropriate to not use os.path in the first place and always use / instead as that's what the protocol uses.

@moscoquera
Copy link
Contributor Author

Hi.

imagine a windows folder called parent and with 2 files inside called childrenA.txt and childrenB.txt:

  • parent:
    childrenA.txt
    childrenB.txt

to access them python will use "parent\childrenA.txt" and "parent\childrenB.txt", if you are trying to copy parent to a remote sever, you will get 3 files:

  • a folder called "parent".
  • an two files called "parent\childrenA.txt" and "parent\childrenB.txt"

when the expected behavior will be a single folder called "parent" with 2 files inside.

@pkittenis
Copy link
Member

Yes, I understand.

The change needed here is for remote_path (only remote path) to always use / for joining. Ie remote_path = '/'.join([remote_dir, file_name]) in both copy_file and copy_remote_file.

Replacing os.path, which is \ on Windows, with / after the path is generated does not make much sense. So if you'd like to make that change, I'd be happy to review it.

when copying files from or to a windows device,  sub-directories structure is not being to be correctly replicated as linux doesn't use '\' as file separator. forcing the remote path to use '/' guarantees the paths are correctly replicated.
@coveralls
Copy link

coveralls commented Sep 19, 2017

Coverage Status

Coverage remained the same at 88.914% when pulling a310fef on moscoquera:master into b53799d on ParallelSSH:master.

@moscoquera
Copy link
Contributor Author

Hi again. sorry for the very late response, i have been busy upgrading a project. i just did the requested changes.

i'd be happy if u can review it.

@coveralls
Copy link

coveralls commented Sep 19, 2017

Coverage Status

Coverage decreased (-3.2%) to 89.367% when pulling 008a45a on moscoquera:master into 52e7974 on ParallelSSH:master.

Copy link
Member

@pkittenis pkittenis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries, thanks for looking into this!

Reviewed, comments in line.

@@ -364,7 +364,7 @@ def _copy_dir(self, local_dir, remote_dir, sftp):
file_list = os.listdir(local_dir)
for file_name in file_list:
local_path = os.path.join(local_dir, file_name)
remote_path = os.path.join(remote_dir, file_name)
remote_path = remote_dir+'/'+file_name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is better written as '/'.join([remote_dir, file_name]).

String concatenation creates new strings on every operation (2 temporary + 1 final in the above case), which is a lot slower than a single join call. This is done for every sub-dir and for every client in host list, so adds up quickly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but, isn't it creating a new array each time?

@@ -455,7 +455,7 @@ def copy_remote_file(self, remote_file, local_file, recurse=False,
def _copy_remote_dir(self, file_list, remote_dir, local_dir, sftp):
for file_name in file_list:
remote_path = os.path.join(remote_dir, file_name)
local_path = os.path.join(local_dir, file_name)
local_path = local_dir+'/'+file_name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remote_path needs changing here, not local_path (local_path is local to client and platform specific). Looking at paramiko source confirms this.

Also same comment as above about '/'.join.

replacing + on string concatenation by join.
@moscoquera
Copy link
Contributor Author

changes are made

@@ -364,7 +364,7 @@ def _copy_dir(self, local_dir, remote_dir, sftp):
file_list = os.listdir(local_dir)
for file_name in file_list:
local_path = os.path.join(local_dir, file_name)
remote_path = os.path.join(remote_dir, file_name)
remote_path = '/'.join([remote_dir,file_name])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flake errors: pssh/ssh_client.py:367:47: E231 missing whitespace after ','

Per https://travis-ci.org/ParallelSSH/parallel-ssh/jobs/279101695

remote_path = os.path.join(remote_dir, file_name)
local_path = os.path.join(local_dir, file_name)
remote_path = '/'.join([remote_dir, file_name])
local_path = os.path.join(local_dir,file_name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pkittenis
Copy link
Member

Thanks, changes look good. Only couple minor changes needed for the flake check to pass, see in line comments and CI job, looks ready otherwise.

Thanks again for the PR.

@coveralls
Copy link

coveralls commented Sep 26, 2017

Coverage Status

Coverage increased (+0.7%) to 89.593% when pulling ba641ec on moscoquera:master into b366c60 on ParallelSSH:master.

@coveralls
Copy link

coveralls commented Sep 26, 2017

Coverage Status

Coverage increased (+0.5%) to 89.367% when pulling ba641ec on moscoquera:master into b366c60 on ParallelSSH:master.

@moscoquera
Copy link
Contributor Author

sure, no problem.

@pkittenis pkittenis merged commit 011dd0f into ParallelSSH:master Sep 27, 2017
@pkittenis
Copy link
Member

Thanks for making these changes :)

FYI, have found a couple more places where remote path needs changing for windows which are used when recurse is enabled. Those changes, along with this fix, will be in next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants