diff --git a/CHANGES b/CHANGES index 8b800ce4e..0c744388c 100644 --- a/CHANGES +++ b/CHANGES @@ -13,7 +13,9 @@ Version 0.11 - Fix exception during "attic create" with repeated files (#39) - New "--exclude-from" option for attic create/extract/verify. - Improved archive metadata deduplication. -- Replace the "verify" command with "extract --dry-run" (#25) +- "attic verify" has been deprecated. Use "attic extract --dry-run" instead. +- "attic prune --hourly|daily|..." has been deprecated. + Use "attic prune --keep-hourly|daily|..." instead. Version 0.10 ------------ diff --git a/attic/archiver.py b/attic/archiver.py index c2fbe4768..9e16a4467 100644 --- a/attic/archiver.py +++ b/attic/archiver.py @@ -374,6 +374,24 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") print('No help available on %s' % (args.topic,)) return self.exit_code + def preprocess_args(self, args): + deprecations = [ + ('--hourly', '--keep-hourly', 'Warning: "--hourly" has been deprecated. Use "--keep-hourly" instead.'), + ('--daily', '--keep-daily', 'Warning: "--daily" has been deprecated. Use "--keep-daily" instead.'), + ('--weekly', '--keep-weekly', 'Warning: "--weekly" has been deprecated. Use "--keep-weekly" instead.'), + ('--monthly', '--keep-monthly', 'Warning: "--monthly" has been deprecated. Use "--keep-monthly" instead.'), + ('--yearly', '--keep-yearly', 'Warning: "--yearly" has been deprecated. Use "--keep-yearly" instead.') + ] + if args and args[0] == 'verify': + print('Warning: "attic verify" has been deprecated. Use "attic extract --dry-run" instead.') + args = ['extract', '--dry-run'] + args[1:] + for i, arg in enumerate(args[:]): + for old_name, new_name, warning in deprecations: + if arg.startswith(old_name): + args[i] = arg.replace(old_name, new_name) + print(warning) + return args + def run(self, args=None): keys_dir = get_keys_dir() if not os.path.exists(keys_dir): @@ -391,6 +409,8 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") # We can't use argparse for "serve" since we don't want it to show up in "Available commands" if args and args[0] == 'serve': return self.do_serve() + if args: + args = self.preprocess_args(args) parser = argparse.ArgumentParser(description='Attic %s - Deduplicated Backups' % __version__) subparsers = parser.add_subparsers(title='Available commands') @@ -468,7 +488,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") description=self.do_extract.__doc__, epilog=extract_epilog) subparser.set_defaults(func=self.do_extract) - subparser.add_argument('--dry-run', dest='dry_run', + subparser.add_argument('-n', '--dry-run', dest='dry_run', default=False, action='store_true', help='do not actually change any files') subparser.add_argument('-e', '--exclude', dest='excludes', @@ -541,17 +561,17 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") description=self.do_prune.__doc__, epilog=prune_epilog) subparser.set_defaults(func=self.do_prune) - subparser.add_argument('--within', dest='within', type=str, metavar='WITHIN', + subparser.add_argument('--keep-within', dest='within', type=str, metavar='WITHIN', help='keep all archives within this time interval') - subparser.add_argument('-H', '--hourly', dest='hourly', type=int, default=0, + subparser.add_argument('-H', '--keep-hourly', dest='hourly', type=int, default=0, help='number of hourly archives to keep') - subparser.add_argument('-d', '--daily', dest='daily', type=int, default=0, + subparser.add_argument('-d', '--keep-daily', dest='daily', type=int, default=0, help='number of daily archives to keep') - subparser.add_argument('-w', '--weekly', dest='weekly', type=int, default=0, + subparser.add_argument('-w', '--keep-weekly', dest='weekly', type=int, default=0, help='number of weekly archives to keep') - subparser.add_argument('-m', '--monthly', dest='monthly', type=int, default=0, + subparser.add_argument('-m', '--keep-monthly', dest='monthly', type=int, default=0, help='number of monthly archives to keep') - subparser.add_argument('-y', '--yearly', dest='yearly', type=int, default=0, + subparser.add_argument('-y', '--keep-yearly', dest='yearly', type=int, default=0, help='number of yearly archives to keep') subparser.add_argument('-p', '--prefix', dest='prefix', type=str, help='only consider archive names starting with this prefix') diff --git a/attic/testsuite/archiver.py b/attic/testsuite/archiver.py index ed58e4651..a163a2df7 100644 --- a/attic/testsuite/archiver.py +++ b/attic/testsuite/archiver.py @@ -11,7 +11,7 @@ from hashlib import sha256 from attic import xattr from attic.archive import Archive from attic.archiver import Archiver -from attic.helpers import Manifest, IntegrityError +from attic.helpers import Manifest from attic.repository import Repository from attic.testsuite import AtticTestCase from attic.crypto import bytes_to_long, num_aes_blocks @@ -240,6 +240,15 @@ class ArchiverTestCase(ArchiverTestCaseBase): # Restore permissions so shutil.rmtree is able to delete it os.system('chmod -R u+w ' + self.repository_path) + def test_cmdline_compatibility(self): + self.create_regual_file('file1', size=1024 * 80) + self.attic('init', self.repository_location) + self.attic('create', self.repository_location + '::test', 'input') + output = self.attic('verify', '-v', self.repository_location + '::test') + self.assert_in('"attic verify" has been deprecated', output) + output = self.attic('prune', self.repository_location, '--hourly=1') + self.assert_in('"--hourly" has been deprecated. Use "--keep-hourly" instead', output) + def test_prune_repository(self): self.attic('init', self.repository_location) self.attic('create', self.repository_location + '::test1', src_dir) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 9eeb043ae..7dfef472e 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -69,7 +69,7 @@ of old archives:: # Use the `prune` subcommand to maintain 7 daily, 4 weekly # and 6 monthly archives. - attic prune -v $REPOSITORY --daily=7 --weekly=4 --monthly=6 + attic prune -v $REPOSITORY --keep-daily=7 --keep-weekly=4 --keep-monthly=6 .. Note:: This script assumes the repository has already been initialized with