Coverage for gsb/export.py: 100%
13 statements
« prev ^ index » next coverage.py v7.2.6, created at 2024-09-08 16:23 -0400
« 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
5import pathvalidate
7from . import _git
8from .manifest import Manifest
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
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.
27 Returns
28 -------
29 str
30 A (hopefully) descriptive archive filename, including a format-specifying
31 extension
33 Notes
34 -----
35 The default choice of extension (and thus format) is:
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}")
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
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.
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 )
80 _git.archive(repo_root, archive_path, revision)