Coverage for gsb/export.py: 100%

13 statements  

« prev     ^ index     » next       coverage.py v7.2.6, created at 2024-09-08 16:23 -0400

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

2import os 

3from pathlib import Path 

4 

5import pathvalidate 

6 

7from . import _git 

8from .manifest import Manifest 

9 

10 

11def generate_archive_name( 

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

13) -> str: 

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

15 

16 Parameters 

17 ---------- 

18 repo_name : str 

19 The alias assigned to the GSB-managed repo 

20 revision : str 

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

22 extension : str, optional 

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

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

25 operating system. 

26 

27 Returns 

28 ------- 

29 str 

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

31 extension 

32 

33 Notes 

34 ----- 

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

36 

37 - zip for Windows 

38 - tar.gz for all other systems 

39 """ 

40 if extension is None: 

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

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

43 

44 

45def export_backup( 

46 repo_root: Path, 

47 revision: str, 

48 archive_path: Path | None = None, 

49) -> None: 

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

51 

52 Parameters 

53 ---------- 

54 repo_root : Path 

55 The directory containing the GSB-managed repo 

56 revision : str 

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

58 archive_path : Path, optional 

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

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

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

62 specified revision. 

63 

64 Raises 

65 ------ 

66 OSError 

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

68 ValueError 

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

70 does not have a valid extension 

71 NotImplementedError 

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

73 supported 

74 """ 

75 if archive_path is None: 

76 archive_path = Path( 

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

78 ) 

79 

80 _git.archive(repo_root, archive_path, revision)