diff --git a/src/local_ops.py b/src/local_ops.py index bda76ac..7d3d440 100644 --- a/src/local_ops.py +++ b/src/local_ops.py @@ -504,8 +504,11 @@ def mkstemp(self, prefix=None): os.close(fd) # Close the file descriptor immediately after creating the file return filename - def copytree(self, src, dst): - return shutil.copytree(src, dst) + def copytree(self, src: str, dst: str) -> str: + assert type(src) is str + assert type(dst) is str + shutil.copytree(src, dst) + return dst # Work with files def write( diff --git a/src/os_ops.py b/src/os_ops.py index fe2a6dc..dc41e3b 100644 --- a/src/os_ops.py +++ b/src/os_ops.py @@ -196,7 +196,9 @@ def mkdtemp(self, prefix=None): def mkstemp(self, prefix=None): raise NotImplementedError() - def copytree(self, src, dst): + def copytree(self, src: str, dst: str) -> str: + assert type(src) is str + assert type(dst) is str raise NotImplementedError() # Work with files diff --git a/src/remote_ops.py b/src/remote_ops.py index 18e197c..3a59bf4 100644 --- a/src/remote_ops.py +++ b/src/remote_ops.py @@ -666,22 +666,21 @@ def mkstemp(self, prefix=None): temp_file = exec_output.strip() return temp_file - def copytree(self, src, dst): + def copytree(self, src: str, dst: str) -> str: assert type(src) is str assert type(dst) is str - if __class__._is_abs_path(dst): - # WTF? - dst = __class__._build_path('~', dst) + abs_dst = self.get_abs_path(dst) if self.isdir(dst): raise FileExistsError("Directory {} already exists.".format(dst)) cmd = "cp -r {} {}".format( __class__._quote_path(src), - __class__._quote_path(dst), + __class__._quote_path(abs_dst), ) - return self.exec_command(cmd) + self.exec_command(cmd, encoding=get_default_encoding()) + return dst # Work with files def write( diff --git a/tests/test_os_ops_common.py b/tests/test_os_ops_common.py index 0312569..ec2654d 100644 --- a/tests/test_os_ops_common.py +++ b/tests/test_os_ops_common.py @@ -3215,7 +3215,8 @@ def test_copytree__empty( dst = os_ops.build_path(tmpdir, "dst") os_ops.makedir(src) - os_ops.copytree(src, dst) + copytree_r = os_ops.copytree(src, dst) + assert copytree_r == dst assert os_ops.path_exists(src) assert os_ops.path_exists(dst) @@ -3224,6 +3225,40 @@ def test_copytree__empty( assert not os_ops.path_exists(tmpdir) return + def test_copytree__empty__relative( + self, + os_ops_descr: OsOpsDescr, + name_with_surprize: tagNameWithSurprize, + ): + assert type(os_ops_descr) is OsOpsDescr + assert type(name_with_surprize) is __class__.tagNameWithSurprize + os_ops = os_ops_descr.os_ops + assert isinstance(os_ops, OsOperations) + + cwd = os_ops.cwd() + + tmpdir = os_ops.mkdtemp(name_with_surprize.value) + + src = os_ops.build_path(tmpdir, "src") + dst = "copytree--" + uuid.uuid4().bytes.hex() + + dst_a = os_ops.build_path(cwd, dst) + + os_ops.makedir(src) + copytree_r = os_ops.copytree(src, dst) + assert copytree_r == dst + + assert os_ops.path_exists(src) + assert os_ops.path_exists(dst) + assert os_ops.path_exists(dst_a) + + os_ops.rmdirs(dst) + assert not os_ops.path_exists(dst) + + os_ops.rmdirs(tmpdir) + assert not os_ops.path_exists(tmpdir) + return + def test_copytree__with_content( self, os_ops_descr: OsOpsDescr, @@ -3248,10 +3283,58 @@ def test_copytree__with_content( src_dir1_file2 = os_ops.build_path(src_dir1, "file2") os_ops.write(src_dir1_file2, "cba") - os_ops.copytree(src, dst) + copytree_r = os_ops.copytree(src, dst) + assert copytree_r == dst + + assert os_ops.path_exists(src) + assert os_ops.path_exists(dst) + + dst_file1 = os_ops.build_path(dst, "file1.dat") + assert os_ops.read(dst_file1, binary=False) == "abc" + dst_dir1 = os_ops.build_path(dst, "dir1") + assert os_ops.path_exists(dst_dir1) + dst_dir1_file2 = os_ops.build_path(dst_dir1, "file2") + assert os_ops.path_exists(dst_dir1_file2) + assert os_ops.read(dst_dir1_file2, binary=False) == "cba" + + os_ops.rmdirs(tmpdir) + assert not os_ops.path_exists(tmpdir) + return + + def test_copytree__with_content__relative( + self, + os_ops_descr: OsOpsDescr, + name_with_surprize: tagNameWithSurprize, + ): + assert type(os_ops_descr) is OsOpsDescr + assert type(name_with_surprize) is __class__.tagNameWithSurprize + os_ops = os_ops_descr.os_ops + assert isinstance(os_ops, OsOperations) + + cwd = os_ops.cwd() + + tmpdir = os_ops.mkdtemp(name_with_surprize.value) + + src = os_ops.build_path(tmpdir, "src") + dst = "copytree--" + uuid.uuid4().bytes.hex() + + dst_a = os_ops.build_path(cwd, dst) + + os_ops.makedir(src) + + src_file1 = os_ops.build_path(src, "file1.dat") + os_ops.write(src_file1, "abc") + src_dir1 = os_ops.build_path(src, "dir1") + os_ops.makedir(src_dir1) + src_dir1_file2 = os_ops.build_path(src_dir1, "file2") + os_ops.write(src_dir1_file2, "cba") + + copytree_r = os_ops.copytree(src, dst) + assert copytree_r == dst assert os_ops.path_exists(src) assert os_ops.path_exists(dst) + assert os_ops.path_exists(dst_a) dst_file1 = os_ops.build_path(dst, "file1.dat") assert os_ops.read(dst_file1, binary=False) == "abc"