From 7ffaa65482a59fa485e7a8f19fe07a33694fc157 Mon Sep 17 00:00:00 2001 From: Anish Athalye Date: Wed, 25 Mar 2020 21:38:39 -0400 Subject: Add --only and --except command-line arguments Internal to Dotbot, we use the name "skip" instead of "except", because the latter is a keyword, and using a name like "except_" didn't seem as nice. --- README.md | 18 ++++++++++++++++++ dotbot/cli.py | 6 +++++- dotbot/dispatcher.py | 8 +++++++- test/tests/except-multi.bash | 21 +++++++++++++++++++++ test/tests/except.bash | 31 +++++++++++++++++++++++++++++++ test/tests/only-multi.bash | 20 ++++++++++++++++++++ test/tests/only.bash | 31 +++++++++++++++++++++++++++++++ 7 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 test/tests/except-multi.bash create mode 100644 test/tests/except.bash create mode 100644 test/tests/only-multi.bash create mode 100644 test/tests/only.bash diff --git a/README.md b/README.md index 1aa5fa8..f5e43c6 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Dotbot makes installing your dotfiles as easy as `git clone $url && cd dotfiles - [Configuration](#configuration) - [Directives](#directives) ([Link](#link), [Create](#create), [Shell](#shell), [Clean](#clean), [Defaults](#defaults)) - [Plugins](#plugins) +- [Command-line Arguments](#command-line-arguments) - [Wiki][wiki] --- @@ -359,6 +360,23 @@ Plugins are loaded using the `--plugin` and `--plugin-dir` options, using either absolute paths or paths relative to the base directory. It is recommended that these options are added directly to the `install` script. +## Command-line Arguments + +Dotbot takes a number of command-line arguments; you can run Dotbot with +`--help`, e.g. by running `./install --help`, to see the full list of options. +Here, we highlight a couple that are particularly interesting. + +### `--only` + +You can call `./install --only [list of directives]`, such as `./install --only +link`, and Dotbot will only run those sections of the config file. + +### `--except` + +You can call `./install --except [list of directives]`, such as `./install +--except shell`, and Dotbot will run all the sections of the config file except +the ones listed. + ## Wiki Check out the [Dotbot wiki][wiki] for more information, tips and tricks, diff --git a/dotbot/cli.py b/dotbot/cli.py index 77bd439..258ea87 100644 --- a/dotbot/cli.py +++ b/dotbot/cli.py @@ -28,6 +28,10 @@ def add_options(parser): action='store_true', help='disable built-in plugins') parser.add_argument('--plugin-dir', action='append', dest='plugin_dirs', default=[], metavar='PLUGIN_DIR', help='load all plugins in PLUGIN_DIR') + parser.add_argument('--only', nargs='+', + help='only run specified directives', metavar='DIRECTIVE') + parser.add_argument('--except', nargs='+', dest='skip', + help='skip specified directives', metavar='DIRECTIVE') parser.add_argument('--no-color', dest='no_color', action='store_true', help='disable color output') parser.add_argument('--version', action='store_true', @@ -78,7 +82,7 @@ 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) + dispatcher = Dispatcher(base_directory, only=options.only, skip=options.skip) success = dispatcher.dispatch(tasks) if success: log.info('\n==> All tasks executed successfully') diff --git a/dotbot/dispatcher.py b/dotbot/dispatcher.py index 36eac02..10e4293 100644 --- a/dotbot/dispatcher.py +++ b/dotbot/dispatcher.py @@ -4,10 +4,12 @@ from .messenger import Messenger from .context import Context class Dispatcher(object): - def __init__(self, base_directory): + def __init__(self, base_directory, only=None, skip=None): self._log = Messenger() self._setup_context(base_directory) self._load_plugins() + self._only = only + self._skip = skip def _setup_context(self, base_directory): path = os.path.abspath( @@ -20,6 +22,10 @@ class Dispatcher(object): success = True for task in tasks: for action in task: + if self._only is not None and action not in self._only \ + or self._skip is not None and action in self._skip: + self._log.info('Skipping action %s' % action) + continue handled = False if action == 'defaults': self._context.set_defaults(task[action]) # replace, not update diff --git a/test/tests/except-multi.bash b/test/tests/except-multi.bash new file mode 100644 index 0000000..4193e66 --- /dev/null +++ b/test/tests/except-multi.bash @@ -0,0 +1,21 @@ +test_description='--except with multiple arguments' +. '../test-lib.bash' + +test_expect_success 'setup' ' +ln -s ${DOTFILES}/nonexistent ~/bad && touch ${DOTFILES}/y +' + +test_expect_success 'run' ' +run_dotbot --except clean shell < ~/x +- link: + ~/y: y +EOF +' + +test_expect_success 'test' ' +[ "$(readlink ~/bad | cut -d/ -f4-)" = "dotfiles/nonexistent" ] && + ! test -f ~/x && test -f ~/y +' diff --git a/test/tests/except.bash b/test/tests/except.bash new file mode 100644 index 0000000..356eaef --- /dev/null +++ b/test/tests/except.bash @@ -0,0 +1,31 @@ +test_description='--except' +. '../test-lib.bash' + +test_expect_success 'setup' ' +echo "apple" > ${DOTFILES}/x +' + +test_expect_success 'run' ' +run_dotbot --except link < ~/y +- link: + ~/x: x +EOF +' + +test_expect_success 'test' ' +grep "pear" ~/y && ! test -f ~/x +' + +test_expect_success 'run 2' ' +run_dotbot --except shell < ~/z +- link: + ~/x: x +' + +test_expect_success 'test' ' +grep "apple" ~/x && ! test -f ~/z +' diff --git a/test/tests/only-multi.bash b/test/tests/only-multi.bash new file mode 100644 index 0000000..e8d8362 --- /dev/null +++ b/test/tests/only-multi.bash @@ -0,0 +1,20 @@ +test_description='--only with multiple arguments' +. '../test-lib.bash' + +test_expect_success 'setup' ' +ln -s ${DOTFILES}/nonexistent ~/bad && touch ${DOTFILES}/y +' + +test_expect_success 'run' ' +run_dotbot --only clean shell < ~/x +- link: + ~/y: y +EOF +' + +test_expect_success 'test' ' +! test -f ~/bad && grep "x" ~/x && ! test -f ~/y +' diff --git a/test/tests/only.bash b/test/tests/only.bash new file mode 100644 index 0000000..5222881 --- /dev/null +++ b/test/tests/only.bash @@ -0,0 +1,31 @@ +test_description='--only' +. '../test-lib.bash' + +test_expect_success 'setup' ' +echo "apple" > ${DOTFILES}/x +' + +test_expect_success 'run' ' +run_dotbot --only shell < ~/y +- link: + ~/x: x +EOF +' + +test_expect_success 'test' ' +grep "pear" ~/y && ! test -f ~/x +' + +test_expect_success 'run 2' ' +run_dotbot --only link < ~/z +- link: + ~/x: x +' + +test_expect_success 'test' ' +grep "apple" ~/x && ! test -f ~/z +' -- cgit v1.2.3