Coverage for gsb/export.py: 100%

13 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-09-08 20:16 +0000

1"""Functionality for creating standalone backups""" 

2 

3import os 

4from pathlib import Path 

5 

6import pathvalidate 

7 

8from . import _git 

9from .manifest import Manifest 

10 

11 

12def generate_archive_name( 

13 repo_name: str, revision: str, extension: str | None = None 

14) -> str: 

15 """Programmatically generate a name for an archived backup 

16 

17 Parameters 

18 ---------- 

19 repo_name : str 

20 The alias assigned to the GSB-managed repo 

21 revision : str 

22 The commit hash or tag name of the backup that's being archived 

23 extension : str, optional 

24 The file extension for the archive (thus specifying the archive's format). 

25 If None is provided, an appropriate one will be chosen based on the 

26 operating system. 

27 

28 Returns 

29 ------- 

30 str 

31 A (hopefully) descriptive archive filename, including a format-specifying 

32 extension 

33 

34 Notes 

35 ----- 

36 The default choice of extension (and thus format) is: 

37 

38 - zip for Windows 

39 - tar.gz for all other systems 

40 """ 

41 if extension is None: 

42 extension = "zip" if os.name == "nt" else "tar.gz" 

43 return pathvalidate.sanitize_filename(f"{repo_name}_{revision}.{extension}") 

44 

45 

46def export_backup( 

47 repo_root: Path, 

48 revision: str, 

49 archive_path: Path | None = None, 

50) -> None: 

51 """Export a backup to a stand-alone archive 

52 

53 Parameters 

54 ---------- 

55 repo_root : Path 

56 The directory containing the GSB-managed repo 

57 revision : str 

58 The commit hash or tag name of the backup to archive 

59 archive_path : Path, optional 

60 The full path to save the archive, including the filename and the 

61 extension. If None is provided, one will be automatically generated 

62 in the current working directory based on the repo's name and the 

63 specified revision. 

64 

65 Raises 

66 ------ 

67 OSError 

68 If the specified repo does not exist or is not a GSB-managed repo 

69 ValueError 

70 If the specified revision does not exist or if the given `archive_path` 

71 does not have a valid extension 

72 NotImplementedError 

73 If the compression schema implied by the `archive_path`'s extension is not 

74 supported 

75 """ 

76 if archive_path is None: 

77 archive_path = Path( 

78 generate_archive_name(Manifest.of(repo_root).name, revision) 

79 ) 

80 

81 _git.archive(repo_root, archive_path, revision)