python (3.12.0)
1 import pathlib
2 import functools
3
4 from typing import Dict, Union
5
6
7 ####
8 # from jaraco.path 3.4.1
9
10 FilesSpec = Dict[str, Union[str, bytes, 'FilesSpec']] # type: ignore
11
12
13 def build(spec: FilesSpec, prefix=pathlib.Path()):
14 """
15 Build a set of files/directories, as described by the spec.
16
17 Each key represents a pathname, and the value represents
18 the content. Content may be a nested directory.
19
20 >>> spec = {
21 ... 'README.txt': "A README file",
22 ... "foo": {
23 ... "__init__.py": "",
24 ... "bar": {
25 ... "__init__.py": "",
26 ... },
27 ... "baz.py": "# Some code",
28 ... }
29 ... }
30 >>> target = getfixture('tmp_path')
31 >>> build(spec, target)
32 >>> target.joinpath('foo/baz.py').read_text(encoding='utf-8')
33 '# Some code'
34 """
35 for name, contents in spec.items():
36 create(contents, pathlib.Path(prefix) / name)
37
38
39 @functools.singledispatch
40 def create(content: Union[str, bytes, FilesSpec], path):
41 path.mkdir(exist_ok=True)
42 build(content, prefix=path) # type: ignore
43
44
45 @create.register
46 def _(content: bytes, path):
47 path.write_bytes(content)
48
49
50 @create.register
51 def _(content: str, path):
52 path.write_text(content, encoding='utf-8')
53
54
55 # end from jaraco.path
56 ####