1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2025-03-06 11:40:31 +00:00

tag: set, add, remove tags

This commit is contained in:
Thomas Waldmann 2024-10-02 23:28:13 +02:00
parent 789ffb0c1b
commit e274860983
No known key found for this signature in database
GPG key ID: 243ACFA951F78E01
9 changed files with 326 additions and 2 deletions

98
docs/man/borg-tag.1 Normal file
View file

@ -0,0 +1,98 @@
.\" Man page generated from reStructuredText.
.
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "BORG-TAG" 1 "2024-10-02" "" "borg backup tool"
.SH NAME
borg-tag \- Manage tags
.SH SYNOPSIS
.sp
borg [common options] tag [options] [NAME]
.SH DESCRIPTION
.sp
Manage archive tags.
.sp
Borg archives can have a set of tags which can be used for matching archives.
.sp
You can set the tags to a specific set of tags or you can add or remove
tags from the current set of tags.
.SH OPTIONS
.sp
See \fIborg\-common(1)\fP for common options of Borg commands.
.SS arguments
.INDENT 0.0
.TP
.B NAME
specify the archive name
.UNINDENT
.SS optional arguments
.INDENT 0.0
.TP
.BI \-\-set \ TAG
set tags (can be given multiple times)
.TP
.BI \-\-add \ TAG
add tags (can be given multiple times)
.TP
.BI \-\-remove \ TAG
remove tags (can be given multiple times)
.UNINDENT
.SS Archive filters
.INDENT 0.0
.TP
.BI \-a \ PATTERN\fR,\fB \ \-\-match\-archives \ PATTERN
only consider archives matching all patterns. see \(dqborg help match\-archives\(dq.
.TP
.BI \-\-sort\-by \ KEYS
Comma\-separated list of sorting keys; valid keys are: timestamp, archive, name, id, tags, host, user; default is: timestamp
.TP
.BI \-\-first \ N
consider first N archives after other filters were applied
.TP
.BI \-\-last \ N
consider last N archives after other filters were applied
.TP
.BI \-\-oldest \ TIMESPAN
consider archives between the oldest archive\(aqs timestamp and (oldest + TIMESPAN), e.g. 7d or 12m.
.TP
.BI \-\-newest \ TIMESPAN
consider archives between the newest archive\(aqs timestamp and (newest \- TIMESPAN), e.g. 7d or 12m.
.TP
.BI \-\-older \ TIMESPAN
consider archives older than (now \- TIMESPAN), e.g. 7d or 12m.
.TP
.BI \-\-newer \ TIMESPAN
consider archives newer than (now \- TIMESPAN), e.g. 7d or 12m.
.UNINDENT
.SH SEE ALSO
.sp
\fIborg\-common(1)\fP
.SH AUTHOR
The Borg Collective
.\" Generated by docutils manpage writer.
.

View file

@ -51,8 +51,9 @@ Usage
usage/create
usage/extract
usage/check
usage/rename
usage/list
usage/tag
usage/rename
usage/diff
usage/delete
usage/prune

1
docs/usage/tag.rst Normal file
View file

@ -0,0 +1 @@
.. include:: tag.rst.inc

93
docs/usage/tag.rst.inc Normal file
View file

@ -0,0 +1,93 @@
.. IMPORTANT: this file is auto-generated from borg's built-in help, do not edit!
.. _borg_tag:
borg tag
--------
.. code-block:: none
borg [common options] tag [options] [NAME]
.. only:: html
.. class:: borg-options-table
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| **positional arguments** |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``NAME`` | specify the archive name |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| **optional arguments** |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``--set TAG`` | set tags (can be given multiple times) |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``--add TAG`` | add tags (can be given multiple times) |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``--remove TAG`` | remove tags (can be given multiple times) |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| .. class:: borg-common-opt-ref |
| |
| :ref:`common_options` |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| **Archive filters** Archive filters can be applied to repository targets. |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``-a PATTERN``, ``--match-archives PATTERN`` | only consider archives matching all patterns. see "borg help match-archives". |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``--sort-by KEYS`` | Comma-separated list of sorting keys; valid keys are: timestamp, archive, name, id, tags, host, user; default is: timestamp |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``--first N`` | consider first N archives after other filters were applied |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``--last N`` | consider last N archives after other filters were applied |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``--oldest TIMESPAN`` | consider archives between the oldest archive's timestamp and (oldest + TIMESPAN), e.g. 7d or 12m. |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``--newest TIMESPAN`` | consider archives between the newest archive's timestamp and (newest - TIMESPAN), e.g. 7d or 12m. |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``--older TIMESPAN`` | consider archives older than (now - TIMESPAN), e.g. 7d or 12m. |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| | ``--newer TIMESPAN`` | consider archives newer than (now - TIMESPAN), e.g. 7d or 12m. |
+-----------------------------------------------------------------------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
.. raw:: html
<script type='text/javascript'>
$(document).ready(function () {
$('.borg-options-table colgroup').remove();
})
</script>
.. only:: latex
NAME
specify the archive name
optional arguments
--set TAG set tags (can be given multiple times)
--add TAG add tags (can be given multiple times)
--remove TAG remove tags (can be given multiple times)
:ref:`common_options`
|
Archive filters
-a PATTERN, --match-archives PATTERN only consider archives matching all patterns. see "borg help match-archives".
--sort-by KEYS Comma-separated list of sorting keys; valid keys are: timestamp, archive, name, id, tags, host, user; default is: timestamp
--first N consider first N archives after other filters were applied
--last N consider last N archives after other filters were applied
--oldest TIMESPAN consider archives between the oldest archive's timestamp and (oldest + TIMESPAN), e.g. 7d or 12m.
--newest TIMESPAN consider archives between the newest archive's timestamp and (newest - TIMESPAN), e.g. 7d or 12m.
--older TIMESPAN consider archives older than (now - TIMESPAN), e.g. 7d or 12m.
--newer TIMESPAN consider archives newer than (now - TIMESPAN), e.g. 7d or 12m.
Description
~~~~~~~~~~~
Manage archive tags.
Borg archives can have a set of tags which can be used for matching archives.
You can set the tags to a specific set of tags or you can add or remove
tags from the current set of tags.

View file

@ -89,6 +89,7 @@ from .repo_delete_cmd import RepoDeleteMixIn
from .repo_list_cmd import RepoListMixIn
from .repo_space_cmd import RepoSpaceMixIn
from .serve_cmd import ServeMixIn
from .tag_cmd import TagMixIn
from .tar_cmds import TarMixIn
from .transfer_cmd import TransferMixIn
from .version_cmd import VersionMixIn
@ -120,6 +121,7 @@ class Archiver(
RepoListMixIn,
RepoSpaceMixIn,
ServeMixIn,
TagMixIn,
TarMixIn,
TransferMixIn,
VersionMixIn,
@ -359,6 +361,7 @@ class Archiver(
self.build_parser_rename(subparsers, common_parser, mid_common_parser)
self.build_parser_repo_space(subparsers, common_parser, mid_common_parser)
self.build_parser_serve(subparsers, common_parser, mid_common_parser)
self.build_parser_tag(subparsers, common_parser, mid_common_parser)
self.build_parser_tar(subparsers, common_parser, mid_common_parser)
self.build_parser_transfer(subparsers, common_parser, mid_common_parser)
self.build_parser_version(subparsers, common_parser, mid_common_parser)

View file

@ -0,0 +1,95 @@
import argparse
from ._common import with_repository, define_archive_filters_group
from ..archive import Archive
from ..constants import * # NOQA
from ..helpers import bin_to_hex, archivename_validator, tag_validator
from ..manifest import Manifest
from ..logger import create_logger
logger = create_logger()
class TagMixIn:
@with_repository(cache=True, compatibility=(Manifest.Operation.WRITE,))
def do_tag(self, args, repository, manifest, cache):
"""Manage tags"""
def tags_set(tags):
"""return a set of tags, removing empty tags"""
return set(tag for tag in tags if tag)
if args.name:
archive_infos = [manifest.archives.get_one([args.name])]
else:
archive_infos = manifest.archives.list_considering(args)
for archive_info in archive_infos:
archive = Archive(manifest, archive_info.id, cache=cache)
if args.set_tags:
archive.tags = tags_set(args.set_tags)
if args.add_tags:
archive.tags |= tags_set(args.add_tags)
if args.remove_tags:
archive.tags -= tags_set(args.remove_tags)
old_id = archive.id
archive.set_meta("tags", list(sorted(archive.tags)))
if old_id != archive.id:
manifest.archives.delete_by_id(old_id)
print(
f"id: {bin_to_hex(old_id):.8} -> {bin_to_hex(archive.id):.8}, "
f"tags: {','.join(sorted(archive.tags))}."
)
def build_parser_tag(self, subparsers, common_parser, mid_common_parser):
from ._common import process_epilog
tag_epilog = process_epilog(
"""
Manage archive tags.
Borg archives can have a set of tags which can be used for matching archives.
You can set the tags to a specific set of tags or you can add or remove
tags from the current set of tags.
"""
)
subparser = subparsers.add_parser(
"tag",
parents=[common_parser],
add_help=False,
description=self.do_tag.__doc__,
epilog=tag_epilog,
formatter_class=argparse.RawDescriptionHelpFormatter,
help="tag archives",
)
subparser.set_defaults(func=self.do_tag)
subparser.add_argument(
"--set",
dest="set_tags",
metavar="TAG",
type=tag_validator,
action="append",
help="set tags (can be given multiple times)",
)
subparser.add_argument(
"--add",
dest="add_tags",
metavar="TAG",
type=tag_validator,
action="append",
help="add tags (can be given multiple times)",
)
subparser.add_argument(
"--remove",
dest="remove_tags",
metavar="TAG",
type=tag_validator,
action="append",
help="remove tags (can be given multiple times)",
)
define_archive_filters_group(subparser)
subparser.add_argument(
"name", metavar="NAME", nargs="?", type=archivename_validator, help="specify the archive name"
)

View file

@ -34,7 +34,7 @@ from .parseformat import format_file_size, parse_file_size, FileSize, parse_stor
from .parseformat import sizeof_fmt, sizeof_fmt_iec, sizeof_fmt_decimal, Location, text_validator
from .parseformat import format_line, replace_placeholders, PlaceholderError, relative_time_marker_validator
from .parseformat import format_archive, parse_stringified_list, clean_lines
from .parseformat import location_validator, archivename_validator, comment_validator
from .parseformat import location_validator, archivename_validator, comment_validator, tag_validator
from .parseformat import BaseFormatter, ArchiveFormatter, ItemFormatter, DiffFormatter, file_status
from .parseformat import swidth_slice, ellipsis_truncate
from .parseformat import BorgJsonEncoder, basic_json_data, json_print, json_dump, prepare_dump_dict

View file

@ -685,6 +685,7 @@ def text_validator(*, name, max_length, min_length=0, invalid_ctrl_chars="\0", i
comment_validator = text_validator(name="comment", max_length=10000)
tag_validator = text_validator(name="tag", min_length=0, max_length=10, invalid_chars=" ,$")
def archivename_validator(text):

View file

@ -0,0 +1,32 @@
from ...constants import * # NOQA
from . import cmd, generate_archiver_tests, RK_ENCRYPTION
pytest_generate_tests = lambda metafunc: generate_archiver_tests(metafunc, kinds="local") # NOQA
def test_tag_set(archivers, request):
archiver = request.getfixturevalue(archivers)
cmd(archiver, "repo-create", RK_ENCRYPTION)
cmd(archiver, "create", "archive", archiver.input_path)
output = cmd(archiver, "tag", "-a", "archive", "--set", "aa")
assert "tags: aa." in output
output = cmd(archiver, "tag", "-a", "archive", "--set", "bb")
assert "tags: bb." in output
output = cmd(archiver, "tag", "-a", "archive", "--set", "bb", "--set", "aa")
assert "tags: aa,bb." in output # sorted!
output = cmd(archiver, "tag", "-a", "archive", "--set", "")
assert "tags: ." in output # no tags!
def test_tag_add_remove(archivers, request):
archiver = request.getfixturevalue(archivers)
cmd(archiver, "repo-create", RK_ENCRYPTION)
cmd(archiver, "create", "archive", archiver.input_path)
output = cmd(archiver, "tag", "-a", "archive", "--add", "aa")
assert "tags: aa." in output
output = cmd(archiver, "tag", "-a", "archive", "--add", "bb")
assert "tags: aa,bb." in output
output = cmd(archiver, "tag", "-a", "archive", "--remove", "aa")
assert "tags: bb." in output
output = cmd(archiver, "tag", "-a", "archive", "--remove", "bb")
assert "tags: ." in output