11# main.py
22
33#/***************************************************************************
4- # * Copyright (C) 2015 Daniel Mueller (deso@posteo.net) *
4+ # * Copyright (C) 2015-2016 Daniel Mueller (deso@posteo.net) *
55# * *
66# * This program is free software: you can redistribute it and/or modify *
77# * it under the terms of the GNU General Public License as published by *
2323 alias ,
2424)
2525from deso .btrfs .argv import (
26- insert as insertArg ,
2726 reorder as reorderArg ,
2827)
2928from deso .btrfs .commands import (
4645 timedelta ,
4746)
4847from argparse import (
48+ Action ,
4949 ArgumentParser ,
5050 ArgumentTypeError ,
5151 HelpFormatter ,
5252 Namespace ,
53- SUPPRESS ,
5453)
5554
5655
@@ -152,17 +151,24 @@ def checkSnapshotExtension(string, namespace, backup=True):
152151 return "%s%s" % (extsep , string )
153152
154153
155- def reverse (_ , namespace ):
156- """Helper function to reverse arguments during parsing."""
157- # In case the reverse option was given we swap the repositories and
158- # the filters.
159- with alias (namespace ) as ns :
160- if ns .reverse :
154+ class ReverseAction (Action ):
155+ """Action to reverse some source/destination arguments."""
156+ def __init__ (self , option_strings , dest , const = None , default = None ,
157+ required = False , help = None , metavar = None ):
158+ """Create a new ReverseAction object."""
159+ super ().__init__ (option_strings = option_strings , dest = dest , nargs = 0 ,
160+ const = const , default = default , required = required ,
161+ help = help )
162+
163+
164+ def __call__ (self , parser , namespace , values , option_string = None ):
165+ """Helper function to reverse arguments during parsing."""
166+ # In case the reverse option was given we swap the repositories and
167+ # the filters.
168+ with alias (namespace ) as ns :
161169 ns .src , ns .dst = ns .dst , ns .src
162170 ns .send_filters , ns .recv_filters = ns .recv_filters , ns .send_filters
163171
164- return None
165-
166172
167173def addStandardArgs (parser ):
168174 """Add the standard arguments --version and --help to an argument parser."""
@@ -179,11 +185,9 @@ def addStandardArgs(parser):
179185def addOptionalArgs (parser , namespace , backup ):
180186 """Add the optional arguments to a parser."""
181187 parser .add_argument (
182- # In order to implement the --join option we use a trick: Since we
183- # cannot use a type field that performs an action for us as we do
184- # for the reverse-hidden-helper option (because this option does not
185- # accept an argument), we append the value 'None' to the
186- # 'send_filters' array that stores all send filters.
188+ # In order to implement the --join option we use a trick: We append
189+ # the value 'None' to the 'send_filters' array that stores all send
190+ # filters.
187191 # TODO: Right now this option can be specified multiple times. That
188192 # is wrong and should not be allowed. However, it is tricky to
189193 # enforce that. Find a way.
@@ -216,17 +220,10 @@ def addOptionalArgs(parser, namespace, backup):
216220 "\" /usr/bin/ssh server\" ." ,
217221 )
218222 parser .add_argument (
219- "--reverse" , action = "store_true" , dest = "reverse" , default = False ,
223+ "--reverse" , action = ReverseAction , dest = "reverse" ,
220224 help = "Reverse (i.e., swap) the source and destination repositories "
221225 "as well as the send and receive filters." ,
222226 )
223- # A helper option that is used to perform the argument reordering
224- # during parsing.
225- parser .add_argument (
226- "--reverse-hidden-helper" , action = "store" , default = None ,
227- dest = "reverse_hidden_helper" , help = SUPPRESS ,
228- type = lambda x : reverse (x , namespace ),
229- )
230227 parser .add_argument (
231228 "--send-filter" , action = "append" , default = None , dest = "send_filters" ,
232229 metavar = "command" , nargs = 1 ,
@@ -426,7 +423,6 @@ def prepare(filters):
426423 del ns .dst
427424 del ns .command
428425 del ns .reverse
429- del ns .reverse_hidden_helper
430426
431427 return command , subvolumes , src_repo , dst_repo
432428
@@ -456,20 +452,17 @@ def main(argv):
456452 # work the option has to be evaluated after all filter options. To
457453 # that end, we move it to the end of the options because the
458454 # ArgumentParser evaluates arguments in the order in which they are
459- # provided in the argument vector. In order to have less branching in
460- # various cases, we want to evaluate the --reverse option on the fly.
461- # The problem there is that it does not accept an argument. So we
462- # insert an artificial, undocumented option that performs the checking
463- # (--reverse-hidden-helper). Because --snapshot-ext already requires
464- # properly ordered arguments, the hidden reverse helper option has to
465- # be evaluated before the former (it also has to be evaluated after
466- # the actual --reverse option, but that is guaranteed since we insert
467- # it at the end) .
455+ # provided in the argument vector.
456+ # In order to have less branching in various cases, we want to
457+ # evaluate the --reverse option on the fly. This option has a special
458+ # action that reverses the source and destination repositories as well
459+ # as the send and receive filters. However, in order for it to work
460+ # correctly, it needs to be evaluated just before the --snapshot-ext
461+ # option (because the latter requires the reordered arguments) but
462+ # after all other options. Hence, we move it to the end right before
463+ # we do the same with the --snapshot-ext option .
468464 args = argv [1 :].copy ()
469-
470- if "--reverse" in args :
471- args = insertArg (args , ["--reverse-hidden-helper" , "42" ])
472-
465+ args = reorderArg (args , "--reverse" )
473466 args = reorderArg (args , "--snapshot-ext" )
474467 parser .parse_args (args , namespace )
475468
0 commit comments