From 4d2e1537f45d9e7e35adf41f5b286776461ab251 Mon Sep 17 00:00:00 2001 From: Subho Banerjee Date: Sun, 12 Sep 2021 19:32:25 -0500 Subject: [PATCH 1/2] adding a exit on failure flag --- dotbot/cli.py | 5 ++++- dotbot/dispatcher.py | 17 +++++++++++++++-- test/tests/exit-on-failure.bash | 19 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 test/tests/exit-on-failure.bash diff --git a/dotbot/cli.py b/dotbot/cli.py index 8883a6b..6c8ee43 100644 --- a/dotbot/cli.py +++ b/dotbot/cli.py @@ -42,6 +42,8 @@ def add_options(parser): help='disable color output') parser.add_argument('--version', action='store_true', help='show program\'s version number and exit') + parser.add_argument('-x', '--exit-on-failure', dest='exit_on_failure', action='store_true', + help='exit after first failed directive') def read_config(config_file): reader = ConfigReader(config_file) @@ -107,7 +109,8 @@ def main(): # default to directory of config file base_directory = os.path.dirname(os.path.abspath(options.config_file)) os.chdir(base_directory) - dispatcher = Dispatcher(base_directory, only=options.only, skip=options.skip, options=options) + dispatcher = Dispatcher(base_directory, only=options.only, skip=options.skip, + exit_on_failure=options.exit_on_failure, options=options) success = dispatcher.dispatch(tasks) if success: log.info('\n==> All tasks executed successfully') diff --git a/dotbot/dispatcher.py b/dotbot/dispatcher.py index 856befa..afeca96 100644 --- a/dotbot/dispatcher.py +++ b/dotbot/dispatcher.py @@ -5,12 +5,14 @@ from .messenger import Messenger from .context import Context class Dispatcher(object): - def __init__(self, base_directory, only=None, skip=None, options=Namespace()): + def __init__(self, base_directory, only=None, skip=None, exit_on_failure=False, + options=Namespace()): self._log = Messenger() self._setup_context(base_directory, options) self._load_plugins() self._only = only self._skip = skip + self._exit = exit_on_failure def _setup_context(self, base_directory, options): path = os.path.abspath( @@ -36,16 +38,27 @@ class Dispatcher(object): for plugin in self._plugins: if plugin.can_handle(action): try: - success &= plugin.handle(action, task[action]) + local_success = plugin.handle(action, task[action]) + if not local_success and self._exit: + # The action has failed exit + self._log.error('Action %s failed' % action) + return False + success &= local_success handled = True except Exception as err: self._log.error( 'An error was encountered while executing action %s' % action) self._log.debug(err) + if self._exit: + # There was an execption exit + return False if not handled: success = False self._log.error('Action %s not handled' % action) + if self._exit: + # Invalid action exit + return False return success def _load_plugins(self): diff --git a/test/tests/exit-on-failure.bash b/test/tests/exit-on-failure.bash new file mode 100644 index 0000000..b55bbe9 --- /dev/null +++ b/test/tests/exit-on-failure.bash @@ -0,0 +1,19 @@ +test_description='test exit on failure' +. '../test-lib.bash' + +test_expect_success 'setup' ' +echo "apple" > ${DOTFILES}/f +' + +test_expect_failure 'run' ' +run_dotbot -x < Date: Sun, 12 Sep 2021 19:40:37 -0500 Subject: [PATCH 2/2] better test case for exit-on-failure --- test/tests/exit-on-failure.bash | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/test/tests/exit-on-failure.bash b/test/tests/exit-on-failure.bash index b55bbe9..aead77b 100644 --- a/test/tests/exit-on-failure.bash +++ b/test/tests/exit-on-failure.bash @@ -2,18 +2,31 @@ test_description='test exit on failure' . '../test-lib.bash' test_expect_success 'setup' ' -echo "apple" > ${DOTFILES}/f +echo "apple" > ${DOTFILES}/f1 && +echo "orange" > ${DOTFILES}/f2 && +echo "pineapple" > ${DOTFILES}/f3 ' -test_expect_failure 'run' ' +test_expect_failure 'run_case1' ' run_dotbot -x <