Fix copying symlinks in Linux
This commit is contained in:
parent
1b6badf375
commit
f01d24f1bd
@ -112,9 +112,12 @@ def copy_direntry(entry: os.DirEntry, dst_path):
|
|||||||
copy_file(entry.path, dst_path)
|
copy_file(entry.path, dst_path)
|
||||||
|
|
||||||
src_stat = entry.stat(follow_symlinks=False)
|
src_stat = entry.stat(follow_symlinks=False)
|
||||||
os.chown(dst_path, src_stat.st_uid, src_stat.st_gid, follow_symlinks=False)
|
if not entry.is_symlink() or os.chown in os.supports_follow_symlinks:
|
||||||
os.chmod(dst_path, src_stat.st_mode, follow_symlinks=False)
|
os.chown(dst_path, src_stat.st_uid, src_stat.st_gid, follow_symlinks=False)
|
||||||
os.utime(dst_path, (src_stat.st_atime, src_stat.st_mtime), follow_symlinks=False)
|
if not entry.is_symlink() or os.chmod in os.supports_follow_symlinks:
|
||||||
|
os.chmod(dst_path, src_stat.st_mode, follow_symlinks=False)
|
||||||
|
if not entry.is_symlink() or os.utime in os.supports_follow_symlinks:
|
||||||
|
os.utime(dst_path, (src_stat.st_atime, src_stat.st_mtime), follow_symlinks=False)
|
||||||
|
|
||||||
|
|
||||||
def update_direntry(src_entry: os.DirEntry, dst_entry: os.DirEntry):
|
def update_direntry(src_entry: os.DirEntry, dst_entry: os.DirEntry):
|
||||||
|
|||||||
@ -20,17 +20,26 @@ class CommonFSTestCase(unittest.TestCase):
|
|||||||
self.tmp_dir_dst.cleanup()
|
self.tmp_dir_dst.cleanup()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_file(parent_dir, prefix=None):
|
def create_file(parent_dir: str, prefix: str = None) -> str:
|
||||||
|
"""
|
||||||
|
Create file with random name in parent_dir.
|
||||||
|
Returns absolute path to created file.
|
||||||
|
"""
|
||||||
fd, path = tempfile.mkstemp(prefix=prefix, dir=parent_dir)
|
fd, path = tempfile.mkstemp(prefix=prefix, dir=parent_dir)
|
||||||
with open(fd, "w") as f:
|
with open(fd, "w") as f:
|
||||||
f.write(string.printable)
|
f.write(string.printable)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_dir(parent_dir, prefix=None):
|
def create_dir(parent_dir: str, prefix: str = None) -> str:
|
||||||
|
"""
|
||||||
|
Create directory with random name in parent_dir.
|
||||||
|
Returns absolute path to created directory.
|
||||||
|
"""
|
||||||
return tempfile.mkdtemp(prefix=prefix, dir=parent_dir)
|
return tempfile.mkdtemp(prefix=prefix, dir=parent_dir)
|
||||||
|
|
||||||
def relpath(self, full_path):
|
def relpath(self, full_path: str) -> str:
|
||||||
|
""" Get relative path for entity in src/dst dirs. """
|
||||||
if full_path.startswith(self.src_dir):
|
if full_path.startswith(self.src_dir):
|
||||||
p_dir = self.src_dir
|
p_dir = self.src_dir
|
||||||
elif full_path.startswith(self.dst_dir):
|
elif full_path.startswith(self.dst_dir):
|
||||||
@ -118,7 +127,8 @@ class TestHardlinkDir(CommonFSTestCase):
|
|||||||
# TODO not finished
|
# TODO not finished
|
||||||
class TestRsync(CommonFSTestCase):
|
class TestRsync(CommonFSTestCase):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_identical_file(file1, file2):
|
def check_identical_file(file1: str, file2: str):
|
||||||
|
""" Check that files are identical. Fails test, if not. """
|
||||||
st1 = os.lstat(file1)
|
st1 = os.lstat(file1)
|
||||||
st2 = os.lstat(file2)
|
st2 = os.lstat(file2)
|
||||||
|
|
||||||
@ -135,7 +145,7 @@ class TestRsync(CommonFSTestCase):
|
|||||||
assert not os.path.lexists(dst_fpath)
|
assert not os.path.lexists(dst_fpath)
|
||||||
|
|
||||||
def test_dst_has_excess_symlink(self):
|
def test_dst_has_excess_symlink(self):
|
||||||
dst_lpath = os.path.join(self.dst_dir, 'broken_symlink')
|
dst_lpath = os.path.join(self.dst_dir, 'nonexisting_file')
|
||||||
os.symlink('broken_symlink', dst_lpath)
|
os.symlink('broken_symlink', dst_lpath)
|
||||||
|
|
||||||
fs.rsync(self.src_dir, self.dst_dir)
|
fs.rsync(self.src_dir, self.dst_dir)
|
||||||
@ -239,3 +249,8 @@ class TestRsync(CommonFSTestCase):
|
|||||||
fs.rsync(self.src_dir, self.dst_dir)
|
fs.rsync(self.src_dir, self.dst_dir)
|
||||||
assert os.path.lexists(dst_fpath)
|
assert os.path.lexists(dst_fpath)
|
||||||
self.check_identical_file(src_fpath, dst_fpath)
|
self.check_identical_file(src_fpath, dst_fpath)
|
||||||
|
|
||||||
|
# TODO add tests for changing ownership
|
||||||
|
# TODO add tests for changing permissions
|
||||||
|
# TODO add tests for changing times (?)
|
||||||
|
# TODO add tests for symlink behaviour
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user