Coverage for sparkle/CLI/help/snapshot_help.py: 85%

60 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-09-29 10:17 +0000

1#!/usr/bin/env python3 

2# -*- coding: UTF-8 -*- 

3"""Helper functions to record and restore a Sparkle platform.""" 

4 

5import shutil 

6import sys 

7import os 

8import time 

9from pathlib import Path 

10import zipfile 

11 

12from sparkle.CLI.help import global_variables as gv 

13from sparkle.tools.general import get_time_pid_random_string 

14from sparkle.platform import Settings 

15 

16 

17def save_current_platform(name: str = None) -> None: 

18 """Store the current Sparkle platform in a .zip file.""" 

19 if name is None: 

20 time_stamp = time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime(time.time())) 

21 try: 

22 login = os.getlogin() 

23 except Exception: # Can fail on for example CI pipelines 

24 login = "unknown" 

25 name = f"Snapshot_{login}_{time_stamp}" 

26 snapshot_tmp_path = gv.settings().DEFAULT_snapshot_dir / name 

27 snapshot_tmp_path.mkdir(parents=True) # Create temporary directory for zip 

28 available_dirs = [p.name for p in Path.cwd().iterdir()] 

29 root_working_dirs = [ 

30 p for p in gv.settings().DEFAULT_working_dirs if p.name in available_dirs 

31 ] 

32 for working_dir in root_working_dirs: 

33 if working_dir.exists(): 

34 shutil.copytree(working_dir, snapshot_tmp_path / working_dir.name) 

35 shutil.make_archive(snapshot_tmp_path, "zip", snapshot_tmp_path) 

36 shutil.rmtree(snapshot_tmp_path) 

37 print(f"Snapshot file {snapshot_tmp_path}.zip saved successfully!") 

38 

39 

40def remove_current_platform(filter: list[Path] = None) -> None: 

41 """Remove the current Sparkle platform.""" 

42 filter = [] if filter is None else filter 

43 for working_dir in gv.settings().DEFAULT_working_dirs: 

44 if working_dir not in filter: 

45 shutil.rmtree(working_dir, ignore_errors=True) 

46 Settings.DEFAULT_previous_settings_path.unlink(missing_ok=True) 

47 

48 

49def create_working_dirs() -> None: 

50 """Create working directories.""" 

51 for working_dir in gv.settings().DEFAULT_working_dirs: 

52 working_dir.mkdir(parents=True, exist_ok=True) 

53 

54 

55def extract_snapshot(snapshot_file: Path) -> None: 

56 """Restore a Sparkle platform from a snapshot. 

57 

58 Args: 

59 snapshot_file: Path to the where the current Sparkle platform should be stored. 

60 """ 

61 tmp_directory = Path(f"tmp_directory_{get_time_pid_random_string()}") 

62 gv.settings().DEFAULT_tmp_output.mkdir(exist_ok=True) 

63 with zipfile.ZipFile(snapshot_file, "r") as zip_ref: 

64 zip_ref.extractall(tmp_directory) 

65 shutil.copytree(tmp_directory, "./", dirs_exist_ok=True) 

66 shutil.rmtree(tmp_directory) 

67 

68 

69def load_snapshot(snapshot_file: Path) -> None: 

70 """Load a Sparkle platform from a snapshot. 

71 

72 Args: 

73 snapshot_file: File path to the file where the Sparkle platform is stored. 

74 """ 

75 if not snapshot_file.exists(): 

76 print(f"ERROR: Snapshot file {snapshot_file} does not exist!") 

77 sys.exit(-1) 

78 if not snapshot_file.suffix == ".zip": 

79 print(f"ERROR: File {snapshot_file} is not a .zip file!") 

80 sys.exit(-1) 

81 print("Cleaning existing Sparkle platform ...") 

82 remove_current_platform() 

83 print("Existing Sparkle platform cleaned!") 

84 

85 print(f"Loading snapshot file {snapshot_file} ...") 

86 extract_snapshot(snapshot_file) 

87 if any([not wd.exists() for wd in gv.settings().DEFAULT_working_dirs]): 

88 missing_dirs = [ 

89 wd.name for wd in gv.settings().DEFAULT_working_dirs if not wd.exists() 

90 ] 

91 print( 

92 "ERROR: Failed to load Sparkle platform! The snapshot file may be outdated" 

93 " or corrupted. Missing the following directories: " 

94 f"{', '.join(missing_dirs)}" 

95 ) 

96 sys.exit(-1) 

97 print(f"Snapshot file {snapshot_file} loaded successfully!")