Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow timespan to be specified with common time units #8626

Merged
merged 9 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/usage/general/date-time.rst.inc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Internally, we store and process date and time as UTC.

.. rubric:: TIMESPAN

Some options accept a TIMESPAN parameter, which can be given as a
number of days (e.g. ``7d``) or months (e.g. ``12m``).

Some options accept a TIMESPAN parameter, which can be given as a number of
years (e.g. ``2y``), months (e.g. ``12m``), weeks (e.g. ``2w``),
days (e.g. ``7d``), hours (e.g. ``8H``), minutes (e.g. ``30M``),
or seconds (e.g. ``150S``).
4 changes: 2 additions & 2 deletions src/borg/helpers/parseformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,10 +579,10 @@ def validator(text):


def relative_time_marker_validator(text: str):
time_marker_regex = r"^\d+[md]$"
time_marker_regex = r"^\d+[ymwdHMS]$"
match = re.compile(time_marker_regex).search(text)
if not match:
raise argparse.ArgumentTypeError(f"Invalid relative time marker used: {text}")
raise argparse.ArgumentTypeError(f"Invalid relative time marker used: {text}, choose from y, m, w, d, H, M, S")
else:
return text

Expand Down
12 changes: 11 additions & 1 deletion src/borg/helpers/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def calculate_relative_offset(format_string, from_ts, earlier=False):
from_ts = archive_ts_now()

if format_string is not None:
offset_regex = re.compile(r"(?P<offset>\d+)(?P<unit>[md])")
offset_regex = re.compile(r"(?P<offset>\d+)(?P<unit>[ymwdHMS])")
match = offset_regex.search(format_string)

if match:
Expand All @@ -131,6 +131,16 @@ def calculate_relative_offset(format_string, from_ts, earlier=False):
return from_ts + timedelta(days=offset)
elif unit == "m":
return offset_n_months(from_ts, offset)
elif unit == "y":
return from_ts.replace(year=from_ts.year + offset)
elif unit == "w":
return from_ts + timedelta(days=offset * 7)
elif unit == "H":
return from_ts + timedelta(seconds=offset * 60 * 60)
elif unit == "M":
return from_ts + timedelta(seconds=offset * 60)
elif unit == "S":
ThomasWaldmann marked this conversation as resolved.
Show resolved Hide resolved
return from_ts + timedelta(seconds=offset)
KenKundert marked this conversation as resolved.
Show resolved Hide resolved

raise ValueError(f"Invalid relative ts offset format: {format_string}")

Expand Down
72 changes: 55 additions & 17 deletions src/borg/testsuite/archiver/check_cmd_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,32 +58,70 @@ def test_date_matching(archivers, request):

shutil.rmtree(archiver.repository_path)
cmd(archiver, "repo-create", RK_ENCRYPTION)
earliest_ts = "2022-11-20T23:59:59"
ts_in_between = "2022-12-18T23:59:59"
create_src_archive(archiver, "archive1", ts=earliest_ts)
create_src_archive(archiver, "archive2", ts=ts_in_between)
create_src_archive(archiver, "archive3")
create_src_archive(archiver, "archive-2022-11-20", ts="2022-11-20T23:59:59")
create_src_archive(archiver, "archive-2022-12-18", ts="2022-12-18T23:59:59")
create_src_archive(archiver, "archive-now")
cmd(archiver, "check", "-v", "--archives-only", "--oldest=23e", exit_code=2)

output = cmd(archiver, "check", "-v", "--archives-only", "--oldest=1Y", exit_code=0)
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output

output = cmd(archiver, "check", "-v", "--archives-only", "--newest=1Y", exit_code=0)
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "check", "-v", "--archives-only", "--oldest=1m", exit_code=0)
assert "archive1" in output
assert "archive2" in output
assert "archive3" not in output
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output

output = cmd(archiver, "check", "-v", "--archives-only", "--newest=1m", exit_code=0)
assert "archive3" in output
assert "archive2" not in output
assert "archive1" not in output
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "check", "-v", "--archives-only", "--newer=1d", exit_code=0)
assert "archive3" in output
assert "archive1" not in output
assert "archive2" not in output
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "check", "-v", "--archives-only", "--older=1d", exit_code=0)
assert "archive1" in output
assert "archive2" in output
assert "archive3" not in output
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output

output = cmd(archiver, "check", "-v", "--archives-only", "--newer=24H", exit_code=0)
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "check", "-v", "--archives-only", "--older=24H", exit_code=0)
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output

output = cmd(archiver, "check", "-v", "--archives-only", "--newer=1440M", exit_code=0)
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "check", "-v", "--archives-only", "--older=1440M", exit_code=0)
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output

output = cmd(archiver, "check", "-v", "--archives-only", "--newer=86400S", exit_code=0)
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "check", "-v", "--archives-only", "--older=86400S", exit_code=0)
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output

# check for output when timespan older than the earliest archive is given. Issue #1711
output = cmd(archiver, "check", "-v", "--archives-only", "--older=9999m", exit_code=0)
Expand Down
76 changes: 58 additions & 18 deletions src/borg/testsuite/archiver/repo_list_cmd_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,32 +57,72 @@ def test_size_nfiles(archivers, request):
def test_date_matching(archivers, request):
archiver = request.getfixturevalue(archivers)
cmd(archiver, "repo-create", RK_ENCRYPTION)
earliest_ts = "2022-11-20T23:59:59"
ts_in_between = "2022-12-18T23:59:59"
create_src_archive(archiver, "archive1", ts=earliest_ts)
create_src_archive(archiver, "archive2", ts=ts_in_between)
create_src_archive(archiver, "archive3")
cmd(archiver, "repo-list", "-v", "--oldest=23e", exit_code=2)

create_src_archive(archiver, "archive-2022-11-20", ts="2022-11-20T23:59:59")
create_src_archive(archiver, "archive-2022-12-18", ts="2022-12-18T23:59:59")
create_src_archive(archiver, "archive-now")

cmd(archiver, "check", "-v", "--oldest=23e", exit_code=2)

output = cmd(archiver, "repo-list", "-v", "--oldest=1Y", exit_code=0)
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output

output = cmd(archiver, "repo-list", "-v", "--newest=1Y", exit_code=0)
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "repo-list", "-v", "--oldest=1m", exit_code=0)
assert "archive1" in output
assert "archive2" in output
assert "archive3" not in output
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output

output = cmd(archiver, "repo-list", "-v", "--newest=1m", exit_code=0)
assert "archive3" in output
assert "archive2" not in output
assert "archive1" not in output
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "repo-list", "-v", "--newer=1d", exit_code=0)
assert "archive3" in output
assert "archive1" not in output
assert "archive2" not in output
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "repo-list", "-v", "--older=1d", exit_code=0)
assert "archive1" in output
assert "archive2" in output
assert "archive3" not in output
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output

output = cmd(archiver, "repo-list", "-v", "--newer=24H", exit_code=0)
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "repo-list", "-v", "--older=24H", exit_code=0)
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output

output = cmd(archiver, "repo-list", "-v", "--newer=1440M", exit_code=0)
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "repo-list", "-v", "--older=1440M", exit_code=0)
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output

output = cmd(archiver, "repo-list", "-v", "--newer=86400S", exit_code=0)
assert "archive-2022-11-20" not in output
assert "archive-2022-12-18" not in output
assert "archive-now" in output

output = cmd(archiver, "repo-list", "-v", "--older=86400S", exit_code=0)
assert "archive-2022-11-20" in output
assert "archive-2022-12-18" in output
assert "archive-now" not in output


def test_repo_list_json(archivers, request):
Expand Down
Loading