Pārlūkot izejas kodu

move delete command to archiver.delete

Thomas Waldmann 2 gadi atpakaļ
vecāks
revīzija
350a8fe252
3 mainītis faili ar 169 papildinājumiem un 148 dzēšanām
  1. 1 0
      setup.cfg
  2. 5 148
      src/borg/archiver/__init__.py
  3. 163 0
      src/borg/archiver/delete.py

+ 1 - 0
setup.cfg

@@ -121,6 +121,7 @@ per_file_ignores =
     src/borg/archiver/config.py:F405,E722
     src/borg/archiver/common.py:E501,F405
     src/borg/archiver/debug.py:F405
+    src/borg/archiver/delete.py:F405
     src/borg/archiver/diff.py:F405
     src/borg/archiver/help.py:E501,F405
     src/borg/archiver/keys.py:F405

+ 5 - 148
src/borg/archiver/__init__.py

@@ -28,7 +28,7 @@ try:
     from .common import with_repository, with_archive, Highlander
     from .. import __version__
     from .. import helpers
-    from ..archive import Archive, ArchiveRecreater, Statistics, is_special
+    from ..archive import Archive, ArchiveRecreater, is_special
     from ..archive import BackupError, BackupOSError, backup_io, OsOpen, stat_update_check
     from ..archive import FilesystemObjectProcessors, MetadataCollector, ChunksProcessor
     from ..cache import Cache
@@ -39,7 +39,7 @@ try:
     from ..helpers import location_validator, archivename_validator, ChunkerParams, Location
     from ..helpers import NameSpec, CommentSpec, FilesCacheMode
     from ..helpers import BaseFormatter, ItemFormatter, ArchiveFormatter
-    from ..helpers import format_timedelta, format_file_size, format_archive
+    from ..helpers import format_timedelta, format_file_size
     from ..helpers import remove_surrogates, bin_to_hex, eval_escapes
     from ..helpers import timestamp
     from ..helpers import get_cache_dir, os_stat
@@ -93,6 +93,7 @@ from .check import CheckMixIn
 from .compact import CompactMixIn
 from .config import ConfigMixIn
 from .debug import DebugMixIn
+from .delete import DeleteMixIn
 from .diff import DiffMixIn
 from .help import HelpMixIn
 from .keys import KeysMixIn
@@ -112,6 +113,7 @@ class Archiver(
     ConfigMixIn,
     CompactMixIn,
     DebugMixIn,
+    DeleteMixIn,
     DiffMixIn,
     TarMixIn,
     BenchmarkMixIn,
@@ -697,83 +699,6 @@ class Archiver(
             pi.finish()
         return self.exit_code
 
-    @with_repository(exclusive=True, manifest=False)
-    def do_delete(self, args, repository):
-        """Delete archives"""
-        self.output_list = args.output_list
-        dry_run = args.dry_run
-        manifest, key = Manifest.load(repository, (Manifest.Operation.DELETE,))
-        archive_names = tuple(x.name for x in manifest.archives.list_considering(args))
-        if not archive_names:
-            return self.exit_code
-        if args.glob_archives is None and args.first == 0 and args.last == 0:
-            self.print_error(
-                "Aborting: if you really want to delete all archives, please use -a '*' "
-                "or just delete the whole repository (might be much faster)."
-            )
-            return EXIT_ERROR
-
-        if args.forced == 2:
-            deleted = False
-            logger_list = logging.getLogger("borg.output.list")
-            for i, archive_name in enumerate(archive_names, 1):
-                try:
-                    current_archive = manifest.archives.pop(archive_name)
-                except KeyError:
-                    self.exit_code = EXIT_WARNING
-                    logger.warning(f"Archive {archive_name} not found ({i}/{len(archive_names)}).")
-                else:
-                    deleted = True
-                    if self.output_list:
-                        msg = "Would delete: {} ({}/{})" if dry_run else "Deleted archive: {} ({}/{})"
-                        logger_list.info(msg.format(format_archive(current_archive), i, len(archive_names)))
-            if dry_run:
-                logger.info("Finished dry-run.")
-            elif deleted:
-                manifest.write()
-                # note: might crash in compact() after committing the repo
-                repository.commit(compact=False)
-                logger.warning('Done. Run "borg check --repair" to clean up the mess.')
-            else:
-                logger.warning("Aborted.")
-            return self.exit_code
-
-        stats = Statistics(iec=args.iec)
-        with Cache(repository, key, manifest, progress=args.progress, lock_wait=self.lock_wait, iec=args.iec) as cache:
-            msg_delete = "Would delete archive: {} ({}/{})" if dry_run else "Deleting archive: {} ({}/{})"
-            msg_not_found = "Archive {} not found ({}/{})."
-            logger_list = logging.getLogger("borg.output.list")
-            delete_count = 0
-            for i, archive_name in enumerate(archive_names, 1):
-                try:
-                    archive_info = manifest.archives[archive_name]
-                except KeyError:
-                    logger.warning(msg_not_found.format(archive_name, i, len(archive_names)))
-                else:
-                    if self.output_list:
-                        logger_list.info(msg_delete.format(format_archive(archive_info), i, len(archive_names)))
-
-                    if not dry_run:
-                        archive = Archive(
-                            repository,
-                            key,
-                            manifest,
-                            archive_name,
-                            cache=cache,
-                            consider_part_files=args.consider_part_files,
-                        )
-                        archive.delete(stats, progress=args.progress, forced=args.forced)
-                        delete_count += 1
-            if delete_count > 0:
-                # only write/commit if we actually changed something, see #6060.
-                manifest.write()
-                repository.commit(compact=False, save_space=args.save_space)
-                cache.commit()
-            if args.stats:
-                log_multi(str(stats), logger=logging.getLogger("borg.output.stats"))
-
-        return self.exit_code
-
     @with_repository(compatibility=(Manifest.Operation.READ,))
     def do_list(self, args, repository, manifest, key):
         """List archive contents"""
@@ -1672,78 +1597,10 @@ class Archiver(
 
         self.build_parser_config(subparsers, common_parser, mid_common_parser)
         self.build_parser_debug(subparsers, common_parser, mid_common_parser)
+        self.build_parser_delete(subparsers, common_parser, mid_common_parser)
         self.build_parser_help(subparsers, common_parser, mid_common_parser, parser)
         self.build_parser_rdelete(subparsers, common_parser, mid_common_parser, parser)
 
-        # borg delete
-        delete_epilog = process_epilog(
-            """
-        This command deletes archives from the repository.
-
-        Important: When deleting archives, repository disk space is **not** freed until
-        you run ``borg compact``.
-
-        When in doubt, use ``--dry-run --list`` to see what would be deleted.
-
-        When using ``--stats``, you will get some statistics about how much data was
-        deleted - the "Deleted data" deduplicated size there is most interesting as
-        that is how much your repository will shrink.
-        Please note that the "All archives" stats refer to the state after deletion.
-
-        You can delete multiple archives by specifying a matching shell pattern,
-        using the ``--glob-archives GLOB`` option (for more info on these patterns,
-        see :ref:`borg_patterns`).
-
-        Always first use ``--dry-run --list`` to see what would be deleted.
-        """
-        )
-        subparser = subparsers.add_parser(
-            "delete",
-            parents=[common_parser],
-            add_help=False,
-            description=self.do_delete.__doc__,
-            epilog=delete_epilog,
-            formatter_class=argparse.RawDescriptionHelpFormatter,
-            help="delete archive",
-        )
-        subparser.set_defaults(func=self.do_delete)
-        subparser.add_argument("-n", "--dry-run", dest="dry_run", action="store_true", help="do not change repository")
-        subparser.add_argument(
-            "--list", dest="output_list", action="store_true", help="output verbose list of archives"
-        )
-        subparser.add_argument(
-            "--consider-checkpoints",
-            action="store_true",
-            dest="consider_checkpoints",
-            help="consider checkpoint archives for deletion (default: not considered).",
-        )
-        subparser.add_argument(
-            "-s", "--stats", dest="stats", action="store_true", help="print statistics for the deleted archive"
-        )
-        subparser.add_argument(
-            "--cache-only",
-            dest="cache_only",
-            action="store_true",
-            help="delete only the local cache for the given repository",
-        )
-        subparser.add_argument(
-            "--force",
-            dest="forced",
-            action="count",
-            default=0,
-            help="force deletion of corrupted archives, " "use ``--force --force`` in case ``--force`` does not work.",
-        )
-        subparser.add_argument(
-            "--keep-security-info",
-            dest="keep_security_info",
-            action="store_true",
-            help="keep the local security info when deleting a repository",
-        )
-        subparser.add_argument(
-            "--save-space", dest="save_space", action="store_true", help="work slower, but using less space"
-        )
-        define_archive_filters_group(subparser)
-
         # borg extract
         extract_epilog = process_epilog(
             """

+ 163 - 0
src/borg/archiver/delete.py

@@ -0,0 +1,163 @@
+import argparse
+import logging
+
+from .common import with_repository
+from ..archive import Archive, Statistics
+from ..cache import Cache
+from ..constants import *  # NOQA
+from ..helpers import Manifest
+from ..helpers import log_multi, format_archive
+
+from ..logger import create_logger
+
+logger = create_logger()
+
+
+class DeleteMixIn:
+    @with_repository(exclusive=True, manifest=False)
+    def do_delete(self, args, repository):
+        """Delete archives"""
+        self.output_list = args.output_list
+        dry_run = args.dry_run
+        manifest, key = Manifest.load(repository, (Manifest.Operation.DELETE,))
+        archive_names = tuple(x.name for x in manifest.archives.list_considering(args))
+        if not archive_names:
+            return self.exit_code
+        if args.glob_archives is None and args.first == 0 and args.last == 0:
+            self.print_error(
+                "Aborting: if you really want to delete all archives, please use -a '*' "
+                "or just delete the whole repository (might be much faster)."
+            )
+            return EXIT_ERROR
+
+        if args.forced == 2:
+            deleted = False
+            logger_list = logging.getLogger("borg.output.list")
+            for i, archive_name in enumerate(archive_names, 1):
+                try:
+                    current_archive = manifest.archives.pop(archive_name)
+                except KeyError:
+                    self.exit_code = EXIT_WARNING
+                    logger.warning(f"Archive {archive_name} not found ({i}/{len(archive_names)}).")
+                else:
+                    deleted = True
+                    if self.output_list:
+                        msg = "Would delete: {} ({}/{})" if dry_run else "Deleted archive: {} ({}/{})"
+                        logger_list.info(msg.format(format_archive(current_archive), i, len(archive_names)))
+            if dry_run:
+                logger.info("Finished dry-run.")
+            elif deleted:
+                manifest.write()
+                # note: might crash in compact() after committing the repo
+                repository.commit(compact=False)
+                logger.warning('Done. Run "borg check --repair" to clean up the mess.')
+            else:
+                logger.warning("Aborted.")
+            return self.exit_code
+
+        stats = Statistics(iec=args.iec)
+        with Cache(repository, key, manifest, progress=args.progress, lock_wait=self.lock_wait, iec=args.iec) as cache:
+            msg_delete = "Would delete archive: {} ({}/{})" if dry_run else "Deleting archive: {} ({}/{})"
+            msg_not_found = "Archive {} not found ({}/{})."
+            logger_list = logging.getLogger("borg.output.list")
+            delete_count = 0
+            for i, archive_name in enumerate(archive_names, 1):
+                try:
+                    archive_info = manifest.archives[archive_name]
+                except KeyError:
+                    logger.warning(msg_not_found.format(archive_name, i, len(archive_names)))
+                else:
+                    if self.output_list:
+                        logger_list.info(msg_delete.format(format_archive(archive_info), i, len(archive_names)))
+
+                    if not dry_run:
+                        archive = Archive(
+                            repository,
+                            key,
+                            manifest,
+                            archive_name,
+                            cache=cache,
+                            consider_part_files=args.consider_part_files,
+                        )
+                        archive.delete(stats, progress=args.progress, forced=args.forced)
+                        delete_count += 1
+            if delete_count > 0:
+                # only write/commit if we actually changed something, see #6060.
+                manifest.write()
+                repository.commit(compact=False, save_space=args.save_space)
+                cache.commit()
+            if args.stats:
+                log_multi(str(stats), logger=logging.getLogger("borg.output.stats"))
+
+        return self.exit_code
+
+    def build_parser_delete(self, subparsers, common_parser, mid_common_parser):
+        from .common import process_epilog, define_archive_filters_group
+
+        delete_epilog = process_epilog(
+            """
+        This command deletes archives from the repository.
+
+        Important: When deleting archives, repository disk space is **not** freed until
+        you run ``borg compact``.
+
+        When in doubt, use ``--dry-run --list`` to see what would be deleted.
+
+        When using ``--stats``, you will get some statistics about how much data was
+        deleted - the "Deleted data" deduplicated size there is most interesting as
+        that is how much your repository will shrink.
+        Please note that the "All archives" stats refer to the state after deletion.
+
+        You can delete multiple archives by specifying a matching shell pattern,
+        using the ``--glob-archives GLOB`` option (for more info on these patterns,
+        see :ref:`borg_patterns`).
+
+        Always first use ``--dry-run --list`` to see what would be deleted.
+        """
+        )
+        subparser = subparsers.add_parser(
+            "delete",
+            parents=[common_parser],
+            add_help=False,
+            description=self.do_delete.__doc__,
+            epilog=delete_epilog,
+            formatter_class=argparse.RawDescriptionHelpFormatter,
+            help="delete archive",
+        )
+        subparser.set_defaults(func=self.do_delete)
+        subparser.add_argument("-n", "--dry-run", dest="dry_run", action="store_true", help="do not change repository")
+        subparser.add_argument(
+            "--list", dest="output_list", action="store_true", help="output verbose list of archives"
+        )
+        subparser.add_argument(
+            "--consider-checkpoints",
+            action="store_true",
+            dest="consider_checkpoints",
+            help="consider checkpoint archives for deletion (default: not considered).",
+        )
+        subparser.add_argument(
+            "-s", "--stats", dest="stats", action="store_true", help="print statistics for the deleted archive"
+        )
+        subparser.add_argument(
+            "--cache-only",
+            dest="cache_only",
+            action="store_true",
+            help="delete only the local cache for the given repository",
+        )
+        subparser.add_argument(
+            "--force",
+            dest="forced",
+            action="count",
+            default=0,
+            help="force deletion of corrupted archives, " "use ``--force --force`` in case ``--force`` does not work.",
+        )
+        subparser.add_argument(
+            "--keep-security-info",
+            dest="keep_security_info",
+            action="store_true",
+            help="keep the local security info when deleting a repository",
+        )
+        subparser.add_argument(
+            "--save-space", dest="save_space", action="store_true", help="work slower, but using less space"
+        )
+        define_archive_filters_group(subparser)