Coverage for gsb/export.py: 100%
13 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-08 20:16 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-08 20:16 +0000
1"""Functionality for creating standalone backups"""
3import os
4from pathlib import Path
6import pathvalidate
8from . import _git
9from .manifest import Manifest
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
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.
28 Returns
29 -------
30 str
31 A (hopefully) descriptive archive filename, including a format-specifying
32 extension
34 Notes
35 -----
36 The default choice of extension (and thus format) is:
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}")
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
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.
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 )
81 _git.archive(repo_root, archive_path, revision)