Skip to content

Commit

Permalink
Implement `minutely' option (issue #5)
Browse files Browse the repository at this point in the history
  • Loading branch information
xolox committed Aug 4, 2016
1 parent be77421 commit b6daf3e
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 21 deletions.
13 changes: 9 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ Please use the ``--dry-run`` option to test the effect of the specified rotation
:widths: 30, 70


"``-M``, ``--minutely=COUNT``","In a literal sense this option sets the number of ""backups per minute"" to
preserve during rotation. For most use cases that doesn't make a lot of
sense :-) but you can combine the ``--minutely`` and ``--relaxed`` options to
preserve more than one backup per hour. Refer to the usage of the ``-H``,
``--hourly`` option for details about ``COUNT``."
"``-H``, ``--hourly=COUNT``","Set the number of hourly backups to preserve during rotation:

- If ``COUNT`` is a number it gives the number of hourly backups to preserve,
Expand All @@ -130,13 +135,13 @@ Please use the ``--dry-run`` option to test the effect of the specified rotation
preserved.
- By default no hourly backups are preserved."
"``-d``, ``--daily=COUNT``","Set the number of daily backups to preserve during rotation. Refer to the
usage of the ``-H``, ``--hourly`` option for details."
usage of the ``-H``, ``--hourly`` option for details about ``COUNT``."
"``-w``, ``--weekly=COUNT``","Set the number of weekly backups to preserve during rotation. Refer to the
usage of the ``-H``, ``--hourly`` option for details."
usage of the ``-H``, ``--hourly`` option for details about ``COUNT``."
"``-m``, ``--monthly=COUNT``","Set the number of monthly backups to preserve during rotation. Refer to the
usage of the ``-H``, ``--hourly`` option for details."
usage of the ``-H``, ``--hourly`` option for details about ``COUNT``."
"``-y``, ``--yearly=COUNT``","Set the number of yearly backups to preserve during rotation. Refer to the
usage of the ``-H``, ``--hourly`` option for details."
usage of the ``-H``, ``--hourly`` option for details about ``COUNT``."
"``-I``, ``--include=PATTERN``","Only process backups that match the shell pattern given by ``PATTERN``. This
argument can be repeated. Make sure to quote ``PATTERN`` so the shell doesn't
expand the pattern before it's received by rotate-backups."
Expand Down
20 changes: 12 additions & 8 deletions rotate_backups/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from verboselogs import VerboseLogger

# Semi-standard module versioning.
__version__ = '4.1'
__version__ = '4.2'

# Initialize a logger for this module.
logger = VerboseLogger(__name__)
Expand All @@ -52,11 +52,14 @@
LOCAL_CONFIG_FILE = '~/.rotate-backups.ini'
"""The pathname of the user specific configuration file (a string)."""

ORDERED_FREQUENCIES = (('hourly', relativedelta(hours=1)),
('daily', relativedelta(days=1)),
('weekly', relativedelta(weeks=1)),
('monthly', relativedelta(months=1)),
('yearly', relativedelta(years=1)))
ORDERED_FREQUENCIES = (
('minutely', relativedelta(minutes=1)),
('hourly', relativedelta(hours=1)),
('daily', relativedelta(days=1)),
('weekly', relativedelta(weeks=1)),
('monthly', relativedelta(months=1)),
('yearly', relativedelta(years=1)),
)
"""
A list of tuples with two values each:
Expand Down Expand Up @@ -314,8 +317,8 @@ def rotation_scheme(self):
The rotation scheme to apply to backups (a dictionary).
Each key in this dictionary defines a rotation frequency (one of the
strings 'hourly', 'daily', 'weekly', 'monthly' and 'yearly') and each
value defines a retention count:
strings 'minutely', 'hourly', 'daily', 'weekly', 'monthly' and
'yearly') and each value defines a retention count:
- An integer value represents the number of backups to preserve in the
given rotation frequency, starting from the most recent backup and
Expand Down Expand Up @@ -527,6 +530,7 @@ def group_backups(self, backups):
"""
backups_by_frequency = dict((frequency, collections.defaultdict(list)) for frequency in SUPPORTED_FREQUENCIES)
for b in backups:
backups_by_frequency['minutely'][(b.year, b.month, b.day, b.hour, b.minute)].append(b)
backups_by_frequency['hourly'][(b.year, b.month, b.day, b.hour)].append(b)
backups_by_frequency['daily'][(b.year, b.month, b.day)].append(b)
backups_by_frequency['weekly'][(b.year, b.week)].append(b)
Expand Down
29 changes: 20 additions & 9 deletions rotate_backups/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@
Supported options:
-M, --minutely=COUNT
In a literal sense this option sets the number of "backups per minute" to
preserve during rotation. For most use cases that doesn't make a lot of
sense :-) but you can combine the --minutely and --relaxed options to
preserve more than one backup per hour. Refer to the usage of the -H,
--hourly option for details about COUNT.
-H, --hourly=COUNT
Set the number of hourly backups to preserve during rotation:
Expand All @@ -44,22 +52,22 @@
-d, --daily=COUNT
Set the number of daily backups to preserve during rotation. Refer to the
usage of the -H, --hourly option for details.
usage of the -H, --hourly option for details about COUNT.
-w, --weekly=COUNT
Set the number of weekly backups to preserve during rotation. Refer to the
usage of the -H, --hourly option for details.
usage of the -H, --hourly option for details about COUNT.
-m, --monthly=COUNT
Set the number of monthly backups to preserve during rotation. Refer to the
usage of the -H, --hourly option for details.
usage of the -H, --hourly option for details about COUNT.
-y, --yearly=COUNT
Set the number of yearly backups to preserve during rotation. Refer to the
usage of the -H, --hourly option for details.
usage of the -H, --hourly option for details about COUNT.
-I, --include=PATTERN
Expand Down Expand Up @@ -186,13 +194,16 @@ def main():
selected_locations = []
# Parse the command line arguments.
try:
options, arguments = getopt.getopt(sys.argv[1:], 'H:d:w:m:y:I:x:jpri:c:r:unvqh', [
'hourly=', 'daily=', 'weekly=', 'monthly=', 'yearly=', 'include=',
'exclude=', 'parallel', 'prefer-recent', 'relaxed', 'ionice=',
'config=', 'use-sudo', 'dry-run', 'verbose', 'quiet', 'help',
options, arguments = getopt.getopt(sys.argv[1:], 'M:H:d:w:m:y:I:x:jpri:c:r:unvqh', [
'minutely=', 'hourly=', 'daily=', 'weekly=', 'monthly=', 'yearly=',
'include=', 'exclude=', 'parallel', 'prefer-recent', 'relaxed',
'ionice=', 'config=', 'use-sudo', 'dry-run', 'verbose', 'quiet',
'help',
])
for option, value in options:
if option in ('-H', '--hourly'):
if option in ('-M', '--minutely'):
rotation_scheme['minutely'] = coerce_retention_period(value)
elif option in ('-H', '--hourly'):
rotation_scheme['hourly'] = coerce_retention_period(value)
elif option in ('-d', '--daily'):
rotation_scheme['daily'] = coerce_retention_period(value)
Expand Down
11 changes: 11 additions & 0 deletions rotate_backups/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,17 @@ def test_prefer_new(self):
assert not os.path.exists(os.path.join(root, 'backup-2016-01-10_21-30-00'))
assert os.path.exists(os.path.join(root, 'backup-2016-01-10_21-45-00'))

def test_minutely_rotation(self):
"""Test rotation with multiple backups per hour."""
with TemporaryDirectory(prefix='rotate-backups-', suffix='-test-suite') as root:
os.mkdir(os.path.join(root, 'backup-2016-01-10_21-15-00'))
os.mkdir(os.path.join(root, 'backup-2016-01-10_21-30-00'))
os.mkdir(os.path.join(root, 'backup-2016-01-10_21-45-00'))
run_cli('--prefer-recent', '--relaxed', '--minutely=2', root)
assert not os.path.exists(os.path.join(root, 'backup-2016-01-10_21-15-00'))
assert os.path.exists(os.path.join(root, 'backup-2016-01-10_21-30-00'))
assert os.path.exists(os.path.join(root, 'backup-2016-01-10_21-45-00'))

def create_sample_backup_set(self, root):
"""Create a sample backup set to be rotated."""
for name in SAMPLE_BACKUP_SET:
Expand Down

0 comments on commit b6daf3e

Please sign in to comment.