Coverage for src / moai_adk / core / project / backup_utils.py: 31.58%

19 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-11-20 20:52 +0900

1"""Backup utility module (SPEC-INIT-003 v0.3.0) 

2 

3Selective backup strategy: 

4- Back up only the required files (OR condition) 

5- Backup path: .moai-backups/backup/ (v0.4.2) 

6""" 

7 

8from pathlib import Path 

9 

10# Backup targets (OR condition - back up when any exist) 

11BACKUP_TARGETS = [ 

12 ".moai/config/config.json", 

13 ".moai/project/", 

14 ".moai/memory/", 

15 ".claude/", 

16 ".github/", 

17 "CLAUDE.md", 

18] 

19 

20# User data protection paths (excluded from backups) 

21PROTECTED_PATHS = [ 

22 ".moai/specs/", 

23 ".moai/reports/", 

24] 

25 

26 

27def has_any_moai_files(project_path: Path) -> bool: 

28 """Check whether any MoAI-ADK files exist (OR condition). 

29 

30 Args: 

31 project_path: Project path. 

32 

33 Returns: 

34 True when any backup target exists. 

35 """ 

36 for target in BACKUP_TARGETS: 

37 target_path = project_path / target 

38 if target_path.exists(): 

39 return True 

40 return False 

41 

42 

43def get_backup_targets(project_path: Path) -> list[str]: 

44 """Return existing backup targets. 

45 

46 Args: 

47 project_path: Project path. 

48 

49 Returns: 

50 List of backup targets that exist. 

51 """ 

52 targets: list[str] = [] 

53 for target in BACKUP_TARGETS: 

54 target_path = project_path / target 

55 if target_path.exists(): 

56 targets.append(target) 

57 return targets 

58 

59 

60def is_protected_path(rel_path: Path) -> bool: 

61 """Check whether the path is protected. 

62 

63 Args: 

64 rel_path: Relative path. 

65 

66 Returns: 

67 True when the path should be excluded from backups. 

68 """ 

69 rel_str = str(rel_path).replace("\\", "/") 

70 return any(rel_str.startswith(p.lstrip("./").rstrip("/")) for p in PROTECTED_PATHS)