Coverage for tarjinja/dirtree.py: 92%

50 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-09-05 14:24 +0000

1# copy directory 

2import os 

3import time 

4from collections.abc import Generator 

5from logging import getLogger 

6 

7from .iface import Input, Output 

8 

9log = getLogger(__name__) 

10 

11 

12class DirInput(Input): 

13 def walk(self) -> Generator[tuple[str, int, float], None, None]: 

14 for root, dirs, files in os.walk(self.ifn): 

15 relpath = os.path.relpath(root, self.ifn) 

16 if relpath == ".": 

17 relpath = "" 

18 for fn in sorted(files): 

19 fromfn = os.path.join(root, fn) 

20 st = os.stat(fromfn) 

21 mode = st.st_mode 

22 yield os.path.join(relpath, fn), mode, st.st_mtime 

23 

24 def readfile(self, fn: str) -> str: 

25 with open(os.path.join(self.ifn, fn)) as ifp: 

26 return ifp.read() 

27 

28 

29class SingleInput(Input): 

30 def walk(self) -> Generator[tuple[str, int, float], None, None]: 

31 st = os.stat(self.ifn) 

32 yield os.path.basename(self.ifn), st.st_mode, st.st_mtime 

33 

34 def readfile(self, fn: str) -> str: 

35 with open(self.ifn) as ifp: 

36 return ifp.read() 

37 

38 

39class DirOutput(Output): 

40 def __init__(self, ofn: str): 

41 super().__init__(ofn) 

42 self.ofn = os.path.abspath(self.ofn) 

43 log.debug("ofn is %s -> %s", ofn, self.ofn) 

44 

45 def writefile(self, fn: str, content: str, mode: int, ts: float | None = None): 

46 fname = os.path.join(self.ofn, fn) 

47 if not os.path.abspath(fname).startswith(self.ofn): 47 ↛ 48line 47 didn't jump to line 48 because the condition on line 47 was never true

48 log.warning("%s is not in %s", fname, self.ofn) 

49 return 

50 dirname = os.path.dirname(fname) 

51 os.makedirs(dirname, exist_ok=True) 

52 with open(fname, "w") as ofp: 

53 ofp.write(content) 

54 os.chmod(fname, mode) 

55 if ts is not None: 55 ↛ exitline 55 didn't return from function 'writefile' because the condition on line 55 was always true

56 os.utime(fname, (ts, ts)) 

57 

58 

59class ListOutput(Output): 

60 def writefile(self, fn: str, content: str, mode: int, ts: float | None = None): 

61 tsstr = "YYYY-mm-dd HH:MM" 

62 if ts is not None: 62 ↛ 64line 62 didn't jump to line 64 because the condition on line 62 was always true

63 tsstr = time.strftime("%Y-%m-%d %H:%M", time.localtime(ts)) 

64 print(f"{mode:o} {len(content)} {tsstr} {fn}")