Skip to content

Commit 4ab5f3b

Browse files
Thom1729FichteFoll
authored andcommitted
Added ResourcePath.copytree (#106)
1 parent 340fc36 commit 4ab5f3b

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

st3/sublime_lib/resource_path.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import posixpath
44
from collections import OrderedDict
5+
import os
56

67
from .vendor.pathlib.pathlib import Path
78
from ._util.glob import get_glob_matcher
@@ -432,6 +433,7 @@ def copy(self, target, exist_ok=True):
432433
and `exist_ok` is ``True`` (the default),
433434
it will be silently replaced.
434435
436+
:raise FileNotFoundError: if there is no resource at this path.
435437
:raise IsADirectoryError: if `target` is a directory.
436438
:raise FileExistsError: if `target` is a file and `exist_ok` is ``False``.
437439
"""
@@ -443,3 +445,25 @@ def copy(self, target, exist_ok=True):
443445
data = self.read_bytes()
444446
with open(str(target), mode + 'b') as file:
445447
file.write(data)
448+
449+
def copytree(self, target, exist_ok=False):
450+
"""
451+
Copy all resources beneath this path into a directory tree rooted at `target`.
452+
453+
All missing parent directories of `target` will be created.
454+
455+
If `exist_ok` is ``False`` (the default),
456+
then `target` must not already exist.
457+
If `exist_ok` is ``True``,
458+
then existing files under `target` will be overwritten.
459+
460+
:raise FileExistsError: if `target` already exists and `exist_ok` is ``False``.
461+
"""
462+
target = Path(target)
463+
464+
os.makedirs(str(target), exist_ok=exist_ok)
465+
466+
for resource in self.rglob('*'):
467+
file_path = target.joinpath(*resource.relative_to(self))
468+
os.makedirs(str(file_path.parent), exist_ok=True)
469+
resource.copy(file_path)

tests/test_resource_path.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,64 @@ def test_copy_directory_error(self):
247247
source.copy(destination)
248248

249249
self.assertTrue(destination.is_dir())
250+
251+
def test_copytree(self):
252+
with tempfile.TemporaryDirectory() as directory:
253+
source = ResourcePath("Packages/test_package")
254+
destination = Path(directory) / 'tree'
255+
256+
source.copytree(destination)
257+
258+
self.assertEqual(
259+
{
260+
path.relative_to(destination).parts
261+
for path in destination.rglob('*')
262+
if path.is_file()
263+
},
264+
{
265+
path.relative_to(source)
266+
for path in source.rglob('*')
267+
}
268+
)
269+
270+
def test_copytree_exists_error(self):
271+
with tempfile.TemporaryDirectory() as directory:
272+
source = ResourcePath("Packages/test_package")
273+
destination = Path(directory) / 'tree'
274+
destination.mkdir()
275+
276+
with self.assertRaises(FileExistsError):
277+
source.copytree(destination)
278+
279+
def test_copytree_exists(self):
280+
with tempfile.TemporaryDirectory() as directory:
281+
source = ResourcePath("Packages/test_package")
282+
destination = Path(directory) / 'tree'
283+
destination.mkdir()
284+
285+
helloworld_file = destination / 'helloworld.txt'
286+
287+
with open(str(helloworld_file), 'w') as file:
288+
file.write("Nothing to see here.\n")
289+
290+
source.copytree(destination, exist_ok=True)
291+
292+
self.assertEqual(
293+
{
294+
path.relative_to(destination).parts
295+
for path in destination.rglob('*')
296+
if path.is_file()
297+
},
298+
{
299+
path.relative_to(source)
300+
for path in source.rglob('*')
301+
}
302+
)
303+
304+
with open(str(helloworld_file)) as file:
305+
helloworld_contents = file.read()
306+
307+
self.assertEqual(
308+
helloworld_contents,
309+
(source / 'helloworld.txt').read_text()
310+
)

0 commit comments

Comments
 (0)