From 4bf8c8a6f8c0841e241c3d11e8c895fc668cbfe3 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sun, 1 Nov 2015 00:40:32 +0100 Subject: [PATCH 1/2] separate parse_args() from run() parse_args concentrates on only processing arguments, including pre and post processing. this needs to be called before run(), which is now receiving the return value of parse_args. this was done so we can have the parsed args outside of the run function, e.g. in main(). --- borg/archiver.py | 32 +++++++++++++++++--------------- borg/testsuite/archiver.py | 3 ++- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/borg/archiver.py b/borg/archiver.py index ff475f378..c5268cb52 100644 --- a/borg/archiver.py +++ b/borg/archiver.py @@ -985,7 +985,21 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") help='additional help on TOPIC') return parser - def run(self, args=None): + def parse_args(self, args=None): + # We can't use argparse for "serve" since we don't want it to show up in "Available commands" + if args: + args = self.preprocess_args(args) + parser = self.build_parser(args) + args = parser.parse_args(args or ['-h']) + update_excludes(args) + return args + + def run(self, args): + os.umask(args.umask) # early, before opening files + self.verbose = args.verbose + RemoteRepository.remote_path = args.remote_path + RemoteRepository.umask = args.umask + setup_logging() check_extension_modules() keys_dir = get_keys_dir() if not os.path.exists(keys_dir): @@ -1002,19 +1016,6 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") # For information about cache directory tags, see: # http://www.brynosaurus.com/cachedir/ """).lstrip()) - - # We can't use argparse for "serve" since we don't want it to show up in "Available commands" - if args: - args = self.preprocess_args(args) - parser = self.build_parser(args) - - args = parser.parse_args(args or ['-h']) - self.verbose = args.verbose - setup_logging() - os.umask(args.umask) - RemoteRepository.remote_path = args.remote_path - RemoteRepository.umask = args.umask - update_excludes(args) if is_slow_msgpack(): logger.warning("Using a pure-python msgpack! This will result in lower performance.") return args.func(args) @@ -1062,7 +1063,8 @@ def main(): # pragma: no cover archiver = Archiver() try: msg = None - exit_code = archiver.run(sys.argv[1:]) + args = archiver.parse_args(sys.argv[1:]) + exit_code = archiver.run(args) except Error as e: msg = e.get_message() if e.traceback: diff --git a/borg/testsuite/archiver.py b/borg/testsuite/archiver.py index 78497e42a..8b30e4feb 100644 --- a/borg/testsuite/archiver.py +++ b/borg/testsuite/archiver.py @@ -93,7 +93,8 @@ def exec_cmd(*args, archiver=None, fork=False, exe=None, **kw): sys.stdout = sys.stderr = output = StringIO() if archiver is None: archiver = Archiver() - ret = archiver.run(list(args)) + args = archiver.parse_args(list(args)) + ret = archiver.run(args) return ret, output.getvalue() finally: sys.stdin, sys.stdout, sys.stderr = stdin, stdout, stderr From 4a1c99524436f870782c67929eedf4723637c90e Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sun, 1 Nov 2015 00:53:55 +0100 Subject: [PATCH 2/2] add --show-rc option enable "terminating with X status, rc N" output, fixes #351 this is needed for tools like borgweb (or in general: when the rc value / exit status should be logged for later review or directly seen on screen). this is off by default, so the output is less verbose (and also does not fail tests which counts lines). --- borg/archiver.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/borg/archiver.py b/borg/archiver.py index c5268cb52..50a4d7017 100644 --- a/borg/archiver.py +++ b/borg/archiver.py @@ -571,6 +571,8 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") common_parser = argparse.ArgumentParser(add_help=False, prog=prog) common_parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', default=False, help='verbose output') + common_parser.add_argument('--show-rc', dest='show_rc', action='store_true', default=False, + help='show/log the return code (rc)') common_parser.add_argument('--no-files-cache', dest='cache_files', action='store_false', help='do not load/update the file metadata cache used to detect unchanged files') common_parser.add_argument('--umask', dest='umask', type=lambda s: int(s, 8), default=RemoteRepository.umask, metavar='M', @@ -1061,9 +1063,9 @@ def main(): # pragma: no cover sys.stderr = io.TextIOWrapper(sys.stderr.buffer, sys.stderr.encoding, 'replace', line_buffering=True) setup_signal_handlers() archiver = Archiver() + msg = None + args = archiver.parse_args(sys.argv[1:]) try: - msg = None - args = archiver.parse_args(sys.argv[1:]) exit_code = archiver.run(args) except Error as e: msg = e.get_message() @@ -1081,16 +1083,17 @@ def main(): # pragma: no cover exit_code = EXIT_ERROR if msg: logger.error(msg) - exit_msg = 'terminating with %s status, rc %d' - if exit_code == EXIT_SUCCESS: - logger.info(exit_msg % ('success', exit_code)) - elif exit_code == EXIT_WARNING: - logger.warning(exit_msg % ('warning', exit_code)) - elif exit_code == EXIT_ERROR: - logger.error(exit_msg % ('error', exit_code)) - else: - # if you see 666 in output, it usually means exit_code was None - logger.error(exit_msg % ('abnormal', exit_code or 666)) + if args.show_rc: + exit_msg = 'terminating with %s status, rc %d' + if exit_code == EXIT_SUCCESS: + logger.info(exit_msg % ('success', exit_code)) + elif exit_code == EXIT_WARNING: + logger.warning(exit_msg % ('warning', exit_code)) + elif exit_code == EXIT_ERROR: + logger.error(exit_msg % ('error', exit_code)) + else: + # if you see 666 in output, it usually means exit_code was None + logger.error(exit_msg % ('abnormal', exit_code or 666)) sys.exit(exit_code)