New Upstream Release - dotdrop

Ready changes

Summary

Merged new upstream version: 1.13.0 (was: 1.12.11).

Resulting package

Built on 2023-05-24T09:44 (took 8m35s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases dotdrop

Lintian Result

Diff

diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644
index cd9ebe8..0000000
--- a/.coveragerc
+++ /dev/null
@@ -1 +0,0 @@
-[run] parallel=True
diff --git a/.github/workflows/snapcraft-release.yml b/.github/workflows/snapcraft-release.yml
index 8a0e5d4..c0ce4c8 100644
--- a/.github/workflows/snapcraft-release.yml
+++ b/.github/workflows/snapcraft-release.yml
@@ -8,10 +8,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
     - uses: actions/checkout@v3
+    - name: snapcraft setup
+      run: |
+        cp -r "${GITHUB_WORKSPACE}packages/snap" "${GITHUB_WORKSPACE}"
+        sed -i 's#source: ../../#source: \.#g' "${GITHUB_WORKSPACE}/snap/snapcraft.yaml"
     - uses: snapcore/action-build@v1
       id: build
-      with:
-        path: packages
     - uses: snapcore/action-publish@v1
       env:
         SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_LOGIN }}
diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml
index d042330..c2e83be 100644
--- a/.github/workflows/testing.yml
+++ b/.github/workflows/testing.yml
@@ -22,19 +22,16 @@ jobs:
         pip install -r tests-requirements.txt
         pip install -r requirements.txt
         npm install -g remark-cli remark-validate-links
+        sudo apt-get install shellcheck
     - name: Run with 1 worker
       run: |
         ./tests.sh
       env:
-        DOTDROP_FORCE_NODEBUG: yes
-        DOTDROP_NOBANNER: yes
         DOTDROP_WORKERS: 1
     - name: Run with 4 workers
       run: |
         ./tests.sh
       env:
-        DOTDROP_FORCE_NODEBUG: yes
-        DOTDROP_NOBANNER: yes
         DOTDROP_WORKERS: 4
     - name: Coveralls
       run: |
diff --git a/.gitignore b/.gitignore
index 1ea6460..6e6f809 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,16 @@
+# python stuff
 *.pyc
 __pycache__
-
-.coverage
-.coverage*
-
 dist/
 build/
 *.egg-info/
 tags
 env
 venv
+
+# coverage stuff
+.coverage
+.coverage*
 htmlcov
 
 # IDE
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b3222b8..8ba9bc7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -163,14 +163,16 @@ dynvariables:
 
 Dotdrop is tested with the use of the [tests.sh](/tests.sh) script.
 
-* Test for PEP8 compliance with `pycodestyle` and `pyflakes`
-* Run the unittest available in [tests directory](/tests)
-* Run the bash script tests in [tests-ng directory](/tests-ng)
+* Test for PEP8 compliance with `pylint`, `pycodestyle` and `pyflakes` (see [check-syntax.sh](/scripts/test-syntax.sh))
+* Test the documentation and links (see [check-doc.sh](/scripts/check-doc.sh))
+* Run the unittests in [tests directory](/tests) with pytest (see [check-unittest.sh](/scripts/check-unittests.sh))
+* Run the blackbox bash script tests in [tests-ng directory](/tests-ng) (see [check-tests-ng.sh](/scripts/check-tests-ng.sh))
 
 ## Testing with unittest
 
 All unittests are available in [the tests directory](/tests)
 and use [Python's unittest](https://docs.python.org/3/library/unittest.html).
+Those are run with the help of [pytest](https://docs.pytest.org/).
 
 The file [helpers.py](/tests/helpers.py) provides different helper methods
 for the tests.
@@ -178,7 +180,7 @@ for the tests.
 ## Testing with bash scripts
 
 The bash scripts are available in [tests-ng directory](/tests-ng).
-These test entire workflows by simulating the use of dotdrop from end to end
+These scripts test entire workflows by simulating the use of dotdrop with a blackbox approach
 for different use-cases (usually described in their filename or in the file header).
 
 Each script starts with the same boilerplate code that you can paste at the
diff --git a/README.md b/README.md
index 4a51c7e..e5206da 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,9 @@
-# <img src="https://raw.githubusercontent.com/deadc0de6/dotdrop/master/dotdrop.svg" width="100" height="100" align="left"> dotdrop
+# <img src="https://raw.githubusercontent.com/deadc0de6/dotdrop/master/assets/dotdrop.svg" width="100" height="100" align="left"> dotdrop
 <br/>
 <br/>
 
 [![GitHub release (latest by date)](https://img.shields.io/github/v/release/deadc0de6/dotdrop)](https://github.com/deadc0de6/dotdrop/releases/latest)
 [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0)
-[![GitHub Repo stars](https://badgen.net/github/stars/deadc0de6/dotdrop)](https://github.com/deadc0de6/dotdrop/)
-
-[![Last commit](https://badgen.net/github/last-commit/deadc0de6/dotdrop)](https://github.com/deadc0de6/dotdrop/commits/master)
-[![Commits since last release](https://img.shields.io/github/commits-since/deadc0de6/dotdrop/latest)](https://github.com/deadc0de6/dotdrop/)
 
 [![Tests Status](https://github.com/deadc0de6/dotdrop/workflows/tests/badge.svg?branch=master)](https://github.com/deadc0de6/dotdrop/actions)
 [![Doc Status](https://readthedocs.org/projects/dotdrop/badge/?version=latest)](https://dotdrop.readthedocs.io/en/latest/?badge=latest)
@@ -52,8 +48,7 @@ Features:
 * Associate transformations for storing encrypted/compressed dotfiles
 * Provide solutions for handling dotfiles containing sensitive information
 
-Also check out the [blog post](https://deadc0de.re/articles/dotfiles.html),
-the [example](#getting-started), the [documentation](https://dotdrop.readthedocs.io/) or
+Check the [example](#getting-started), the [documentation](https://dotdrop.readthedocs.io/) or
 how [people are using dotdrop](https://dotdrop.readthedocs.io/en/latest/misc/people-using-dotdrop/)
 for more.
 
diff --git a/dotdrop.svg b/assets/dotdrop.svg
similarity index 100%
rename from dotdrop.svg
rename to assets/dotdrop.svg
diff --git a/completion/generate.sh b/completion/generate.sh
index 5c1a984..c49bac8 100755
--- a/completion/generate.sh
+++ b/completion/generate.sh
@@ -13,17 +13,7 @@ if ! hash ${bin}; then
   exit 1
 fi
 
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found!"
-    exit 1
-  fi
-fi
-
-cur=$(dirname "$(${rl} "${0}")")
+cur=$(cd "$(dirname "${0}")" && pwd)
 opwd=$(pwd)
 
 # output files
@@ -34,11 +24,11 @@ dt_zsh="${compl}/_dotdrop-completion.zsh"
 dt_bash="${compl}/dotdrop-completion.bash"
 
 # generate for dotdrop.sh
-cd ${cur}/..
+cd "${cur}"/..
 docopt-completion ./dotdrop.sh --manual-zsh
-mv ./_dotdrop.sh ${dtsh_zsh}
+mv ./_dotdrop.sh "${dtsh_zsh}"
 docopt-completion ./dotdrop.sh --manual-bash
-mv ./dotdrop.sh.sh ${dtsh_bash}
+mv ./dotdrop.sh.sh "${dtsh_bash}"
 
 # generate for dotdrop
 vbin="virtualenv"
@@ -46,18 +36,19 @@ if ! hash ${vbin}; then
   echo "\"${vbin}\" not found!"
   exit 1
 fi
-cd ${cur}/..
+cd "${cur}"/..
 venv="/tmp/dotdrop-venv"
 ${vbin} -p python3 ${venv}
+# shellcheck source=/dev/null
 source ${venv}/bin/activate
 python setup.py install
 cd /tmp
 docopt-completion dotdrop --manual-zsh
-mv ./_dotdrop ${dt_zsh}
+mv ./_dotdrop "${dt_zsh}"
 docopt-completion dotdrop --manual-bash
-mv ./dotdrop.sh ${dt_bash}
+mv ./dotdrop.sh "${dt_bash}"
 deactivate
 rm -rf ${venv}
 
 # pivot back
-cd ${opwd}
+cd "${opwd}"
diff --git a/debian/changelog b/debian/changelog
index d4bb5eb..fc26abf 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+dotdrop (1.13.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Wed, 24 May 2023 09:36:49 -0000
+
 dotdrop (1.12.9-1) unstable; urgency=medium
 
   * New upstream version 1.12.9.
diff --git a/docs/README.md b/docs/README.md
index 24c1902..2024690 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -14,7 +14,6 @@ For more, check:
 
 * [A quick overview of dotdrop features](https://deadc0de.re/dotdrop/)
 * [The walkthrough example](https://github.com/deadc0de6/dotdrop#getting-started)
-* [The blogpost on dotdrop](https://deadc0de.re/articles/dotfiles.html)
 * [How people are using dotdrop](misc/people-using-dotdrop.md)
 
 For more config files examples, [search GitHub](https://github.com/search?q=filename%3Aconfig.yaml+dotdrop&type=Code).
diff --git a/docs/config/config-dotfiles.md b/docs/config/config-dotfiles.md
index 82c801b..e591628 100644
--- a/docs/config/config-dotfiles.md
+++ b/docs/config/config-dotfiles.md
@@ -51,8 +51,7 @@ executed when the dotfile is installed (that is, when
 the version present in dotdrop differs from the one
 in the filesystem).
 
-For example, let's consider
-[Vundle](https://github.com/VundleVim/Vundle.vim), used
+For example, let's consider Vundle, used
 to manage Vim's plugins.  The following action could
 be set to update and install the plugins when `vimrc` is
 deployed:
diff --git a/docs/config/config-file.md b/docs/config/config-file.md
index 099c804..5754516 100644
--- a/docs/config/config-file.md
+++ b/docs/config/config-file.md
@@ -335,7 +335,7 @@ Dotdrop should be able to handle `toml` config file however this
 feature hasn't been extensively tested.
 A base [config.toml](/config.toml) is available to get started.
 
-The script [yaml-to-toml.py](https://github.com/deadc0de6/dotdrop/blob/master/scripts/yaml-to-toml.py) allows to convert a `yaml` dotdrop
+The script [yaml_to_toml.py](https://github.com/deadc0de6/dotdrop/blob/master/scripts/yaml_to_toml.py) allows to convert a `yaml` dotdrop
 config file to `toml`.
 
 For more see issue [#343](https://github.com/deadc0de6/dotdrop/issues/343).
\ No newline at end of file
diff --git a/docs/config/config-variables.md b/docs/config/config-variables.md
index 02ba751..e9d63c7 100644
--- a/docs/config/config-variables.md
+++ b/docs/config/config-variables.md
@@ -41,4 +41,16 @@ will result in the following available variables:
 * dvar1: `dvar1`
 * dvar2: `dvar1 dvar2`
 * dvar3: `dvar1 dvar2 dvar3`
-* dvar4: `var1 var2 var3`
\ No newline at end of file
+* dvar4: `var1 var2 var3`
+
+Config variables can be nested as shown below:
+```yaml
+variables:
+  rofi:
+    background_color: "rgba ( 33, 33, 33, 100 % );"
+  polybar:
+    background_color: "#cc222222"
+```
+
+Where the above would be referenced using `{{@@ rofi.background_color @@}}`
+and `{{@@ polybar.background_color @@}}`.
\ No newline at end of file
diff --git a/docs/howto/test-latest-dotdrop.md b/docs/howto/test-latest-dotdrop.md
new file mode 100644
index 0000000..abe4cfa
--- /dev/null
+++ b/docs/howto/test-latest-dotdrop.md
@@ -0,0 +1,14 @@
+# Test latest dotdrop
+
+If you installed dotdrop from a package but want to test
+you current setup with the latest version from git
+(or from a specific branch), you can do the following
+
+```bash
+$ cd /tmp/
+$ git clone https://github.com/deadc0de6/dotdrop.git
+$ cd dotdrop
+## switch to a specific branch if needed
+$ git checkout <branch-name>
+$ ./dotdrop.sh --cfg <path-to-your-config-file.yaml>
+```
\ No newline at end of file
diff --git a/docs/installation.md b/docs/installation.md
index 808695f..4059a77 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -163,7 +163,7 @@ $ brew install dotdrop
 
 ## Debian
 
-[Debian package](https://packages.debian.org/sid/dotdrop)
+[Debian package](https://packages.debian.org/sid/dotdrop) in sid (unstable)
 
 Install dotdrop
 ```bash
@@ -172,7 +172,7 @@ sudo apt install dotdrop
 
 ## Ubuntu
 
-[Ubuntu package](https://packages.ubuntu.com/lunar/dotdrop)
+[Ubuntu package](https://packages.ubuntu.com/lunar/dotdrop) in lunar (23.04)
 
 Install dotdrop
 ```bash
@@ -223,11 +223,9 @@ dotdrop depends on the following tools:
 
 * `diff` (unless a different tool is used, see [diff_command](config/config-config.md#config-block))
 * `git` (only if using the entry point script [dotdrop.sh](https://github.com/deadc0de6/dotdrop/blob/master/dotdrop.sh))
-* `readlink` or `realpath` (only if using the entry point script [dotdrop.sh](https://github.com/deadc0de6/dotdrop/blob/master/dotdrop.sh))
 
 For macOS users, make sure to install the below packages through [Homebrew](https://brew.sh/):
 
-* [coreutils](https://formulae.brew.sh/formula/coreutils) (only if using the entry point script [dotdrop.sh](https://github.com/deadc0de6/dotdrop/blob/master/dotdrop.sh) which uses realpath)
 * [libmagic](https://formulae.brew.sh/formula/libmagic) (for python-magic)
 
 For WSL (Windows Subsystem for Linux), make sure to install `python-magic-bin`:
diff --git a/dotdrop.sh b/dotdrop.sh
index 70eb9ba..a4b86e5 100755
--- a/dotdrop.sh
+++ b/dotdrop.sh
@@ -2,24 +2,10 @@
 # author: deadc0de6 (https://github.com/deadc0de6)
 # Copyright (c) 2017, deadc0de6
 
-# check for readlink/realpath presence
-# https://github.com/deadc0de6/dotdrop/issues/6
-rl="readlink -f"
-
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found!" && exit 1
-  fi
-fi
-
 # setup variables
 args=("$@")
-cur=$(dirname "$(${rl} "${0}")")
+cur=$(cd "$(dirname "${0}")" && pwd)
 opwd=$(pwd)
-cfg="${cur}/config.yaml"
-sub="dotdrop"
 
 # pivot
 cd "${cur}" || { echo "Directory \"${cur}\" doesn't exist, aborting." && exit 1; }
@@ -33,7 +19,7 @@ fi
 # check python executable
 pybin="python3"
 hash ${pybin} 2>/dev/null || pybin="python"
-[[ "`${pybin} -V 2>&1`" =~ "Python 3" ]] || { echo "install Python 3" && exit 1; }
+[[ "$(${pybin} -V 2>&1)" =~ "Python 3" ]] || { echo "install Python 3" && exit 1; }
 
 # launch dotdrop
 PYTHONPATH=dotdrop:${PYTHONPATH} ${pybin} -m dotdrop.dotdrop "${args[@]}"
diff --git a/dotdrop/cfg_aggregator.py b/dotdrop/cfg_aggregator.py
index 381a388..c1a79c4 100644
--- a/dotdrop/cfg_aggregator.py
+++ b/dotdrop/cfg_aggregator.py
@@ -19,7 +19,8 @@ from dotdrop.profile import Profile
 from dotdrop.action import Action, Transform
 from dotdrop.logger import Logger
 from dotdrop.utils import strip_home, debug_list, debug_dict
-from dotdrop.exceptions import UndefinedException, YamlException
+from dotdrop.exceptions import UndefinedException, YamlException, \
+    ConfigException
 
 
 TILD = '~'
@@ -273,37 +274,48 @@ class CfgAggregator:
                                reloading=reloading,
                                debug=self.debug)
 
+        self.log.dbg('parsing cfgyaml into cfg_aggregator')
+
         # settings
+        self.log.dbg('parsing settings')
         self.settings = Settings.parse(None, self.cfgyaml.settings)
         self.key_prefix = self.settings.key_prefix
         self.key_separator = self.settings.key_separator
 
         # dotfiles
+        self.log.dbg('parsing dotfiles')
         self.dotfiles = Dotfile.parse_dict(self.cfgyaml.dotfiles)
         debug_list('dotfiles', self.dotfiles, self.debug)
 
         # profiles
+        self.log.dbg('parsing profiles')
         self.profiles = Profile.parse_dict(self.cfgyaml.profiles)
         debug_list('profiles', self.profiles, self.debug)
 
         # actions
+        self.log.dbg('parsing actions')
         self.actions = Action.parse_dict(self.cfgyaml.actions)
         debug_list('actions', self.actions, self.debug)
 
         # trans_r
+        self.log.dbg('parsing trans_r')
         self.trans_r = Transform.parse_dict(self.cfgyaml.trans_r)
         debug_list('trans_r', self.trans_r, self.debug)
 
         # trans_w
+        self.log.dbg('parsing trans_w')
         self.trans_w = Transform.parse_dict(self.cfgyaml.trans_w)
         debug_list('trans_w', self.trans_w, self.debug)
 
         # variables
+        self.log.dbg('parsing variables')
         self.variables = self.cfgyaml.variables
         debug_dict('variables', self.variables, self.debug)
 
+        self.log.dbg('enrich variables')
         self._enrich_variables()
 
+        self.log.dbg('patch keys...')
         # patch dotfiles in profiles
         self._patch_keys_to_objs(self.profiles,
                                  "dotfiles", self.get_dotfile)
@@ -332,6 +344,8 @@ class CfgAggregator:
                                  self._get_trans_w_args(self.get_trans_w),
                                  islist=False)
 
+        self.log.dbg('done parsing cfgyaml into cfg_aggregator')
+
     def _enrich_variables(self):
         """
         enrich available variables
@@ -400,7 +414,7 @@ class CfgAggregator:
                     err = f'{container} does not contain'
                     err += f' a {keys} entry named {key}'
                     self.log.err(err)
-                    raise Exception(err)
+                    raise ConfigException(err)
                 objects.append(obj)
             if not islist:
                 objects = objects[0]
diff --git a/dotdrop/cfg_yaml.py b/dotdrop/cfg_yaml.py
index 8c57964..984d32b 100644
--- a/dotdrop/cfg_yaml.py
+++ b/dotdrop/cfg_yaml.py
@@ -188,7 +188,7 @@ class CfgYaml:
         self._add_variables(dvariables, template=False)
 
         # now template variables and dynvariables from the same pool
-        self._rec_resolve_variables(self.variables)
+        self.variables = self._rec_resolve_variables(self.variables)
         # and execute dvariables
         # since this is done after recursively resolving variables
         # and dynvariables this means that variables referencing
@@ -256,7 +256,7 @@ class CfgYaml:
         # process imported variables (import_variables)
         newvars = self._import_variables()
         self._clear_profile_vars(newvars)
-        self._add_variables(newvars)
+        self._add_variables(newvars, prio=True)
 
         # process imported actions (import_actions)
         self._import_actions()
@@ -873,7 +873,7 @@ class CfgYaml:
         self._redefine_templater()
         if template:
             # rec resolve variables with new ones
-            self._rec_resolve_variables(self.variables)
+            self.variables = self._rec_resolve_variables(self.variables)
         if shell and new:
             # shell exec
             self._shell_exec_dvars(self.variables, keys=new.keys())
@@ -1038,11 +1038,11 @@ class CfgYaml:
                                     mandatory=False)
 
             merged = self._merge_dict(dvar, var)
-            self._rec_resolve_variables(merged)
+            merged = self._rec_resolve_variables(merged)
             if dvar.keys():
                 self._shell_exec_dvars(merged, keys=dvar.keys())
             self._clear_profile_vars(merged)
-            newvars = self._merge_dict(newvars, merged)
+            newvars = self._merge_dict(merged, newvars)
         if self._debug:
             self._debug_dict('imported variables', newvars)
         return newvars
@@ -1398,11 +1398,11 @@ class CfgYaml:
         template an item using the templategen
         will raise an exception if template failed and exc_if_fail
         """
-        if not Templategen.var_is_template(item):
+        if not Templategen.string_is_template(item):
             return item
         try:
             val = item
-            while Templategen.var_is_template(val):
+            while Templategen.string_is_template(val):
                 val = self._tmpl.generate_string(val)
         except UndefinedException as exc:
             if exc_if_fail:
@@ -1502,14 +1502,21 @@ class CfgYaml:
         templ = Templategen(variables=var,
                             func_file=func_files,
                             filter_file=filter_files)
+        newvars = variables.copy()
         for k in variables.keys():
             val = variables[k]
             while Templategen.var_is_template(val):
-                val = templ.generate_string(val)
-                variables[k] = val
-                templ.update_variables(variables)
-        if variables is self.variables:
+                val = templ.generate_string_or_dict(val)
+                if isinstance(val, dict):
+                    for sub in val:
+                        subkey = f'{k}.{sub}'
+                        newvars[subkey] = val[sub]
+                else:
+                    newvars[k] = val
+                templ.update_variables(newvars)
+        if newvars is self.variables:
             self._redefine_templater()
+        return newvars
 
     def _get_profile_included_vars(self):
         """
@@ -1748,6 +1755,7 @@ class CfgYaml:
             if self._debug:
                 self._dbg(f'{k}: `{val}` -> {out}')
             dic[k] = out
+            self._debug_dict('dynvars after', dic)
 
     @classmethod
     def _check_minversion(cls, minversion):
diff --git a/dotdrop/dotdrop.py b/dotdrop/dotdrop.py
index 14094ce..939c201 100644
--- a/dotdrop/dotdrop.py
+++ b/dotdrop/dotdrop.py
@@ -24,7 +24,8 @@ from dotdrop.utils import get_tmpdir, removepath, \
     adapt_workers, check_version, pivot_path
 from dotdrop.linktypes import LinkTypes
 from dotdrop.exceptions import YamlException, \
-    UndefinedException, UnmetDependency
+    UndefinedException, UnmetDependency, \
+    ConfigException, OptionsException
 
 LOG = Logger()
 TRANS_SUFFIX = 'trans'
@@ -140,9 +141,10 @@ def _dotfile_compare(opts, dotfile, tmp):
     ignores = patch_ignores(ignores, dotfile.dst, debug=opts.debug)
 
     insttmp = None
-    if dotfile.template and Templategen.is_template(src,
-                                                    ignore=ignores,
-                                                    debug=opts.debug):
+    if dotfile.template and \
+        Templategen.path_is_template(src,
+                                     ignore=ignores,
+                                     debug=opts.debug):
         # install dotfile to temporary dir for compare
         ret, err, insttmp = inst.install_to_temp(templ, tmp, src, dotfile.dst,
                                                  is_template=True,
@@ -216,7 +218,7 @@ def _dotfile_install(opts, dotfile, tmpdir=None):
     ignores = list(set(opts.install_ignore + dotfile.instignore))
     ignores = patch_ignores(ignores, dotfile.dst, debug=opts.debug)
 
-    is_template = dotfile.template and Templategen.is_template(
+    is_template = dotfile.template and Templategen.path_is_template(
         dotfile.src,
         ignore=ignores,
     )
@@ -242,7 +244,7 @@ def _dotfile_install(opts, dotfile, tmpdir=None):
                 return False, dotfile.key, None
             src = tmp
         # make sure to re-evaluate if is template
-        is_template = dotfile.template and Templategen.is_template(
+        is_template = dotfile.template and Templategen.path_is_template(
             src,
             ignore=ignores,
         )
@@ -388,7 +390,7 @@ def _workdir_enum(opts):
         if dotfile.link == LinkTypes.NOLINK:
             # ignore not link files
             continue
-        if not Templategen.is_template(src):
+        if not Templategen.path_is_template(src):
             # ignore not template
             continue
         newpath = pivot_path(dotfile.dst, opts.workdir,
@@ -581,7 +583,7 @@ def cmd_files(opts):
     for dotfile in opts.dotfiles:
         if opts.files_templateonly:
             src = os.path.join(opts.dotpath, dotfile.src)
-            if not Templategen.is_template(src):
+            if not Templategen.path_is_template(src):
                 continue
         if opts.files_grepable:
             fmt = f'{dotfile.key},'
@@ -745,7 +747,7 @@ def _detail(dotpath, dotfile):
     path = os.path.join(dotpath, os.path.expanduser(dotfile.src))
     if not os.path.isdir(path):
         template = 'no'
-        if dotfile.template and Templategen.is_template(path):
+        if dotfile.template and Templategen.path_is_template(path):
             template = 'yes'
         LOG.sub(f'{path} (template:{template})')
     else:
@@ -753,7 +755,7 @@ def _detail(dotpath, dotfile):
             for file in files:
                 fpath = os.path.join(root, file)
                 template = 'no'
-                if dotfile.template and Templategen.is_template(fpath):
+                if dotfile.template and Templategen.path_is_template(fpath):
                     template = 'yes'
                 LOG.sub(f'{fpath} (template:{template})')
 
@@ -877,10 +879,16 @@ def main():
     try:
         opts = Options()
     except YamlException as exc:
-        LOG.err(f'config error: {exc}')
+        LOG.err(f'error (yaml): {exc}')
+        return False
+    except ConfigException as exc:
+        LOG.err(f'error (config): {exc}')
         return False
     except UndefinedException as exc:
-        LOG.err(f'config error: {exc}')
+        LOG.err(f'error (deps): {exc}')
+        return False
+    except OptionsException as exc:
+        LOG.err(f'error (options): {exc}')
         return False
 
     if opts.debug:
diff --git a/dotdrop/exceptions.py b/dotdrop/exceptions.py
index 1c2503a..f5df6ed 100644
--- a/dotdrop/exceptions.py
+++ b/dotdrop/exceptions.py
@@ -10,6 +10,14 @@ class YamlException(Exception):
     """exception in CfgYaml"""
 
 
+class ConfigException(Exception):
+    """exception in config parsing/aggregation"""
+
+
+class OptionsException(Exception):
+    """dotdrop options exception"""
+
+
 class UndefinedException(Exception):
     """exception in templating"""
 
diff --git a/dotdrop/linktypes.py b/dotdrop/linktypes.py
index 08b2b9d..1279f47 100644
--- a/dotdrop/linktypes.py
+++ b/dotdrop/linktypes.py
@@ -25,7 +25,7 @@ class LinkTypes(IntEnum):
         try:
             return key if isinstance(key, cls) else cls[key.upper()]
         except KeyError as exc:
-            if default:
+            if default and isinstance(default, cls):
                 return default
             err = f'bad {cls.__name__} value: "{key}"'
             raise ValueError(err) from exc
diff --git a/dotdrop/options.py b/dotdrop/options.py
index 9c8f78d..2ea8231 100644
--- a/dotdrop/options.py
+++ b/dotdrop/options.py
@@ -20,7 +20,7 @@ from dotdrop.logger import Logger
 from dotdrop.cfg_aggregator import CfgAggregator
 from dotdrop.action import Action
 from dotdrop.utils import uniq_list, debug_list, debug_dict
-from dotdrop.exceptions import YamlException
+from dotdrop.exceptions import YamlException, OptionsException
 
 ENV_PROFILE = 'DOTDROP_PROFILE'
 ENV_CONFIG = 'DOTDROP_CONFIG'
@@ -157,6 +157,8 @@ class Options(AttrMonitor):
         # selected profile
         self.profile = self.args['--profile']
         self.confpath = self._get_config_path()
+        self.confpath = os.path.abspath(self.confpath)
+        self.log.dbg(f'config abs path: {self.confpath}')
         if not self.confpath:
             raise YamlException('no config file found')
         if not os.path.exists(self.confpath):
@@ -216,36 +218,45 @@ class Options(AttrMonitor):
         """get the config path"""
         # cli provided
         if self.args['--cfg']:
+            self.log.dbg(f'config from --cfg {self.args["--cfg"]}')
             return os.path.expanduser(self.args['--cfg'])
 
         # environment variable provided
         if ENV_CONFIG in os.environ:
+            self.log.dbg(f'config from env {ENV_CONFIG}')
             return os.path.expanduser(os.environ[ENV_CONFIG])
 
         # look in current directory
         if os.path.exists(CONFIGFILEYAML):
+            self.log.dbg(f'config from yaml in current dir {CONFIGFILEYAML}')
             return CONFIGFILEYAML
 
         # look in current directory
         if os.path.exists(CONFIGFILETOML):
+            self.log.dbg(f'config from toml in current dir {CONFIGFILETOML}')
             return CONFIGFILETOML
 
         path = self._get_config_from_env(CONFIGFILEYAML)
         if path:
+            self.log.dbg(f'config from env with {CONFIGFILEYAML}')
             return path
 
         path = self._get_config_from_env(CONFIGFILETOML)
         if path:
+            self.log.dbg(f'config from env with {CONFIGFILETOML}')
             return path
 
         path = self._get_config_from_fs(CONFIGFILEYAML)
         if path:
+            self.log.dbg(f'config from fs with {CONFIGFILEYAML}')
             return path
 
         path = self._get_config_from_fs(CONFIGFILETOML)
         if path:
+            self.log.dbg(f'config from fs with {CONFIGFILETOML}')
             return path
 
+        self.log.dbg('no config file found')
         return None
 
     def _header(self):
@@ -421,4 +432,4 @@ class Options(AttrMonitor):
 
     def _attr_set(self, attr):
         """error when some inexistent attr is set"""
-        raise Exception(f'bad option: {attr}')
+        raise OptionsException(f'bad option: {attr}')
diff --git a/dotdrop/templategen.py b/dotdrop/templategen.py
index a3e9865..8e75f9d 100644
--- a/dotdrop/templategen.py
+++ b/dotdrop/templategen.py
@@ -110,6 +110,38 @@ class Templategen:
             err = f'undefined variable: {exc.message}'
             raise UndefinedException(err) from exc
 
+    def generate_dict(self, dic):
+        """
+        template each entry of the dict where only
+        the value of each entry is templated (recursively)
+        may raise a UndefinedException
+        in case a variable is undefined
+        """
+        if not dic:
+            return dic
+        for key in dic:
+            value = dic[key]
+            if isinstance(value, str):
+                dic[key] = self.generate_string(value)
+                continue
+            if isinstance(value, dict):
+                dic[key] = self.generate_dict(value)
+                continue
+            continue
+        return dic
+
+    def generate_string_or_dict(self, content):
+        """
+        render template from string or dict
+        may raise a UndefinedException
+        in case a variable is undefined
+        """
+        if isinstance(content, str):
+            return self.generate_string(content)
+        if isinstance(content, dict):
+            return self.generate_dict(content)
+        raise UndefinedError(f'could not template {content}')
+
     def add_tmp_vars(self, newvars=None):
         """add vars to the globals, make sure to call restore_vars"""
         saved_variables = self.variables.copy()
@@ -217,7 +249,7 @@ class Templategen:
         return data.decode('utf-8', 'replace')
 
     @staticmethod
-    def is_template(path, ignore=None, debug=False):
+    def path_is_template(path, ignore=None, debug=False):
         """recursively check if any file is a template within path"""
         if debug:
             LOG.dbg(f'is template: {path}', force=True)
@@ -240,19 +272,45 @@ class Templategen:
             fpath = os.path.join(path, entry)
             if not os.path.isfile(fpath):
                 # recursively explore directory
-                if Templategen.is_template(fpath, ignore=ignore, debug=debug):
+                if Templategen.path_is_template(fpath,
+                                                ignore=ignore,
+                                                debug=debug):
                     return True
             else:
                 # check if file is a template
-                if Templategen._is_template(fpath, ignore=ignore, debug=debug):
+                if Templategen._is_template(fpath,
+                                            ignore=ignore,
+                                            debug=debug):
                     return True
         return False
 
     @staticmethod
-    def var_is_template(string):
+    def string_is_template(string):
         """check if variable contains template(s)"""
         return VAR_START in str(string)
 
+    @staticmethod
+    def dict_is_template(dic):
+        """check if dict contains template(s)"""
+        for key in dic:
+            value = dic[key]
+            if isinstance(value, str):
+                isit = Templategen.string_is_template(value)
+                if isit:
+                    return True
+            elif isinstance(value, dict):
+                return Templategen.dict_is_template(value)
+        return False
+
+    @staticmethod
+    def var_is_template(something):
+        """check if string or dict is template"""
+        if isinstance(something, str):
+            return Templategen.string_is_template(something)
+        if isinstance(something, dict):
+            return Templategen.dict_is_template(something)
+        return False
+
     @staticmethod
     def _is_template(path, ignore, debug=False):
         """test if file pointed by path is a template"""
diff --git a/dotdrop/updater.py b/dotdrop/updater.py
index 97e5a77..f5ccaf5 100644
--- a/dotdrop/updater.py
+++ b/dotdrop/updater.py
@@ -166,8 +166,9 @@ class Updater:
         return tmp
 
     def _is_template(self, path):
-        if not Templategen.is_template(path, ignore=self.ignores,
-                                       debug=self.debug):
+        if not Templategen.path_is_template(path,
+                                            ignore=self.ignores,
+                                            debug=self.debug):
             self.log.dbg(f'{path} is NO template')
             return False
         self.log.warn(f'{path} uses template, update manually')
diff --git a/dotdrop/utils.py b/dotdrop/utils.py
index 6b5bf00..dc79987 100644
--- a/dotdrop/utils.py
+++ b/dotdrop/utils.py
@@ -354,6 +354,7 @@ def dependencies_met():
 
     # check python deps
 # pylint: disable=C0415
+
     # python-magic
     name = 'python-magic'
     err = f'missing python module \"{name}\"'
@@ -372,7 +373,7 @@ def dependencies_met():
         from docopt import docopt
         assert docopt
     except ImportError as exc:
-        raise Exception(err) from exc
+        raise UnmetDependency(err) from exc
 
     # jinja2
     name = 'jinja2'
@@ -381,7 +382,7 @@ def dependencies_met():
         import jinja2
         assert jinja2
     except ImportError as exc:
-        raise Exception(err) from exc
+        raise UnmetDependency(err) from exc
 
     # ruamel.yaml
     name = 'ruamel.yaml'
@@ -390,7 +391,7 @@ def dependencies_met():
         from ruamel.yaml import YAML
         assert YAML
     except ImportError as exc:
-        raise Exception(err) from exc
+        raise UnmetDependency(err) from exc
 
     # toml
     name = 'toml'
@@ -399,7 +400,7 @@ def dependencies_met():
         import toml
         assert toml
     except ImportError as exc:
-        raise Exception(err) from exc
+        raise UnmetDependency(err) from exc
 
     # distro
     name = 'distro'
@@ -408,7 +409,7 @@ def dependencies_met():
         import distro
         assert distro
     except ImportError as exc:
-        raise Exception(err) from exc
+        raise UnmetDependency(err) from exc
 
 # pylint: enable=C0415
 
@@ -495,17 +496,31 @@ def debug_dict(title, elems, debug):
 
 
 def check_version():
-    """check dotdrop version on github and compare with current"""
+    """
+    get dotdrop latest version on github
+    compare with "version"
+    and emit warning in case new version is available
+    """
     url = 'https://api.github.com/repos/deadc0de6/dotdrop/releases/latest'
-    req = requests.get(url, timeout=1)
+    try:
+        req = requests.get(url, timeout=1)
+    except requests.exceptions.RequestException:
+        # request failed
+        return
     if not req:
+        # request failed
+        return
+    if req.status_code != 200:
+        # request failed
         return
+    # get json
     try:
         latest = req.json()['name']
     except json.decoder.JSONDecodeError:
         return
     except ValueError:
         return
+    # compare
     if latest.startswith('v'):
         latest = latest[1:]
     if version.parse(VERSION) < version.parse(latest):
diff --git a/dotdrop/version.py b/dotdrop/version.py
index c0946a2..d511c0f 100644
--- a/dotdrop/version.py
+++ b/dotdrop/version.py
@@ -3,4 +3,4 @@ author: deadc0de6 (https://github.com/deadc0de6)
 Copyright (c) 2018, deadc0de6
 """
 
-__version__ = '1.12.9'
+__version__ = '1.13.0'
diff --git a/manpage/dotdrop.1 b/manpage/dotdrop.1
index 32224ce..9ea3ffa 100644
--- a/manpage/dotdrop.1
+++ b/manpage/dotdrop.1
@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
-.TH dotdrop 1 "25 January 2023" "dotdrop-1.12.9" "Save your dotfiles once, deploy them everywhere"
+.TH dotdrop 1 "22 April 2023" "dotdrop-1.13.0" "Save your dotfiles once, deploy them everywhere"
 .SH NAME
 \fBdotdrop \fP- save your dotfiles once, deploy them everywhere
 \fB
diff --git a/manpage/generate.sh b/manpage/generate.sh
index b47a904..92a9398 100755
--- a/manpage/generate.sh
+++ b/manpage/generate.sh
@@ -3,14 +3,7 @@
 # Copyright (c) 2023, deadc0de6
 
 # get current working directory
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found!" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
+cur=$(cd "$(dirname "${0}")" && pwd)
 
 # extract version from git latest tag
 #version=$(git describe --tags --abbrev=0)
diff --git a/mkdocs.yml b/mkdocs.yml
index dd0e657..8b82519 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -43,6 +43,7 @@ nav:
     - 'Prompt user for variables': 'howto/prompt-user-for-variables.md'
     - 'Share content across dotfiles': 'howto/sharing-content.md'
     - 'Symlink dotfiles': 'howto/symlink-dotfiles.md'
+    - 'Test latest dotdrop': 'howto/test-latest-dotdrop.md'
     - '': ''
     - '': ''
 markdown_extensions:
diff --git a/packages/arch-dotdrop/PKGBUILD b/packages/arch-dotdrop/PKGBUILD
index b354c44..4dfb4d1 100644
--- a/packages/arch-dotdrop/PKGBUILD
+++ b/packages/arch-dotdrop/PKGBUILD
@@ -24,5 +24,7 @@ package() {
   install -Dm644 ${srcdir}/${pkgname}/completion/dotdrop-completion.bash "${pkgdir}/usr/share/bash-completion/completions/${pkgname}"
   install -Dm644 ${srcdir}/${pkgname}/completion/_dotdrop-completion.zsh "${pkgdir}/usr/share/zsh/site-functions/_${pkgname}"
   install -Dm644 ${srcdir}/${pkgname}/completion/dotdrop.fish "${pkgdir}/usr/share/fish/completions/${pkgname}.fish"
+  install -Dm644 ${srcdir}/${pkgname}/LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
+  install -Dm644 ${srcdir}/${pkgname}/README.md "${pkgdir}/usr/share/doc/${pkgname}/README.md"
 }
 
diff --git a/packages/genpkg.sh b/packages/genpkg.sh
index 080f0f3..f4916a6 100755
--- a/packages/genpkg.sh
+++ b/packages/genpkg.sh
@@ -8,26 +8,17 @@
 up()
 {
   # update pkgver
-  [ "${1}" != "" ] && sed -i "s/^pkgver=.*$/pkgver=${1}/g" ${pkgfile}
+  [ "${1}" != "" ] && sed -i "s/^pkgver=.*$/pkgver=${1}/g" "${pkgfile}"
   # create srcinfo
   rm -f .SRCINFO
   makepkg --printsrcinfo > .SRCINFO
 }
 
 # pivot
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found!" && exit 1
-  fi
-fi
-# cur
-cur=`dirname $(${rl} "${0}")`
-opwd=`pwd`
+cur=$(cd "$(dirname "${0}")" && pwd)
+opwd=$(pwd)
 pkgfile="PKGBUILD"
-cd ${cur}
+cd "${cur}" || exit 1
 
 ########################
 # update arch package
@@ -35,10 +26,10 @@ cd ${cur}
 ########################
 dir="arch-dotdrop"
 echo "doing ${dir} ..."
-cd ${dir}
-version="`git describe --abbrev=0 --tags | sed 's/^v//g'`"
-up ${version}
-cd ${OLDPWD}
+cd ${dir} || exit 1
+version="$(git describe --abbrev=0 --tags | sed 's/^v//g')"
+up "${version}"
+cd "${OLDPWD}" || exit 1
 
 #########################
 ## update arch package
@@ -53,4 +44,4 @@ cd ${OLDPWD}
 #cd ${OLDPWD}
 
 # pivot back
-cd ${opwd}
+cd "${opwd}" || exit
diff --git a/scripts/change-link.py b/scripts/change_link.py
similarity index 100%
rename from scripts/change-link.py
rename to scripts/change_link.py
diff --git a/test-doc.sh b/scripts/check-doc.sh
similarity index 95%
rename from test-doc.sh
rename to scripts/check-doc.sh
index 7997153..6bb3193 100755
--- a/test-doc.sh
+++ b/scripts/check-doc.sh
@@ -2,6 +2,9 @@
 # author: deadc0de6 (https://github.com/deadc0de6)
 # Copyright (c) 2022, deadc0de6
 
+# stop on first error
+set -e
+
 ## test doc external links
 find . -type f -iname '*.md' | while read -r line; do
   ./scripts/check_links.py "${line}"
diff --git a/scripts/check-syntax.sh b/scripts/check-syntax.sh
new file mode 100755
index 0000000..f533e88
--- /dev/null
+++ b/scripts/check-syntax.sh
@@ -0,0 +1,116 @@
+#!/bin/sh
+# author: deadc0de6 (https://github.com/deadc0de6)
+# Copyright (c) 2022, deadc0de6
+
+# stop on first error
+set -e
+
+# ensure binaries are here
+if ! which shellcheck >/dev/null 2>&1; then
+  echo "Install shellcheck"
+  exit 1
+fi
+echo "=> shellcheck version:"
+shellcheck --version
+
+# python tools versions
+if ! which pylint >/dev/null 2>&1; then
+  echo "Install pylint"
+  exit 1
+fi
+echo "=> pylint version:"
+pylint --version
+
+if ! which pycodestyle >/dev/null 2>&1; then
+  echo "Install pycodestyle"
+  exit 1
+fi
+echo "=> pycodestyle version:"
+pycodestyle --version
+
+if ! which pyflakes >/dev/null 2>&1; then
+  echo "Install pyflakes"
+  exit 1
+fi
+echo "=> pyflakes version:"
+pyflakes --version
+
+# PEP8 tests
+# W503: Line break occurred before a binary operator
+# W504: Line break occurred after a binary operator
+echo "---------------------------------"
+echo "checking dotdrop with pycodestyle"
+pycodestyle --ignore=W503,W504 dotdrop/
+pycodestyle scripts/
+
+# pyflakes tests
+echo "------------------------------"
+echo "checking dotdrop with pyflakes"
+pyflakes dotdrop/
+
+# pylint
+echo "----------------------------"
+echo "checking dotdrop with pylint"
+# https://pylint.pycqa.org/en/latest/user_guide/checkers/features.html
+# R0902: too-many-instance-attributes
+# R0913: too-many-arguments
+# R0903: too-few-public-methods
+# R0914: too-many-locals
+# R0915: too-many-statements
+# R0912: too-many-branches
+# R0911: too-many-return-statements
+# R0904: too-many-public-methods
+pylint \
+  --disable=R0902 \
+  --disable=R0913 \
+  --disable=R0903 \
+  --disable=R0914 \
+  --disable=R0915 \
+  --disable=R0912 \
+  --disable=R0911 \
+  --disable=R0904 \
+  dotdrop/
+
+# check shell scripts
+# SC2002: Useless cat
+# SC2126: Consider using grep -c instead of grep|wc -l
+# SC2129: Consider using { cmd1; cmd2; } >> file instead of individual redirects
+# SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly with $?
+# SC1004: This backslash+linefeed is literal. Break outside single quotes if you just want to break the line
+echo "--------------------------------------"
+echo "checking shell scripts with shellcheck"
+find . -iname '*.sh' | while read -r script; do
+  echo "checking ${script}"
+  shellcheck -x \
+    -e SC2002 \
+    -e SC2126 \
+    -e SC2129 \
+    -e SC2181 \
+    -e SC1004 \
+    -e SC1117 \
+    -e SC2230 \
+    "${script}"
+done
+
+# check other python scripts
+echo "-----------------------------------------"
+echo "checking other python scripts with pylint"
+find . -name "*.py" -not -path "./dotdrop/*" | while read -r script; do
+  echo "checking ${script}"
+  pylint -sn \
+    --disable=R0914 \
+    --disable=R0915 \
+    --disable=R0913 \
+    "${script}"
+done
+
+echo "------------------------"
+echo "checking for more issues"
+set +e
+exceptions="save_uservariables_name\|@@\|diff_cmd\|original,\|modified,"
+# f-string errors and missing f literal
+find dotdrop/ -iname '*.py' -exec grep --with-filename -n -v "f'" {} \; | grep -v "{'" | grep -v "${exceptions}" | grep "'.*}" && echo "bad string format (1)" && exit 1
+find dotdrop/ -iname '*.py' -exec grep --with-filename -n -v 'f"' {} \; | grep -v "f'" | grep -v '{"' | grep -v "${exceptions}" | grep '".*}' && echo "bad string format (2)" && exit 1
+set -e
+
+echo "syntax OK"
\ No newline at end of file
diff --git a/scripts/check-tests-ng.sh b/scripts/check-tests-ng.sh
new file mode 100755
index 0000000..390cd9f
--- /dev/null
+++ b/scripts/check-tests-ng.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+# author: deadc0de6 (https://github.com/deadc0de6)
+# Copyright (c) 2023, deadc0de6
+
+# stop on first error
+set -e
+
+tmpworkdir="/tmp/dotdrop-tests-workdir"
+export DOTDROP_WORKDIR="${tmpworkdir}"
+
+# check if tmp dir is present
+workdir_tmp_exists="no"
+[ -d "${HOME}/.config/dotdrop/tmp" ] && workdir_tmp_exists="yes"
+
+# run bash tests
+if [ -z "${GITHUB_WORKFLOW}" ]; then
+  ## local
+  tests-ng/tests_launcher.py
+else
+  ## CI/CD
+  # running multiple jobs in parallel sometimes
+  # messes with the results on remote servers
+  tests-ng/tests_launcher.py 1
+fi
+
+# clear workdir
+[ "${workdir_tmp_exists}" = "no" ] && rm -rf ~/.config/dotdrop/tmp
+# clear temp workdir
+rm -rf "${tmpworkdir}"
\ No newline at end of file
diff --git a/scripts/check-unittests.sh b/scripts/check-unittests.sh
new file mode 100755
index 0000000..f79cf3e
--- /dev/null
+++ b/scripts/check-unittests.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+# author: deadc0de6 (https://github.com/deadc0de6)
+# Copyright (c) 2023, deadc0de6
+
+# stop on first error
+set -e
+
+if [ -n "${DOTDROP_WORKERS}" ]; then
+  unset DOTDROP_WORKERS
+  echo "DISABLE workers for unittests"
+fi
+
+coverage run -p -m pytest tests
\ No newline at end of file
diff --git a/scripts/check_links.py b/scripts/check_links.py
index ba6799b..d7a91f2 100755
--- a/scripts/check_links.py
+++ b/scripts/check_links.py
@@ -9,10 +9,22 @@ URL checking script
 import sys
 import re
 from urllib.parse import urlparse
+from urllib3 import Retry
 import requests
+from requests.adapters import HTTPAdapter
 
 
-TIMEOUT = 3
+RED = '\033[91m'
+GREEN = '\033[92m'
+YELLOW = '\033[93m'
+BLUE = '\033[94m'
+MAGENTA = '\033[95m'
+RESET = '\033[0m'
+
+RETRY_TOTAL = 10
+RETRY_CONNECT = 5
+
+TIMEOUT = 10
 VALID_RET = [
     200,
     302,
@@ -20,6 +32,7 @@ VALID_RET = [
 IGNORES = [
   'badgen.net',
 ]
+IGNORE_GENERIC = []
 USER_AGENT = (
     'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
     'AppleWebKit/537.36 (KHTML, like Gecko) '
@@ -43,34 +56,70 @@ def get_links(path):
     return urls
 
 
+def get_session():
+    """get a session with retry"""
+    session = requests.Session()
+    retry_on = [404, 429, 500, 502, 503, 504]
+    retry = Retry(total=RETRY_TOTAL,
+                  connect=RETRY_CONNECT,
+                  status=RETRY_CONNECT,
+                  backoff_factor=1,
+                  allowed_methods=False,
+                  status_forcelist=retry_on)
+    adapter = HTTPAdapter(max_retries=retry)
+    session.mount('http://', adapter)
+    session.mount('https://', adapter)
+    return session
+
+
 def check_links(urls):
     """check urls"""
     cnt = 0
     ign = 0
     for url in urls:
         cnt += 1
+        ignored = False
+        print(f'    checking {MAGENTA}{url}{RESET}')
+        for ignore in IGNORE_GENERIC:
+            if ignore in url:
+                print(f'    {YELLOW}[IGN]{RESET} {url}')
+                ign += 1
+                ignored = True
+                break
+        if ignored:
+            continue
         hostname = urlparse(url).hostname
         if hostname in IGNORES:
-            print(f'    [IGN] {url}')
+            print(f'    {YELLOW}[IGN]{RESET} {url}')
             ign += 1
             continue
 
         verb = 'head'
-        ret = requests.head(url,
-                            timeout=TIMEOUT,
-                            allow_redirects=True,
-                            headers=HEADERS).status_code
+        try:
+            ret = requests.head(url,
+                                timeout=TIMEOUT,
+                                allow_redirects=True,
+                                headers=HEADERS).status_code
+        # pylint: disable=W0703
+        except Exception:
+            ret = 404
         if ret not in VALID_RET:
+            msg = (
+                f'    {YELLOW}[WARN]{RESET} HEAD {url} returned {ret}'
+                f' ... checking with GET'
+            )
+            print(msg)
             verb = 'get'
-            ret = requests.get(url,
-                               timeout=TIMEOUT,
-                               allow_redirects=True,
-                               headers=HEADERS).status_code
+            sess = get_session()
+            ret = sess.get(url,
+                           timeout=TIMEOUT,
+                           allow_redirects=True,
+                           headers=HEADERS).status_code
             if ret not in VALID_RET:
-                print(f'    [ERROR] {url} returned {ret}')
+                print(f'    {RED}[ERROR]{RESET} {url} returned {ret}')
                 return False
-        print(f'    [OK-{verb}-{ret}] {url}')
-    print(f'OK - total {cnt} links checked ({ign} ignored)')
+        print(f'    [{GREEN}OK{RESET}-{verb}-{ret}] {MAGENTA}{url}{RESET}')
+    print(f'    {GREEN}OK{RESET} - total {cnt} links checked ({ign} ignored)')
     return True
 
 
@@ -79,19 +128,14 @@ if __name__ == '__main__':
         print(f'usage: {sys.argv[0]} <path>')
         sys.exit(1)
 
-    print(f'checking {sys.argv[1]} for links...')
+    print(f'checking {BLUE}{sys.argv[1]}{RESET} for links...')
     links = get_links(sys.argv[1])
     print(f'    found {len(links)} links')
     try:
         if not check_links(links):
             sys.exit(1)
-    except ValueError as exc:
+    # pylint: disable=W0703
+    except Exception as exc:
         print(f'error {exc}')
         sys.exit(1)
-    except urlparse.URLError as exc:
-        print(f'urlparse error {exc}')
-        sys.exit(1)
-    except requests.exceptions.RequestException as exc:
-        print(f'requests error {exc}')
-        sys.exit(1)
     sys.exit(0)
diff --git a/scripts/dotdrop-version-manager.sh b/scripts/dotdrop-version-manager.sh
index d647821..9ee4819 100755
--- a/scripts/dotdrop-version-manager.sh
+++ b/scripts/dotdrop-version-manager.sh
@@ -104,6 +104,7 @@ need_update_stable()
   last=$(get_latest)
   cur=$(get_current_tag)
   # get short tag if on a lightweight tag
+  # shellcheck disable=SC2001
   tag=$(echo "$cur" | sed 's/\(v.*\)-[0-9]*.-.*$/\1/g')
   if [ "${tag}" != "${last}" ]; then
     echo "new stable version available: ${last}" && exit 1
diff --git a/scripts/yaml-to-toml.py b/scripts/yaml_to_toml.py
similarity index 89%
rename from scripts/yaml-to-toml.py
rename to scripts/yaml_to_toml.py
index 604df87..0185a15 100755
--- a/scripts/yaml-to-toml.py
+++ b/scripts/yaml_to_toml.py
@@ -24,20 +24,20 @@ def yaml_load(path):
 
 def replace_none(content):
     """replace any occurence of None with empty string"""
-    n = {}
+    new = {}
     for k in content:
         if content[k] is None:
             if k == 'dotfiles':
                 continue
             if k == 'profiles':
                 continue
-            n[k] = ""
+            new[k] = ""
             continue
         if isinstance(content[k], dict):
-            n[k] = replace_none(content[k])
+            new[k] = replace_none(content[k])
             continue
-        n[k] = content[k]
-    return n
+        new[k] = content[k]
+    return new
 
 
 def toml_dump(content):
diff --git a/test-ng.sh b/test-ng.sh
deleted file mode 100755
index f004a7c..0000000
--- a/test-ng.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-# author: deadc0de6 (https://github.com/deadc0de6)
-# Copyright (c) 2023, deadc0de6
-
-# stop on first error
-set -e
-
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found!" && exit 1
-  fi
-fi
-cur=`dirname $(${rl} "${0}")`
-
-tmpworkdir="/tmp/dotdrop-tests-workdir"
-export DOTDROP_WORKDIR="${tmpworkdir}"
-
-workers=${DOTDROP_WORKERS}
-if [ ! -z ${workers} ]; then
-  DOTDROP_WORKERS=${workers}
-  echo "ENABLE workers: ${workers}"
-fi
-
-# run bash tests
-export DOTDROP_DEBUG="yes"
-unset DOTDROP_FORCE_NODEBUG
-workdir_tmp_exists="no"
-[ -d "~/.config/dotdrop/tmp" ] && workdir_tmp_exists="yes"
-if [ -z ${GITHUB_WORKFLOW} ]; then
-  ## local
-  export COVERAGE_FILE=
-  tests-ng/tests-launcher.py
-else
-  ## CI/CD
-  export COVERAGE_FILE="${cur}/.coverage"
-  # running multiple jobs in parallel sometimes
-  # messes with the results on remote servers
-  tests-ng/tests-launcher.py 1
-fi
-
-# clear workdir
-[ "${workdir_tmp_exists}" = "no" ] && rm -rf ~/.config/dotdrop/tmp
-# clear temp workdir
-rm -rf "${tmpworkdir}"
\ No newline at end of file
diff --git a/test-syntax.sh b/test-syntax.sh
deleted file mode 100755
index 1e99e0b..0000000
--- a/test-syntax.sh
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/sh
-# author: deadc0de6 (https://github.com/deadc0de6)
-# Copyright (c) 2022, deadc0de6
-
-# stop on first error
-#set -ev
-set -e
-
-# versions
-echo "pylint version:"
-pylint --version
-echo "pycodestyle version:"
-pycodestyle --version
-echo "pyflakes version:"
-pyflakes --version
-
-# PEP8 tests
-which pycodestyle >/dev/null 2>&1
-[ "$?" != "0" ] && echo "Install pycodestyle" && exit 1
-echo "testing with pycodestyle"
-# W503: Line break occurred before a binary operator
-# W504: Line break occurred after a binary operator
-pycodestyle --ignore=W503,W504 dotdrop/
-pycodestyle tests/
-pycodestyle scripts/
-
-# pyflakes tests
-echo "testing with pyflakes"
-pyflakes dotdrop/
-pyflakes tests/
-pyflakes scripts/
-
-# pylint
-echo "testing with pylint"
-# https://pylint.pycqa.org/en/latest/user_guide/checkers/features.html
-# R0902: too-many-instance-attributes
-# R0913: too-many-arguments
-# R0903: too-few-public-methods
-# R0914: too-many-locals
-# R0915: too-many-statements
-# R0912: too-many-branches
-# R0911: too-many-return-statements
-# R0904: too-many-public-methods
-pylint \
-  --disable=R0902 \
-  --disable=R0913 \
-  --disable=R0903 \
-  --disable=R0914 \
-  --disable=R0915 \
-  --disable=R0912 \
-  --disable=R0911 \
-  --disable=R0904 \
-  dotdrop/
-
-# C0103: invalid-name
-pylint \
-  --disable=R0902 \
-  --disable=R0913 \
-  --disable=R0903 \
-  --disable=R0914 \
-  --disable=R0915 \
-  --disable=R0912 \
-  --disable=R0911 \
-  --disable=R0904 \
-  --disable=C0103 \
-  scripts/
-
-set +e
-exceptions="save_uservariables_name\|@@\|diff_cmd\|original,\|modified,"
-# f-string errors and missing f literal
-find dotdrop/ -iname '*.py' -exec grep --with-filename -n -v "f'" {} \; | grep -v "{'" | grep -v "${exceptions}" | grep "'.*}" && echo "bad string format (1): ${errs}" && exit 1
-find dotdrop/ -iname '*.py' -exec grep --with-filename -n -v 'f"' {} \; | grep -v "f'" | grep -v '{"' | grep -v "${exceptions}" | grep '".*}' && echo "bad string format (2): ${errs}" && exit 1
-set -e
-
-echo "syntax OK"
\ No newline at end of file
diff --git a/test-unittest.sh b/test-unittest.sh
deleted file mode 100755
index bf37316..0000000
--- a/test-unittest.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-# author: deadc0de6 (https://github.com/deadc0de6)
-# Copyright (c) 2023, deadc0de6
-
-# stop on first error
-set -e
-
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found!" && exit 1
-  fi
-fi
-cur=`dirname $(${rl} "${0}")`
-
-workers=${DOTDROP_WORKERS}
-if [ ! -z ${workers} ]; then
-  unset DOTDROP_WORKERS
-  echo "DISABLE workers"
-fi
-
-# execute tests with coverage
-if [ -z ${GITHUB_WORKFLOW} ]; then
-  ## local
-  export COVERAGE_FILE=
-  # do not print debugs when running tests (faster)
-  # tests
-  PYTHONPATH="dotdrop" nose2 --with-coverage --coverage dotdrop --plugin=nose2.plugins.mp -N0
-else
-  ## CI/CD
-  export COVERAGE_FILE="${cur}/.coverage"
-  # tests
-  PYTHONPATH="dotdrop" nose2 --with-coverage --coverage dotdrop
-fi
-#PYTHONPATH="dotdrop" python3 -m pytest tests
\ No newline at end of file
diff --git a/tests-ng/actions-args-template.sh b/tests-ng/actions-args-template.sh
index bec2560..f4c10c7 100755
--- a/tests-ng/actions-args-template.sh
+++ b/tests-ng/actions-args-template.sh
@@ -6,41 +6,20 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -61,12 +40,12 @@ should_grep() {
 }
 
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -75,7 +54,7 @@ clear_on_exit "${tmpa}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 actions:
   pre:
     preaction: "echo {0} > {1}"
@@ -123,23 +102,23 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo 'test' > ${tmps}/dotfiles/abc
+echo 'test' > "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks action
-[ ! -e ${tmpa}/pre ] && echo 'pre action not executed' && exit 1
-[ ! -e ${tmpa}/post ] && echo 'post action not executed' && exit 1
-[ ! -e ${tmpa}/naked ] && echo 'naked action not executed'  && exit 1
-[ ! -e ${tmpa}/profile ] && echo 'profile action not executed'  && exit 1
-[ ! -e ${tmpa}/dyn ] && echo 'dynamic acton action not executed'  && exit 1
-should_grep pre_var ${tmpa}/pre
-should_grep post_var ${tmpa}/post
-should_grep naked_var ${tmpa}/naked
-should_grep profile_var ${tmpa}/profile
-should_grep profile_var_2 ${tmpa}/profile
-should_grep "$USER" ${tmpa}/dyn
+[ ! -e "${tmpa}"/pre ] && echo 'pre action not executed' && exit 1
+[ ! -e "${tmpa}"/post ] && echo 'post action not executed' && exit 1
+[ ! -e "${tmpa}"/naked ] && echo 'naked action not executed'  && exit 1
+[ ! -e "${tmpa}"/profile ] && echo 'profile action not executed'  && exit 1
+[ ! -e "${tmpa}"/dyn ] && echo 'dynamic acton action not executed'  && exit 1
+should_grep pre_var "${tmpa}"/pre
+should_grep post_var "${tmpa}"/post
+should_grep naked_var "${tmpa}"/naked
+should_grep profile_var "${tmpa}"/profile
+should_grep profile_var_2 "${tmpa}"/profile
+should_grep "$USER" "${tmpa}"/dyn
 
 echo "OK"
 exit 0
diff --git a/tests-ng/actions-args.sh b/tests-ng/actions-args.sh
index 028586f..8ae14c3 100755
--- a/tests-ng/actions-args.sh
+++ b/tests-ng/actions-args.sh
@@ -6,53 +6,32 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmpa}"
 clear_on_exit "${tmps}"
@@ -61,7 +40,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 actions:
   pre:
     preaction: echo '{0} {1}' > ${tmpa}/pre
@@ -92,29 +71,29 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "test" > ${tmps}/dotfiles/abc
+echo "test" > "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 --verbose
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 --verbose
 
 # checks
-[ ! -e ${tmpa}/pre ] && echo "pre arg action not found" && exit 1
-grep test1 ${tmpa}/pre >/dev/null
-grep test2 ${tmpa}/pre >/dev/null
+[ ! -e "${tmpa}"/pre ] && echo "pre arg action not found" && exit 1
+grep test1 "${tmpa}"/pre >/dev/null
+grep test2 "${tmpa}"/pre >/dev/null
 
-[ ! -e ${tmpa}/post ] && echo "post arg action not found" && exit 1
-grep test3 ${tmpa}/post >/dev/null
-grep test4 ${tmpa}/post >/dev/null
-grep test5 ${tmpa}/post >/dev/null
+[ ! -e "${tmpa}"/post ] && echo "post arg action not found" && exit 1
+grep test3 "${tmpa}"/post >/dev/null
+grep test4 "${tmpa}"/post >/dev/null
+grep test5 "${tmpa}"/post >/dev/null
 
-[ ! -e ${tmpa}/naked ] && echo "naked arg action not found" && exit 1
-grep "test6 something" ${tmpa}/naked >/dev/null
+[ ! -e "${tmpa}"/naked ] && echo "naked arg action not found" && exit 1
+grep "test6 something" "${tmpa}"/naked >/dev/null
 
-[ ! -e ${tmpa}/empty ] && echo "empty arg action not found" && exit 1
-grep empty ${tmpa}/empty >/dev/null
+[ ! -e "${tmpa}"/empty ] && echo "empty arg action not found" && exit 1
+grep empty "${tmpa}"/empty >/dev/null
 
-[ ! -e ${tmpa}/tgt ] && echo "tgt arg action not found" && exit 1
-grep tgt ${tmpa}/tgt >/dev/null
+[ ! -e "${tmpa}"/tgt ] && echo "tgt arg action not found" && exit 1
+grep tgt "${tmpa}"/tgt >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/actions-default.sh b/tests-ng/actions-default.sh
index 7aed2ad..da1d01c 100755
--- a/tests-ng/actions-default.sh
+++ b/tests-ng/actions-default.sh
@@ -6,53 +6,32 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -61,7 +40,7 @@ clear_on_exit "${tmpa}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 actions:
   pre:
     failpre: "false"
@@ -99,37 +78,37 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo 'test' > ${tmps}/dotfiles/abc
+echo 'test' > "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks pre action
-[ ! -e ${tmpa}/pre ] && echo 'pre action not executed' && exit 1
-[ ! -e ${tmpa}/preinside ] && echo 'pre action not executed' && exit 1
-grep pre ${tmpa}/pre >/dev/null
-grep preinside ${tmpa}/preinside >/dev/null
+[ ! -e "${tmpa}"/pre ] && echo 'pre action not executed' && exit 1
+[ ! -e "${tmpa}"/preinside ] && echo 'pre action not executed' && exit 1
+grep pre "${tmpa}"/pre >/dev/null
+grep preinside "${tmpa}"/preinside >/dev/null
 # checks post action
-[ ! -e ${tmpa}/post ] && echo 'post action not executed' && exit 1
-[ ! -e ${tmpa}/postinside ] && echo 'post action not executed' && exit 1
-grep post ${tmpa}/post >/dev/null
-grep postinside ${tmpa}/postinside >/dev/null
+[ ! -e "${tmpa}"/post ] && echo 'post action not executed' && exit 1
+[ ! -e "${tmpa}"/postinside ] && echo 'post action not executed' && exit 1
+grep post "${tmpa}"/post >/dev/null
+grep postinside "${tmpa}"/postinside >/dev/null
 # checks naked action
-[ ! -e ${tmpa}/naked ] && echo 'naked action not executed'  && exit 1
-[ ! -e ${tmpa}/nakedinside ] && echo 'naked action not executed'  && exit 1
-grep naked ${tmpa}/naked >/dev/null
-grep nakedinside ${tmpa}/nakedinside >/dev/null
+[ ! -e "${tmpa}"/naked ] && echo 'naked action not executed'  && exit 1
+[ ! -e "${tmpa}"/nakedinside ] && echo 'naked action not executed'  && exit 1
+grep naked "${tmpa}"/naked >/dev/null
+grep nakedinside "${tmpa}"/nakedinside >/dev/null
 
 # test default action run
-cd ${ddpath} | ${bin} install -fa -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -fa -c "${cfg}" -p p1 -V
 
-cnt=`cat ${tmpa}/append | wc -l`
+cnt=$(cat "${tmpa}"/append | wc -l)
 [ "${cnt}" != "2" ] && echo "default_actions not run on -a" && exit 1
 
 # clear
-rm -f ${tmpa}/naked* ${tmpa}/pre* ${tmpa}/post* ${tmpd}/abc
+rm -f "${tmpa}"/naked* "${tmpa}"/pre* "${tmpa}"/post* "${tmpd}"/abc
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 actions:
   pre:
     failpre: "false"
@@ -152,9 +131,9 @@ _EOF
 # ensure failing actions make the installation fail
 # install
 set +e
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 set -e
-[ -e ${tmpd}/abc ] && exit 1
+[ -e "${tmpd}"/abc ] && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/actions-empty-dir.sh b/tests-ng/actions-empty-dir.sh
index b19d3a6..689393a 100755
--- a/tests-ng/actions-empty-dir.sh
+++ b/tests-ng/actions-empty-dir.sh
@@ -6,53 +6,32 @@
 # returns 1 in case of error
 #
 
-# exit on first error
-set -ev
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+## start-cookie
+set -e
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -61,7 +40,7 @@ clear_on_exit "${tmpa}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 actions:
   clearemptydir: find -L '{0}' -empty -xtype d -delete
 config:
@@ -105,87 +84,87 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-mkdir ${tmps}/dotfiles/dir1
-mkdir ${tmps}/dotfiles/dir1/empty
-echo "to-ignore" > ${tmps}/dotfiles/dir1/empty/this.ignore
-mkdir ${tmps}/dotfiles/dir1/not-empty
-echo "file" > ${tmps}/dotfiles/dir1/not-empty/file
-mkdir ${tmps}/dotfiles/dir1/sub
-mkdir ${tmps}/dotfiles/dir1/sub/empty
-echo "to-ignore-too" > ${tmps}/dotfiles/dir1/sub/empty/that.ignore
+mkdir "${tmps}"/dotfiles/dir1
+mkdir "${tmps}"/dotfiles/dir1/empty
+echo "to-ignore" > "${tmps}"/dotfiles/dir1/empty/this.ignore
+mkdir "${tmps}"/dotfiles/dir1/not-empty
+echo "file" > "${tmps}"/dotfiles/dir1/not-empty/file
+mkdir "${tmps}"/dotfiles/dir1/sub
+mkdir "${tmps}"/dotfiles/dir1/sub/empty
+echo "to-ignore-too" > "${tmps}"/dotfiles/dir1/sub/empty/that.ignore
 
 # create the dotfile
-mkdir ${tmps}/dotfiles/dir2
-mkdir ${tmps}/dotfiles/dir2/empty
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir2/empty/this.ignore
-mkdir ${tmps}/dotfiles/dir2/not-empty
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir2/not-empty/file
-mkdir ${tmps}/dotfiles/dir2/sub
-mkdir ${tmps}/dotfiles/dir2/sub/empty
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir2/sub/empty/that.ignore
+mkdir "${tmps}"/dotfiles/dir2
+mkdir "${tmps}"/dotfiles/dir2/empty
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dir2/empty/this.ignore
+mkdir "${tmps}"/dotfiles/dir2/not-empty
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dir2/not-empty/file
+mkdir "${tmps}"/dotfiles/dir2/sub
+mkdir "${tmps}"/dotfiles/dir2/sub/empty
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dir2/sub/empty/that.ignore
 
 # create the dotfile
-mkdir ${tmps}/dotfiles/dir3
-mkdir ${tmps}/dotfiles/dir3/empty
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir3/empty/this.ignore
-mkdir ${tmps}/dotfiles/dir3/not-empty
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir3/not-empty/file
-mkdir ${tmps}/dotfiles/dir3/sub
-mkdir ${tmps}/dotfiles/dir3/sub/empty
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir3/sub/empty/that.ignore
+mkdir "${tmps}"/dotfiles/dir3
+mkdir "${tmps}"/dotfiles/dir3/empty
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dir3/empty/this.ignore
+mkdir "${tmps}"/dotfiles/dir3/not-empty
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dir3/not-empty/file
+mkdir "${tmps}"/dotfiles/dir3/sub
+mkdir "${tmps}"/dotfiles/dir3/sub/empty
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dir3/sub/empty/that.ignore
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks normal
-[ ! -d ${tmpd}/dir1 ] && exit 1
-[ -d ${tmpd}/dir1/empty ] && exit 1
-[ -e ${tmpd}/dir1/empty/this.ignore ] && exit 1
-[ ! -d ${tmpd}/dir1/not-empty ] && exit 1
-[ ! -e ${tmpd}/dir1/not-empty/file ] && exit 1
-[ -d ${tmpd}/dir1/sub ] && exit 1
-[ -d ${tmpd}/dir1/sub/empty ] && exit 1
-[ -e ${tmpd}/dir1/sub/empty/that.ignore ] && exit 1
-grep "file" ${tmpd}/dir1/not-empty/file
+[ ! -d "${tmpd}"/dir1 ] && exit 1
+[ -d "${tmpd}"/dir1/empty ] && exit 1
+[ -e "${tmpd}"/dir1/empty/this.ignore ] && exit 1
+[ ! -d "${tmpd}"/dir1/not-empty ] && exit 1
+[ ! -e "${tmpd}"/dir1/not-empty/file ] && exit 1
+[ -d "${tmpd}"/dir1/sub ] && exit 1
+[ -d "${tmpd}"/dir1/sub/empty ] && exit 1
+[ -e "${tmpd}"/dir1/sub/empty/that.ignore ] && exit 1
+grep "file" "${tmpd}"/dir1/not-empty/file
 
 # checks link_children
-[ ! -d ${tmpd}/dir2 ] && exit 1
-[ ! -h ${tmpd}/dir2/empty ] && exit 1
-[ -e ${tmpd}/dir2/empty/this.ignore ] && exit 1
-[ ! -d ${tmpd}/dir2/not-empty ] && exit 1
-[ ! -h ${tmpd}/dir2/not-empty ] && exit 1
-[ ! -e ${tmpd}/dir2/not-empty/file ] && exit 1
-[ -d ${tmpd}/dir2/sub ] && exit 1
-[ -d ${tmpd}/dir2/sub/empty ] && exit 1
-[ -e ${tmpd}/dir2/sub/empty/that.ignore ] && exit 1
-grep "p1" ${tmpd}/dir2/not-empty/file
+[ ! -d "${tmpd}"/dir2 ] && exit 1
+[ ! -h "${tmpd}"/dir2/empty ] && exit 1
+[ -e "${tmpd}"/dir2/empty/this.ignore ] && exit 1
+[ ! -d "${tmpd}"/dir2/not-empty ] && exit 1
+[ ! -h "${tmpd}"/dir2/not-empty ] && exit 1
+[ ! -e "${tmpd}"/dir2/not-empty/file ] && exit 1
+[ -d "${tmpd}"/dir2/sub ] && exit 1
+[ -d "${tmpd}"/dir2/sub/empty ] && exit 1
+[ -e "${tmpd}"/dir2/sub/empty/that.ignore ] && exit 1
+grep "p1" "${tmpd}"/dir2/not-empty/file
 
 # checks link
-[ ! -d ${tmpd}/dir3 ] && exit 1
-[ ! -h ${tmpd}/dir3 ] && exit 1
-[ -d ${tmpd}/dir3/empty ] && exit 1
-[ -e ${tmpd}/dir3/empty/this.ignore ] && exit 1
-[ ! -d ${tmpd}/dir3/not-empty ] && exit 1
-[ ! -e ${tmpd}/dir3/not-empty/file ] && exit 1
-[ -d ${tmpd}/dir3/sub ] && exit 1
-[ -d ${tmpd}/dir3/sub/empty ] && exit 1
-[ -e ${tmpd}/dir3/sub/empty/that.ignore ] && exit 1
-grep "p1" ${tmpd}/dir3/not-empty/file
+[ ! -d "${tmpd}"/dir3 ] && exit 1
+[ ! -h "${tmpd}"/dir3 ] && exit 1
+[ -d "${tmpd}"/dir3/empty ] && exit 1
+[ -e "${tmpd}"/dir3/empty/this.ignore ] && exit 1
+[ ! -d "${tmpd}"/dir3/not-empty ] && exit 1
+[ ! -e "${tmpd}"/dir3/not-empty/file ] && exit 1
+[ -d "${tmpd}"/dir3/sub ] && exit 1
+[ -d "${tmpd}"/dir3/sub/empty ] && exit 1
+[ -e "${tmpd}"/dir3/sub/empty/that.ignore ] && exit 1
+grep "p1" "${tmpd}"/dir3/not-empty/file
 
 # second install won't trigger the action
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V  # 2>&1 | tee ${tmpa}/log
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V  # 2>&1 | tee ${tmpa}/log
 
 # check normal
-[ -d ${tmpd}/dir1/empty ] && echo "empty directory not cleaned" && exit 1
-[ -d ${tmpd}/dir1/sub/empty ] && echo "empty directory not cleaned" && exit 1
+[ -d "${tmpd}"/dir1/empty ] && echo "empty directory not cleaned" && exit 1
+[ -d "${tmpd}"/dir1/sub/empty ] && echo "empty directory not cleaned" && exit 1
 
 # check link_children
-[ -d ${tmpd}/dir2/empty ] && echo "empty directory not cleaned" && exit 1
-[ -d ${tmpd}/dir2/sub/empty ] && echo "empty directory not cleaned" && exit 1
+[ -d "${tmpd}"/dir2/empty ] && echo "empty directory not cleaned" && exit 1
+[ -d "${tmpd}"/dir2/sub/empty ] && echo "empty directory not cleaned" && exit 1
 
 # check link
-[ -d ${tmpd}/dir3/empty ] && echo "empty directory not cleaned" && exit 1
-[ -d ${tmpd}/dir3/sub/empty ] && echo "empty directory not cleaned" && exit 1
+[ -d "${tmpd}"/dir3/empty ] && echo "empty directory not cleaned" && exit 1
+[ -d "${tmpd}"/dir3/sub/empty ] && echo "empty directory not cleaned" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/actions-pre.sh b/tests-ng/actions-pre.sh
index ffbbdc4..91226c2 100755
--- a/tests-ng/actions-pre.sh
+++ b/tests-ng/actions-pre.sh
@@ -6,41 +6,20 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -54,12 +33,12 @@ grep_or_fail()
 }
 
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -68,7 +47,7 @@ clear_on_exit "${tmpa}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 actions:
   pre:
     failpre: "false"
@@ -130,53 +109,53 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo 'test' > ${tmps}/dotfiles/abc
-echo 'link' > ${tmps}/dotfiles/link
-echo 'fail' > ${tmps}/dotfiles/fail
+echo 'test' > "${tmps}"/dotfiles/abc
+echo 'link' > "${tmps}"/dotfiles/link
+echo 'fail' > "${tmps}"/dotfiles/fail
 
-mkdir -p ${tmps}/dotfiles/dir
-echo 'test1' > ${tmps}/dotfiles/dir/file1
-echo 'test2' > ${tmps}/dotfiles/dir/file2
+mkdir -p "${tmps}"/dotfiles/dir
+echo 'test1' > "${tmps}"/dotfiles/dir/file1
+echo 'test2' > "${tmps}"/dotfiles/dir/file2
 
-mkdir -p ${tmps}/dotfiles/dlink
-echo 'test3' > ${tmps}/dotfiles/dlink/dfile1
-echo 'test4' > ${tmps}/dotfiles/dlink/dfile2
+mkdir -p "${tmps}"/dotfiles/dlink
+echo 'test3' > "${tmps}"/dotfiles/dlink/dfile1
+echo 'test4' > "${tmps}"/dotfiles/dlink/dfile2
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks
-[ ! -e ${tmpa}/pre ] && echo 'pre action not executed' && exit 1
-grep_or_fail pre ${tmpa}/pre
-[ ! -e ${tmpa}/naked ] && echo 'naked action not executed'  && exit 1
-grep_or_fail naked ${tmpa}/naked
-
-[ ! -e ${tmpa}/multiple ] && echo 'pre action multiple not executed' && exit 1
-grep_or_fail multiple ${tmpa}/multiple
-[ "`wc -l ${tmpa}/multiple | awk '{print $1}'`" -gt "1" ] && echo 'pre action multiple executed twice' && exit 1
-
-[ ! -e ${tmpa}/pre2 ] && echo 'pre action 2 not executed' && exit 1
-grep_or_fail pre2 ${tmpa}/pre2
-[ ! -e ${tmpa}/naked2 ] && echo 'naked action 2 not executed'  && exit 1
-grep_or_fail naked2 ${tmpa}/naked2
-
-[ ! -e ${tmpa}/multiple2 ] && echo 'pre action multiple 2 not executed' && exit 1
-grep_or_fail multiple2 ${tmpa}/multiple2
-[ "`wc -l ${tmpa}/multiple2 | awk '{print $1}'`" -gt "1" ] && echo 'pre action multiple 2 executed twice' && exit 1
-[ ! -e ${tmpa}/naked3 ] && echo 'naked action 3 not executed'  && exit 1
-grep_or_fail naked3 ${tmpa}/naked3
+[ ! -e "${tmpa}"/pre ] && echo 'pre action not executed' && exit 1
+grep_or_fail pre "${tmpa}"/pre
+[ ! -e "${tmpa}"/naked ] && echo 'naked action not executed'  && exit 1
+grep_or_fail naked "${tmpa}"/naked
+
+[ ! -e "${tmpa}"/multiple ] && echo 'pre action multiple not executed' && exit 1
+grep_or_fail multiple "${tmpa}"/multiple
+[ "$(wc -l "${tmpa}"/multiple | awk '{print $1}')" -gt "1" ] && echo 'pre action multiple executed twice' && exit 1
+
+[ ! -e "${tmpa}"/pre2 ] && echo 'pre action 2 not executed' && exit 1
+grep_or_fail pre2 "${tmpa}"/pre2
+[ ! -e "${tmpa}"/naked2 ] && echo 'naked action 2 not executed'  && exit 1
+grep_or_fail naked2 "${tmpa}"/naked2
+
+[ ! -e "${tmpa}"/multiple2 ] && echo 'pre action multiple 2 not executed' && exit 1
+grep_or_fail multiple2 "${tmpa}"/multiple2
+[ "$(wc -l "${tmpa}"/multiple2 | awk '{print $1}')" -gt "1" ] && echo 'pre action multiple 2 executed twice' && exit 1
+[ ! -e "${tmpa}"/naked3 ] && echo 'naked action 3 not executed'  && exit 1
+grep_or_fail naked3 "${tmpa}"/naked3
 
 # remove the pre action result and re-install
-rm ${tmpa}/pre
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ -e ${tmpa}/pre ] && echo "pre exists" && exit 1
+rm "${tmpa}"/pre
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ -e "${tmpa}"/pre ] && echo "pre exists" && exit 1
 
 # ensure failing actions make the installation fail
 # install
 set +e
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p2 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p2 -V
 set -e
-[ -e ${tmpd}/fail ] && echo "fail exists" && exit 1
+[ -e "${tmpd}"/fail ] && echo "fail exists" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/actions-template.sh b/tests-ng/actions-template.sh
index ee27c5a..2746eae 100755
--- a/tests-ng/actions-template.sh
+++ b/tests-ng/actions-template.sh
@@ -6,53 +6,32 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -61,7 +40,7 @@ clear_on_exit "${tmpa}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 actions:
   pre:
     preaction: "echo {{@@ _dotfile_abs_src @@}} > {0}"
@@ -88,23 +67,23 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo 'test' > ${tmps}/dotfiles/abc
+echo 'test' > "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks action
-[ ! -e ${tmpa}/pre ] && echo 'pre action not executed' && exit 1
-[ ! -e ${tmpa}/post ] && echo 'post action not executed' && exit 1
-[ ! -e ${tmpa}/naked ] && echo 'naked action not executed'  && exit 1
-grep abc ${tmpa}/pre >/dev/null
-grep abc ${tmpa}/post >/dev/null
-grep abc ${tmpa}/naked >/dev/null
+[ ! -e "${tmpa}"/pre ] && echo 'pre action not executed' && exit 1
+[ ! -e "${tmpa}"/post ] && echo 'post action not executed' && exit 1
+[ ! -e "${tmpa}"/naked ] && echo 'naked action not executed'  && exit 1
+grep abc "${tmpa}"/pre >/dev/null
+grep abc "${tmpa}"/post >/dev/null
+grep abc "${tmpa}"/naked >/dev/null
 
 # clear
-rm -f ${tmpa}/naked* ${tmpa}/pre* ${tmpa}/post* ${tmpd}/abc
+rm -f "${tmpa}"/naked* "${tmpa}"/pre* "${tmpa}"/post* "${tmpd}"/abc
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 actions:
   pre:
     preaction: "echo {{@@ _dotfile_abs_dst @@}} > ${tmpa}/pre"
@@ -130,15 +109,15 @@ profiles:
 _EOF
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks action
-[ ! -e ${tmpa}/pre ] && echo 'pre action not executed' && exit 1
-[ ! -e ${tmpa}/post ] && echo 'post action not executed' && exit 1
-[ ! -e ${tmpa}/naked ] && echo 'naked action not executed'  && exit 1
-grep "${tmpd}/abc" ${tmpa}/pre >/dev/null
-grep "${tmpd}/abc" ${tmpa}/post >/dev/null
-grep "${tmpd}/abc" ${tmpa}/naked >/dev/null
+[ ! -e "${tmpa}"/pre ] && echo 'pre action not executed' && exit 1
+[ ! -e "${tmpa}"/post ] && echo 'post action not executed' && exit 1
+[ ! -e "${tmpa}"/naked ] && echo 'naked action not executed'  && exit 1
+grep "${tmpd}/abc" "${tmpa}"/pre >/dev/null
+grep "${tmpd}/abc" "${tmpa}"/post >/dev/null
+grep "${tmpd}/abc" "${tmpa}"/naked >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/actions.sh b/tests-ng/actions.sh
index 5f3abf2..b7281b8 100755
--- a/tests-ng/actions.sh
+++ b/tests-ng/actions.sh
@@ -6,53 +6,32 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -61,7 +40,7 @@ clear_on_exit "${tmpa}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 actions:
   pre:
     preaction: echo 'pre' > ${tmpa}/pre
@@ -105,34 +84,34 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "test" > ${tmps}/dotfiles/abc
+echo "test" > "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V 2>&1 | tee ${tmpa}/log
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V 2>&1 | tee "${tmpa}"/log
 
 # checks
-[ ! -e ${tmpa}/pre ] && exit 1
-grep pre ${tmpa}/pre >/dev/null
-[ ! -e ${tmpa}/post ] && exit 1
-grep post ${tmpa}/post >/dev/null
-[ ! -e ${tmpa}/naked ] && exit 1
-grep naked ${tmpa}/naked >/dev/null
-[ ! -e ${tmpa}/pre2 ] && exit 1
-grep pre2 ${tmpa}/pre2 >/dev/null
-[ ! -e ${tmpa}/post2 ] && exit 1
-grep post ${tmpa}/post2 >/dev/null
-[ ! -e ${tmpa}/log ] && exit 1
-grep "executing \"echo 'naked' > ${tmpa}/naked" ${tmpa}/log >/dev/null
-grep "executing \"echo 'silent'" ${tmpa}/log >/dev/null && false
-grep "executing silent action \"_silentaction\"" ${tmpa}/log >/dev/null
-[ ! -e ${tmpa}/expandvariable ] && exit 1
-grep xxx ${tmpa}/expandvariable >/dev/null
+[ ! -e "${tmpa}"/pre ] && exit 1
+grep pre "${tmpa}"/pre >/dev/null
+[ ! -e "${tmpa}"/post ] && exit 1
+grep post "${tmpa}"/post >/dev/null
+[ ! -e "${tmpa}"/naked ] && exit 1
+grep naked "${tmpa}"/naked >/dev/null
+[ ! -e "${tmpa}"/pre2 ] && exit 1
+grep pre2 "${tmpa}"/pre2 >/dev/null
+[ ! -e "${tmpa}"/post2 ] && exit 1
+grep post "${tmpa}"/post2 >/dev/null
+[ ! -e "${tmpa}"/log ] && exit 1
+grep "executing \"echo 'naked' > ${tmpa}/naked" "${tmpa}"/log >/dev/null
+grep "executing \"echo 'silent'" "${tmpa}"/log >/dev/null && false
+grep "executing silent action \"_silentaction\"" "${tmpa}"/log >/dev/null
+[ ! -e "${tmpa}"/expandvariable ] && exit 1
+grep xxx "${tmpa}"/expandvariable >/dev/null
 
 # fake action
-[ ! -e ${tmpa}/fake ] && echo 'fake post action not executed' && exit 1
-grep fake ${tmpa}/fake >/dev/null
-[ ! -e ${tmpa}/fake_pre ] && echo 'fake pre action not executed' && exit 1
-grep 'fake pre' ${tmpa}/fake_pre >/dev/null
+[ ! -e "${tmpa}"/fake ] && echo 'fake post action not executed' && exit 1
+grep fake "${tmpa}"/fake >/dev/null
+[ ! -e "${tmpa}"/fake_pre ] && echo 'fake pre action not executed' && exit 1
+grep 'fake pre' "${tmpa}"/fake_pre >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/bad-diff-cmd.sh b/tests-ng/bad-diff-cmd.sh
index 0422f1d..5802102 100755
--- a/tests-ng/bad-diff-cmd.sh
+++ b/tests-ng/bad-diff-cmd.sh
@@ -6,53 +6,32 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 
 clear_on_exit "${basedir}"
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -63,13 +42,13 @@ profiles:
 _EOF
 
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg}
+cd "${ddpath}" | ${bin} compare -c "${cfg}"
 [ "$?" = "0" ] && exit 1
 
-out=$(cd ${ddpath} | ${bin} compare -c ${cfg})
+out=$(cd "${ddpath}" | ${bin} compare -c "${cfg}")
 echo "${out}" | grep -i 'traceback' && exit 1
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -80,10 +59,10 @@ profiles:
 _EOF
 
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg}
+cd "${ddpath}" | ${bin} compare -c "${cfg}"
 [ "$?" = "0" ] && exit 1
 
-out=$(cd ${ddpath} | ${bin} compare -c ${cfg})
+out=$(cd "${ddpath}" | ${bin} compare -c "${cfg}")
 echo "${out}" | grep -i 'traceback' && exit 1
 
 echo "OK"
diff --git a/tests-ng/chmod-compare.sh b/tests-ng/chmod-compare.sh
index 6cf2ac3..1e07bdf 100755
--- a/tests-ng/chmod-compare.sh
+++ b/tests-ng/chmod-compare.sh
@@ -5,51 +5,30 @@
 # test chmod on compare
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -57,40 +36,40 @@ clear_on_exit "${tmpd}"
 
 # create the dotfile
 dnormal="${tmpd}/dir_normal"
-mkdir -p ${dnormal}
-echo "dir_normal/f1" > ${dnormal}/file1
-echo "dir_normal/f2" > ${dnormal}/file2
-chmod 777 ${dnormal}
+mkdir -p "${dnormal}"
+echo "dir_normal/f1" > "${dnormal}"/file1
+echo "dir_normal/f2" > "${dnormal}"/file2
+chmod 777 "${dnormal}"
 
 dlink="${tmpd}/dir_link"
-mkdir -p ${dlink}
-echo "dir_link/f1" > ${dlink}/file1
-echo "dir_link/f2" > ${dlink}/file2
-chmod 777 ${dlink}
+mkdir -p "${dlink}"
+echo "dir_link/f1" > "${dlink}"/file1
+echo "dir_link/f2" > "${dlink}"/file2
+chmod 777 "${dlink}"
 
 dlinkchildren="${tmpd}/dir_link_children"
-mkdir -p ${dlinkchildren}
-echo "dir_linkchildren/f1" > ${dlinkchildren}/file1
-echo "dir_linkchildren/f2" > ${dlinkchildren}/file2
-chmod 777 ${dlinkchildren}
+mkdir -p "${dlinkchildren}"
+echo "dir_linkchildren/f1" > "${dlinkchildren}"/file1
+echo "dir_linkchildren/f2" > "${dlinkchildren}"/file2
+chmod 777 "${dlinkchildren}"
 
 fnormal="${tmpd}/filenormal"
-echo "filenormal" > ${fnormal}
-chmod 777 ${fnormal}
+echo "filenormal" > "${fnormal}"
+chmod 777 "${fnormal}"
 
 flink="${tmpd}/filelink"
-echo "filelink" > ${flink}
-chmod 777 ${flink}
+echo "filelink" > "${flink}"
+chmod 777 "${flink}"
 
-echo "f777" > ${tmps}/dotfiles/f777
-chmod 700 ${tmps}/dotfiles/f777
+echo "f777" > "${tmps}"/dotfiles/f777
+chmod 700 "${tmps}"/dotfiles/f777
 
 toimport="${dnormal} ${dlink} ${dlinkchildren} ${fnormal} ${flink}"
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -108,27 +87,27 @@ _EOF
 #cat ${cfg}
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1
 
 # compare
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1
 
 # import
 for i in ${toimport}; do
-  cd ${ddpath} | ${bin} import -c ${cfg} -f -p p1 ${i}
+  cd "${ddpath}" | ${bin} import -c "${cfg}" -f -p p1 "${i}"
 done
 
 #cat ${cfg}
 
 # patch rights
-chmod 700 ${dnormal}
-chmod 700 ${dlink}
-chmod 700 ${dlinkchildren}
-chmod 700 ${fnormal}
-chmod 700 ${flink}
+chmod 700 "${dnormal}"
+chmod 700 "${dlink}"
+chmod 700 "${dlinkchildren}"
+chmod 700 "${fnormal}"
+chmod 700 "${flink}"
 
 set +e
-out=`cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 2>&1`
+out=$(cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 2>&1)
 cnt=$(echo "${out}" | grep 'modes differ' | wc -l)
 set -e
 [ "${cnt}" != "5" ] && echo "${out}" && echo "compare modes failed (${cnt}, expecting 5)" && exit 1
diff --git a/tests-ng/chmod-import.sh b/tests-ng/chmod-import.sh
index 4cd652e..c67798e 100755
--- a/tests-ng/chmod-import.sh
+++ b/tests-ng/chmod-import.sh
@@ -7,41 +7,20 @@
 # with different link
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -50,21 +29,22 @@ echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
 # $1 file
 chmod_to_umask()
 {
-  u=`umask`
-  u=`echo ${u} | sed 's/^0*//'`
-  if [ -d ${1} ]; then
+  u=$(umask)
+  # shellcheck disable=SC2001
+  u=$(echo "${u}" | sed 's/^0*//')
+  if [ -d "${1}" ]; then
     v=$((777 - u))
   else
     v=$((666 - u))
   fi
-  chmod ${v} ${1}
+  chmod ${v} "${1}"
 }
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -72,37 +52,37 @@ clear_on_exit "${tmpd}"
 
 # create the dotfiles
 dnormal="${tmpd}/dir_normal"
-mkdir -p ${dnormal}
-echo "dir_normal/f1" > ${dnormal}/file1
-echo "dir_normal/f2" > ${dnormal}/file2
-chmod 777 ${dnormal}
+mkdir -p "${dnormal}"
+echo "dir_normal/f1" > "${dnormal}"/file1
+echo "dir_normal/f2" > "${dnormal}"/file2
+chmod 777 "${dnormal}"
 
 dlink="${tmpd}/dir_link"
-mkdir -p ${dlink}
-echo "dir_link/f1" > ${dlink}/file1
-echo "dir_link/f2" > ${dlink}/file2
-chmod 777 ${dlink}
+mkdir -p "${dlink}"
+echo "dir_link/f1" > "${dlink}"/file1
+echo "dir_link/f2" > "${dlink}"/file2
+chmod 777 "${dlink}"
 
 dlinkchildren="${tmpd}/dir_link_children"
-mkdir -p ${dlinkchildren}
-echo "dir_linkchildren/f1" > ${dlinkchildren}/file1
-echo "dir_linkchildren/f2" > ${dlinkchildren}/file2
-chmod 777 ${dlinkchildren}
+mkdir -p "${dlinkchildren}"
+echo "dir_linkchildren/f1" > "${dlinkchildren}"/file1
+echo "dir_linkchildren/f2" > "${dlinkchildren}"/file2
+chmod 777 "${dlinkchildren}"
 
 fnormal="${tmpd}/filenormal"
-echo "filenormal" > ${fnormal}
-chmod 777 ${fnormal}
+echo "filenormal" > "${fnormal}"
+chmod 777 "${fnormal}"
 
 flink="${tmpd}/filelink"
-echo "filelink" > ${flink}
-chmod 777 ${flink}
+echo "filelink" > "${flink}"
+chmod 777 "${flink}"
 
 toimport="${dnormal} ${dlink} ${dlinkchildren} ${fnormal} ${flink}"
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -114,20 +94,20 @@ _EOF
 
 # import without --preserve-mode
 for i in ${toimport}; do
-  cd ${ddpath} | ${bin} import -c ${cfg} -f -p p1 -V ${i}
+  cd "${ddpath}" | ${bin} import -c "${cfg}" -f -p p1 -V "${i}"
 done
 
-cat ${cfg}
+cat "${cfg}"
 
 # list files
-cd ${ddpath} | ${bin} detail -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} detail -c "${cfg}" -p p1 -V
 
-tot=`echo ${toimport} | wc -w`
-cnt=`cat ${cfg} | grep "chmod: '777'" | wc -l`
+tot=$(echo "${toimport}" | wc -w)
+cnt=$(cat "${cfg}" | grep "chmod: '777'" | wc -l)
 [ "${cnt}" != "${tot}" ] && echo "not all chmod inserted (1)" && exit 1
 
 ## with link
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -137,29 +117,29 @@ profiles:
 _EOF
 
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 
 # import without --preserve-mode and link
 for i in ${toimport}; do
-  cd ${ddpath} | ${bin} import -c ${cfg} -l absolute -f -p p1 -V ${i}
+  cd "${ddpath}" | ${bin} import -c "${cfg}" -l absolute -f -p p1 -V "${i}"
 done
 
-cat ${cfg}
+cat "${cfg}"
 
 # list files
-cd ${ddpath} | ${bin} detail -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} detail -c "${cfg}" -p p1 -V
 
-tot=`echo ${toimport} | wc -w`
-cnt=`cat ${cfg} | grep "chmod: '777'" | wc -l`
+tot=$(echo "${toimport}" | wc -w)
+cnt=$(cat "${cfg}" | grep "chmod: '777'" | wc -l)
 [ "${cnt}" != "${tot}" ] && echo "not all chmod inserted (2)" && exit 1
 
-tot=`echo ${toimport} | wc -w`
-cnt=`cat ${cfg} | grep 'link: absolute' | wc -l`
+tot=$(echo "${toimport}" | wc -w)
+cnt=$(cat "${cfg}" | grep 'link: absolute' | wc -l)
 [ "${cnt}" != "${tot}" ] && echo "not all link inserted" && exit 1
 
 ## --preserve-mode
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -169,26 +149,26 @@ profiles:
 _EOF
 
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 
 # import with --preserve-mode
 for i in ${toimport}; do
-  chmod_to_umask ${i}
-  cd ${ddpath} | ${bin} import -c ${cfg} -m -f -p p1 -V ${i}
+  chmod_to_umask "${i}"
+  cd "${ddpath}" | ${bin} import -c "${cfg}" -m -f -p p1 -V "${i}"
 done
 
-cat ${cfg}
+cat "${cfg}"
 
 # list files
-cd ${ddpath} | ${bin} detail -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} detail -c "${cfg}" -p p1 -V
 
-tot=`echo ${toimport} | wc -w`
-cnt=`cat ${cfg} | grep "chmod: " | wc -l`
+tot=$(echo "${toimport}" | wc -w)
+cnt=$(cat "${cfg}" | grep "chmod: " | wc -l)
 [ "${cnt}" != "${tot}" ] && echo "not all chmod inserted (3)" && exit 1
 
 ## import normal
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -198,25 +178,25 @@ profiles:
 _EOF
 
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 
 # import without --preserve-mode
 for i in ${toimport}; do
-  chmod_to_umask ${i}
-  cd ${ddpath} | ${bin} import -c ${cfg} -f -p p1 -V ${i}
+  chmod_to_umask "${i}"
+  cd "${ddpath}" | ${bin} import -c "${cfg}" -f -p p1 -V "${i}"
 done
 
-cat ${cfg}
+cat "${cfg}"
 
 # list files
-cd ${ddpath} | ${bin} detail -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} detail -c "${cfg}" -p p1 -V
 
-cnt=`cat ${cfg} | grep chmod | wc -l`
+cnt=$(cat "${cfg}" | grep chmod | wc -l)
 [ "${cnt}" != "0" ] && echo "chmod inserted but not needed" && exit 1
 
 ## with config option chmod_on_import
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -227,23 +207,23 @@ profiles:
 _EOF
 
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 
 # import
 for i in ${toimport}; do
-  chmod_to_umask ${i}
-  cd ${ddpath} | ${bin} import -c ${cfg} -f -p p1 -V ${i}
+  chmod_to_umask "${i}"
+  cd "${ddpath}" | ${bin} import -c "${cfg}" -f -p p1 -V "${i}"
 done
 
-cat ${cfg}
+cat "${cfg}"
 
 # list files
-cd ${ddpath} | ${bin} detail -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} detail -c "${cfg}" -p p1 -V
 
-cat ${cfg}
-tot=`echo ${toimport} | wc -w`
-cnt=`cat ${cfg} | grep "chmod: " | wc -l`
+cat "${cfg}"
+tot=$(echo "${toimport}" | wc -w)
+cnt=$(cat "${cfg}" | grep "chmod: " | wc -l)
 [ "${cnt}" != "${tot}" ] && echo "not all chmod inserted (3)" && exit 1
 
 echo "OK"
diff --git a/tests-ng/chmod-install.sh b/tests-ng/chmod-install.sh
index e635dc5..7cfab4e 100755
--- a/tests-ng/chmod-install.sh
+++ b/tests-ng/chmod-install.sh
@@ -7,41 +7,20 @@
 # with different link
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -52,33 +31,27 @@ echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
 has_rights()
 {
   echo "testing ${1} is ${2}"
-  [ ! -e "$1" ] && echo "`basename $1` does not exist" && exit 1
-  local mode=`stat -L -c '%a' "$1"`
-  [ "${mode}" != "$2" ] && echo "bad mode for `basename $1` (${mode} VS expected ${2})" && exit 1
+  [ ! -e "$1" ] && echo "$(basename "$1") does not exist" && exit 1
+  local mode
+  mode=$(stat -L -c '%a' "$1")
+  [ "${mode}" != "$2" ] && echo "bad mode for $(basename "$1") (${mode} VS expected ${2})" && exit 1
   true
 }
 
 get_file_mode()
 {
-  u=`umask`
-  u=`echo ${u} | sed 's/^0*//'`
+  u=$(umask)
+  # shellcheck disable=2001
+  u=$(echo "${u}" | sed 's/^0*//')
   v=$((666 - u))
   echo "${v}"
 }
 
-get_dir_mode()
-{
-  u=`umask`
-  u=`echo ${u} | sed 's/^0*//'`
-  v=$((777 - u))
-  echo "${v}"
-}
-
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -87,42 +60,42 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-echo 'f777' > ${tmps}/dotfiles/f777
-chmod 700 ${tmps}/dotfiles/f777
-echo 'link' > ${tmps}/dotfiles/link
-chmod 777 ${tmps}/dotfiles/link
-mkdir -p ${tmps}/dotfiles/dir
-echo "f1" > ${tmps}/dotfiles/dir/f1
+echo 'f777' > "${tmps}"/dotfiles/f777
+chmod 700 "${tmps}"/dotfiles/f777
+echo 'link' > "${tmps}"/dotfiles/link
+chmod 777 "${tmps}"/dotfiles/link
+mkdir -p "${tmps}"/dotfiles/dir
+echo "f1" > "${tmps}"/dotfiles/dir/f1
 
-echo "exists" > ${tmps}/dotfiles/exists
-chmod 644 ${tmps}/dotfiles/exists
-echo "exists" > ${tmpd}/exists
-chmod 644 ${tmpd}/exists
+echo "exists" > "${tmps}"/dotfiles/exists
+chmod 644 "${tmps}"/dotfiles/exists
+echo "exists" > "${tmpd}"/exists
+chmod 644 "${tmpd}"/exists
 
-echo "existslink" > ${tmps}/dotfiles/existslink
-chmod 777 ${tmps}/dotfiles/existslink
-chmod 644 ${tmpd}/exists
+echo "existslink" > "${tmps}"/dotfiles/existslink
+chmod 777 "${tmps}"/dotfiles/existslink
+chmod 644 "${tmpd}"/exists
 
-mkdir -p ${tmps}/dotfiles/direxists
-echo "f1" > ${tmps}/dotfiles/direxists/f1
-mkdir -p ${tmpd}/direxists
-echo "f1" > ${tmpd}/direxists/f1
-chmod 644 ${tmpd}/direxists/f1
-chmod 744 ${tmpd}/direxists
+mkdir -p "${tmps}"/dotfiles/direxists
+echo "f1" > "${tmps}"/dotfiles/direxists/f1
+mkdir -p "${tmpd}"/direxists
+echo "f1" > "${tmpd}"/direxists/f1
+chmod 644 "${tmpd}"/direxists/f1
+chmod 744 "${tmpd}"/direxists
 
-mkdir -p ${tmps}/dotfiles/linkchildren
-echo "f1" > ${tmps}/dotfiles/linkchildren/f1
-mkdir -p ${tmps}/dotfiles/linkchildren/d1
-echo "f2" > ${tmps}/dotfiles/linkchildren/d1/f2
+mkdir -p "${tmps}"/dotfiles/linkchildren
+echo "f1" > "${tmps}"/dotfiles/linkchildren/f1
+mkdir -p "${tmps}"/dotfiles/linkchildren/d1
+echo "f2" > "${tmps}"/dotfiles/linkchildren/d1/f2
 
-echo '{{@@ profile @@}}' > ${tmps}/dotfiles/symlinktemplate
+echo '{{@@ profile @@}}' > "${tmps}"/dotfiles/symlinktemplate
 
-mkdir -p ${tmps}/dotfiles/symlinktemplatedir
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/symlinktemplatedir/t
+mkdir -p "${tmps}"/dotfiles/symlinktemplatedir
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/symlinktemplatedir/t
 
-echo 'nomode' > ${tmps}/dotfiles/nomode
+echo 'nomode' > "${tmps}"/dotfiles/nomode
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -197,7 +170,7 @@ _EOF
 
 # install
 echo "first install round"
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p1 -V
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 -V
 echo "first install round"
 
 has_rights "${tmpd}/f777" "777"
@@ -212,24 +185,24 @@ has_rights "${tmpd}/linkchildren/f1" "644"
 has_rights "${tmpd}/linkchildren/d1" "755"
 has_rights "${tmpd}/linkchildren/d1/f2" "644"
 has_rights "${tmpd}/symlinktemplate" "777"
-m=`get_file_mode`
+m=$(get_file_mode)
 has_rights "${tmpd}/nomode" "${m}"
 
-grep 'p1' ${tmpd}/symlinktemplate
-grep 'p1' ${tmpd}/symlinktemplatedir/t
+grep 'p1' "${tmpd}"/symlinktemplate
+grep 'p1' "${tmpd}"/symlinktemplatedir/t
 
 ## second round
-echo "exists" > ${tmps}/dotfiles/exists
-chmod 600 ${tmps}/dotfiles/exists
-echo "exists" > ${tmpd}/exists
-chmod 600 ${tmpd}/exists
+echo "exists" > "${tmps}"/dotfiles/exists
+chmod 600 "${tmps}"/dotfiles/exists
+echo "exists" > "${tmpd}"/exists
+chmod 600 "${tmpd}"/exists
 
-chmod 700 ${tmpd}/linkchildren
+chmod 700 "${tmpd}"/linkchildren
 
-chmod 600 ${tmpd}/symlinktemplate
+chmod 600 "${tmpd}"/symlinktemplate
 
 echo "second install round"
-cd ${ddpath} | ${bin} install -c ${cfg} -p p2 -f -V
+cd "${ddpath}" | ${bin} install -c "${cfg}" -p p2 -f -V
 echo "second install round"
 
 has_rights "${tmpd}/exists" "777"
@@ -237,39 +210,43 @@ has_rights "${tmpd}/linkchildren/f1" "644"
 has_rights "${tmpd}/linkchildren/d1" "755"
 has_rights "${tmpd}/linkchildren/d1/f2" "644"
 has_rights "${tmpd}/symlinktemplate" "777"
-m=`get_file_mode`
+m=$(get_file_mode)
 has_rights "${tmpd}/nomode" "${m}"
 
 ## no user confirmation expected
 ## same mode
 echo "same mode"
-echo "nomode" > ${tmps}/dotfiles/nomode
-chmod 600 ${tmps}/dotfiles/nomode
-echo "nomode" > ${tmpd}/nomode
-chmod 600 ${tmpd}/nomode
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p2 -V f_nomode
+echo "nomode" > "${tmps}"/dotfiles/nomode
+chmod 600 "${tmps}"/dotfiles/nomode
+echo "nomode" > "${tmpd}"/nomode
+chmod 600 "${tmpd}"/nomode
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p2 -V f_nomode
 echo "same mode"
 has_rights "${tmpd}/nomode" "600"
 
 ## no user confirmation with force
 ## different mode
 echo "different mode"
-echo "nomode" > ${tmps}/dotfiles/nomode
-chmod 600 ${tmps}/dotfiles/nomode
-echo "nomode" > ${tmpd}/nomode
-chmod 700 ${tmpd}/nomode
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p2 -V f_nomode
+echo "nomode" > "${tmps}"/dotfiles/nomode
+chmod 600 "${tmps}"/dotfiles/nomode
+echo "nomode" > "${tmpd}"/nomode
+chmod 700 "${tmpd}"/nomode
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p2 -V f_nomode
 echo "different mode (1)"
 has_rights "${tmpd}/nomode" "600"
 
 ## user confirmation expected
 ## different mode
 echo "different mode"
-echo "nomode" > ${tmps}/dotfiles/nomode
-chmod 600 ${tmps}/dotfiles/nomode
-echo "nomode" > ${tmpd}/nomode
-chmod 700 ${tmpd}/nomode
-cd ${ddpath} | printf 'y\ny\n' | ${bin} install -f -c ${cfg} -p p2 -V f_nomode
+echo "nomode" > "${tmps}"/dotfiles/nomode
+chmod 600 "${tmps}"/dotfiles/nomode
+echo "nomode" > "${tmpd}"/nomode
+chmod 700 "${tmpd}"/nomode
+(
+  cd "${ddpath}"
+  printf 'y\ny\n' | ${bin} install -f -c "${cfg}" -p p2 -V f_nomode
+  exit $?
+)
 echo "different mode (2)"
 has_rights "${tmpd}/nomode" "600"
 
diff --git a/tests-ng/chmod-more.sh b/tests-ng/chmod-more.sh
index 001734a..51c3971 100755
--- a/tests-ng/chmod-more.sh
+++ b/tests-ng/chmod-more.sh
@@ -7,41 +7,20 @@
 # with different link
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -52,30 +31,18 @@ echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
 has_rights()
 {
   echo "testing ${1} is ${2}"
-  [ ! -e "$1" ] && echo "`basename $1` does not exist" && exit 1
-  local mode=`stat -L -c '%a' "$1"`
-  [ "${mode}" != "$2" ] && echo "bad mode for `basename $1` (${mode} instead of ${2})" && exit 1
+  [ ! -e "$1" ] && echo "$(basename "$1") does not exist" && exit 1
+  local mode
+  mode=$(stat -L -c '%a' "$1")
+  [ "${mode}" != "$2" ] && echo "bad mode for $(basename "$1") (${mode} instead of ${2})" && exit 1
   true
 }
 
-# $1 file
-chmod_to_umask()
-{
-  u=`umask`
-  u=`echo ${u} | sed 's/^0*//'`
-  if [ -d ${1} ]; then
-    v=$((777 - u))
-  else
-    v=$((666 - u))
-  fi
-  chmod ${v} ${1}
-}
-
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -83,21 +50,21 @@ clear_on_exit "${tmpd}"
 
 # create the dotfiles
 f1="${tmpd}/f1"
-touch ${f1}
-chmod 777 ${f1}
-stat -c '%a' ${f1}
+touch "${f1}"
+chmod 777 "${f1}"
+stat -c '%a' "${f1}"
 
 f2="${tmpd}/f2"
-touch ${f2}
-chmod 644 ${f2}
-stat -c '%a' ${f2}
+touch "${f2}"
+chmod 644 "${f2}"
+stat -c '%a' "${f2}"
 
 toimport="${f1} ${f2}"
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -109,11 +76,11 @@ _EOF
 
 # import without --preserve-mode
 for i in ${toimport}; do
-  stat -c '%a' ${i}
-  cd ${ddpath} | ${bin} import -c ${cfg} -f -p p1 -V ${i}
+  stat -c '%a' "${i}"
+  cd "${ddpath}" | ${bin} import -c "${cfg}" -f -p p1 -V "${i}"
 done
 
-cat ${cfg}
+cat "${cfg}"
 
 has_rights "${tmpd}/f1" "777"
 has_rights "${tmps}/dotfiles/${tmpd}/f1" "777"
@@ -121,7 +88,7 @@ has_rights "${tmpd}/f2" "644"
 has_rights "${tmps}/dotfiles/${tmpd}/f2" "644"
 
 # install
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p1 -V | grep '0 dotfile(s) installed' || (echo "should not install" && exit 1)
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 -V | grep '0 dotfile(s) installed' || (echo "should not install" && exit 1)
 
 echo "OK"
 exit 0
diff --git a/tests-ng/chmod-preserve-install.sh b/tests-ng/chmod-preserve-install.sh
index 3ff2330..af8e5c0 100755
--- a/tests-ng/chmod-preserve-install.sh
+++ b/tests-ng/chmod-preserve-install.sh
@@ -5,41 +5,20 @@
 # test chmod preserve on install
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -50,9 +29,10 @@ echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
 has_rights()
 {
   echo "testing ${1} is ${2}"
-  [ ! -e "$1" ] && echo "`basename $1` does not exist" && exit 1
-  local mode=`stat -L -c '%a' "$1"`
-  [ "${mode}" != "$2" ] && echo "bad mode for `basename $1` (${mode} VS expected ${2})" && exit 1
+  [ ! -e "$1" ] && echo "$(basename "$1") does not exist" && exit 1
+  local mode
+  mode=$(stat -L -c '%a' "$1")
+  [ "${mode}" != "$2" ] && echo "bad mode for $(basename "$1") (${mode} VS expected ${2})" && exit 1
   true
 }
 
@@ -60,39 +40,43 @@ has_rights()
 is_same_as()
 {
   echo "testing ${1} has same rights than ${2}"
-  [ ! -e "$1" ] && echo "`basename $1` does not exist" && exit 1
-  [ ! -e "$2" ] && echo "`basename $2` does not exist" && exit 1
+  [ ! -e "$1" ] && echo "$(basename "$1") does not exist" && exit 1
+  [ ! -e "$2" ] && echo "$(basename "$2") does not exist" && exit 1
 
-  local mode1=`stat -L -c '%a' "$1"`
+  local mode1
+  mode1=$(stat -L -c '%a' "$1")
   echo "$1: ${mode1}"
-  local mode2=`stat -L -c '%a' "$2"`
+  local mode2
+  mode2=$(stat -L -c '%a' "$2")
   echo "$2: ${mode2}"
 
-  [ "${mode1}" != "${mode2}" ] && echo "`basename $1` (${mode1}) does not have same mode as `basename $2` (${mode2})" && exit 1
+  [ "${mode1}" != "${mode2}" ] && echo "$(basename "$1") (${mode1}) does not have same mode as $(basename "$2") (${mode2})" && exit 1
   true
 }
 
 get_default_file_mode()
 {
-  u=`umask`
-  u=`echo ${u} | sed 's/^0*//'`
+  u=$(umask)
+  # shellcheck disable=SC2001
+  u=$(echo "${u}" | sed 's/^0*//')
   v=$((666 - u))
   echo "${v}"
 }
 
 get_default_dir_mode()
 {
-  u=`umask`
-  u=`echo ${u} | sed 's/^0*//'`
+  u=$(umask)
+  # shellcheck disable=SC2001
+  u=$(echo "${u}" | sed 's/^0*//')
   v=$((777 - u))
   echo "${v}"
 }
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -106,70 +90,70 @@ cfg="${tmps}/config.yaml"
 ##
 
 # file
-echo 'f777' > ${tmps}/dotfiles/f777
-chmod 700 ${tmps}/dotfiles/f777
+echo 'f777' > "${tmps}"/dotfiles/f777
+chmod 700 "${tmps}"/dotfiles/f777
 
 # link
-echo 'link' > ${tmps}/dotfiles/link
-chmod 700 ${tmps}/dotfiles/link
+echo 'link' > "${tmps}"/dotfiles/link
+chmod 700 "${tmps}"/dotfiles/link
 
 # directory
-mkdir -p ${tmps}/dotfiles/dir
-echo "f1" > ${tmps}/dotfiles/dir/f1
-chmod 700 ${tmps}/dotfiles/dir
-chmod 700 ${tmps}/dotfiles/dir/f1
+mkdir -p "${tmps}"/dotfiles/dir
+echo "f1" > "${tmps}"/dotfiles/dir/f1
+chmod 700 "${tmps}"/dotfiles/dir
+chmod 700 "${tmps}"/dotfiles/dir/f1
 
 # template
-echo '{{@@ profile @@}}' > ${tmps}/dotfiles/template
-chmod 700 ${tmps}/dotfiles/template
+echo '{{@@ profile @@}}' > "${tmps}"/dotfiles/template
+chmod 700 "${tmps}"/dotfiles/template
 
 # link template
-echo '{{@@ profile @@}}' > ${tmps}/dotfiles/link-template
-chmod 700 ${tmps}/dotfiles/link-template
+echo '{{@@ profile @@}}' > "${tmps}"/dotfiles/link-template
+chmod 700 "${tmps}"/dotfiles/link-template
 
 ##
 # existing files
 ##
 
 # file
-echo "exists-original" > ${tmps}/dotfiles/exists
-chmod 644 ${tmps}/dotfiles/exists
-echo "exists" > ${tmpd}/exists
-chmod 700 ${tmpd}/exists
+echo "exists-original" > "${tmps}"/dotfiles/exists
+chmod 644 "${tmps}"/dotfiles/exists
+echo "exists" > "${tmpd}"/exists
+chmod 700 "${tmpd}"/exists
 
 # link
-echo "existslink" > ${tmps}/dotfiles/existslink
-chmod 700 ${tmps}/dotfiles/existslink
-ln -s ${tmps}/dotfiles/existslink ${tmpd}/existslink
+echo "existslink" > "${tmps}"/dotfiles/existslink
+chmod 700 "${tmps}"/dotfiles/existslink
+ln -s "${tmps}"/dotfiles/existslink "${tmpd}"/existslink
 
 # directory
-mkdir -p ${tmps}/dotfiles/direxists
-echo "f1-original" > ${tmps}/dotfiles/direxists/f1
-mkdir -p ${tmpd}/direxists
-echo "f1" > ${tmpd}/direxists/f1
-chmod 700 ${tmpd}/direxists/f1
-chmod 700 ${tmpd}/direxists
+mkdir -p "${tmps}"/dotfiles/direxists
+echo "f1-original" > "${tmps}"/dotfiles/direxists/f1
+mkdir -p "${tmpd}"/direxists
+echo "f1" > "${tmpd}"/direxists/f1
+chmod 700 "${tmpd}"/direxists/f1
+chmod 700 "${tmpd}"/direxists
 
 # link children
-mkdir -p ${tmps}/dotfiles/linkchildren
-echo "f1-original" > ${tmps}/dotfiles/linkchildren/f1
-chmod 700 ${tmps}/dotfiles/linkchildren/f1
-mkdir -p ${tmps}/dotfiles/linkchildren/d1
-chmod 700 ${tmps}/dotfiles/linkchildren/d1
-echo "f2-original" > ${tmps}/dotfiles/linkchildren/d1/f2
-chmod 700 ${tmps}/dotfiles/linkchildren/d1/f2
-
-mkdir -p ${tmpd}/linkchildren
-chmod 700 ${tmpd}/linkchildren
-echo "f1" > ${tmpd}/linkchildren/f1
-mkdir -p ${tmpd}/linkchildren/d1
-echo "f2" > ${tmpd}/linkchildren/d1/f2
+mkdir -p "${tmps}"/dotfiles/linkchildren
+echo "f1-original" > "${tmps}"/dotfiles/linkchildren/f1
+chmod 700 "${tmps}"/dotfiles/linkchildren/f1
+mkdir -p "${tmps}"/dotfiles/linkchildren/d1
+chmod 700 "${tmps}"/dotfiles/linkchildren/d1
+echo "f2-original" > "${tmps}"/dotfiles/linkchildren/d1/f2
+chmod 700 "${tmps}"/dotfiles/linkchildren/d1/f2
+
+mkdir -p "${tmpd}"/linkchildren
+chmod 700 "${tmpd}"/linkchildren
+echo "f1" > "${tmpd}"/linkchildren/f1
+mkdir -p "${tmpd}"/linkchildren/d1
+echo "f2" > "${tmpd}"/linkchildren/d1/f2
 
 # no mode
-echo 'nomode-original' > ${tmps}/dotfiles/nomode
-echo 'nomode' > ${tmpd}/nomode
+echo 'nomode-original' > "${tmps}"/dotfiles/nomode
+echo 'nomode' > "${tmpd}"/nomode
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -235,23 +219,23 @@ profiles:
 _EOF
 #cat ${cfg}
 
-exists_before=`stat -L -c '%a' "${tmpd}/exists"`
-direxists_before=`stat -L -c '%a' "${tmpd}/direxists"`
-direxists_f1_before=`stat -L -c '%a' "${tmpd}/direxists/f1"`
+exists_before=$(stat -L -c '%a' "${tmpd}/exists")
+direxists_before=$(stat -L -c '%a' "${tmpd}/direxists")
+direxists_f1_before=$(stat -L -c '%a' "${tmpd}/direxists/f1")
 
 # install
 echo "first round"
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 echo "first round"
 
 # non-existing but will create with "default" rights on preserve
 # 644 for file
 # 755 for directory
 # link will get the rights of the file it points to
-has_rights "${tmpd}/f777" "`get_default_file_mode`"
+has_rights "${tmpd}/f777" "$(get_default_file_mode)"
 has_rights "${tmpd}/link" "700"
-has_rights "${tmpd}/dir" "`get_default_dir_mode`"
-has_rights "${tmpd}/template" "`get_default_file_mode`"
+has_rights "${tmpd}/dir" "$(get_default_dir_mode)"
+has_rights "${tmpd}/template" "$(get_default_file_mode)"
 # first install to workdir (def rights) and then symlink
 has_rights "${tmpd}/link-template" "644"
 [ -L "${tmpd}/link-template" ] && echo "link-template is not a symlink" && exit 1
@@ -275,20 +259,20 @@ has_rights "${tmpd}/linkchildren/d1" "700" # points back to dotpath
 has_rights "${tmpd}/linkchildren/d1/f2" "700"
 
 # modify
-echo 'f777-2' >> ${tmps}/dotfiles/f777
-chmod 701 ${tmps}/dotfiles/f777
-echo 'link-2' >> ${tmps}/dotfiles/link
-chmod 701 ${tmps}/dotfiles/link
-echo "f1-2" >> ${tmps}/dotfiles/dir/f1
-chmod 701 ${tmps}/dotfiles/dir
-chmod 701 ${tmps}/dotfiles/dir/f1
-
-f777_before=`stat -L -c '%a' "${tmpd}/f777"`
-link_before=`stat -L -c '%a' "${tmpd}/link"`
-dir_before=`stat -L -c '%a' "${tmpd}/dir"`
+echo 'f777-2' >> "${tmps}"/dotfiles/f777
+chmod 701 "${tmps}"/dotfiles/f777
+echo 'link-2' >> "${tmps}"/dotfiles/link
+chmod 701 "${tmps}"/dotfiles/link
+echo "f1-2" >> "${tmps}"/dotfiles/dir/f1
+chmod 701 "${tmps}"/dotfiles/dir
+chmod 701 "${tmps}"/dotfiles/dir/f1
+
+f777_before=$(stat -L -c '%a' "${tmpd}/f777")
+link_before=$(stat -L -c '%a' "${tmpd}/link")
+dir_before=$(stat -L -c '%a' "${tmpd}/dir")
 
 echo "second round"
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 echo "second round"
 
 # existing
diff --git a/tests-ng/chmod-preserve-update.sh b/tests-ng/chmod-preserve-update.sh
index ab9c5d7..366447e 100755
--- a/tests-ng/chmod-preserve-update.sh
+++ b/tests-ng/chmod-preserve-update.sh
@@ -5,51 +5,30 @@
 # test chmod preserve on update
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -60,46 +39,46 @@ clear_on_exit "${tmpd}"
 ##
 
 # file
-echo "exists-original" > ${tmps}/dotfiles/exists
-chmod 644 ${tmps}/dotfiles/exists
-echo "exists" > ${tmpd}/exists
-chmod 700 ${tmpd}/exists
+echo "exists-original" > "${tmps}"/dotfiles/exists
+chmod 644 "${tmps}"/dotfiles/exists
+echo "exists" > "${tmpd}"/exists
+chmod 700 "${tmpd}"/exists
 
 # link
-echo "existslink" > ${tmps}/dotfiles/existslink
-chmod 700 ${tmps}/dotfiles/existslink
-ln -s ${tmps}/dotfiles/existslink ${tmpd}/existslink
+echo "existslink" > "${tmps}"/dotfiles/existslink
+chmod 700 "${tmps}"/dotfiles/existslink
+ln -s "${tmps}"/dotfiles/existslink "${tmpd}"/existslink
 
 # directory
-mkdir -p ${tmps}/dotfiles/direxists
-echo "f1-original" > ${tmps}/dotfiles/direxists/f1
-mkdir -p ${tmpd}/direxists
-echo "f1" > ${tmpd}/direxists/f1
-chmod 700 ${tmpd}/direxists/f1
-chmod 700 ${tmpd}/direxists
+mkdir -p "${tmps}"/dotfiles/direxists
+echo "f1-original" > "${tmps}"/dotfiles/direxists/f1
+mkdir -p "${tmpd}"/direxists
+echo "f1" > "${tmpd}"/direxists/f1
+chmod 700 "${tmpd}"/direxists/f1
+chmod 700 "${tmpd}"/direxists
 
 # link children
-mkdir -p ${tmps}/dotfiles/linkchildren
-echo "f1-original" > ${tmps}/dotfiles/linkchildren/f1
-chmod 700 ${tmps}/dotfiles/linkchildren/f1
-mkdir -p ${tmps}/dotfiles/linkchildren/d1
-chmod 700 ${tmps}/dotfiles/linkchildren/d1
-echo "f2-original" > ${tmps}/dotfiles/linkchildren/d1/f2
-chmod 700 ${tmps}/dotfiles/linkchildren/d1/f2
-
-mkdir -p ${tmpd}/linkchildren
-chmod 700 ${tmpd}/linkchildren
-echo "f1" > ${tmpd}/linkchildren/f1
-mkdir -p ${tmpd}/linkchildren/d1
-echo "f2" > ${tmpd}/linkchildren/d1/f2
+mkdir -p "${tmps}"/dotfiles/linkchildren
+echo "f1-original" > "${tmps}"/dotfiles/linkchildren/f1
+chmod 700 "${tmps}"/dotfiles/linkchildren/f1
+mkdir -p "${tmps}"/dotfiles/linkchildren/d1
+chmod 700 "${tmps}"/dotfiles/linkchildren/d1
+echo "f2-original" > "${tmps}"/dotfiles/linkchildren/d1/f2
+chmod 700 "${tmps}"/dotfiles/linkchildren/d1/f2
+
+mkdir -p "${tmpd}"/linkchildren
+chmod 700 "${tmpd}"/linkchildren
+echo "f1" > "${tmpd}"/linkchildren/f1
+mkdir -p "${tmpd}"/linkchildren/d1
+echo "f2" > "${tmpd}"/linkchildren/d1/f2
 
 # no mode
-echo 'nomode-original' > ${tmps}/dotfiles/nomode
-echo 'nomode' > ${tmpd}/nomode
+echo 'nomode-original' > "${tmps}"/dotfiles/nomode
+echo 'nomode' > "${tmpd}"/nomode
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -140,13 +119,13 @@ _EOF
 #cat ${cfg}
 
 echo "update"
-cd ${ddpath} | ${bin} update -f -c ${cfg} -p p1 -V ${tmpd}/exists
-cd ${ddpath} | ${bin} update -f -c ${cfg} -p p1 -V ${tmpd}/existslink
-cd ${ddpath} | ${bin} update -f -c ${cfg} -p p1 -V ${tmpd}/direxists
-cd ${ddpath} | ${bin} update -f -c ${cfg} -p p1 -V ${tmpd}/linkchildren
-cd ${ddpath} | ${bin} update -f -c ${cfg} -p p1 -V ${tmpd}/nomode
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" -p p1 -V "${tmpd}"/exists
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" -p p1 -V "${tmpd}"/existslink
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" -p p1 -V "${tmpd}"/direxists
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" -p p1 -V "${tmpd}"/linkchildren
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" -p p1 -V "${tmpd}"/nomode
 
-count=$(cat ${cfg} | grep chmod | grep -v 'chmod: preserve\|force_chmod' | wc -l)
+count=$(cat "${cfg}" | grep chmod | grep -v 'chmod: preserve\|force_chmod' | wc -l)
 echo "${count}"
 [ "${count}" != "0" ] && echo "chmod altered" && exit 1
 
diff --git a/tests-ng/chmod-update.sh b/tests-ng/chmod-update.sh
index 5e38fbd..85773cc 100755
--- a/tests-ng/chmod-update.sh
+++ b/tests-ng/chmod-update.sh
@@ -5,51 +5,30 @@
 # test chmod on update
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -57,32 +36,32 @@ clear_on_exit "${tmpd}"
 
 # create the dotfile
 dnormal="${tmpd}/dir_normal"
-mkdir -p ${dnormal}
-echo "dir_normal/f1" > ${dnormal}/file1
-echo "dir_normal/f2" > ${dnormal}/file2
+mkdir -p "${dnormal}"
+echo "dir_normal/f1" > "${dnormal}"/file1
+echo "dir_normal/f2" > "${dnormal}"/file2
 
 dlink="${tmpd}/dir_link"
-mkdir -p ${dlink}
-echo "dir_link/f1" > ${dlink}/file1
-echo "dir_link/f2" > ${dlink}/file2
+mkdir -p "${dlink}"
+echo "dir_link/f1" > "${dlink}"/file1
+echo "dir_link/f2" > "${dlink}"/file2
 
 dlinkchildren="${tmpd}/dir_link_children"
-mkdir -p ${dlinkchildren}
-echo "dir_linkchildren/f1" > ${dlinkchildren}/file1
-echo "dir_linkchildren/f2" > ${dlinkchildren}/file2
+mkdir -p "${dlinkchildren}"
+echo "dir_linkchildren/f1" > "${dlinkchildren}"/file1
+echo "dir_linkchildren/f2" > "${dlinkchildren}"/file2
 
 fnormal="${tmpd}/filenormal"
-echo "filenormal" > ${fnormal}
+echo "filenormal" > "${fnormal}"
 
 flink="${tmpd}/filelink"
-echo "filelink" > ${flink}
+echo "filelink" > "${flink}"
 
 toimport="${dnormal} ${dlink} ${dlinkchildren} ${fnormal} ${flink}"
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -93,64 +72,69 @@ _EOF
 
 # import
 for i in ${toimport}; do
-  cd ${ddpath} | ${bin} import -c ${cfg} -f -p p1 -V ${i}
+  cd "${ddpath}" | ${bin} import -c "${cfg}" -f -p p1 -V "${i}"
 done
 
-cat ${cfg}
+cat "${cfg}"
 
 # test no chmod
-cnt=`cat ${cfg} | grep chmod | wc -l`
+cnt=$(cat "${cfg}" | grep chmod | wc -l)
 [ "${cnt}" != "0" ] && echo "chmod wrongly inserted" && exit 1
 
 ######################
 # update dnormal
-chmod 777 ${dnormal}
-cd ${ddpath} | ${bin} update -c ${cfg} -f -p p1 -V ${dnormal}
+chmod 777 "${dnormal}"
+cd "${ddpath}" | ${bin} update -c "${cfg}" -f -p p1 -V "${dnormal}"
 
 # check rights updated
-[ "`stat -c '%a' ${tmps}/dotfiles/${tmpd}/$(basename ${dnormal})`" != "777" ] && echo "rights not updated (1)" && exit 1
+bname=$(basename "${dnormal}")
+[ "$(stat -c '%a' "${tmps}"/dotfiles/"${tmpd}"/"${bname}")" != "777" ] && echo "rights not updated (1)" && exit 1
 
-cnt=`cat ${cfg} | grep "chmod: '777'" | wc -l`
+cnt=$(cat "${cfg}" | grep "chmod: '777'" | wc -l)
 [ "${cnt}" != "1" ] && echo "chmod not updated (1)" && exit 1
 
 ######################
 # update dlink
-chmod 777 ${dlink}
-cd ${ddpath} | ${bin} update -c ${cfg} -f -p p1 -V ${dlink}
+chmod 777 "${dlink}"
+cd "${ddpath}" | ${bin} update -c "${cfg}" -f -p p1 -V "${dlink}"
 
 # check rights updated
-[ "`stat -c '%a' ${tmps}/dotfiles/${tmpd}/$(basename ${dlink})`" != "777" ] && echo "rights not updated (2)" && exit 1
-cnt=`cat ${cfg} | grep "chmod: '777'" | wc -l`
+bname=$(basename "${dlink}")
+[ "$(stat -c '%a' "${tmps}"/dotfiles/"${tmpd}"/"${bname}")" != "777" ] && echo "rights not updated (2)" && exit 1
+cnt=$(cat "${cfg}" | grep "chmod: '777'" | wc -l)
 [ "${cnt}" != "2" ] && echo "chmod not updated (2)" && exit 1
 
 ######################
 # update dlinkchildren
-chmod 777 ${dlinkchildren}
-cd ${ddpath} | ${bin} update -c ${cfg} -f -p p1 -V ${dlinkchildren}
+chmod 777 "${dlinkchildren}"
+cd "${ddpath}" | ${bin} update -c "${cfg}" -f -p p1 -V "${dlinkchildren}"
 
 # check rights updated
-[ "`stat -c '%a' ${tmps}/dotfiles/${tmpd}/$(basename ${dlinkchildren})`" != "777" ] && echo "rights not updated (3)" && exit 1
-cnt=`cat ${cfg} | grep "chmod: '777'" | wc -l`
+bname=$(basename "${dlinkchildren}")
+[ "$(stat -c '%a' "${tmps}"/dotfiles/"${tmpd}"/"${bname}")" != "777" ] && echo "rights not updated (3)" && exit 1
+cnt=$(cat "${cfg}" | grep "chmod: '777'" | wc -l)
 [ "${cnt}" != "3" ] && echo "chmod not updated (3)" && exit 1
 
 ######################
 # update fnormal
-chmod 777 ${fnormal}
-cd ${ddpath} | ${bin} update -c ${cfg} -f -p p1 -V ${fnormal}
+chmod 777 "${fnormal}"
+cd "${ddpath}" | ${bin} update -c "${cfg}" -f -p p1 -V "${fnormal}"
 
 # check rights updated
-[ "`stat -c '%a' ${tmps}/dotfiles/${tmpd}/$(basename ${fnormal})`" != "777" ] && echo "rights not updated (4)" && exit 1
-cnt=`cat ${cfg} | grep "chmod: '777'" | wc -l`
+bname=$(basename "${fnormal}")
+[ "$(stat -c '%a' "${tmps}"/dotfiles/"${tmpd}"/"${bname}")" != "777" ] && echo "rights not updated (4)" && exit 1
+cnt=$(cat "${cfg}" | grep "chmod: '777'" | wc -l)
 [ "${cnt}" != "4" ] && echo "chmod not updated (4)" && exit 1
 
 ######################
 # update flink
-chmod 777 ${flink}
-cd ${ddpath} | ${bin} update -c ${cfg} -f -p p1 -V ${flink}
+chmod 777 "${flink}"
+cd "${ddpath}" | ${bin} update -c "${cfg}" -f -p p1 -V "${flink}"
 
 # check rights updated
-[ "`stat -c '%a' ${tmps}/dotfiles/${tmpd}/$(basename ${flink})`" != "777" ] && echo "rights not updated (5)" && exit 1
-cnt=`cat ${cfg} | grep "chmod: '777'" | wc -l`
+bname=$(basename "${flink}")
+[ "$(stat -c '%a' "${tmps}"/dotfiles/"${tmpd}"/"${bname}")" != "777" ] && echo "rights not updated (5)" && exit 1
+cnt=$(cat "${cfg}" | grep "chmod: '777'" | wc -l)
 [ "${cnt}" != "5" ] && echo "chmod not updated (5)" && exit 1
 
 echo "OK"
diff --git a/tests-ng/clear-workdir.sh b/tests-ng/clear-workdir.sh
index 89a4f30..af63b70 100755
--- a/tests-ng/clear-workdir.sh
+++ b/tests-ng/clear-workdir.sh
@@ -6,54 +6,33 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${basedir}/dotfiles
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${basedir}"/dotfiles
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 if [ -z "${DOTDROP_WORKDIR}" ]; then
-  tmpw=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+  tmpw=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
   export DOTDROP_WORKDIR="${tmpw}"
   clear_on_exit "${tmpw}"
 fi
@@ -61,11 +40,11 @@ fi
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
-echo "{{@@ profile @@}}" > ${basedir}/dotfiles/x
+echo "{{@@ profile @@}}" > "${basedir}"/dotfiles/x
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -82,30 +61,33 @@ profiles:
 _EOF
 
 echo "[+] install (1)"
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p1 --verbose | grep '^1 dotfile(s) installed.$'
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 --verbose | grep '^1 dotfile(s) installed.$'
 [ "$?" != "0" ] && exit 1
 
-[ ! -e ${tmpd}/x ] && echo "f_x not installed" && exit 1
-[ ! -h ${tmpd}/x ] && echo "f_x not symlink" && exit 1
-[ ! -e ${DOTDROP_WORKDIR}/${tmpd}/x ] && echo "f_x not in workdir (${DOTDROP_WORKDIR}/${tmpd})" && exit 1
+[ ! -e "${tmpd}"/x ] && echo "f_x not installed" && exit 1
+[ ! -h "${tmpd}"/x ] && echo "f_x not symlink" && exit 1
+[ ! -e "${DOTDROP_WORKDIR}"/"${tmpd}"/x ] && echo "f_x not in workdir (${DOTDROP_WORKDIR}/${tmpd})" && exit 1
 
 # add file
-touch ${DOTDROP_WORKDIR}/new
+touch "${DOTDROP_WORKDIR}"/new
 
 echo "[+] re-install with clear-workdir in cli"
-cd ${ddpath} | printf "y\n" | ${bin} install -W -c ${cfg} -p p1 --verbose
-[ "$?" != "0" ] && exit 1
+(
+  cd "${ddpath}"
+  printf "y\n" | ${bin} install -W -c "${cfg}" -p p1 --verbose
+  exit $?
+)
 
-[ ! -e ${tmpd}/x ] && echo "f_x not installed" && exit 1
-[ ! -h ${tmpd}/x ] && echo "f_x not symlink" && exit 1
-[ ! -e ${DOTDROP_WORKDIR}/${tmpd}/x ] && echo "f_x not in workdir (${DOTDROP_WORKDIR}/${tmpd})" && exit 1
-[ -e ${DOTDROP_WORKDIR}/new ] && echo "workdir not cleared (1)" && exit 1
+[ ! -e "${tmpd}"/x ] && echo "f_x not installed" && exit 1
+[ ! -h "${tmpd}"/x ] && echo "f_x not symlink" && exit 1
+[ ! -e "${DOTDROP_WORKDIR}"/"${tmpd}"/x ] && echo "f_x not in workdir (${DOTDROP_WORKDIR}/${tmpd})" && exit 1
+[ -e "${DOTDROP_WORKDIR}"/new ] && echo "workdir not cleared (1)" && exit 1
 
 # add file
-touch ${DOTDROP_WORKDIR}/new
+touch "${DOTDROP_WORKDIR}"/new
 
 echo "[+] re-install with config clear-workdir in config"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -121,13 +103,16 @@ profiles:
     dotfiles:
     - f_x
 _EOF
-cd ${ddpath} | printf "y\n" | ${bin} install -W -c ${cfg} -p p1 --verbose
-[ "$?" != "0" ] && exit 1
-
-[ ! -e ${tmpd}/x ] && echo "f_x not installed" && exit 1
-[ ! -h ${tmpd}/x ] && echo "f_x not symlink" && exit 1
-[ ! -e ${DOTDROP_WORKDIR}/${tmpd}/x ] && echo "f_x not in workdir (${DOTDROP_WORKDIR}/${tmpd})" && exit 1
-[ -e ${DOTDROP_WORKDIR}/new ] && echo "workdir not cleared (2)" && exit 1
+(
+  cd "${ddpath}"
+  printf "y\n" | ${bin} install -W -c "${cfg}" -p p1 --verbose
+  exit $?
+)
+
+[ ! -e "${tmpd}"/x ] && echo "f_x not installed" && exit 1
+[ ! -h "${tmpd}"/x ] && echo "f_x not symlink" && exit 1
+[ ! -e "${DOTDROP_WORKDIR}"/"${tmpd}"/x ] && echo "f_x not in workdir (${DOTDROP_WORKDIR}/${tmpd})" && exit 1
+[ -e "${DOTDROP_WORKDIR}"/new ] && echo "workdir not cleared (2)" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/compare-diff-types.sh b/tests-ng/compare-diff-types.sh
new file mode 100755
index 0000000..9e76b68
--- /dev/null
+++ b/tests-ng/compare-diff-types.sh
@@ -0,0 +1,85 @@
+#!/usr/bin/env bash
+# author: deadc0de6 (https://github.com/deadc0de6)
+# Copyright (c) 2023, deadc0de6
+#
+# test updates
+# returns 1 in case of error
+#
+
+## start-cookie
+set -e
+cur=$(cd "$(dirname "${0}")" && pwd)
+ddpath="${cur}/../"
+export PYTHONPATH="${ddpath}:${PYTHONPATH}"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
+
+################################################################
+# this is the test
+################################################################
+
+# dotdrop directory
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+echo "[+] dotdrop dir: ${basedir}"
+echo "[+] dotpath dir: ${basedir}/dotfiles"
+mkdir -p "${basedir}/dotfiles"
+
+# the dotfile to be imported
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+
+clear_on_exit "${basedir}"
+clear_on_exit "${tmpd}"
+
+# create the config file
+cfg="${basedir}/config.yaml"
+cat > "${cfg}" << _EOF
+config:
+  backup: true
+  create: true
+  dotpath: dotfiles
+dotfiles:
+  f_file:
+    src: file
+    dst: ${tmpd}/file
+  d_file:
+    src: dir
+    dst: ${tmpd}/dir
+profiles:
+  p1:
+    dotfiles:
+    - f_file
+  p2:
+    dotfiles:
+    - d_file
+_EOF
+
+# file and dir
+echo "test" > "${basedir}"/dotfiles/file
+mkdir "${tmpd}"/file
+
+# dir and file
+mkdir "${basedir}"/dotfiles/dir
+echo "test" > "${tmpd}"/dir
+
+# compare
+echo "[+] comparing p1"
+set +e
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 --verbose
+[ "$?" = "0" ] && exit 1
+set -e
+
+echo "[+] comparing p2"
+set +e
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p2 --verbose
+[ "$?" = "0" ] && exit 1
+set -e
+
+echo "OK"
+exit 0
diff --git a/tests-ng/compare-ignore-missing.sh b/tests-ng/compare-ignore-missing.sh
index c055f49..d7b70f5 100755
--- a/tests-ng/compare-ignore-missing.sh
+++ b/tests-ng/compare-ignore-missing.sh
@@ -6,64 +6,48 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 dt="${basedir}/dotfiles"
-mkdir -p ${dt}/folder
-touch ${dt}/folder/a
+mkdir -p "${dt}"/folder
+touch "${dt}"/folder/a
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # some files
-cp -r ${dt}/folder ${tmpd}/
-mkdir -p ${tmpd}/folder
-touch ${tmpd}/folder/b
-mkdir ${tmpd}/folder/c
+cp -r "${dt}"/folder "${tmpd}"/
+mkdir -p "${tmpd}"/folder
+touch "${tmpd}"/folder/b
+mkdir "${tmpd}"/folder/c
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -85,7 +69,7 @@ _EOF
 # Expect diff
 echo "[+] test with no ignore-missing setting"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --profile=p1
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose --profile=p1
 [ "$?" = "0" ] && exit 1
 set -e
 
@@ -96,7 +80,7 @@ set -e
 # Expect no diff
 echo "[+] test with command-line flag"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --profile=p1 --ignore-missing
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose --profile=p1 --ignore-missing
 [ "$?" != "0" ] && exit 1
 set -e
 
@@ -104,7 +88,7 @@ set -e
 # Test with global option
 #
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -123,7 +107,7 @@ _EOF
 # Expect no diff
 echo "[+] test global option"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --profile=p1
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose --profile=p1
 [ "$?" != "0" ] && exit 1
 set -e
 
@@ -131,7 +115,7 @@ set -e
 # Test with dotfile option
 #
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -150,7 +134,7 @@ _EOF
 # Expect no diff
 echo "[+] test dotfile option"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --profile=p1
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose --profile=p1
 [ "$?" != "0" ] && exit 1
 set -e
 
diff --git a/tests-ng/compare-ignore-relative.sh b/tests-ng/compare-ignore-relative.sh
index dea2790..2fe84e9 100755
--- a/tests-ng/compare-ignore-relative.sh
+++ b/tests-ng/compare-ignore-relative.sh
@@ -6,83 +6,62 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # some files
-mkdir -p ${tmpd}/{program,config,vscode}
-touch ${tmpd}/program/a
-touch ${tmpd}/config/a
-touch ${tmpd}/vscode/extensions.txt
-touch ${tmpd}/vscode/keybindings.json
+mkdir -p "${tmpd}"/{program,config,vscode}
+touch "${tmpd}"/program/a
+touch "${tmpd}"/config/a
+touch "${tmpd}"/vscode/extensions.txt
+touch "${tmpd}"/vscode/keybindings.json
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f --verbose -c ${cfg} ${tmpd}/program || exit 1
-cd ${ddpath} | ${bin} import -f --verbose -c ${cfg} ${tmpd}/config || exit 1
-cd ${ddpath} | ${bin} import -f --verbose -c ${cfg} ${tmpd}/vscode || exit 1
+cd "${ddpath}" | ${bin} import -f --verbose -c "${cfg}" "${tmpd}"/program || exit 1
+cd "${ddpath}" | ${bin} import -f --verbose -c "${cfg}" "${tmpd}"/config || exit 1
+cd "${ddpath}" | ${bin} import -f --verbose -c "${cfg}" "${tmpd}"/vscode || exit 1
 
 # add files on filesystem
 echo "[+] add files"
-touch ${tmpd}/program/b
-touch ${tmpd}/config/b
+touch "${tmpd}"/program/b
+touch "${tmpd}"/config/b
 
 # expects diff
 echo "[+] comparing normal - diffs expected"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose
 ret="$?"
 echo ${ret}
 [ "${ret}" = "0" ] && exit 1
@@ -92,78 +71,78 @@ set -e
 patt="b"
 echo "[+] comparing with ignore (pattern: ${patt}) - no diff expected"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --ignore=${patt}
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose --ignore=${patt}
 [ "$?" != "0" ] && exit 1
 set -e
 
 # adding ignore in dotfile
 cfg2="${basedir}/config2.yaml"
-sed '/d_config:/a \ \ \ \ cmpignore:\n\ \ \ \ - "b"' ${cfg} > ${cfg2}
+sed '/d_config:/a \ \ \ \ cmpignore:\n\ \ \ \ - "b"' "${cfg}" > "${cfg2}"
 #cat ${cfg2}
 
 # expects one diff
 echo "[+] comparing with ignore in dotfile - diff expected"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose
 [ "$?" = "0" ] && exit 1
 set -e
 
 # adding ignore in dotfile
 cfg2="${basedir}/config2.yaml"
-sed '/d_config:/a \ \ \ \ cmpignore:\n\ \ \ \ - "b"' ${cfg} > ${cfg2}
-sed -i '/d_program:/a \ \ \ \ cmpignore:\n\ \ \ \ - "b"' ${cfg2}
+sed '/d_config:/a \ \ \ \ cmpignore:\n\ \ \ \ - "b"' "${cfg}" > "${cfg2}"
+sed -i '/d_program:/a \ \ \ \ cmpignore:\n\ \ \ \ - "b"' "${cfg2}"
 #cat ${cfg2}
 
 # expects no diff
 echo "[+] comparing with ignore in dotfile - no diff expected"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose
 [ "$?" != "0" ] && exit 1
 set -e
 
 # update files
-echo touched > ${tmpd}/vscode/extensions.txt
-echo touched > ${tmpd}/vscode/keybindings.json
+echo touched > "${tmpd}"/vscode/extensions.txt
+echo touched > "${tmpd}"/vscode/keybindings.json
 
 # expect two diffs
 echo "[+] comparing - diff expected"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -C ${tmpd}/vscode
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -C "${tmpd}"/vscode
 [ "$?" = "0" ] && exit 1
 set -e
 
 # expects no diff
 echo "[+] comparing with ignore in dotfile - no diff expected"
-sed '/d_vscode:/a \ \ \ \ cmpignore:\n\ \ \ \ - "extensions.txt"\n\ \ \ \ - "keybindings.json"' ${cfg} > ${cfg2}
+sed '/d_vscode:/a \ \ \ \ cmpignore:\n\ \ \ \ - "extensions.txt"\n\ \ \ \ - "keybindings.json"' "${cfg}" > "${cfg2}"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose -C ${tmpd}/vscode
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose -C "${tmpd}"/vscode
 [ "$?" != "0" ] && exit 1
 set -e
 
 ####################
 # test for #149
 ####################
-mkdir -p ${tmpd}/.zsh
-touch ${tmpd}/.zsh/somefile
-mkdir -p ${tmpd}/.zsh/plugins
-touch ${tmpd}/.zsh/plugins/someplugin
+mkdir -p "${tmpd}"/.zsh
+touch "${tmpd}"/.zsh/somefile
+mkdir -p "${tmpd}"/.zsh/plugins
+touch "${tmpd}"/.zsh/plugins/someplugin
 
 echo "[+] import .zsh"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/.zsh
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/.zsh
 
 # no diff expected
 echo "[+] comparing .zsh"
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -C ${tmpd}/.zsh --ignore=${patt}
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -C "${tmpd}"/.zsh --ignore=${patt}
 [ "$?" != "0" ] && exit 1
 
 # add some files
-touch ${tmpd}/.zsh/plugins/ignore-1.zsh
-touch ${tmpd}/.zsh/plugins/ignore-2.zsh
+touch "${tmpd}"/.zsh/plugins/ignore-1.zsh
+touch "${tmpd}"/.zsh/plugins/ignore-2.zsh
 
 # expects diff
 echo "[+] comparing .zsh with new files"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -C ${tmpd}/.zsh
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -C "${tmpd}"/.zsh
 ret="$?"
 echo ${ret}
 [ "${ret}" = "0" ] && exit 1
@@ -173,15 +152,15 @@ set -e
 patt="plugins/ignore-*.zsh"
 echo "[+] comparing with ignore (pattern: ${patt}) - no diff expected"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -C ${tmpd}/.zsh --ignore=${patt}
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -C "${tmpd}"/.zsh --ignore="${patt}"
 [ "$?" != "0" ] && exit 1
 set -e
 
 # expects no diff
 echo "[+] comparing with ignore in dotfile - no diff expected"
-sed '/d_zsh:/a \ \ \ \ cmpignore:\n\ \ \ \ - "plugins/ignore-*.zsh"' ${cfg} > ${cfg2}
+sed '/d_zsh:/a \ \ \ \ cmpignore:\n\ \ \ \ - "plugins/ignore-*.zsh"' "${cfg}" > "${cfg2}"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose -C ${tmpd}/.zsh
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose -C "${tmpd}"/.zsh
 [ "$?" != "0" ] && exit 1
 set -e
 
diff --git a/tests-ng/compare-ignore.sh b/tests-ng/compare-ignore.sh
index 28da8e7..5f90182 100755
--- a/tests-ng/compare-ignore.sh
+++ b/tests-ng/compare-ignore.sh
@@ -6,84 +6,63 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # some files
-mkdir -p ${tmpd}/{program,config}
-touch ${tmpd}/program/a
-touch ${tmpd}/config/a
-mkdir ${tmpd}/vscode
-touch ${tmpd}/vscode/extensions.txt
-touch ${tmpd}/vscode/keybindings.json
+mkdir -p "${tmpd}"/{program,config}
+touch "${tmpd}"/program/a
+touch "${tmpd}"/config/a
+mkdir "${tmpd}"/vscode
+touch "${tmpd}"/vscode/extensions.txt
+touch "${tmpd}"/vscode/keybindings.json
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/config
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/vscode
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/program
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/config
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/vscode
 
 # add files
 echo "[+] add files"
-touch ${tmpd}/program/b
-touch ${tmpd}/config/b
+touch "${tmpd}"/program/b
+touch "${tmpd}"/config/b
 
 # expects diff
 echo "[+] comparing normal - 2 diffs"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose
 [ "$?" = "0" ] && exit 1
 set -e
 
@@ -91,7 +70,7 @@ set -e
 patt="${tmpd}/config/b"
 echo "[+] comparing with ignore (pattern: ${patt}) - 1 diff"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --ignore=${patt}
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose --ignore="${patt}"
 [ "$?" = "0" ] && exit 1
 set -e
 
@@ -99,7 +78,7 @@ set -e
 patt="*b"
 echo "[+] comparing with ignore (pattern: ${patt}) - 0 diff"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --ignore=${patt}
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose --ignore="${patt}"
 [ "$?" != "0" ] && exit 1
 set -e
 
@@ -107,7 +86,7 @@ set -e
 patt="*/config/*b"
 echo "[+] comparing with ignore (pattern: ${patt}) - 1 diff"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --ignore=${patt}
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose --ignore="${patt}"
 [ "$?" = "0" ] && exit 1
 set -e
 
@@ -115,86 +94,86 @@ set -e
 
 # adding ignore in dotfile
 cfg2="${basedir}/config2.yaml"
-sed '/d_config:/a \ \ \ \ cmpignore:\n\ \ \ \ - "*/config/b"' ${cfg} > ${cfg2}
+sed '/d_config:/a \ \ \ \ cmpignore:\n\ \ \ \ - "*/config/b"' "${cfg}" > "${cfg2}"
 #cat ${cfg2}
 
 # expects one diff
 echo "[+] comparing with ignore in dotfile - 1 diff"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose
 [ "$?" = "0" ] && exit 1
 set -e
 
 # adding ignore in dotfile
 cfg2="${basedir}/config2.yaml"
-sed '/d_config:/a \ \ \ \ cmpignore:\n\ \ \ \ - "*b"' ${cfg} > ${cfg2}
-sed -i '/d_program:/a \ \ \ \ cmpignore:\n\ \ \ \ - "*b"' ${cfg2}
+sed '/d_config:/a \ \ \ \ cmpignore:\n\ \ \ \ - "*b"' "${cfg}" > "${cfg2}"
+sed -i '/d_program:/a \ \ \ \ cmpignore:\n\ \ \ \ - "*b"' "${cfg2}"
 #cat ${cfg2}
 
 # expects no diff
 patt="*b"
 echo "[+] comparing with ignore in dotfile - 0 diff"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose
 [ "$?" != "0" ] && exit 1
 set -e
 
 # update files
-echo touched > ${tmpd}/vscode/extensions.txt
-echo touched > ${tmpd}/vscode/keybindings.json
+echo touched > "${tmpd}"/vscode/extensions.txt
+echo touched > "${tmpd}"/vscode/keybindings.json
 
 # expect two diffs
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -C ${tmpd}/vscode
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -C "${tmpd}"/vscode
 [ "$?" = "0" ] && exit 1
 set -e
 
 # expects no diff
-sed '/d_vscode:/a \ \ \ \ cmpignore:\n\ \ \ \ - "*extensions.txt"\n\ \ \ \ - "*keybindings.json"' ${cfg} > ${cfg2}
+sed '/d_vscode:/a \ \ \ \ cmpignore:\n\ \ \ \ - "*extensions.txt"\n\ \ \ \ - "*keybindings.json"' "${cfg}" > "${cfg2}"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose -C ${tmpd}/vscode
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose -C "${tmpd}"/vscode
 [ "$?" != "0" ] && exit 1
 set -e
 
 # clean
-rm -rf ${basedir}/dotfiles
-mkdir -p ${basedir}/dotfiles
+rm -rf "${basedir}"/dotfiles
+mkdir -p "${basedir}"/dotfiles
 
 # create dotfiles/dirs
-mkdir -p ${tmpd}/{program,config,vscode}
-touch ${tmpd}/program/a
-touch ${tmpd}/config/a
-touch ${tmpd}/vscode/extensions.txt
-touch ${tmpd}/vscode/keybindings.json
-touch ${tmpd}/vscode/keybindings.json
+mkdir -p "${tmpd}"/{program,config,vscode}
+touch "${tmpd}"/program/a
+touch "${tmpd}"/config/a
+touch "${tmpd}"/vscode/extensions.txt
+touch "${tmpd}"/vscode/keybindings.json
+touch "${tmpd}"/vscode/keybindings.json
 
 # create the config file
 cfg="${basedir}/config3.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program ${tmpd}/config ${tmpd}/vscode
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/program "${tmpd}"/config "${tmpd}"/vscode
 
 # create the files to ignore
-touch ${tmpd}/program/.DS_Store
-touch ${tmpd}/config/.DS_Store
-touch ${tmpd}/vscode/.DS_Store
+touch "${tmpd}"/program/.DS_Store
+touch "${tmpd}"/config/.DS_Store
+touch "${tmpd}"/vscode/.DS_Store
 
 # ensure not imported
-found=`find ${basedir}/dotfiles/ -iname '.DS_Store'`
+found=$(find "${basedir}"/dotfiles/ -iname '.DS_Store')
 [ "${found}" != "" ] && echo "imported ???" && exit 1
 
 # general ignore
 echo "[+] comparing ..."
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -i '*/.DS_Store'
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -i '*/.DS_Store'
 [ "$?" != "0" ] && exit 1
 
 # general ignore
 echo "[+] comparing2  ..."
-sed '/^config:$/a\ \ cmpignore:\n\ \ - "*/.DS_Store"' ${cfg} > ${cfg2}
-cat ${cfg2}
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose
+sed '/^config:$/a\ \ cmpignore:\n\ \ - "*/.DS_Store"' "${cfg}" > "${cfg2}"
+cat "${cfg2}"
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose
 [ "$?" != "0" ] && exit 1
 
 echo "OK"
diff --git a/tests-ng/compare-include.sh b/tests-ng/compare-include.sh
index 43832e3..137abd5 100755
--- a/tests-ng/compare-include.sh
+++ b/tests-ng/compare-include.sh
@@ -5,63 +5,42 @@
 # test compare in profile which includes another
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the dotfiles already imported
-echo "already in" > ${tmps}/dotfiles/abc
-cp ${tmps}/dotfiles/abc ${tmpd}/abc
+echo "already in" > "${tmps}"/dotfiles/abc
+cp "${tmps}"/dotfiles/abc "${tmpd}"/abc
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -84,36 +63,36 @@ profiles:
     dotfiles:
     - f_abc
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
-cd ${ddpath} | ${bin} files -c ${cfg} -p p0
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p0
 
-cnt=`cd ${ddpath} | ${bin} files -c ${cfg} -p p0 | grep '^f_' | wc -l`
+cnt=$(cd "${ddpath}" | ${bin} files -c "${cfg}" -p p0 | grep '^f_' | wc -l)
 [ "${cnt}" != "1" ] && echo "this is bad" && exit 1
 
 # compare
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p0
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p0
 
 echo "modifying"
-echo 'modified' > ${tmpd}/abc
+echo 'modified' > "${tmpd}"/abc
 
 # compare
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p0
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p0
 ret=$?
 [ "${ret}" = "0" ] && echo "compare should fail (returned ${ret})" && exit 1
 set -e
 
 # count
-cnt=`cd ${ddpath} | ${bin} files -c ${cfg} -p p0 -b | grep '^f_' | wc -l`
+cnt=$(cd "${ddpath}" | ${bin} files -c "${cfg}" -p p0 -b | grep '^f_' | wc -l)
 [ "${cnt}" != "2" ] && echo "not enough dotfile" exit 1
 
 ## without dotfiles: entry
 # reset dotfile content
-echo "already in" > ${tmps}/dotfiles/abc
-cp ${tmps}/dotfiles/abc ${tmpd}/abc
+echo "already in" > "${tmps}"/dotfiles/abc
+cp "${tmps}"/dotfiles/abc "${tmpd}"/abc
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -134,28 +113,28 @@ profiles:
     dotfiles:
     - f_abc
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
-cd ${ddpath} | ${bin} files -c ${cfg} -p p0
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p0
 
-cnt=`cd ${ddpath} | ${bin} files -c ${cfg} -p p0 | grep '^f_' | wc -l`
+cnt=$(cd "${ddpath}" | ${bin} files -c "${cfg}" -p p0 | grep '^f_' | wc -l)
 [ "${cnt}" != "1" ] && echo "this is bad" && exit 1
 
 # compare
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p0
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p0
 
 echo "modifying"
-echo 'modified' > ${tmpd}/abc
+echo 'modified' > "${tmpd}"/abc
 
 # compare
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p0
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p0
 ret=$?
 [ "${ret}" = "0" ] && echo "compare should fail (returned ${ret})" && exit 1
 set -e
 
 # count
-cnt=`cd ${ddpath} | ${bin} files -c ${cfg} -p p0 -b | grep '^f_' | wc -l`
+cnt=$(cd "${ddpath}" | ${bin} files -c "${cfg}" -p p0 -b | grep '^f_' | wc -l)
 [ "${cnt}" != "2" ] && echo "not enough dotfile" exit 1
 
 echo "OK"
diff --git a/tests-ng/compare-negative-ignore-relative.sh b/tests-ng/compare-negative-ignore-relative.sh
index b78ee7d..ea4aaec 100755
--- a/tests-ng/compare-negative-ignore-relative.sh
+++ b/tests-ng/compare-negative-ignore-relative.sh
@@ -5,106 +5,61 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-if [ $(uname) = Darwin ]; then
-  # Unfortunately, readlink works differently on macOS than it does on GNU/Linux
-  # (the -f option behaves differently) and the realpath command does not exist.
-  # Workarounds I find on the Internet suggest just using Homebrew to install coreutils
-  # so you can get the GNU coreutils on your Mac. But, I don't want this script to
-  # assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
-  # they then installed the GNU coreutils.
-  readlink() {
-    TARGET_FILE=$1
-
-    cd `dirname $TARGET_FILE`
-    TARGET_FILE=`basename $TARGET_FILE`
-
-    # Iterate down a (possible) chain of symlinks
-    while [ -L "$TARGET_FILE" ]; do
-      TARGET_FILE=`readlink $TARGET_FILE`
-      cd `dirname $TARGET_FILE`
-      TARGET_FILE=`basename $TARGET_FILE`
-    done
-
-    # Compute the canonicalized name by finding the physical path
-    # for the directory we're in and appending the target file.
-    PHYS_DIR=`pwd -P`
-    RESULT=$PHYS_DIR/$TARGET_FILE
-    echo $RESULT
-  }
-  rl="readlink"
-else
-  rl="readlink -f"
-  if ! ${rl} "${0}" >/dev/null 2>&1; then
-    rl="realpath"
-
-    if ! hash ${rl}; then
-      echo "\"${rl}\" not found !" && exit 1
-    fi
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ -n "${1}" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # some files
-mkdir -p ${tmpd}/program/ignore_me
-echo "some data" > ${tmpd}/program/a
-echo "some data" > ${tmpd}/program/ignore_me/b
-echo "some data" > ${tmpd}/program/ignore_me/c
+mkdir -p "${tmpd}"/program/ignore_me
+echo "some data" > "${tmpd}"/program/a
+echo "some data" > "${tmpd}"/program/ignore_me/b
+echo "some data" > "${tmpd}"/program/ignore_me/c
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/program
 
 # make some changes to generate a diff
-echo "some other data" > ${tmpd}/program/a
-echo "some other data" > ${tmpd}/program/ignore_me/b
-echo "some other data" > ${tmpd}/program/ignore_me/c
+echo "some other data" > "${tmpd}"/program/a
+echo "some other data" > "${tmpd}"/program/ignore_me/b
+echo "some other data" > "${tmpd}"/program/ignore_me/c
 
 # expects two diffs (no need to test comparing normal - 3 diffs, as that is taken care of in compare-negative-ignore.sh)
 patt0="ignore_me/*"
 patt1="!ignore_me/c"
 echo "[+] comparing with ignore (patterns: ${patt0} and ${patt1}) - 2 diffs"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --ignore=${patt0} --ignore=${patt1}
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose --ignore="${patt0}" --ignore=${patt1}
 [ "$?" = "0" ] && exit 1
 set -e
 
@@ -112,16 +67,16 @@ set -e
 # Test ignores specified in config.yaml
 ########################################
 # add some files
-mkdir -p ${tmpd}/.zsh
-echo "some data" > ${tmpd}/.zsh/somefile
-mkdir -p ${tmpd}/.zsh/plugins
-echo "some data" > ${tmpd}/.zsh/plugins/someplugin
+mkdir -p "${tmpd}"/.zsh
+echo "some data" > "${tmpd}"/.zsh/somefile
+mkdir -p "${tmpd}"/.zsh/plugins
+echo "some data" > "${tmpd}"/.zsh/plugins/someplugin
 
 echo "[+] import .zsh"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/.zsh
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/.zsh
 
-touch ${tmpd}/.zsh/plugins/ignore-1.zsh
-touch ${tmpd}/.zsh/plugins/ignore-2.zsh
+touch "${tmpd}"/.zsh/plugins/ignore-1.zsh
+touch "${tmpd}"/.zsh/plugins/ignore-2.zsh
 
 # adding ignore in config.yaml
 cfg2="${basedir}/config2.yaml"
@@ -129,21 +84,21 @@ sed '/d_zsh:/a\
 \ \ \ \ cmpignore:\
 \ \ \ \ - "plugins/ignore-?.zsh"\
 \ \ \ \ - "!plugins/ignore-2.zsh"
-' ${cfg} > ${cfg2}
+' "${cfg}" > "${cfg2}"
 
 # expects one diff
 patt0="plugins/ignore-?.zsh"
 patt1="!plugins/ignore-2.zsh"
 echo "[+] comparing with ignore (patterns: ${patt0} and ${patt1}) - 1 diff"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -C ${tmpd}/.zsh --ignore=${patt0} --ignore=${patt1}
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -C "${tmpd}"/.zsh --ignore="${patt0}" --ignore=${patt1}
 [ "$?" = "0" ] && exit 1
 set -e
 
 # expects one diff
 echo "[+] comparing .zsh with ignore in dotfile - 1 diff expected"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose -C ${tmpd}/.zsh
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose -C "${tmpd}"/.zsh
 ret="$?"
 echo ${ret}
 [ "${ret}" = "0" ] && exit 1
diff --git a/tests-ng/compare-negative-ignore.sh b/tests-ng/compare-negative-ignore.sh
index 2b79f7b..facbb23 100755
--- a/tests-ng/compare-negative-ignore.sh
+++ b/tests-ng/compare-negative-ignore.sh
@@ -8,50 +8,12 @@
 # exit on first error
 #set -e
 
-# all this crap to get current path
-if [ $(uname) = Darwin ]; then
-  # Unfortunately, readlink works differently on macOS than it does on GNU/Linux
-  # (the -f option behaves differently) and the realpath command does not exist.
-  # Workarounds I find on the Internet suggest just using Homebrew to install coreutils
-  # so you can get the GNU coreutils on your Mac. But, I don't want this script to
-  # assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
-  # they then installed the GNU coreutils.
-  readlink() {
-    TARGET_FILE=$1
-
-    cd `dirname $TARGET_FILE`
-    TARGET_FILE=`basename $TARGET_FILE`
-
-    # Iterate down a (possible) chain of symlinks
-    while [ -L "$TARGET_FILE" ]; do
-      TARGET_FILE=`readlink $TARGET_FILE`
-      cd `dirname $TARGET_FILE`
-      TARGET_FILE=`basename $TARGET_FILE`
-    done
-
-    # Compute the canonicalized name by finding the physical path
-    # for the directory we're in and appending the target file.
-    PHYS_DIR=`pwd -P`
-    RESULT=$PHYS_DIR/$TARGET_FILE
-    echo $RESULT
-  }
-  rl="readlink"
-else
-  rl="readlink -f"
-  if ! ${rl} "${0}" >/dev/null 2>&1; then
-    rl="realpath"
-
-    if ! hash ${rl}; then
-      echo "\"${rl}\" not found !" && exit 1
-    fi
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
+cur=$(cd "$(dirname "${0}")" && pwd)
 
 # dotdrop path can be pass as argument
 ddpath="${cur}/../"
 [ -n "${1}" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
+[ ! -d "${ddpath}" ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
 
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
 bin="python3 -m dotdrop.dotdrop"
@@ -60,47 +22,48 @@ echo "dotdrop path: ${ddpath}"
 echo "pythonpath: ${PYTHONPATH}"
 
 # get the helpers
-source ${cur}/helpers
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
 
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # some files
-mkdir -p ${tmpd}/program/ignore_me
-echo "some data" > ${tmpd}/program/a
-echo "some data" > ${tmpd}/program/ignore_me/b
-echo "some data" > ${tmpd}/program/ignore_me/c
+mkdir -p "${tmpd}"/program/ignore_me
+echo "some data" > "${tmpd}"/program/a
+echo "some data" > "${tmpd}"/program/ignore_me/b
+echo "some data" > "${tmpd}"/program/ignore_me/c
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/program
 
 # make some changes to generate a diff
-echo "some other data" > ${tmpd}/program/a
-echo "some other data" > ${tmpd}/program/ignore_me/b
-echo "some other data" > ${tmpd}/program/ignore_me/c
+echo "some other data" > "${tmpd}"/program/a
+echo "some other data" > "${tmpd}"/program/ignore_me/b
+echo "some other data" > "${tmpd}"/program/ignore_me/c
 
 echo "[+] comparing normal - 3 diffs"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose
 [ "$?" = 0 ] && exit 1 # We don't want an exit status of 0
 set -e
 
@@ -109,22 +72,23 @@ patt0="*/ignore_me/*"
 patt1="!*/ignore_me/c"
 echo "[+] comparing with ignore (patterns: ${patt0} and ${patt1}) - 2 diffs"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --ignore=${patt0} --ignore=${patt1}
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose --ignore="${patt0}" --ignore="${patt1}"
 [ "$?" = "0" ] && exit 1
 set -e
 
 # Adding ignore in dotfile
 cfg2="${basedir}/config2.yaml"
+# shellcheck disable=SC1004
 sed '/d_program:/a\
 \ \ \ \ cmpignore:\
 \ \ \ \ - "*/ignore_me/*"\
 \ \ \ \ - "!*/ignore_me/c"
-' ${cfg} > ${cfg2}
+' "${cfg}" > "${cfg2}"
 
 # still expects two diffs
 echo "[+] comparing with ignore in dotfile - 2 diffs"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose
 [ "$?" = "0" ] && exit 1
 set -e
 
diff --git a/tests-ng/compare-profile-check.sh b/tests-ng/compare-profile-check.sh
index b71f043..9c38b93 100755
--- a/tests-ng/compare-profile-check.sh
+++ b/tests-ng/compare-profile-check.sh
@@ -6,36 +6,20 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -43,25 +27,25 @@ echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
 
 
 # dotdrop directory
-tmps=`mktemp -d --suffix='-dotdrop-tests-source' || mktemp -d`
+tmps=$(mktemp -d --suffix='-dotdrop-tests-source' || mktemp -d)
 dt="${tmps}/dotfiles"
-mkdir -p ${dt}
+mkdir -p "${dt}"
 
 xori="profile x"
-xori="profile y"
-echo "${xori}" > ${dt}/file_x
-echo "${yori}" > ${dt}/file_y
+yori="profile y"
+echo "${xori}" > "${dt}"/file_x
+echo "${yori}" > "${dt}"/file_y
 
 # fs dotfiles
-tmpd=`mktemp -d --suffix='-dotdrop-tests-dest' || mktemp -d`
-touch ${tmpd}/file
+tmpd=$(mktemp -d --suffix='-dotdrop-tests-dest' || mktemp -d)
+touch "${tmpd}"/file
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -81,65 +65,65 @@ profiles:
     dotfiles:
     - f_file_y
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
 # reset
-echo "${xori}" > ${dt}/file_x
-echo "${yori}" > ${dt}/file_y
+echo "${xori}" > "${dt}"/file_x
+echo "${yori}" > "${dt}"/file_y
 
 echo "test compare profile x (ok)"
-echo "${xori}" > ${tmpd}/file
+echo "${xori}" > "${tmpd}"/file
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -p x -C ${tmpd}/file
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -p x -C "${tmpd}"/file
 [ "$?" != "0" ] && exit 1
 set -e
 
 echo "test compare profile x (not ok)"
-echo "${yori}" > ${tmpd}/file
+echo "${yori}" > "${tmpd}"/file
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -p x -C ${tmpd}/file
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -p x -C "${tmpd}"/file
 [ "$?" = "0" ] && exit 1
 set -e
 
 echo "test compare profile y (ok)"
-echo "${yori}" > ${tmpd}/file
+echo "${yori}" > "${tmpd}"/file
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -p y -C ${tmpd}/file
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -p y -C "${tmpd}"/file
 [ "$?" != "0" ] && exit 1
 set -e
 
 echo "test compare profile y (not ok)"
-echo "${xori}" > ${tmpd}/file
+echo "${xori}" > "${tmpd}"/file
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -p y -C ${tmpd}/file
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -p y -C "${tmpd}"/file
 [ "$?" = "0" ] && exit 1
 set -e
 
 echo "test compare profile x generic (ok)"
-echo "${xori}" > ${tmpd}/file
+echo "${xori}" > "${tmpd}"/file
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -p x
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -p x
 [ "$?" != "0" ] && exit 1
 set -e
 
 echo "test compare profile x generic (not ok)"
-echo "${yori}" > ${tmpd}/file
+echo "${yori}" > "${tmpd}"/file
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -p x
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -p x
 [ "$?" = "0" ] && exit 1
 set -e
 
 echo "test compare profile y generic (ok)"
-echo "${yori}" > ${tmpd}/file
+echo "${yori}" > "${tmpd}"/file
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -p y
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -p y
 [ "$?" != "0" ] && exit 1
 set -e
 
 echo "test compare profile y generic (not ok)"
-echo "${xori}" > ${tmpd}/file
+echo "${xori}" > "${tmpd}"/file
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -p y
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -p y
 [ "$?" = "0" ] && exit 1
 set -e
 
diff --git a/tests-ng/compare.sh b/tests-ng/compare.sh
index 0fdd0a5..4e05197 100755
--- a/tests-ng/compare.sh
+++ b/tests-ng/compare.sh
@@ -6,121 +6,100 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # single file
-echo 'unique' > ${tmpd}/uniquefile
+echo 'unique' > "${tmpd}"/uniquefile
 
 # hierarchy from https://pymotw.com/2/filecmp/
 # create the hierarchy
 # for dir1 (originally imported directory))))
-mkdir ${tmpd}/dir1
-touch ${tmpd}/dir1/file_only_in_dir1
-mkdir -p ${tmpd}/dir1/dir_only_in_dir1
-mkdir -p ${tmpd}/dir1/common_dir
-echo 'this file is the same' > ${tmpd}/dir1/common_file
-echo 'in dir1' > ${tmpd}/dir1/not_the_same
-echo 'This is a file in dir1' > ${tmpd}/dir1/file_in_dir1
-mkdir -p ${tmpd}/dir1/sub/sub2
-mkdir -p ${tmpd}/dir1/notindir2/notindir2
-echo 'first' > ${tmpd}/dir1/sub/sub2/different
+mkdir "${tmpd}"/dir1
+touch "${tmpd}"/dir1/file_only_in_dir1
+mkdir -p "${tmpd}"/dir1/dir_only_in_dir1
+mkdir -p "${tmpd}"/dir1/common_dir
+echo 'this file is the same' > "${tmpd}"/dir1/common_file
+echo 'in dir1' > "${tmpd}"/dir1/not_the_same
+echo 'This is a file in dir1' > "${tmpd}"/dir1/file_in_dir1
+mkdir -p "${tmpd}"/dir1/sub/sub2
+mkdir -p "${tmpd}"/dir1/notindir2/notindir2
+echo 'first' > "${tmpd}"/dir1/sub/sub2/different
 #tree ${tmpd}/dir1
 
 # create the hierarchy
 # for dir2 (modified original for update)
-mkdir ${tmpd}/dir2
-touch ${tmpd}/dir2/file_only_in_dir2
-mkdir -p ${tmpd}/dir2/dir_only_in_dir2
-mkdir -p ${tmpd}/dir2/common_dir
-echo 'this file is the same' > ${tmpd}/dir2/common_file
-echo 'in dir2' > ${tmpd}/dir2/not_the_same
-mkdir -p ${tmpd}/dir2/file_in_dir1
-mkdir -p ${tmpd}/dir2/sub/sub2
-echo 'modified' > ${tmpd}/dir2/sub/sub2/different
-mkdir -p ${tmpd}/dir2/new/new2
+mkdir "${tmpd}"/dir2
+touch "${tmpd}"/dir2/file_only_in_dir2
+mkdir -p "${tmpd}"/dir2/dir_only_in_dir2
+mkdir -p "${tmpd}"/dir2/common_dir
+echo 'this file is the same' > "${tmpd}"/dir2/common_file
+echo 'in dir2' > "${tmpd}"/dir2/not_the_same
+mkdir -p "${tmpd}"/dir2/file_in_dir1
+mkdir -p "${tmpd}"/dir2/sub/sub2
+echo 'modified' > "${tmpd}"/dir2/sub/sub2/different
+mkdir -p "${tmpd}"/dir2/new/new2
 #tree ${tmpd}/dir2
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import dir1
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/dir1
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/uniquefile
-cat ${cfg}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/dir1
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/uniquefile
+cat "${cfg}"
 
 # let's see the dotpath
 #tree ${basedir}/dotfiles
 
 # change dir1 to dir2 in deployed
 echo "[+] change dir"
-rm -rf ${tmpd}/dir1
-mv ${tmpd}/dir2 ${tmpd}/dir1
+rm -rf "${tmpd}"/dir1
+mv "${tmpd}"/dir2 "${tmpd}"/dir1
 #tree ${tmpd}/dir1
 
 # change unique file
-echo 'changed' > ${tmpd}/uniquefile
+echo 'changed' > "${tmpd}"/uniquefile
 
 # compare
 echo "[+] comparing"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose
 [ "$?" = "0" ] && exit 1
 set -e
 
 echo "[+] comparing with file-only"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -L
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -L
 [ "$?" = "0" ] && exit 1
 set -e
 
diff --git a/tests-ng/corner-case.sh b/tests-ng/corner-case.sh
index b74ab22..dc34f87 100755
--- a/tests-ng/corner-case.sh
+++ b/tests-ng/corner-case.sh
@@ -11,48 +11,27 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
@@ -62,7 +41,7 @@ export DOTDROP_WORKERS=1
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -83,24 +62,24 @@ profiles:
 _EOF
 
 echo "[+] test install dry"
-cd ${ddpath} | ${bin} install -c ${cfg} --dry -p p1 --verbose f_x
+cd "${ddpath}" | ${bin} install -c "${cfg}" --dry -p p1 --verbose f_x
 [ "$?" != "0" ] && exit 1
 
 echo "[+] test install show-diff"
-cd ${ddpath} | ${bin} install -c ${cfg} -p p1 --verbose f_x
+cd "${ddpath}" | ${bin} install -c "${cfg}" -p p1 --verbose f_x
 [ "$?" != "0" ] && exit 1
-cd ${ddpath} | ${bin} install -D -c ${cfg} -p p1 --verbose f_x
+cd "${ddpath}" | ${bin} install -D -c "${cfg}" -p p1 --verbose f_x
 [ "$?" != "0" ] && exit 1
 
 echo "[+] test install not existing src"
-cd ${ddpath} | ${bin} install -c ${cfg} -f --dry -p p1 --verbose f_y
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f --dry -p p1 --verbose f_y
 
 echo "[+] test install to temp"
-cd ${ddpath} | ${bin} install -t -c ${cfg} -p p1 --verbose f_x > ${basedir}/log 2>&1
+cd "${ddpath}" | ${bin} install -t -c "${cfg}" -p p1 --verbose f_x > "${basedir}"/log 2>&1
 [ "$?" != "0" ] && echo "install to tmp failed" && exit 1
 
 # cleaning
-tmpfile=`cat ${basedir}/log | grep 'installed to tmp ' | sed 's/^.*to tmp "\(.*\)"./\1/'`
+tmpfile=$(cat "${basedir}"/log | grep 'installed to tmp ' | sed 's/^.*to tmp "\(.*\)"./\1/')
 echo "tmpfile: ${tmpfile}"
 rm -rf "${tmpfile}"
 
diff --git a/tests-ng/deprecated-link.sh b/tests-ng/deprecated-link.sh
index edf67e2..71cec7c 100755
--- a/tests-ng/deprecated-link.sh
+++ b/tests-ng/deprecated-link.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -58,7 +37,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -103,38 +82,38 @@ profiles:
     - f_children2
     - f_children3
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
 # create the dotfiles
-echo "test" > ${tmps}/dotfiles/abc
-echo "test" > ${tmpd}/abc
+echo "test" > "${tmps}"/dotfiles/abc
+echo "test" > "${tmpd}"/abc
 
 # compare
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1
 # install
 #cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
 
-cat ${cfg}
+cat "${cfg}"
 
 # fail if find some of these entries
 echo "========> test for bad entries"
 set +e
-grep 'link_children: true' ${cfg} >/dev/null && exit 1
-grep 'link_children: false' ${cfg} >/dev/null && exit 1
-grep 'link: true' ${cfg} >/dev/null && exit 1
-grep 'link: false' ${cfg} >/dev/null && exit 1
-grep 'link_by_default: true' ${cfg} >/dev/null && exit 1
-grep 'link_by_default: false' ${cfg} >/dev/null && exit 1
+grep 'link_children: true' "${cfg}" >/dev/null && exit 1
+grep 'link_children: false' "${cfg}" >/dev/null && exit 1
+grep 'link: true' "${cfg}" >/dev/null && exit 1
+grep 'link: false' "${cfg}" >/dev/null && exit 1
+grep 'link_by_default: true' "${cfg}" >/dev/null && exit 1
+grep 'link_by_default: false' "${cfg}" >/dev/null && exit 1
 set -e
 
 # test values have been correctly updated
 echo "========> test for updated entries"
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | grep '^f_link' | head -1 | grep ',link:absolute,'
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | grep '^f_nolink'    | head -1 | grep ',link:nolink,'
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | grep '^f_nolink1'   | head -1 | grep ',link:nolink,'
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | grep '^f_children'  | head -1 | grep ',link:link_children,'
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | grep '^f_children2' | head -1 | grep ',link:link_children,'
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | grep '^f_children3' | head -1 | grep ',link:nolink,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | grep '^f_link' | head -1 | grep ',link:absolute,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | grep '^f_nolink'    | head -1 | grep ',link:nolink,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | grep '^f_nolink1'   | head -1 | grep ',link:nolink,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | grep '^f_children'  | head -1 | grep ',link:link_children,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | grep '^f_children2' | head -1 | grep ',link:link_children,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | grep '^f_children3' | head -1 | grep ',link:nolink,'
 
 echo "OK"
 exit 0
diff --git a/tests-ng/diff-cmd.sh b/tests-ng/diff-cmd.sh
index 604d9f9..792d95f 100755
--- a/tests-ng/diff-cmd.sh
+++ b/tests-ng/diff-cmd.sh
@@ -6,63 +6,42 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # some files
-echo "original" > ${tmpd}/singlefile
+echo "original" > "${tmpd}"/singlefile
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -73,52 +52,52 @@ _EOF
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/singlefile
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/singlefile
 
 # modify the file
-echo "modified" > ${tmpd}/singlefile
+echo "modified" > "${tmpd}"/singlefile
 
 # default diff (unified)
 echo "[+] comparing with default diff (unified)"
 set +e
-cd ${ddpath} | ${bin} compare -b -c ${cfg} 2>/dev/null | grep -v '=>' | grep -v '\->' | grep -v 'dotfile(s) compared' | sed '$d' | grep -v '^+++\|^---' > ${tmpd}/normal
-diff -u -r ${tmpd}/singlefile ${basedir}/dotfiles/${tmpd}/singlefile | grep -v '^+++\|^---' > ${tmpd}/real
+cd "${ddpath}" | ${bin} compare -b -c "${cfg}" 2>/dev/null | grep -v '=>' | grep -v '\->' | grep -v 'dotfile(s) compared' | sed '$d' | grep -v '^+++\|^---' > "${tmpd}"/normal
+diff -u -r "${tmpd}"/singlefile "${basedir}"/dotfiles/"${tmpd}"/singlefile | grep -v '^+++\|^---' > "${tmpd}"/real
 set -e
 
 # verify
-diff ${tmpd}/normal ${tmpd}/real || exit 1
+diff "${tmpd}"/normal "${tmpd}"/real || exit 1
 
 # adding normal diff
 cfg2="${basedir}/config2.yaml"
-sed '/dotpath: dotfiles/a \ \ diff_command: "diff -r {0} {1}"' ${cfg} > ${cfg2}
+sed '/dotpath: dotfiles/a \ \ diff_command: "diff -r {0} {1}"' "${cfg}" > "${cfg2}"
 #cat ${cfg2}
 
 # normal diff
 echo "[+] comparing with normal diff"
 set +e
-cd ${ddpath} | ${bin} compare -b -c ${cfg2} 2>/dev/null | grep -v '=>' | grep -v '\->' | grep -v 'dotfile(s) compared' | sed '$d' > ${tmpd}/unified
-diff -r ${tmpd}/singlefile ${basedir}/dotfiles/${tmpd}/singlefile > ${tmpd}/real
+cd "${ddpath}" | ${bin} compare -b -c "${cfg2}" 2>/dev/null | grep -v '=>' | grep -v '\->' | grep -v 'dotfile(s) compared' | sed '$d' > "${tmpd}"/unified
+diff -r "${tmpd}"/singlefile "${basedir}"/dotfiles/"${tmpd}"/singlefile > "${tmpd}"/real
 set -e
 
 # verify
 #cat ${tmpd}/unified
 #cat ${tmpd}/real
-diff ${tmpd}/unified ${tmpd}/real || exit 1
+diff "${tmpd}"/unified "${tmpd}"/real || exit 1
 
 # adding fake diff
 cfg3="${basedir}/config3.yaml"
-sed '/dotpath: dotfiles/a \ \ diff_command: "echo fakediff"' ${cfg} > ${cfg3}
+sed '/dotpath: dotfiles/a \ \ diff_command: "echo fakediff"' "${cfg}" > "${cfg3}"
 #cat ${cfg3}
 
 # fake diff
 echo "[+] comparing with fake diff"
 set +e
-cd ${ddpath} | ${bin} compare -b -c ${cfg3} 2>/dev/null | grep -v '=>' | grep -v '\->' | grep -v 'dotfile(s) compared' | sed '$d' > ${tmpd}/fake
+cd "${ddpath}" | ${bin} compare -b -c "${cfg3}" 2>/dev/null | grep -v '=>' | grep -v '\->' | grep -v 'dotfile(s) compared' | sed '$d' > "${tmpd}"/fake
 set -e
 
 # verify
 #cat ${tmpd}/fake
-grep fakediff ${tmpd}/fake &> /dev/null || exit 1
+grep fakediff "${tmpd}"/fake &> /dev/null || exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/dir-import-update.sh b/tests-ng/dir-import-update.sh
index 39c7908..919347d 100755
--- a/tests-ng/dir-import-update.sh
+++ b/tests-ng/dir-import-update.sh
@@ -6,71 +6,49 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-dotfiles="${basedir}/dotfiles"
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotdrop dir: ${basedir}"
 # the dotfile
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-create_dir ${tmpd}
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+create_dir "${tmpd}"
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import the dir
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"
 
 # change token
-echo "changed" > ${token}
+echo "changed" > "${token}"
 
 # update
-cd ${ddpath} | ${bin} update -f -c ${cfg} ${tmpd} --verbose
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" "${tmpd}" --verbose
 
-grep 'changed' ${token} >/dev/null 2>&1
+grep 'changed' "${token}" >/dev/null 2>&1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/dotdrop-variables.sh b/tests-ng/dotdrop-variables.sh
index 2561747..2a7f796 100755
--- a/tests-ng/dotdrop-variables.sh
+++ b/tests-ng/dotdrop-variables.sh
@@ -6,52 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 #echo "dotfile source: ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -60,7 +39,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -78,18 +57,18 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "dotpath: {{@@ _dotdrop_dotpath @@}}" > ${tmps}/dotfiles/abc
-echo "cfgpath: {{@@ _dotdrop_cfgpath @@}}" >> ${tmps}/dotfiles/abc
-echo "workdir: {{@@ _dotdrop_workdir @@}}" >> ${tmps}/dotfiles/abc
+echo "dotpath: {{@@ _dotdrop_dotpath @@}}" > "${tmps}"/dotfiles/abc
+echo "cfgpath: {{@@ _dotdrop_cfgpath @@}}" >> "${tmps}"/dotfiles/abc
+echo "workdir: {{@@ _dotdrop_workdir @@}}" >> "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
-cat ${tmpd}/abc
+cat "${tmpd}"/abc
 
-grep "^dotpath: ${tmps}/dotfiles$" ${tmpd}/abc >/dev/null
-grep "^cfgpath: ${tmps}/config.yaml$" ${tmpd}/abc >/dev/null
-grep "^workdir: /tmp/xxx$" ${tmpd}/abc >/dev/null
+grep "^dotpath: ${tmps}/dotfiles$" "${tmpd}"/abc >/dev/null
+grep "^cfgpath: ${tmps}/config.yaml$" "${tmpd}"/abc >/dev/null
+grep "^workdir: /tmp/xxx$" "${tmpd}"/abc >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/dotfile-no-src.sh b/tests-ng/dotfile-no-src.sh
index fea77de..80778bf 100755
--- a/tests-ng/dotfile-no-src.sh
+++ b/tests-ng/dotfile-no-src.sh
@@ -6,53 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-#set -v
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -61,7 +39,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -77,19 +55,19 @@ _EOF
 #cat ${cfg}
 
 # create the dotfiles
-echo "abc" > ${tmps}/dotfiles/abc
+echo "abc" > "${tmps}"/dotfiles/abc
 
 ###########################
 # test install and compare
 ###########################
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 [ "$?" != "0" ] && exit 1
 
 # checks
-[ ! -e ${tmpd}/abc ] && exit 1
-grep 'abc' ${tmpd}/abc
+[ ! -e "${tmpd}"/abc ] && exit 1
+grep 'abc' "${tmpd}"/abc
 
 echo "OK"
 exit 0
diff --git a/tests-ng/dotfile-sub-variables.sh b/tests-ng/dotfile-sub-variables.sh
index d223772..cc7ffd5 100755
--- a/tests-ng/dotfile-sub-variables.sh
+++ b/tests-ng/dotfile-sub-variables.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -58,7 +37,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -75,32 +54,32 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-mkdir -p ${tmps}/dotfiles/abc
+mkdir -p "${tmps}"/dotfiles/abc
 # file1
-echo 'src:{{@@ _dotfile_sub_abs_src @@}}' > ${tmps}/dotfiles/abc/file1
-echo 'dst:{{@@ _dotfile_sub_abs_dst @@}}' >> ${tmps}/dotfiles/abc/file1
+echo 'src:{{@@ _dotfile_sub_abs_src @@}}' > "${tmps}"/dotfiles/abc/file1
+echo 'dst:{{@@ _dotfile_sub_abs_dst @@}}' >> "${tmps}"/dotfiles/abc/file1
 
 # file2
-mkdir -p ${tmps}/dotfiles/abc/subdir
-echo 'src:{{@@ _dotfile_sub_abs_src @@}}' > ${tmps}/dotfiles/abc/subdir/file2
-echo 'dst:{{@@ _dotfile_sub_abs_dst @@}}' >> ${tmps}/dotfiles/abc/subdir/file2
+mkdir -p "${tmps}"/dotfiles/abc/subdir
+echo 'src:{{@@ _dotfile_sub_abs_src @@}}' > "${tmps}"/dotfiles/abc/subdir/file2
+echo 'dst:{{@@ _dotfile_sub_abs_dst @@}}' >> "${tmps}"/dotfiles/abc/subdir/file2
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks
-[ ! -d ${tmpd}/abc ] && echo 'dotfile not installed' && exit 1
-[ ! -e ${tmpd}/abc/file1 ] && echo 'dotfile sub src not installed' && exit 1
-[ ! -e ${tmpd}/abc/subdir/file2 ] && echo 'dotfile sub dst not installed' && exit 1
+[ ! -d "${tmpd}"/abc ] && echo 'dotfile not installed' && exit 1
+[ ! -e "${tmpd}"/abc/file1 ] && echo 'dotfile sub src not installed' && exit 1
+[ ! -e "${tmpd}"/abc/subdir/file2 ] && echo 'dotfile sub dst not installed' && exit 1
 
-cat ${tmpd}/abc/file1
-cat ${tmpd}/abc/subdir/file2
+cat "${tmpd}"/abc/file1
+cat "${tmpd}"/abc/subdir/file2
 
-grep "src:${tmps}/dotfiles/abc/file1" ${tmpd}/abc/file1 >/dev/null
-grep "dst:${tmpd}/abc/file1" ${tmpd}/abc/file1>/dev/null
+grep "src:${tmps}/dotfiles/abc/file1" "${tmpd}"/abc/file1 >/dev/null
+grep "dst:${tmpd}/abc/file1" "${tmpd}"/abc/file1>/dev/null
 
-grep "src:${tmps}/dotfiles/abc/subdir/file2" ${tmpd}/abc/subdir/file2 >/dev/null
-grep "dst:${tmpd}/abc/subdir/file2" ${tmpd}/abc/subdir/file2 >/dev/null
+grep "src:${tmps}/dotfiles/abc/subdir/file2" "${tmpd}"/abc/subdir/file2 >/dev/null
+grep "dst:${tmpd}/abc/subdir/file2" "${tmpd}"/abc/subdir/file2 >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/dotfile-variables.sh b/tests-ng/dotfile-variables.sh
index f96f215..c29deaf 100755
--- a/tests-ng/dotfile-variables.sh
+++ b/tests-ng/dotfile-variables.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -58,7 +37,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -75,21 +54,21 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo 'src:{{@@ _dotfile_abs_src @@}}' > ${tmps}/dotfiles/abc
-echo 'dst:{{@@ _dotfile_abs_dst @@}}' >> ${tmps}/dotfiles/abc
-echo 'key:{{@@ _dotfile_key @@}}' >> ${tmps}/dotfiles/abc
-echo 'link:{{@@ _dotfile_link @@}}' >> ${tmps}/dotfiles/abc
+echo 'src:{{@@ _dotfile_abs_src @@}}' > "${tmps}"/dotfiles/abc
+echo 'dst:{{@@ _dotfile_abs_dst @@}}' >> "${tmps}"/dotfiles/abc
+echo 'key:{{@@ _dotfile_key @@}}' >> "${tmps}"/dotfiles/abc
+echo 'link:{{@@ _dotfile_link @@}}' >> "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks
-[ ! -e ${tmpd}/abc ] && echo 'dotfile not installed' && exit 1
-cat ${tmpd}/abc
-grep "src:${tmps}/dotfiles/abc" ${tmpd}/abc >/dev/null
-grep "dst:${tmpd}/abc" ${tmpd}/abc >/dev/null
-grep "key:f_abc" ${tmpd}/abc >/dev/null
-grep "link:nolink" ${tmpd}/abc >/dev/null
+[ ! -e "${tmpd}"/abc ] && echo 'dotfile not installed' && exit 1
+cat "${tmpd}"/abc
+grep "src:${tmps}/dotfiles/abc" "${tmpd}"/abc >/dev/null
+grep "dst:${tmpd}/abc" "${tmpd}"/abc >/dev/null
+grep "key:f_abc" "${tmpd}"/abc >/dev/null
+grep "link:nolink" "${tmpd}"/abc >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/dotfiles-all.sh b/tests-ng/dotfiles-all.sh
index 72c42e2..1e1cb0b 100755
--- a/tests-ng/dotfiles-all.sh
+++ b/tests-ng/dotfiles-all.sh
@@ -6,53 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-#set -v
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -61,7 +39,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -84,31 +62,31 @@ _EOF
 #cat ${cfg}
 
 # create the dotfiles
-echo "abc" > ${tmps}/dotfiles/abc
-echo "def" > ${tmps}/dotfiles/def
-echo "ghi" > ${tmps}/dotfiles/ghi
+echo "abc" > "${tmps}"/dotfiles/abc
+echo "def" > "${tmps}"/dotfiles/def
+echo "ghi" > "${tmps}"/dotfiles/ghi
 
 ###########################
 # test install and compare
 ###########################
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 [ "$?" != "0" ] && exit 1
 
 # checks
-[ ! -e ${tmpd}/abc ] && exit 1
-[ ! -e ${tmpd}/def ] && exit 1
-[ ! -e ${tmpd}/ghi ] && exit 1
+[ ! -e "${tmpd}"/abc ] && exit 1
+[ ! -e "${tmpd}"/def ] && exit 1
+[ ! -e "${tmpd}"/ghi ] && exit 1
 
 # modify the dotfiles
-echo "abc-modified" > ${tmps}/dotfiles/abc
-echo "def-modified" > ${tmps}/dotfiles/def
-echo "ghi-modified" > ${tmps}/dotfiles/ghi
+echo "abc-modified" > "${tmps}"/dotfiles/abc
+echo "def-modified" > "${tmps}"/dotfiles/def
+echo "ghi-modified" > "${tmps}"/dotfiles/ghi
 
 # compare
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -b -V
 ret="$?"
 set -e
 [ "$ret" = "0" ] && exit 1
diff --git a/tests-ng/dotfiles-dyn-paths.sh b/tests-ng/dotfiles-dyn-paths.sh
index d91c1e2..0a10301 100755
--- a/tests-ng/dotfiles-dyn-paths.sh
+++ b/tests-ng/dotfiles-dyn-paths.sh
@@ -6,53 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-#set -v
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -61,7 +39,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -82,18 +60,18 @@ _EOF
 #cat ${cfg}
 
 # create the dotfiles
-echo "abc" > ${tmps}/dotfiles/abc
+echo "abc" > "${tmps}"/dotfiles/abc
 
 ###########################
 # test install and compare
 ###########################
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 [ "$?" != "0" ] && exit 1
 
 # checks
-[ ! -e ${tmpd}/abc ] && exit 1
+[ ! -e "${tmpd}"/abc ] && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/double-config-import.sh b/tests-ng/double-config-import.sh
index 7987351..ab45f2f 100755
--- a/tests-ng/double-config-import.sh
+++ b/tests-ng/double-config-import.sh
@@ -5,41 +5,20 @@
 # test error report on importing the same sub-config file more than once
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -57,7 +36,7 @@ error_log="${dst}/error.log"
 
 # bottom-level
 bottom_level_cfg="${src}/bottom-level.yaml"
-cat > ${bottom_level_cfg} << _EOF
+cat > "${bottom_level_cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -70,7 +49,7 @@ touch "${src}/dotfiles/bottom"
 
 # mid-level
 mid_level_cfg="${src}/mid-level.yaml"
-cat > ${mid_level_cfg} << _EOF
+cat > "${mid_level_cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -85,7 +64,7 @@ _EOF
 
 # top-level
 top_level_cfg="${src}/top-level.yaml"
-cat > ${top_level_cfg} << _EOF
+cat > "${top_level_cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -101,7 +80,7 @@ _EOF
 
 # install
 set +e
-cd ${ddpath} | ${bin} install -f -c ${top_level_cfg} -p top-level 2> "${error_log}"
+cd "${ddpath}" | ${bin} install -f -c "${top_level_cfg}" -p top-level 2> "${error_log}"
 set -e
 
 # checks
diff --git a/tests-ng/dry.sh b/tests-ng/dry.sh
index 1ae188d..df54e82 100755
--- a/tests-ng/dry.sh
+++ b/tests-ng/dry.sh
@@ -5,56 +5,35 @@
 # test dry
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 # workdir
-tmpw=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpw=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 export DOTDROP_WORKDIR="${tmpw}"
 # temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -65,23 +44,23 @@ clear_on_exit "${tmpa}"
 # test install
 # -----------------------------
 # cleaning
-rm -rf ${tmps}/*
-mkdir -p ${tmps}/dotfiles
-rm -rf ${tmpw}/*
-rm -rf ${tmpd}/*
-rm -rf ${tmpa}/*
+rm -rf "${tmps:?}"/*
+mkdir -p "${tmps}"/dotfiles
+rm -rf "${tmpw:?}"/*
+rm -rf "${tmpd:?}"/*
+rm -rf "${tmpa:?}"/*
 # create the config file
 cfg="${tmps}/config.yaml"
 
-echo '{{@@ profile @@}}' > ${tmps}/dotfiles/file
-echo '{{@@ profile @@}}' > ${tmps}/dotfiles/link
-mkdir -p ${tmps}/dotfiles/dir
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir/f1
-mkdir -p ${tmps}/dotfiles/dirchildren
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dirchildren/f1
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dirchildren/f2
+echo '{{@@ profile @@}}' > "${tmps}"/dotfiles/file
+echo '{{@@ profile @@}}' > "${tmps}"/dotfiles/link
+mkdir -p "${tmps}"/dotfiles/dir
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dir/f1
+mkdir -p "${tmps}"/dotfiles/dirchildren
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dirchildren/f1
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dirchildren/f2
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -130,33 +109,33 @@ _EOF
 
 # install
 echo "dry install"
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p1 -V --dry
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 -V --dry
 
-cnt=`ls -1 ${tmpd} | wc -l`
-ls -1 ${tmpd}
-[ "${cnt}" != "0" ] && echo "dry install failed (1)" && exit 1
+cnt=$(find "${tmpd}" -depth 1 -type f | wc -l)
+ls -1 "${tmpd}"
+[ "${cnt}" != "0" ] && echo "dry install failed (1 -> ${cnt})" && exit 1
 
-cnt=`ls -1 ${tmpw} | wc -l`
-ls -1 ${tmpw}
-[ "${cnt}" != "0" ] && echo "dry install failed (2)" && exit 1
+cnt=$(find "${tmpw}" -depth 1 -type f | wc -l)
+ls -1 "${tmpw}"
+[ "${cnt}" != "0" ] && echo "dry install failed (2 -> ${cnt})" && exit 1
 
-cnt=`ls -1 ${tmpa} | wc -l`
-ls -1 ${tmpa}
-[ "${cnt}" != "0" ] && echo "dry install failed (3)" && exit 1
+cnt=$(find "${tmpa}" -depth 1 -type f | wc -l)
+ls -1 "${tmpa}"
+[ "${cnt}" != "0" ] && echo "dry install failed (3 -> ${cnt})" && exit 1
 
 # -----------------------------
 # test import
 # -----------------------------
 # cleaning
-rm -rf ${tmps}/*
-mkdir -p ${tmps}/dotfiles
-rm -rf ${tmpw}/*
-rm -rf ${tmpd}/*
-rm -rf ${tmpa}/*
+rm -rf "${tmps:?}"/*
+mkdir -p "${tmps}"/dotfiles
+rm -rf "${tmpw:?}"/*
+rm -rf "${tmpd:?}"/*
+rm -rf "${tmpa:?}"/*
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -165,54 +144,52 @@ config:
 dotfiles:
 profiles:
 _EOF
-cp ${cfg} ${tmpa}/config.yaml
+cp "${cfg}" "${tmpa}"/config.yaml
 
-echo 'content' > ${tmpd}/file
-echo 'content' > ${tmpd}/link
-mkdir -p ${tmpd}/dir
-echo "content" > ${tmpd}/dir/f1
-mkdir -p ${tmpd}/dirchildren
-echo "content" > ${tmpd}/dirchildren/f1
-echo "content" > ${tmpd}/dirchildren/f2
-
-dotfiles="${tmpd}/file ${tmpd}/link ${tmpd}/dir ${tmpd}/dirchildren"
+echo 'content' > "${tmpd}"/file
+echo 'content' > "${tmpd}"/link
+mkdir -p "${tmpd}"/dir
+echo "content" > "${tmpd}"/dir/f1
+mkdir -p "${tmpd}"/dirchildren
+echo "content" > "${tmpd}"/dirchildren/f1
+echo "content" > "${tmpd}"/dirchildren/f2
 
 echo "dry import"
-cd ${ddpath} | ${bin} import -c ${cfg} -f -p p1 -V --dry ${dotfiles}
+cd "${ddpath}" | ${bin} import -c "${cfg}" -f -p p1 -V --dry "${tmpd}"/file "${tmpd}"/link "${tmpd}"/dir "${tmpd}"/dirchildren
 
-cnt=`ls -1 ${tmps}/dotfiles | wc -l`
-ls -1 ${tmps}/dotfiles
-[ "${cnt}" != "0" ] && echo "dry import failed (1)" && exit 1
+cnt=$(find "${tmps}"/dotfiles -depth 1 | wc -l)
+ls -1 "${tmps}"/dotfiles
+[ "${cnt}" != "0" ] && echo "dry import failed (1 -> ${cnt})" && exit 1
 
-diff ${cfg} ${tmpa}/config.yaml || (echo "dry import failed (2)" && exit 1)
+diff "${cfg}" "${tmpa}"/config.yaml || (echo "dry import failed (2)" && exit 1)
 
 # -----------------------------
 # test update
 # -----------------------------
 # cleaning
-rm -rf ${tmps}/*
-mkdir -p ${tmps}/dotfiles
-rm -rf ${tmpw}/*
-rm -rf ${tmpd}/*
-rm -rf ${tmpa}/*
-
-echo 'original' > ${tmps}/dotfiles/file
-echo 'original' > ${tmps}/dotfiles/link
-mkdir -p ${tmps}/dotfiles/dir
-echo "original" > ${tmps}/dotfiles/dir/f1
-mkdir -p ${tmps}/dotfiles/dirchildren
-echo "original" > ${tmps}/dotfiles/dirchildren/f1
-echo "original" > ${tmps}/dotfiles/dirchildren/f2
-
-echo 'modified' > ${tmpd}/file
-echo 'modified' > ${tmpd}/link
-mkdir -p ${tmpd}/dir
-echo "modified" > ${tmpd}/dir/f1
-mkdir -p ${tmpd}/dirchildren
-echo "modified" > ${tmpd}/dirchildren/f1
-echo "modified" > ${tmpd}/dirchildren/f2
-
-cat > ${cfg} << _EOF
+rm -rf "${tmps:?}"/*
+mkdir -p "${tmps}"/dotfiles
+rm -rf "${tmpw:?}"/*
+rm -rf "${tmpd:?}"/*
+rm -rf "${tmpa:?}"/*
+
+echo 'original' > "${tmps}"/dotfiles/file
+echo 'original' > "${tmps}"/dotfiles/link
+mkdir -p "${tmps}"/dotfiles/dir
+echo "original" > "${tmps}"/dotfiles/dir/f1
+mkdir -p "${tmps}"/dotfiles/dirchildren
+echo "original" > "${tmps}"/dotfiles/dirchildren/f1
+echo "original" > "${tmps}"/dotfiles/dirchildren/f2
+
+echo 'modified' > "${tmpd}"/file
+echo 'modified' > "${tmpd}"/link
+mkdir -p "${tmpd}"/dir
+echo "modified" > "${tmpd}"/dir/f1
+mkdir -p "${tmpd}"/dirchildren
+echo "modified" > "${tmpd}"/dirchildren/f1
+echo "modified" > "${tmpd}"/dirchildren/f2
+
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -241,39 +218,38 @@ profiles:
     - d_dir
     - d_dirchildren
 _EOF
-cp ${cfg} ${tmpa}/config.yaml
+cp "${cfg}" "${tmpa}"/config.yaml
 
 echo "dry update"
-dotfiles="${tmpd}/file ${tmpd}/link ${tmpd}/dir ${tmpd}/dirchildren"
-cd ${ddpath} | ${bin} update -c ${cfg} -f -p p1 -V --dry ${dotfiles}
+cd "${ddpath}" | ${bin} update -c "${cfg}" -f -p p1 -V --dry "${tmpd}"/file "${tmpd}"/link "${tmpd}"/dir "${tmpd}"/dirchildren
 
-grep 'modified' ${tmps}/dotfiles/file   && echo "dry update failed (1)" && exit 1
-grep 'modified' ${tmps}/dotfiles/link   && echo "dry update failed (2)" && exit 1
-grep "modified" ${tmps}/dotfiles/dir/f1 && echo "dry update failed (3)" && exit 1
-grep "modified" ${tmps}/dotfiles/dirchildren/f1 && echo "dry update failed (4)" && exit 1
-grep "modified" ${tmps}/dotfiles/dirchildren/f2 && echo "dry update failed (5)" && exit 1
+grep 'modified' "${tmps}"/dotfiles/file   && echo "dry update failed (1)" && exit 1
+grep 'modified' "${tmps}"/dotfiles/link   && echo "dry update failed (2)" && exit 1
+grep "modified" "${tmps}"/dotfiles/dir/f1 && echo "dry update failed (3)" && exit 1
+grep "modified" "${tmps}"/dotfiles/dirchildren/f1 && echo "dry update failed (4)" && exit 1
+grep "modified" "${tmps}"/dotfiles/dirchildren/f2 && echo "dry update failed (5)" && exit 1
 
-diff ${cfg} ${tmpa}/config.yaml || (echo "dry update failed (6)" && exit 1)
+diff "${cfg}" "${tmpa}"/config.yaml || (echo "dry update failed (6)" && exit 1)
 
 # -----------------------------
 # test remove
 # -----------------------------
 # cleaning
-rm -rf ${tmps}/*
-mkdir -p ${tmps}/dotfiles
-rm -rf ${tmpw}/*
-rm -rf ${tmpd}/*
-rm -rf ${tmpa}/*
-
-echo '{{@@ profile @@}}' > ${tmps}/dotfiles/file
-echo '{{@@ profile @@}}' > ${tmps}/dotfiles/link
-mkdir -p ${tmps}/dotfiles/dir
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir/f1
-mkdir -p ${tmps}/dotfiles/dirchildren
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dirchildren/f1
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dirchildren/f2
-
-cat > ${cfg} << _EOF
+rm -rf "${tmps:?}"/*
+mkdir -p "${tmps}"/dotfiles
+rm -rf "${tmpw:?}"/*
+rm -rf "${tmpd:?}"/*
+rm -rf "${tmpa:?}"/*
+
+echo '{{@@ profile @@}}' > "${tmps}"/dotfiles/file
+echo '{{@@ profile @@}}' > "${tmps}"/dotfiles/link
+mkdir -p "${tmps}"/dotfiles/dir
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dir/f1
+mkdir -p "${tmps}"/dotfiles/dirchildren
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dirchildren/f1
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dirchildren/f2
+
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -302,21 +278,20 @@ profiles:
     - d_dir
     - d_dirchildren
 _EOF
-cp ${cfg} ${tmpa}/config.yaml
+cp "${cfg}" "${tmpa}"/config.yaml
 
 echo "dry remove"
-dotfiles="${tmpd}/file ${tmpd}/link ${tmpd}/dir ${tmpd}/dirchildren"
-cd ${ddpath} | ${bin} remove -c ${cfg} -f -p p1 -V --dry ${dotfiles}
+cd "${ddpath}" | ${bin} remove -c "${cfg}" -f -p p1 -V --dry "${tmpd}"/file "${tmpd}"/link "${tmpd}"/dir "${tmpd}"/dirchildren
 
-[ ! -e ${tmps}/dotfiles/file ] && echo "dry remove failed (1)" && exit 1
-[ ! -e ${tmps}/dotfiles/link ] && echo "dry remove failed (2)" && exit 1
-[ ! -d ${tmps}/dotfiles/dir ] && echo "dry remove failed (3)" && exit 1
-[ ! -e ${tmps}/dotfiles/dir/f1 ] && echo "dry remove failed (4)" && exit 1
-[ ! -d ${tmps}/dotfiles/dirchildren ] && echo "dry remove failed (5)" && exit 1
-[ ! -e ${tmps}/dotfiles/dirchildren/f1 ] && echo "dry remove failed (6)" && exit 1
-[ ! -e ${tmps}/dotfiles/dirchildren/f2 ] && echo "dry remove failed (7)" && exit 1
+[ ! -e "${tmps}"/dotfiles/file ] && echo "dry remove failed (1)" && exit 1
+[ ! -e "${tmps}"/dotfiles/link ] && echo "dry remove failed (2)" && exit 1
+[ ! -d "${tmps}"/dotfiles/dir ] && echo "dry remove failed (3)" && exit 1
+[ ! -e "${tmps}"/dotfiles/dir/f1 ] && echo "dry remove failed (4)" && exit 1
+[ ! -d "${tmps}"/dotfiles/dirchildren ] && echo "dry remove failed (5)" && exit 1
+[ ! -e "${tmps}"/dotfiles/dirchildren/f1 ] && echo "dry remove failed (6)" && exit 1
+[ ! -e "${tmps}"/dotfiles/dirchildren/f2 ] && echo "dry remove failed (7)" && exit 1
 
-diff ${cfg} ${tmpa}/config.yaml || (echo "dry remove failed (8)" && exit 1)
+diff "${cfg}" "${tmpa}"/config.yaml || (echo "dry remove failed (8)" && exit 1)
 
 echo "OK"
 exit 0
diff --git a/tests-ng/duplicate-key.sh b/tests-ng/duplicate-key.sh
index f40f798..44011f0 100755
--- a/tests-ng/duplicate-key.sh
+++ b/tests-ng/duplicate-key.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -58,7 +37,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -75,30 +54,30 @@ _EOF
 #cat ${cfg}
 
 # create the imported one
-mkdir -p ${tmps}/dotfiles/${tmpd}
-echo "test" > ${tmps}/dotfiles/${tmpd}/abc
-echo "test" > ${tmpd}/abc
+mkdir -p "${tmps}"/dotfiles/"${tmpd}"
+echo "test" > "${tmps}"/dotfiles/"${tmpd}"/abc
+echo "test" > "${tmpd}"/abc
 
 # create the to-be-imported
-mkdir -p ${tmpd}/sub
-echo "test2" > ${tmpd}/sub/abc
+mkdir -p "${tmpd}"/sub
+echo "test2" > "${tmpd}"/sub/abc
 
-mkdir -p ${tmpd}/sub/sub2
-echo "test2" > ${tmpd}/sub/sub2/abc
+mkdir -p "${tmpd}"/sub/sub2
+echo "test2" > "${tmpd}"/sub/sub2/abc
 
-mkdir -p ${tmpd}/sub/sub
-echo "test2" > ${tmpd}/sub/sub/abc
+mkdir -p "${tmpd}"/sub/sub
+echo "test2" > "${tmpd}"/sub/sub/abc
 
 # import
-cd ${ddpath} | ${bin} import -f --verbose -c ${cfg} -p p2 \
-  ${tmpd}/abc \
-  ${tmpd}/sub/abc \
-  ${tmpd}/sub/abc \
-  ${tmpd}/sub/sub/abc \
-  ${tmpd}/sub/sub2/abc
+cd "${ddpath}" | ${bin} import -f --verbose -c "${cfg}" -p p2 \
+  "${tmpd}"/abc \
+  "${tmpd}"/sub/abc \
+  "${tmpd}"/sub/abc \
+  "${tmpd}"/sub/sub/abc \
+  "${tmpd}"/sub/sub2/abc
 
 # count dotfiles for p2
-cnt=`cd ${ddpath} | ${bin} files --verbose -c ${cfg} -p p2 -b | grep '^f_' | wc -l`
+cnt=$(cd "${ddpath}" | ${bin} files --verbose -c "${cfg}" -p p2 -b | grep '^f_' | wc -l)
 [ "${cnt}" != "4" ] && echo "bad count for p2: ${cnt} != 4" && exit 1
 
 echo "OK"
diff --git a/tests-ng/dynactions.sh b/tests-ng/dynactions.sh
index a9f50fa..ba363f4 100755
--- a/tests-ng/dynactions.sh
+++ b/tests-ng/dynactions.sh
@@ -6,53 +6,32 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -61,7 +40,7 @@ clear_on_exit "${tmpa}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 variables:
   var1: "var1"
   var2: "{{@@ var1 @@}} var2"
@@ -104,25 +83,25 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "test" > ${tmps}/dotfiles/abc
+echo "test" > "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 --verbose
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 --verbose
 
 # checks
-[ ! -e ${tmpa}/preaction1 ] && exit 1
-[ ! -e ${tmpa}/preaction2 ] && exit 1
-[ ! -e ${tmpa}/postaction1 ] && exit 1
-[ ! -e ${tmpa}/postaction2 ] && exit 1
-[ ! -e ${tmpa}/naked1 ] && exit 1
-[ ! -e ${tmpa}/naked2 ] && exit 1
-
-grep 'var1 var2 var3' ${tmpa}/preaction1 >/dev/null
-grep 'dvar1 dvar2 dvar3' ${tmpa}/preaction2 >/dev/null
-grep 'var1 var2 var3' ${tmpa}/postaction1 >/dev/null
-grep 'dvar1 dvar2 dvar3' ${tmpa}/postaction2 >/dev/null
-grep 'var1 var2 var3' ${tmpa}/naked1 >/dev/null
-grep 'dvar1 dvar2 dvar3' ${tmpa}/naked2 >/dev/null
+[ ! -e "${tmpa}"/preaction1 ] && exit 1
+[ ! -e "${tmpa}"/preaction2 ] && exit 1
+[ ! -e "${tmpa}"/postaction1 ] && exit 1
+[ ! -e "${tmpa}"/postaction2 ] && exit 1
+[ ! -e "${tmpa}"/naked1 ] && exit 1
+[ ! -e "${tmpa}"/naked2 ] && exit 1
+
+grep 'var1 var2 var3' "${tmpa}"/preaction1 >/dev/null
+grep 'dvar1 dvar2 dvar3' "${tmpa}"/preaction2 >/dev/null
+grep 'var1 var2 var3' "${tmpa}"/postaction1 >/dev/null
+grep 'dvar1 dvar2 dvar3' "${tmpa}"/postaction2 >/dev/null
+grep 'var1 var2 var3' "${tmpa}"/naked1 >/dev/null
+grep 'dvar1 dvar2 dvar3' "${tmpa}"/naked2 >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/dyndotfilepaths.sh b/tests-ng/dyndotfilepaths.sh
index 8696d63..6034d36 100755
--- a/tests-ng/dyndotfilepaths.sh
+++ b/tests-ng/dyndotfilepaths.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -58,9 +37,9 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-dst=`echo ${tmpd} | rev`
+dst=$(echo "${tmpd}" | rev)
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -79,15 +58,15 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "{{@@ dpath @@}}" > ${tmps}/dotfiles/abc
+echo "{{@@ dpath @@}}" > "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 #cat ${tmpd}/abc
 
-[ ! -e ${tmpd}/abc ] && echo "abc not installed dynamically" && exit 1
-grep "^${tmpd}" ${tmpd}/abc >/dev/null
+[ ! -e "${tmpd}"/abc ] && echo "abc not installed dynamically" && exit 1
+grep "^${tmpd}" "${tmpd}"/abc >/dev/null
 
 #cat ${tmpd}/abc
 
diff --git a/tests-ng/dynextvariables.sh b/tests-ng/dynextvariables.sh
index 4b06c3c..d788cbe 100755
--- a/tests-ng/dynextvariables.sh
+++ b/tests-ng/dynextvariables.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -63,7 +42,7 @@ pvars="${tmps}/p1_vars.yaml"
 pvarin="${tmps}/inprofile_vars.yaml"
 pvarout="${tmps}/outprofile_vars.yaml"
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -92,64 +71,64 @@ _EOF
 #cat ${cfg}
 
 # create the external variables file
-cat > ${extvars} << _EOF
+cat > "${extvars}" << _EOF
 variables:
   vara: "extvar1"
 dynvariables:
   dvara: "echo extdvar1"
 _EOF
-cat > ${extdvars} << _EOF
+cat > "${extdvars}" << _EOF
 variables:
   varb: "extvar2"
 dynvariables:
   dvarb: "echo extdvar2"
 _EOF
-cat > ${pvars} << _EOF
+cat > "${pvars}" << _EOF
 variables:
   pvar: "pvar1"
 dynvariables:
   pdvar: "echo pdvar1"
 _EOF
-cat > ${pvarin} << _EOF
+cat > "${pvarin}" << _EOF
 variables:
   test: profileok
 _EOF
-cat > ${pvarout} << _EOF
+cat > "${pvarout}" << _EOF
 variables:
   test: profilenotok
 _EOF
 
 # create the dotfile
-echo "var1: {{@@ var1 @@}}" > ${tmps}/dotfiles/abc
-echo "dvar1: {{@@ dvar1 @@}}" >> ${tmps}/dotfiles/abc
+echo "var1: {{@@ var1 @@}}" > "${tmps}"/dotfiles/abc
+echo "dvar1: {{@@ dvar1 @@}}" >> "${tmps}"/dotfiles/abc
 # from var file 1
-echo "vara: {{@@ vara @@}}" >> ${tmps}/dotfiles/abc
-echo "dvara: {{@@ dvara @@}}" >> ${tmps}/dotfiles/abc
+echo "vara: {{@@ vara @@}}" >> "${tmps}"/dotfiles/abc
+echo "dvara: {{@@ dvara @@}}" >> "${tmps}"/dotfiles/abc
 # from var file 2
-echo "varb: {{@@ varb @@}}" >> ${tmps}/dotfiles/abc
-echo "dvarb: {{@@ dvarb @@}}" >> ${tmps}/dotfiles/abc
+echo "varb: {{@@ varb @@}}" >> "${tmps}"/dotfiles/abc
+echo "dvarb: {{@@ dvarb @@}}" >> "${tmps}"/dotfiles/abc
 # from var file 3
-echo "pvar: {{@@ pvar @@}}" >> ${tmps}/dotfiles/abc
-echo "pdvar: {{@@ pdvar @@}}" >> ${tmps}/dotfiles/abc
+echo "pvar: {{@@ pvar @@}}" >> "${tmps}"/dotfiles/abc
+echo "pdvar: {{@@ pdvar @@}}" >> "${tmps}"/dotfiles/abc
 # from profile variable
-echo "test: {{@@ test @@}}" >> ${tmps}/dotfiles/abc
+echo "test: {{@@ test @@}}" >> "${tmps}"/dotfiles/abc
 
 #cat ${tmps}/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-
-cat ${tmpd}/abc
-
-grep '^var1: var' ${tmpd}/abc >/dev/null
-grep '^dvar1: dynvar' ${tmpd}/abc >/dev/null
-grep '^vara: extvar1' ${tmpd}/abc >/dev/null
-grep '^dvara: extdvar1' ${tmpd}/abc >/dev/null
-grep '^varb: extvar2' ${tmpd}/abc >/dev/null
-grep '^dvarb: extdvar2' ${tmpd}/abc >/dev/null
-grep '^pvar: pvar1' ${tmpd}/abc >/dev/null
-grep '^pdvar: pdvar1' ${tmpd}/abc >/dev/null
-grep '^test: profileok' ${tmpd}/abc >/dev/null
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+
+cat "${tmpd}"/abc
+
+grep '^var1: var' "${tmpd}"/abc >/dev/null
+grep '^dvar1: dynvar' "${tmpd}"/abc >/dev/null
+grep '^vara: extvar1' "${tmpd}"/abc >/dev/null
+grep '^dvara: extdvar1' "${tmpd}"/abc >/dev/null
+grep '^varb: extvar2' "${tmpd}"/abc >/dev/null
+grep '^dvarb: extdvar2' "${tmpd}"/abc >/dev/null
+grep '^pvar: pvar1' "${tmpd}"/abc >/dev/null
+grep '^pdvar: pdvar1' "${tmpd}"/abc >/dev/null
+grep '^test: profileok' "${tmpd}"/abc >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/dyninclude.sh b/tests-ng/dyninclude.sh
index 8d147c5..86367d6 100755
--- a/tests-ng/dyninclude.sh
+++ b/tests-ng/dyninclude.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -58,7 +37,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 variables:
   var1: "_1"
 dynvariables:
@@ -92,25 +71,25 @@ _EOF
 
 # create the dotfile
 c1="content:abc"
-echo "${c1}" > ${tmps}/dotfiles/abc
+echo "${c1}" > "${tmps}"/dotfiles/abc
 c2="content:def"
-echo "${c2}" > ${tmps}/dotfiles/def
+echo "${c2}" > "${tmps}"/dotfiles/def
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p profile_3 --verbose
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p profile_3 --verbose
 
 # check dotfile exists
-[ ! -e ${tmpd}/abc ] && exit 1
+[ ! -e "${tmpd}"/abc ] && exit 1
 #cat ${tmpd}/abc
-grep ${c1} ${tmpd}/abc >/dev/null || exit 1
+grep ${c1} "${tmpd}"/abc >/dev/null || exit 1
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p profile_4 --verbose
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p profile_4 --verbose
 
 # check dotfile exists
-[ ! -e ${tmpd}/def ] && exit 1
+[ ! -e "${tmpd}"/def ] && exit 1
 #cat ${tmpd}/def
-grep ${c2} ${tmpd}/def >/dev/null || exit 1
+grep ${c2} "${tmpd}"/def >/dev/null || exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/dynvariables.sh b/tests-ng/dynvariables.sh
index dfb5e45..42f0ccd 100755
--- a/tests-ng/dynvariables.sh
+++ b/tests-ng/dynvariables.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -58,15 +37,15 @@ clear_on_exit "${tmpd}"
 
 # create a shell script
 export TESTENV="this is my testenv"
-scr=`mktemp --suffix='-dotdrop-tests' || mktemp -d`
-chmod +x ${scr}
-echo -e "#!/bin/bash\necho $TESTENV\n" >> ${scr}
+scr=$(mktemp --suffix='-dotdrop-tests' || mktemp -d)
+chmod +x "${scr}"
+echo -e "#!/bin/bash\necho $TESTENV\n" >> "${scr}"
 clear_on_exit "${scr}"
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -88,28 +67,29 @@ profiles:
     dotfiles:
     - f_abc
 _EOF
-#cat ${cfg}
+#cat "${cfg}"
 
 # create the dotfile
-echo "{{@@ var1 @@}}" > ${tmps}/dotfiles/abc
-echo "{{@@ dvar1 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ dvar2 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ dvar3 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ dvar4 @@}}" >> ${tmps}/dotfiles/abc
-echo "test" >> ${tmps}/dotfiles/abc
+echo "{{@@ var1 @@}}" > "${tmps}"/dotfiles/abc
+echo "{{@@ dvar1 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ dvar2 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ dvar3 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ dvar4 @@}}" >> "${tmps}"/dotfiles/abc
+echo "test" >> "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
+#cat "${cfg}"
 echo "-----"
-cat ${tmpd}/abc
+cat "${tmpd}"/abc
 echo "-----"
 
-grep '^this is some test' ${tmpd}/abc >/dev/null
-grep '^# author: deadc0de6' ${tmpd}/abc >/dev/null
-grep '^tset,emos,si,siht' ${tmpd}/abc >/dev/null
-grep "^${TESTENV}" ${tmpd}/abc > /dev/null
-grep '^4ravd_eht' ${tmpd}/abc >/dev/null
+grep '^this is some test' "${tmpd}"/abc >/dev/null
+grep '^# shellcheck' "${tmpd}"/abc >/dev/null
+grep '^tset,emos,si,siht' "${tmpd}"/abc >/dev/null
+grep "^${TESTENV}" "${tmpd}"/abc > /dev/null
+grep '^4ravd_eht' "${tmpd}"/abc >/dev/null
 
 #cat ${tmpd}/abc
 
diff --git a/tests-ng/env.sh b/tests-ng/env.sh
index 41ef0e1..aa6415a 100755
--- a/tests-ng/env.sh
+++ b/tests-ng/env.sh
@@ -5,54 +5,33 @@
 # test import with env variables
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
-tmpx=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-tmpy=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpx=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+tmpy=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -60,15 +39,15 @@ clear_on_exit "${tmpx}"
 clear_on_exit "${tmpy}"
 
 # create the dotfile
-mkdir -p ${tmpd}/adir
-echo "adir/file1" > ${tmpd}/adir/file1
-echo "adir/fil2" > ${tmpd}/adir/file2
-echo "file3" > ${tmpd}/file3
+mkdir -p "${tmpd}"/adir
+echo "adir/file1" > "${tmpd}"/adir/file1
+echo "adir/fil2" > "${tmpd}"/adir/file2
+echo "file3" > "${tmpd}"/file3
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -88,42 +67,54 @@ export DOTDROP_WORKDIR="${tmpy}"
 export DOTDROP_WORKERS="1"
 
 # import
-cd ${ddpath} | ${bin} import -f ${tmpd}/adir
-cd ${ddpath} | ${bin} import -f ${tmpd}/file3
+cd "${ddpath}" | ${bin} import -f "${tmpd}"/adir
+cd "${ddpath}" | ${bin} import -f "${tmpd}"/file3
 
-cat ${cfg}
+cat "${cfg}"
 
 # ensure exists and is not link
-[ ! -d ${tmps}/dotfiles/${tmpd}/adir ] && echo "not a directory" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/adir/file1 ] && echo "not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/adir/file2 ] && echo "not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/file3 ] && echo "not a file" && exit 1
+[ ! -d "${tmps}"/dotfiles/"${tmpd}"/adir ] && echo "not a directory" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/adir/file1 ] && echo "not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/adir/file2 ] && echo "not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/file3 ] && echo "not a file" && exit 1
 
-cat ${cfg} | grep ${tmpd}/adir >/dev/null 2>&1
-cat ${cfg} | grep ${tmpd}/file3 >/dev/null 2>&1
+cat "${cfg}" | grep "${tmpd}"/adir >/dev/null 2>&1
+cat "${cfg}" | grep "${tmpd}"/file3 >/dev/null 2>&1
 
-nb=`cat ${cfg} | grep d_adir | wc -l`
+nb=$(cat "${cfg}" | grep d_adir | wc -l)
 [ "${nb}" != "2" ] && echo 'bad config1' && exit 1
-nb=`cat ${cfg} | grep f_file3 | wc -l`
+nb=$(cat "${cfg}" | grep f_file3 | wc -l)
 [ "${nb}" != "2" ] && echo 'bad config2' && exit 1
 
-cntpre=`find ${tmps}/dotfiles -type f | wc -l`
+cntpre=$(find "${tmps}"/dotfiles -type f | wc -l)
 
 export DOTDROP_FORCE_NODEBUG=
 
 # compare
-cd ${ddpath} | ${bin} compare
+cd "${ddpath}" | ${bin} compare
 
 # install
-cd ${ddpath} | ${bin} install -f
+cd "${ddpath}" | ${bin} install -f
 
 # reimport
-cd ${ddpath} | ${bin} import -f ${tmpd}/adir
-cd ${ddpath} | ${bin} import -f ${tmpd}/file3
+cd "${ddpath}" | ${bin} import -f "${tmpd}"/adir
+cd "${ddpath}" | ${bin} import -f "${tmpd}"/file3
 
-cntpost=`find ${tmps}/dotfiles -type f | wc -l`
+cntpost=$(find "${tmps}"/dotfiles -type f | wc -l)
 
 [ "${cntpost}" != "${cntpre}" ] && echo "import failed" && exit 1
 
+# for coverage
+export DOTDROP_CONFIG="${cfg}"
+export DOTDROP_PROFILE="p1"
+export DOTDROP_VERBOSE="yes"
+unset DOTDROP_FORCE_NODEBUG
+unset DOTDROP_NOBANNER
+export DOTDROP_TMPDIR="${tmpx}"
+export DOTDROP_WORKDIR="${tmpy}"
+export DOTDROP_WORKERS="1"
+
+cd "${ddpath}" | ${bin} files
+
 echo "OK"
 exit 0
diff --git a/tests-ng/ext-actions.sh b/tests-ng/ext-actions.sh
index 7dc168f..21bab53 100755
--- a/tests-ng/ext-actions.sh
+++ b/tests-ng/ext-actions.sh
@@ -6,60 +6,39 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 clear_on_exit "${tmpa}"
 
 act="${tmps}/actions.yaml"
-cat > ${act} << _EOF
+cat > "${act}" << _EOF
 actions:
   pre:
     preaction: echo 'pre' > ${tmpa}/pre
@@ -72,7 +51,7 @@ _EOF
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -98,26 +77,26 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "test" > ${tmps}/dotfiles/abc
+echo "test" > "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks
-[ ! -e ${tmpa}/pre ] && exit 1
-grep pre ${tmpa}/pre >/dev/null
+[ ! -e "${tmpa}"/pre ] && exit 1
+grep pre "${tmpa}"/pre >/dev/null
 echo "pre is ok"
 
-[ ! -e ${tmpa}/post ] && exit 1
-grep post ${tmpa}/post >/dev/null
+[ ! -e "${tmpa}"/post ] && exit 1
+grep post "${tmpa}"/post >/dev/null
 echo "post is ok"
 
-[ ! -e ${tmpa}/naked ] && exit 1
-grep naked ${tmpa}/naked >/dev/null
+[ ! -e "${tmpa}"/naked ] && exit 1
+grep naked "${tmpa}"/naked >/dev/null
 echo "naked is ok"
 
-[ ! -e ${tmpa}/write ] && exit 1
-grep over ${tmpa}/write >/dev/null
+[ ! -e "${tmpa}"/write ] && exit 1
+grep over "${tmpa}"/write >/dev/null
 echo "write is ok"
 
 echo "OK"
diff --git a/tests-ng/extvariables.sh b/tests-ng/extvariables.sh
index a432afd..57c8356 100755
--- a/tests-ng/extvariables.sh
+++ b/tests-ng/extvariables.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -59,13 +38,13 @@ clear_on_exit "${tmpd}"
 # create the config file
 extvars="${tmps}/variables.yaml"
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
   dotpath: dotfiles
   import_variables:
-  - $(basename ${extvars})
+  - $(basename "${extvars}")
 variables:
   var1: "var1"
   var2: "{{@@ var1 @@}} var2"
@@ -97,7 +76,7 @@ _EOF
 #cat ${cfg}
 
 # create the external variables file
-cat > ${extvars} << _EOF
+cat > "${extvars}" << _EOF
 variables:
   varx: "exttest"
 dynvariables:
@@ -106,47 +85,47 @@ dynvariables:
 _EOF
 
 # create the dotfile
-echo "var3: {{@@ var3 @@}}" > ${tmps}/dotfiles/abc
-echo "dvar3: {{@@ dvar3 @@}}" >> ${tmps}/dotfiles/abc
-echo "var4: {{@@ var4 @@}}" >> ${tmps}/dotfiles/abc
-echo "dvar4: {{@@ dvar4 @@}}" >> ${tmps}/dotfiles/abc
-echo "varx: {{@@ varx @@}}" >> ${tmps}/dotfiles/abc
-echo "evar1: {{@@ evar1 @@}}" >> ${tmps}/dotfiles/abc
-echo "provar: {{@@ provar @@}}" >> ${tmps}/dotfiles/abc
-echo "theprofile: {{@@ theprofile @@}}" >> ${tmps}/dotfiles/abc
+echo "var3: {{@@ var3 @@}}" > "${tmps}"/dotfiles/abc
+echo "dvar3: {{@@ dvar3 @@}}" >> "${tmps}"/dotfiles/abc
+echo "var4: {{@@ var4 @@}}" >> "${tmps}"/dotfiles/abc
+echo "dvar4: {{@@ dvar4 @@}}" >> "${tmps}"/dotfiles/abc
+echo "varx: {{@@ varx @@}}" >> "${tmps}"/dotfiles/abc
+echo "evar1: {{@@ evar1 @@}}" >> "${tmps}"/dotfiles/abc
+echo "provar: {{@@ provar @@}}" >> "${tmps}"/dotfiles/abc
+echo "theprofile: {{@@ theprofile @@}}" >> "${tmps}"/dotfiles/abc
 
-echo "theprofile: {{@@ theprofile @@}}" > ${tmps}/dotfiles/def
+echo "theprofile: {{@@ theprofile @@}}" > "${tmps}"/dotfiles/def
 
 #cat ${tmps}/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 echo "check1"
-cat ${tmpd}/abc
-grep '^var3: var1 var2 var3' ${tmpd}/abc >/dev/null
-grep '^dvar3: dvar1 dvar2 dvar3' ${tmpd}/abc >/dev/null
-grep '^var4: echo var1 var2 var3' ${tmpd}/abc >/dev/null
-grep '^dvar4: var1 var2 var3' ${tmpd}/abc >/dev/null
-grep '^varx: profvarx' ${tmpd}/abc >/dev/null
-grep '^evar1: extevar1' ${tmpd}/abc >/dev/null
-grep '^provar: provar' ${tmpd}/abc >/dev/null
-grep '^theprofile: p1' ${tmpd}/abc >/dev/null
+cat "${tmpd}"/abc
+grep '^var3: var1 var2 var3' "${tmpd}"/abc >/dev/null
+grep '^dvar3: dvar1 dvar2 dvar3' "${tmpd}"/abc >/dev/null
+grep '^var4: echo var1 var2 var3' "${tmpd}"/abc >/dev/null
+grep '^dvar4: var1 var2 var3' "${tmpd}"/abc >/dev/null
+grep '^varx: profvarx' "${tmpd}"/abc >/dev/null
+grep '^evar1: extevar1' "${tmpd}"/abc >/dev/null
+grep '^provar: provar' "${tmpd}"/abc >/dev/null
+grep '^theprofile: p1' "${tmpd}"/abc >/dev/null
 
 # check def
-[ ! -e ${tmpd}/p1 ] && echo "def not created" && exit 1
-grep '^theprofile: p1' ${tmpd}/p1 >/dev/null
+[ ! -e "${tmpd}"/p1 ] && echo "def not created" && exit 1
+grep '^theprofile: p1' "${tmpd}"/p1 >/dev/null
 
-rm -f ${tmpd}/abc
+rm -f "${tmpd}"/abc
 
 #cat ${tmpd}/abc
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
   dotpath: dotfiles
   import_variables:
-  - $(basename ${extvars})
+  - $(basename "${extvars}")
 dotfiles:
   f_abc:
     dst: ${tmpd}/abc
@@ -162,7 +141,7 @@ _EOF
 #cat ${cfg}
 
 # create the external variables file
-cat > ${extvars} << _EOF
+cat > "${extvars}" << _EOF
 variables:
   var1: "extvar1"
   varx: "exttest"
@@ -177,26 +156,26 @@ dynvariables:
 _EOF
 
 # create the dotfile
-echo "var3: {{@@ var3 @@}}" > ${tmps}/dotfiles/abc
-echo "dvar3: {{@@ dvar3 @@}}" >> ${tmps}/dotfiles/abc
-echo "var4: {{@@ var4 @@}}" >> ${tmps}/dotfiles/abc
-echo "dvar4: {{@@ dvar4 @@}}" >> ${tmps}/dotfiles/abc
-echo "varx: {{@@ varx @@}}" >> ${tmps}/dotfiles/abc
-echo "vary: {{@@ vary @@}}" >> ${tmps}/dotfiles/abc
+echo "var3: {{@@ var3 @@}}" > "${tmps}"/dotfiles/abc
+echo "dvar3: {{@@ dvar3 @@}}" >> "${tmps}"/dotfiles/abc
+echo "var4: {{@@ var4 @@}}" >> "${tmps}"/dotfiles/abc
+echo "dvar4: {{@@ dvar4 @@}}" >> "${tmps}"/dotfiles/abc
+echo "varx: {{@@ varx @@}}" >> "${tmps}"/dotfiles/abc
+echo "vary: {{@@ vary @@}}" >> "${tmps}"/dotfiles/abc
 
 #cat ${tmps}/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 echo "test2"
-cat ${tmpd}/abc
-grep '^var3: extvar1 var2 var3' ${tmpd}/abc >/dev/null
-grep '^dvar3: extdvar1 dvar2 dvar3' ${tmpd}/abc >/dev/null
-grep '^var4: echo extvar1 var2 var3' ${tmpd}/abc >/dev/null
-grep '^dvar4: extvar1 var2 var3' ${tmpd}/abc >/dev/null
-grep '^varx: profvarx' ${tmpd}/abc >/dev/null
-grep '^vary: profvary' ${tmpd}/abc >/dev/null
+cat "${tmpd}"/abc
+grep '^var3: extvar1 var2 var3' "${tmpd}"/abc >/dev/null
+grep '^dvar3: extdvar1 dvar2 dvar3' "${tmpd}"/abc >/dev/null
+grep '^var4: echo extvar1 var2 var3' "${tmpd}"/abc >/dev/null
+grep '^dvar4: extvar1 var2 var3' "${tmpd}"/abc >/dev/null
+grep '^varx: profvarx' "${tmpd}"/abc >/dev/null
+grep '^vary: profvary' "${tmpd}"/abc >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/filter_file.sh b/tests-ng/filter_file.sh
index 933a34c..7613112 100755
--- a/tests-ng/filter_file.sh
+++ b/tests-ng/filter_file.sh
@@ -6,55 +6,34 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
-filter_file=`mktemp`
-filter_file2=`mktemp`
-filter_file3=`mktemp`
+filter_file=$(mktemp)
+filter_file2=$(mktemp)
+filter_file3=$(mktemp)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -66,7 +45,7 @@ clear_on_exit "${filter_file3}"
 cfg="${tmps}/config.yaml"
 cfgext="${tmps}/ext.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -89,7 +68,7 @@ variables:
 _EOF
 #cat ${cfg}
 
-cat > ${cfgext} << _EOF
+cat > "${cfgext}" << _EOF
 config:
   backup: true
   create: true
@@ -100,46 +79,46 @@ profiles:
 dotfiles:
 _EOF
 
-cat << _EOF > ${filter_file}
+cat << _EOF > "${filter_file}"
 def filter1(arg1):
   return "filtered"
 def filter2(arg1, arg2=''):
   return arg2
 _EOF
 
-cat << _EOF > ${filter_file2}
+cat << _EOF > "${filter_file2}"
 def filter3(integer):
   return str(int(integer) - 10)
 _EOF
 
-cat << _EOF > ${filter_file3}
+cat << _EOF > "${filter_file3}"
 def filter_ext(arg1):
   return "external"
 _EOF
 
 # create the dotfile
-echo "this is the test dotfile" > ${tmps}/dotfiles/abc
+echo "this is the test dotfile" > "${tmps}"/dotfiles/abc
 
 # test imported function
-echo "{{@@ "abc" | filter1 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ "arg1" | filter2('arg2') @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ "13" | filter3() @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ "something" | filter_ext() @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ filt @@}}variable" >> ${tmps}/dotfiles/abc
+echo "{{@@ \"abc\" | filter1 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ \"arg1\" | filter2('arg2') @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ \"13\" | filter3() @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ \"something\" | filter_ext() @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ filt @@}}variable" >> "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 #cat ${tmpd}/abc
 
-grep '^filtered$' ${tmpd}/abc >/dev/null
-grep '^arg2$' ${tmpd}/abc >/dev/null
-grep '^3$' ${tmpd}/abc >/dev/null
-grep '^external$' ${tmpd}/abc >/dev/null
+grep '^filtered$' "${tmpd}"/abc >/dev/null
+grep '^arg2$' "${tmpd}"/abc >/dev/null
+grep '^3$' "${tmpd}"/abc >/dev/null
+grep '^external$' "${tmpd}"/abc >/dev/null
 set +e
-grep '^something$' ${tmpd}/abc >/dev/null && exit 1
+grep '^something$' "${tmpd}"/abc >/dev/null && exit 1
 set -e
-grep '^filteredvariable$' ${tmpd}/abc > /dev/null
+grep '^filteredvariable$' "${tmpd}"/abc > /dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/force-actions.sh b/tests-ng/force-actions.sh
index 78d08ac..97fa63d 100755
--- a/tests-ng/force-actions.sh
+++ b/tests-ng/force-actions.sh
@@ -6,53 +6,32 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -61,7 +40,7 @@ clear_on_exit "${tmpa}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 actions:
   pre:
     preaction: echo 'pre' > ${tmpa}/pre
@@ -92,34 +71,34 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "test" > ${tmps}/dotfiles/abc
+echo "test" > "${tmps}"/dotfiles/abc
 # deploy the dotfile
-cp ${tmps}/dotfiles/abc ${tmpd}/abc
+cp "${tmps}"/dotfiles/abc "${tmpd}"/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks
-[ -e ${tmpa}/pre ] && exit 1
-[ -e ${tmpa}/post ] && exit 1
-[ -e ${tmpa}/naked ] && exit 1
-[ -e ${tmpa}/pre2 ] && exit 1
-[ -e ${tmpa}/post2 ] && exit 1
+[ -e "${tmpa}"/pre ] && exit 1
+[ -e "${tmpa}"/post ] && exit 1
+[ -e "${tmpa}"/naked ] && exit 1
+[ -e "${tmpa}"/pre2 ] && exit 1
+[ -e "${tmpa}"/post2 ] && exit 1
 
 # install and force
-cd ${ddpath} | ${bin} install -f -a -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -a -c "${cfg}" -p p1 -V
 
 # checks
-[ ! -e ${tmpa}/pre ] && exit 1
-grep pre ${tmpa}/pre >/dev/null
-[ ! -e ${tmpa}/post ] && exit 1
-grep post ${tmpa}/post >/dev/null
-[ ! -e ${tmpa}/naked ] && exit 1
-grep naked ${tmpa}/naked >/dev/null
-[ ! -e ${tmpa}/pre2 ] && exit 1
-grep pre2 ${tmpa}/pre2 >/dev/null
-[ ! -e ${tmpa}/post2 ] && exit 1
-grep post2 ${tmpa}/post2 >/dev/null
+[ ! -e "${tmpa}"/pre ] && exit 1
+grep pre "${tmpa}"/pre >/dev/null
+[ ! -e "${tmpa}"/post ] && exit 1
+grep post "${tmpa}"/post >/dev/null
+[ ! -e "${tmpa}"/naked ] && exit 1
+grep naked "${tmpa}"/naked >/dev/null
+[ ! -e "${tmpa}"/pre2 ] && exit 1
+grep pre2 "${tmpa}"/pre2 >/dev/null
+[ ! -e "${tmpa}"/post2 ] && exit 1
+grep post2 "${tmpa}"/post2 >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/func_file.sh b/tests-ng/func_file.sh
index 65f5ca6..a760cba 100755
--- a/tests-ng/func_file.sh
+++ b/tests-ng/func_file.sh
@@ -6,55 +6,34 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
-func_file=`mktemp`
-func_file2=`mktemp`
-func_file3=`mktemp`
+func_file=$(mktemp)
+func_file2=$(mktemp)
+func_file3=$(mktemp)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -66,7 +45,7 @@ clear_on_exit "${func_file3}"
 cfg="${tmps}/config.yaml"
 cfgext="${tmps}/ext.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -89,7 +68,7 @@ variables:
 _EOF
 #cat ${cfg}
 
-cat > ${cfgext} << _EOF
+cat > "${cfgext}" << _EOF
 config:
   backup: true
   create: true
@@ -100,62 +79,62 @@ dotfiles:
 profiles:
 _EOF
 
-cat << _EOF > ${func_file}
+cat << _EOF > "${func_file}"
 def func1(something):
   if something:
     return True
   return False
 _EOF
 
-cat << _EOF > ${func_file2}
+cat << _EOF > "${func_file2}"
 def func2(inp):
   return not inp
 _EOF
 
-cat << _EOF > ${func_file3}
+cat << _EOF > "${func_file3}"
 def func3(inp):
   return 42
 _EOF
 
 # create the dotfile
-echo "this is the test dotfile" > ${tmps}/dotfiles/abc
+echo "this is the test dotfile" > "${tmps}"/dotfiles/abc
 
 # test imported function
-echo "{%@@ if func1(True) @@%}" >> ${tmps}/dotfiles/abc
-echo "this should exist" >> ${tmps}/dotfiles/abc
-echo "{%@@ endif @@%}" >> ${tmps}/dotfiles/abc
+echo "{%@@ if func1(True) @@%}" >> "${tmps}"/dotfiles/abc
+echo "this should exist" >> "${tmps}"/dotfiles/abc
+echo "{%@@ endif @@%}" >> "${tmps}"/dotfiles/abc
 
-echo "{%@@ if not func1(False) @@%}" >> ${tmps}/dotfiles/abc
-echo "this should exist too" >> ${tmps}/dotfiles/abc
-echo "{%@@ endif @@%}" >> ${tmps}/dotfiles/abc
+echo "{%@@ if not func1(False) @@%}" >> "${tmps}"/dotfiles/abc
+echo "this should exist too" >> "${tmps}"/dotfiles/abc
+echo "{%@@ endif @@%}" >> "${tmps}"/dotfiles/abc
 
-echo "{%@@ if func2(True) @@%}" >> ${tmps}/dotfiles/abc
-echo "nope" >> ${tmps}/dotfiles/abc
-echo "{%@@ endif @@%}" >> ${tmps}/dotfiles/abc
+echo "{%@@ if func2(True) @@%}" >> "${tmps}"/dotfiles/abc
+echo "nope" >> "${tmps}"/dotfiles/abc
+echo "{%@@ endif @@%}" >> "${tmps}"/dotfiles/abc
 
-echo "{%@@ if func2(False) @@%}" >> ${tmps}/dotfiles/abc
-echo "yes" >> ${tmps}/dotfiles/abc
-echo "{%@@ endif @@%}" >> ${tmps}/dotfiles/abc
+echo "{%@@ if func2(False) @@%}" >> "${tmps}"/dotfiles/abc
+echo "yes" >> "${tmps}"/dotfiles/abc
+echo "{%@@ endif @@%}" >> "${tmps}"/dotfiles/abc
 
-echo "{%@@ if func3("whatever") == 42 @@%}" >> ${tmps}/dotfiles/abc
-echo "externalok" >> ${tmps}/dotfiles/abc
-echo "{%@@ endif @@%}" >> ${tmps}/dotfiles/abc
+echo "{%@@ if func3(\"whatever\") == 42 @@%}" >> "${tmps}"/dotfiles/abc
+echo "externalok" >> "${tmps}"/dotfiles/abc
+echo "{%@@ endif @@%}" >> "${tmps}"/dotfiles/abc
 
-echo "{{@@ func @@}}added" >> ${tmps}/dotfiles/abc
+echo "{{@@ func @@}}added" >> "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 #cat ${tmpd}/abc
 
-grep '^this should exist$' ${tmpd}/abc >/dev/null
-grep '^this should exist too$' ${tmpd}/abc >/dev/null
-grep '^yes$' ${tmpd}/abc >/dev/null
-grep '^externalok$' ${tmpd}/abc >/dev/null
+grep '^this should exist$' "${tmpd}"/abc >/dev/null
+grep '^this should exist too$' "${tmpd}"/abc >/dev/null
+grep '^yes$' "${tmpd}"/abc >/dev/null
+grep '^externalok$' "${tmpd}"/abc >/dev/null
 set +e
-grep '^nope$' ${tmpd}/abc >/dev/null && exit 1
+grep '^nope$' "${tmpd}"/abc >/dev/null && exit 1
 set -e
-grep '^Falseadded$' ${tmpd}/abc >/dev/null
+grep '^Falseadded$' "${tmpd}"/abc >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/global-compare-ignore.sh b/tests-ng/global-compare-ignore.sh
index 7b3da57..4f3bc8e 100755
--- a/tests-ng/global-compare-ignore.sh
+++ b/tests-ng/global-compare-ignore.sh
@@ -6,65 +6,44 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # some files
-mkdir -p ${tmpd}/{program,config}
-touch ${tmpd}/program/a
-touch ${tmpd}/config/a
+mkdir -p "${tmpd}"/{program,config}
+touch "${tmpd}"/program/a
+touch "${tmpd}"/config/a
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -75,36 +54,35 @@ _EOF
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/config
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/program
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/config
 
 # add files
 echo "[+] add files"
-touch ${tmpd}/program/b
-touch ${tmpd}/config/b
+touch "${tmpd}"/program/b
+touch "${tmpd}"/config/b
 
 # adding ignore in dotfile
 cfg2="${basedir}/config2.yaml"
-sed '/dotpath: dotfiles/a \ \ cmpignore:\n\ \ \ \ - "*/config/b"' ${cfg} > ${cfg2}
-cat ${cfg2}
+sed '/dotpath: dotfiles/a \ \ cmpignore:\n\ \ \ \ - "*/config/b"' "${cfg}" > "${cfg2}"
+cat "${cfg2}"
 
 # expects one diff
 echo "[+] comparing with ignore in dotfile - 1 diff"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose
 [ "$?" = "0" ] && exit 1
 set -e
 
 # adding ignore in dotfile
 cfg2="${basedir}/config2.yaml"
-sed '/dotpath: dotfiles/a \ \ cmpignore:\n\ \ \ \ - "*b"' ${cfg} > ${cfg2}
-cat ${cfg2}
+sed '/dotpath: dotfiles/a \ \ cmpignore:\n\ \ \ \ - "*b"' "${cfg}" > "${cfg2}"
+cat "${cfg2}"
 
 # expects no diff
-patt="*b"
 echo "[+] comparing with ignore in dotfile - 0 diff"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose
 [ "$?" != "0" ] && exit 1
 set -e
 
diff --git a/tests-ng/global-compare-negative-ignore.sh b/tests-ng/global-compare-negative-ignore.sh
index 00cf4a7..0c09a34 100755
--- a/tests-ng/global-compare-negative-ignore.sh
+++ b/tests-ng/global-compare-negative-ignore.sh
@@ -5,99 +5,54 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-if [ $(uname) = Darwin ]; then
-  # Unfortunately, readlink works differently on macOS than it does on GNU/Linux
-  # (the -f option behaves differently) and the realpath command does not exist.
-  # Workarounds I find on the Internet suggest just using Homebrew to install coreutils
-  # so you can get the GNU coreutils on your Mac. But, I don't want this script to
-  # assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
-  # they then installed the GNU coreutils.
-  readlink() {
-    TARGET_FILE=$1
-
-    cd `dirname $TARGET_FILE`
-    TARGET_FILE=`basename $TARGET_FILE`
-
-    # Iterate down a (possible) chain of symlinks
-    while [ -L "$TARGET_FILE" ]; do
-      TARGET_FILE=`readlink $TARGET_FILE`
-      cd `dirname $TARGET_FILE`
-      TARGET_FILE=`basename $TARGET_FILE`
-    done
-
-    # Compute the canonicalized name by finding the physical path
-    # for the directory we're in and appending the target file.
-    PHYS_DIR=`pwd -P`
-    RESULT=$PHYS_DIR/$TARGET_FILE
-    echo $RESULT
-  }
-  rl="readlink"
-else
-  rl="readlink -f"
-  if ! ${rl} "${0}" >/dev/null 2>&1; then
-    rl="realpath"
-
-    if ! hash ${rl}; then
-      echo "\"${rl}\" not found !" && exit 1
-    fi
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ -n "${1}" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"{ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # some files
-mkdir -p ${tmpd}/{program,config}
-touch ${tmpd}/program/a
-touch ${tmpd}/config/a
+mkdir -p "${tmpd}"/{program,config}
+touch "${tmpd}"/program/a
+touch "${tmpd}"/config/a
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/config
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/program
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/config
 
 # add files
 echo "[+] add files"
-touch ${tmpd}/program/b
-touch ${tmpd}/config/b
+touch "${tmpd}"/program/b
+touch "${tmpd}"/config/b
 
 # adding ignore in dotfile
 cfg2="${basedir}/config2.yaml"
@@ -105,13 +60,13 @@ sed '/dotpath: dotfiles/a\
 \ \ cmpignore:\
 \ \ \ \ - "*/config/*"\
 \ \ \ \ - "!*/config/a"\
-' ${cfg} > ${cfg2}
-cat ${cfg2}
+' "${cfg}" > "${cfg2}"
+cat "${cfg2}"
 
 # expects one diff
 echo "[+] comparing with ignore in dotfile - 1 diff"
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose
+cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose
 [ "$?" = "0" ] && exit 1
 set -e
 
diff --git a/tests-ng/global-update-ignore.sh b/tests-ng/global-update-ignore.sh
index 60e18c0..48856f2 100755
--- a/tests-ng/global-update-ignore.sh
+++ b/tests-ng/global-update-ignore.sh
@@ -6,64 +6,43 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 dt="${tmps}/dotfiles"
-mkdir -p ${dt}
-mkdir -p ${dt}/a/{b,c}
-echo 'a' > ${dt}/a/b/abfile
-echo 'a' > ${dt}/a/c/acfile
+mkdir -p "${dt}"
+mkdir -p "${dt}"/a/{b,c}
+echo 'a' > "${dt}"/a/b/abfile
+echo 'a' > "${dt}"/a/c/acfile
 
 # fs dotfiles
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-cp -r ${dt}/a ${tmpd}/
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+cp -r "${dt}"/a "${tmpd}"/
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -87,25 +66,25 @@ _EOF
 
 # edit/add files
 echo "[+] edit/add files"
-touch ${tmpd}/a/newfile
-echo 'b' > ${tmpd}/a/c/acfile
-mkdir -p ${tmpd}/a/newdir/b
-touch ${tmpd}/a/newdir/b/c
+touch "${tmpd}"/a/newfile
+echo 'b' > "${tmpd}"/a/c/acfile
+mkdir -p "${tmpd}"/a/newdir/b
+touch "${tmpd}"/a/newdir/b/c
 
 #tree ${tmpd}/a
 
 # update
 echo "[+] update"
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key f_abc
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=p1 --key f_abc
 
 #tree ${dt}
 
 # check files haven't been updated
-[ ! -e ${dt}/a/c/acfile ] && echo "acfile not found" && exit 1
+[ ! -e "${dt}"/a/c/acfile ] && echo "acfile not found" && exit 1
 set +e
-grep 'b' ${dt}/a/c/acfile || (echo "acfile not updated" && exit 1)
+grep 'b' "${dt}"/a/c/acfile || (echo "acfile not updated" && exit 1)
 set -e
-[ -e ${dt}/a/newfile ] && echo "newfile found" && exit 1
+[ -e "${dt}"/a/newfile ] && echo "newfile found" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/global-update-negative-ignore.sh b/tests-ng/global-update-negative-ignore.sh
index 5afa67d..14793e1 100755
--- a/tests-ng/global-update-negative-ignore.sh
+++ b/tests-ng/global-update-negative-ignore.sh
@@ -5,90 +5,45 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-if [ $(uname) = Darwin ]; then
-  # Unfortunately, readlink works differently on macOS than it does on GNU/Linux
-  # (the -f option behaves differently) and the realpath command does not exist.
-  # Workarounds I find on the Internet suggest just using Homebrew to install coreutils
-  # so you can get the GNU coreutils on your Mac. But, I don't want this script to
-  # assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
-  # they then installed the GNU coreutils.
-  readlink() {
-    TARGET_FILE=$1
-
-    cd `dirname $TARGET_FILE`
-    TARGET_FILE=`basename $TARGET_FILE`
-
-    # Iterate down a (possible) chain of symlinks
-    while [ -L "$TARGET_FILE" ]; do
-      TARGET_FILE=`readlink $TARGET_FILE`
-      cd `dirname $TARGET_FILE`
-      TARGET_FILE=`basename $TARGET_FILE`
-    done
-
-    # Compute the canonicalized name by finding the physical path
-    # for the directory we're in and appending the target file.
-    PHYS_DIR=`pwd -P`
-    RESULT=$PHYS_DIR/$TARGET_FILE
-    echo $RESULT
-  }
-  rl="readlink"
-else
-  rl="readlink -f"
-  if ! ${rl} "${0}" >/dev/null 2>&1; then
-    rl="realpath"
-
-    if ! hash ${rl}; then
-      echo "\"${rl}\" not found !" && exit 1
-    fi
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ -n "${1}" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
-mkdir -p ${basedir}/dotfiles/a/{b,c}
-echo 'a' > ${basedir}/dotfiles/a/b/abfile1
-echo 'a' > ${basedir}/dotfiles/a/b/abfile2
-echo 'a' > ${basedir}/dotfiles/a/b/abfile3
-echo 'a' > ${basedir}/dotfiles/a/c/acfile
+mkdir -p "${basedir}"/dotfiles/a/{b,c}
+echo 'a' > "${basedir}"/dotfiles/a/b/abfile1
+echo 'a' > "${basedir}"/dotfiles/a/b/abfile2
+echo 'a' > "${basedir}"/dotfiles/a/b/abfile3
+echo 'a' > "${basedir}"/dotfiles/a/c/acfile
 
 # the dotfile to be updated
-tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
-cp -r ${basedir}/dotfiles/a ${tmpd}/
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
+cp -r "${basedir}"/dotfiles/a "${tmpd}"/
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -110,26 +65,26 @@ _EOF
 
 # edit/add files
 echo "[+] edit/add files"
-mkdir -p ${tmpd}/a/newdir/b
-echo 'b' > ${tmpd}/a/b/abfile1
-echo 'b' > ${tmpd}/a/b/abfile2
-echo 'b' > ${tmpd}/a/b/abfile3
-echo 'b' > ${tmpd}/a/b/abfile4
-touch ${tmpd}/a/newdir/b/{c,d}
+mkdir -p "${tmpd}"/a/newdir/b
+echo 'b' > "${tmpd}"/a/b/abfile1
+echo 'b' > "${tmpd}"/a/b/abfile2
+echo 'b' > "${tmpd}"/a/b/abfile3
+echo 'b' > "${tmpd}"/a/b/abfile4
+touch "${tmpd}"/a/newdir/b/{c,d}
 
 # update
 echo "[+] update"
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key f_abc
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=p1 --key f_abc
 
 # check files haven't been updated
 set +e
-grep 'a' ${basedir}/dotfiles/a/b/abfile1 >/dev/null 2>&1 || (echo "abfile1 should not have been updated" && exit 1)
-grep 'a' ${basedir}/dotfiles/a/b/abfile2 >/dev/null 2>&1 || (echo "abfile2 should not have been updated" && exit 1)
-grep 'b' ${basedir}/dotfiles/a/b/abfile3 >/dev/null 2>&1 || (echo "abfile3 was not updated" && exit 1)
+grep 'a' "${basedir}"/dotfiles/a/b/abfile1 >/dev/null 2>&1 || (echo "abfile1 should not have been updated" && exit 1)
+grep 'a' "${basedir}"/dotfiles/a/b/abfile2 >/dev/null 2>&1 || (echo "abfile2 should not have been updated" && exit 1)
+grep 'b' "${basedir}"/dotfiles/a/b/abfile3 >/dev/null 2>&1 || (echo "abfile3 was not updated" && exit 1)
 set -e
-[ -e ${basedir}/dotfiles/a/b/abfile4 ] && echo "abfile4 should not have been updated" && exit 1
-[ -e ${basedir}/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been updated" && exit 1
-[ ! -e ${basedir}/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been updated" && exit 1
+[ -e "${basedir}"/dotfiles/a/b/abfile4 ] && echo "abfile4 should not have been updated" && exit 1
+[ -e "${basedir}"/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been updated" && exit 1
+[ ! -e "${basedir}"/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been updated" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/globs.sh b/tests-ng/globs.sh
index 5ae60bf..f2d77de 100755
--- a/tests-ng/globs.sh
+++ b/tests-ng/globs.sh
@@ -9,53 +9,32 @@
 # - profile import
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # temporary
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -66,18 +45,18 @@ clear_on_exit "${tmpa}"
 ###########
 # create the action files
 actionsd="${tmps}/actions"
-mkdir -p ${actionsd}
-cat > ${actionsd}/action1.yaml << _EOF
+mkdir -p "${actionsd}"
+cat > "${actionsd}"/action1.yaml << _EOF
 actions:
   fromaction1: echo "fromaction1" > ${tmpa}/fromaction1
 _EOF
-cat > ${actionsd}/action2.yaml << _EOF
+cat > "${actionsd}"/action2.yaml << _EOF
 actions:
   fromaction2: echo "fromaction2" > ${tmpa}/fromaction2
 _EOF
 
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -98,18 +77,18 @@ profiles:
 _EOF
 
 # create the source
-mkdir -p ${tmps}/dotfiles/
-echo "abc" > ${tmps}/dotfiles/abc
+mkdir -p "${tmps}"/dotfiles/
+echo "abc" > "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p1 -V
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 -V
 
 # checks
-[ ! -e ${tmpd}/abc ] && echo "dotfile not installed" && exit 1
-[ ! -e  ${tmpa}/fromaction1 ] && echo "action1 not executed" && exit 1
-grep fromaction1 ${tmpa}/fromaction1
-[ ! -e  ${tmpa}/fromaction2 ] && echo "action2 not executed" && exit 1
-grep fromaction2 ${tmpa}/fromaction2
+[ ! -e "${tmpd}"/abc ] && echo "dotfile not installed" && exit 1
+[ ! -e  "${tmpa}"/fromaction1 ] && echo "action1 not executed" && exit 1
+grep fromaction1 "${tmpa}"/fromaction1
+[ ! -e  "${tmpa}"/fromaction2 ] && echo "action2 not executed" && exit 1
+grep fromaction2 "${tmpa}"/fromaction2
 
 echo "OK"
 exit 0
diff --git a/tests-ng/header.sh b/tests-ng/header.sh
index bd0ae5b..6cc5278 100755
--- a/tests-ng/header.sh
+++ b/tests-ng/header.sh
@@ -6,52 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 #echo "dotfile source: ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -60,7 +39,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -77,17 +56,17 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "{{@@ header() @@}}" > ${tmps}/dotfiles/abc
-echo "{{@@ header('# ') @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ header('// ') @@}}" >> ${tmps}/dotfiles/abc
-echo "test" >> ${tmps}/dotfiles/abc
+echo "{{@@ header() @@}}" > "${tmps}"/dotfiles/abc
+echo "{{@@ header('# ') @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ header('// ') @@}}" >> "${tmps}"/dotfiles/abc
+echo "test" >> "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1
 
-grep '^This dotfile is managed using dotdrop' ${tmpd}/abc >/dev/null
-grep '^# This dotfile is managed using dotdrop' ${tmpd}/abc >/dev/null
-grep '^// This dotfile is managed using dotdrop' ${tmpd}/abc >/dev/null
+grep '^This dotfile is managed using dotdrop' "${tmpd}"/abc >/dev/null
+grep '^# This dotfile is managed using dotdrop' "${tmpd}"/abc >/dev/null
+grep '^// This dotfile is managed using dotdrop' "${tmpd}"/abc >/dev/null
 
 #cat ${tmpd}/abc
 
diff --git a/tests-ng/helpers b/tests-ng/helpers
index 2876dfd..c7180da 100644
--- a/tests-ng/helpers
+++ b/tests-ng/helpers
@@ -1,3 +1,4 @@
+# shellcheck disable=SC2148
 # author: deadc0de6 (https://github.com/deadc0de6)
 # Copyright (c) 2017, deadc0de6
 #
@@ -14,6 +15,7 @@ declare -a to_be_cleared
 clear_on_exit()
 {
   local len="${#to_be_cleared[*]}"
+  # shellcheck disable=SC2004
   to_be_cleared[${len}]="$1"
   if [ "${len}" = "0" ]; then
     # set trap
@@ -37,14 +39,16 @@ on_exit()
 create_dir()
 {
   dirs="a/aa a/ab a/ac b/ba c"
-  mkdir -p ${1}
+  mkdir -p "${1}"
   for d in ${dirs}; do
     # create some dirs
-    mkdir -p ${1}/${d}
+    mkdir -p "${1}"/"${d}"
     # create some files
-    fn=`echo ${d} | sed 's#/#-#g'`
+    # shellcheck disable=SC2001
+    fn=$(echo "${d}" | sed 's#/#-#g')
     f="${1}/${d}/${fn}"
-    echo "${d}" > ${f}
+    echo "${d}" > "${f}"
+    # shellcheck disable=SC2034
     token=${f}
   done
 }
@@ -54,7 +58,7 @@ create_dir()
 # $1: path to save to
 create_conf()
 {
-  cat > ${1} << _EOF
+  cat > "${1}" << _EOF
 config:
   backup: true
   create: true
diff --git a/tests-ng/ignore-empty.sh b/tests-ng/ignore-empty.sh
index 8e265ef..6670289 100755
--- a/tests-ng/ignore-empty.sh
+++ b/tests-ng/ignore-empty.sh
@@ -6,52 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 #echo "dotfile source: ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -61,7 +40,7 @@ clear_on_exit "${tmpd}"
 cfg="${tmps}/config.yaml"
 
 # globally
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -79,19 +58,19 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-mkdir -p ${tmps}/dotfiles/d1
-echo "{#@@ should be stripped @@#}" > ${tmps}/dotfiles/d1/empty
-echo "not empty" > ${tmps}/dotfiles/d1/notempty
+mkdir -p "${tmps}"/dotfiles/d1
+echo "{#@@ should be stripped @@#}" > "${tmps}"/dotfiles/d1/empty
+echo "not empty" > "${tmps}"/dotfiles/d1/notempty
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # test existence
-[ -e ${tmpd}/d1/empty ] && echo 'empty should not exist' && exit 1
-[ ! -e ${tmpd}/d1/notempty ] && echo 'not empty should exist' && exit 1
+[ -e "${tmpd}"/d1/empty ] && echo 'empty should not exist' && exit 1
+[ ! -e "${tmpd}"/d1/notempty ] && echo 'not empty should exist' && exit 1
 
 # through the dotfile
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -110,14 +89,14 @@ _EOF
 #cat ${cfg}
 
 # clean destination
-rm -rf ${tmpd}/*
+rm -rf "${tmpd:?}"/*
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # test existence
-[ -e ${tmpd}/d1/empty ] && echo 'empty should not exist' && exit 1
-[ ! -e ${tmpd}/d1/notempty ] && echo 'not empty should exist' && exit 1
+[ -e "${tmpd}"/d1/empty ] && echo 'empty should not exist' && exit 1
+[ ! -e "${tmpd}"/d1/notempty ] && echo 'not empty should exist' && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/import-as.sh b/tests-ng/import-as.sh
index c1ca48f..e12c362 100755
--- a/tests-ng/import-as.sh
+++ b/tests-ng/import-as.sh
@@ -5,68 +5,47 @@
 # test basic import
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
-clear_on_exit "~/.dotdrop.test"
-clear_on_exit "~/.dotdrop-dotfiles-test"
+clear_on_exit "${HOME}/.dotdrop.test"
+clear_on_exit "${HOME}/.dotdrop-dotfiles-test"
 
 # create the dotfile
-mkdir -p ${tmpd}/adir
-echo "adir/file1" > ${tmpd}/adir/file1
-echo "adir/fil2" > ${tmpd}/adir/file2
-echo "file3" > ${tmpd}/file3
+mkdir -p "${tmpd}"/adir
+echo "adir/file1" > "${tmpd}"/adir/file1
+echo "adir/fil2" > "${tmpd}"/adir/file2
+echo "file3" > "${tmpd}"/file3
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -77,47 +56,47 @@ _EOF
 #cat ${cfg}
 
 # import
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/adir
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/file3
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/adir
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/file3
 
 echo "import --as dotfiles"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p2 -V ${tmpd}/adir --as ~/config/adir
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p2 -V ${tmpd}/file3 --as ~/config2/file3
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p2 -V "${tmpd}"/adir --as ~/config/adir
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p2 -V "${tmpd}"/file3 --as ~/config2/file3
 
-cat ${cfg}
+cat "${cfg}"
 
 set +e
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p2 -V ${tmpd}/adir --as ~/config/should_not && echo "dual dst imported" && exit 1
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p2 -V "${tmpd}"/adir --as ~/config/should_not && echo "dual dst imported" && exit 1
 set -e
-cat ${cfg} | grep should_not && echo "dual dst imported" && exit 1
+cat "${cfg}" | grep should_not && echo "dual dst imported" && exit 1
 
-cat ${cfg}
+cat "${cfg}"
 
 echo "ensure exists and is not link"
-[ ! -d ${tmps}/dotfiles/${tmpd}/adir ] && echo "not a directory" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/adir/file1 ] && echo "not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/adir/file2 ] && echo "not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/file3 ] && echo "not a file" && exit 1
+[ ! -d "${tmps}"/dotfiles/"${tmpd}"/adir ] && echo "not a directory" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/adir/file1 ] && echo "not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/adir/file2 ] && echo "not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/file3 ] && echo "not a file" && exit 1
 
 echo "ensure --as are correctly imported"
-[ ! -d ${tmps}/dotfiles/config/adir ] && echo "not a directory" && exit 1
-[ ! -e ${tmps}/dotfiles/config/adir/file1 ] && echo "not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/config/adir/file2 ] && echo "not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/config2/file3 ] && echo "not a file" && exit 1
+[ ! -d "${tmps}"/dotfiles/config/adir ] && echo "not a directory" && exit 1
+[ ! -e "${tmps}"/dotfiles/config/adir/file1 ] && echo "not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/config/adir/file2 ] && echo "not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/config2/file3 ] && echo "not a file" && exit 1
 
-cat ${cfg} | grep ${tmpd}/adir >/dev/null 2>&1
-cat ${cfg} | grep ${tmpd}/file3 >/dev/null 2>&1
+cat "${cfg}" | grep "${tmpd}"/adir >/dev/null 2>&1
+cat "${cfg}" | grep "${tmpd}"/file3 >/dev/null 2>&1
 
-cat ${cfg} | grep config/adir >/dev/null 2>&1
-cat ${cfg} | grep config2/file3 >/dev/null 2>&1
+cat "${cfg}" | grep config/adir >/dev/null 2>&1
+cat "${cfg}" | grep config2/file3 >/dev/null 2>&1
 
-nb=`cat ${cfg} | grep d_adir | wc -l`
+nb=$(cat "${cfg}" | grep d_adir | wc -l)
 [ "${nb}" != "2" ] && echo 'bad config1' && exit 1
-nb=`cat ${cfg} | grep f_file3 | wc -l`
+nb=$(cat "${cfg}" | grep f_file3 | wc -l)
 [ "${nb}" != "2" ] && echo 'bad config2' && exit 1
 
-cat ${cfg} | grep "src: config/adir" || exit 1
-cat ${cfg} | grep "src: config2/file3" || exit 1
+cat "${cfg}" | grep "src: config/adir" || exit 1
+cat "${cfg}" | grep "src: config2/file3" || exit 1
 
 # test import from sub in home
 mkdir -p ~/.dotdrop-dotfiles-test/{dotfiles,config}
@@ -137,11 +116,11 @@ dotfiles:
 profiles:
 _EOF
 
-cd ${ddpath} | ${bin} import -f -b -c ${cfg} -p test -V ~/.dotdrop.test --as=~/.whatever
+cd "${ddpath}" | ${bin} import -f -b -c ${cfg} -p test -V ~/.dotdrop.test --as=~/.whatever
 #cat ${cfg}
 
 [ ! -e ~/.dotdrop-dotfiles-test/dotfiles/whatever ] && echo 'tild imported' && exit 1
-cat ${cfg} | grep '~/.whatever' && echo 'import with tild failed' && exit 1
+cat ${cfg} | grep "${HOME}/.whatever" && echo 'import with tild failed' && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/import-configs.sh b/tests-ng/import-configs.sh
index b81c39e..4b4f829 100755
--- a/tests-ng/import-configs.sh
+++ b/tests-ng/import-configs.sh
@@ -5,52 +5,31 @@
 # import config testing
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles-other
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles-other
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -59,7 +38,7 @@ clear_on_exit "${tmpd}"
 cfg1="${tmps}/config1.yaml"
 cfg2="${tmps}/config2.yaml"
 
-cat > ${cfg1} << _EOF
+cat > "${cfg1}" << _EOF
 config:
   backup: true
   create: true
@@ -91,7 +70,7 @@ profiles:
     - psubsub
 _EOF
 
-cat > ${cfg2} << _EOF
+cat > "${cfg2}" << _EOF
 config:
   backup: true
   create: true
@@ -117,47 +96,47 @@ profiles:
 _EOF
 
 # create the source
-mkdir -p ${tmps}/dotfiles/
-echo "abc" > ${tmps}/dotfiles/abc
-echo "{{@@ _dotfile_abs_dst @@}}" >> ${tmps}/dotfiles/abc
+mkdir -p "${tmps}"/dotfiles/
+echo "abc" > "${tmps}"/dotfiles/abc
+echo "{{@@ _dotfile_abs_dst @@}}" >> "${tmps}"/dotfiles/abc
 
-echo "def" > ${tmps}/dotfiles-other/def
-echo "{{@@ _dotfile_abs_dst @@}}" >> ${tmps}/dotfiles-other/def
+echo "def" > "${tmps}"/dotfiles-other/def
+echo "{{@@ _dotfile_abs_dst @@}}" >> "${tmps}"/dotfiles-other/def
 
-echo "ghi" > ${tmps}/dotfiles-other/ghi
-echo "{{@@ _dotfile_abs_dst @@}}" >> ${tmps}/dotfiles-other/ghi
+echo "ghi" > "${tmps}"/dotfiles-other/ghi
+echo "{{@@ _dotfile_abs_dst @@}}" >> "${tmps}"/dotfiles-other/ghi
 
-echo "zzz" > ${tmps}/dotfiles/zzz
-echo "{{@@ _dotfile_abs_dst @@}}" >> ${tmps}/dotfiles/zzz
+echo "zzz" > "${tmps}"/dotfiles/zzz
+echo "{{@@ _dotfile_abs_dst @@}}" >> "${tmps}"/dotfiles/zzz
 
-echo "sub" > ${tmps}/dotfiles/sub
-echo "{{@@ _dotfile_abs_dst @@}}" >> ${tmps}/dotfiles/sub
+echo "sub" > "${tmps}"/dotfiles/sub
+echo "{{@@ _dotfile_abs_dst @@}}" >> "${tmps}"/dotfiles/sub
 
-mkdir -p ${tmps}/dotfiles-other/subdir/sub
-echo "subsub" > ${tmps}/dotfiles-other/subdir/sub/asub
-echo "{{@@ _dotfile_abs_dst @@}}" >> ${tmps}/dotfiles-other/subdir/sub/asub
+mkdir -p "${tmps}"/dotfiles-other/subdir/sub
+echo "subsub" > "${tmps}"/dotfiles-other/subdir/sub/asub
+echo "{{@@ _dotfile_abs_dst @@}}" >> "${tmps}"/dotfiles-other/subdir/sub/asub
 
 # files comparison
-cd ${ddpath} | ${bin} files -c ${cfg1} -G -p p0 | grep '^f_def'
-cd ${ddpath} | ${bin} files -c ${cfg1} -G -p p1 | grep '^f_abc'
-cd ${ddpath} | ${bin} files -c ${cfg1} -G -p p2 | grep '^f_def'
-cd ${ddpath} | ${bin} files -c ${cfg1} -G -p p3 | grep '^f_zzz'
-cd ${ddpath} | ${bin} files -c ${cfg1} -G -p pup | grep '^f_sub'
-cd ${ddpath} | ${bin} files -c ${cfg1} -G -p psubsub | grep '^f_sub'
+cd "${ddpath}" | ${bin} files -c "${cfg1}" -G -p p0 | grep '^f_def'
+cd "${ddpath}" | ${bin} files -c "${cfg1}" -G -p p1 | grep '^f_abc'
+cd "${ddpath}" | ${bin} files -c "${cfg1}" -G -p p2 | grep '^f_def'
+cd "${ddpath}" | ${bin} files -c "${cfg1}" -G -p p3 | grep '^f_zzz'
+cd "${ddpath}" | ${bin} files -c "${cfg1}" -G -p pup | grep '^f_sub'
+cd "${ddpath}" | ${bin} files -c "${cfg1}" -G -p psubsub | grep '^f_sub'
 
 # test compare too
-cd ${ddpath} | ${bin} install -c ${cfg1} -p p2 -V -f
-cd ${ddpath} | ${bin} compare -c ${cfg1} -p p2 -V
+cd "${ddpath}" | ${bin} install -c "${cfg1}" -p p2 -V -f
+cd "${ddpath}" | ${bin} compare -c "${cfg1}" -p p2 -V
 
-[ ! -s ${tmpd}/def ] && echo "def not installed" && exit 1
-[ ! -s ${tmpd}/subdir/sub/asub ] && echo "asub not installed" && exit 1
+[ ! -s "${tmpd}"/def ] && echo "def not installed" && exit 1
+[ ! -s "${tmpd}"/subdir/sub/asub ] && echo "asub not installed" && exit 1
 
 # test with non-existing dotpath this time
 
-rm -rf ${tmps}/dotfiles
-rm -rf ${tmpd}/*
+rm -rf "${tmps}"/dotfiles
+rm -rf "${tmpd:?}"/*
 
-cat > ${cfg1} << _EOF
+cat > "${cfg1}" << _EOF
 config:
   backup: true
   create: true
@@ -167,7 +146,7 @@ config:
 dotfiles:
 profiles:
 _EOF
-cat > ${cfg2} << _EOF
+cat > "${cfg2}" << _EOF
 config:
   backup: true
   create: true
@@ -182,14 +161,14 @@ profiles:
     - f_asub
 _EOF
 
-cd ${ddpath} | ${bin} install -c ${cfg1} -p p2 -V -f
-cd ${ddpath} | ${bin} compare -c ${cfg1} -p p2 -V
+cd "${ddpath}" | ${bin} install -c "${cfg1}" -p p2 -V -f
+cd "${ddpath}" | ${bin} compare -c "${cfg1}" -p p2 -V
 
 # test with same profile defined in both
-rm -rf ${tmps}/dotfiles
-rm -rf ${tmpd}/*
+rm -rf "${tmps}"/dotfiles
+rm -rf "${tmpd:?}"/*
 
-cat > ${cfg1} << _EOF
+cat > "${cfg1}" << _EOF
 config:
   backup: true
   create: true
@@ -205,7 +184,7 @@ profiles:
     dotfiles:
     - f_abc
 _EOF
-cat > ${cfg2} << _EOF
+cat > "${cfg2}" << _EOF
 config:
   backup: true
   create: true
@@ -221,30 +200,30 @@ profiles:
 _EOF
 
 # create the source
-mkdir -p ${tmps}/dotfiles/
+mkdir -p "${tmps}"/dotfiles/
 
-echo "abc" > ${tmps}/dotfiles/abc
-echo "{{@@ _dotfile_abs_dst @@}}" >> ${tmps}/dotfiles/abc
-rm -f ${tmpd}/abc
+echo "abc" > "${tmps}"/dotfiles/abc
+echo "{{@@ _dotfile_abs_dst @@}}" >> "${tmps}"/dotfiles/abc
+rm -f "${tmpd}"/abc
 
-echo "def" > ${tmps}/dotfiles/def
-echo "{{@@ _dotfile_abs_dst @@}}" >> ${tmps}/dotfiles/def
-rm -f ${tmpd}/def
+echo "def" > "${tmps}"/dotfiles/def
+echo "{{@@ _dotfile_abs_dst @@}}" >> "${tmps}"/dotfiles/def
+rm -f "${tmpd}"/def
 
 # files listing
 echo "file listing"
-cd ${ddpath} | ${bin} files -c ${cfg1} -p p1 -G | grep '^f_abc'
-cd ${ddpath} | ${bin} files -c ${cfg1} -p p1 -G | grep '^f_def'
+cd "${ddpath}" | ${bin} files -c "${cfg1}" -p p1 -G | grep '^f_abc'
+cd "${ddpath}" | ${bin} files -c "${cfg1}" -p p1 -G | grep '^f_def'
 
 # install and compare
 echo "installing ..."
-cd ${ddpath} | ${bin} install -c ${cfg1} -p p1 -V -f
+cd "${ddpath}" | ${bin} install -c "${cfg1}" -p p1 -V -f
 echo "comparing ..."
-cd ${ddpath} | ${bin} compare -c ${cfg1} -p p1 -V
+cd "${ddpath}" | ${bin} compare -c "${cfg1}" -p p1 -V
 
 # check exists
-[ ! -s ${tmpd}/abc ] && echo "(same) abc not installed" && exit 1
-[ ! -s ${tmpd}/def ] && echo "(same) def not installed" && exit 1
+[ ! -s "${tmpd}"/abc ] && echo "(same) abc not installed" && exit 1
+[ ! -s "${tmpd}"/def ] && echo "(same) def not installed" && exit 1
 
 
 echo "OK"
diff --git a/tests-ng/import-configs2.sh b/tests-ng/import-configs2.sh
index 24ca4c0..215bad3 100755
--- a/tests-ng/import-configs2.sh
+++ b/tests-ng/import-configs2.sh
@@ -5,63 +5,42 @@
 # import config testing
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile sources
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 first="${tmps}/first"
 second="${tmps}/second"
-mkdir -p ${first} ${second}
+mkdir -p "${first}" "${second}"
 
 # create the config file
 cfg1="${first}/config.yaml"
 cfg2="${second}/config.yaml"
 
-cat > ${cfg1} << _EOF
+cat > "${cfg1}" << _EOF
 config:
   backup: true
   create: true
@@ -80,7 +59,7 @@ profiles:
     - f_abc
 _EOF
 
-cat > ${cfg2} << _EOF
+cat > "${cfg2}" << _EOF
 config:
   backup: true
   create: true
@@ -96,24 +75,24 @@ profiles:
 _EOF
 
 # create the source
-echo "abc" > ${first}/abc
-echo "{{@@ _dotfile_abs_dst @@}}" >> ${first}/abc
+echo "abc" > "${first}"/abc
+echo "{{@@ _dotfile_abs_dst @@}}" >> "${first}"/abc
 
-echo "def" > ${second}/def
-echo "{{@@ _dotfile_abs_dst @@}}" >> ${second}/def
+echo "def" > "${second}"/def
+echo "{{@@ _dotfile_abs_dst @@}}" >> "${second}"/def
 
 # files comparison
-cd ${ddpath} | ${bin} files -c ${cfg1} -G -p p0 | grep '^f_abc'
-cd ${ddpath} | ${bin} files -c ${cfg1} -G -p p0 | grep '^f_def'
-cd ${ddpath} | ${bin} files -c ${cfg1} -G -p p1 | grep '^f_def'
-cd ${ddpath} | ${bin} files -c ${cfg2} -G -p p1 | grep '^f_def'
+cd "${ddpath}" | ${bin} files -c "${cfg1}" -G -p p0 | grep '^f_abc'
+cd "${ddpath}" | ${bin} files -c "${cfg1}" -G -p p0 | grep '^f_def'
+cd "${ddpath}" | ${bin} files -c "${cfg1}" -G -p p1 | grep '^f_def'
+cd "${ddpath}" | ${bin} files -c "${cfg2}" -G -p p1 | grep '^f_def'
 
 # test compare too
-cd ${ddpath} | ${bin} install -c ${cfg1} -p p0 -V -f
-cd ${ddpath} | ${bin} compare -c ${cfg1} -p p0 -V
+cd "${ddpath}" | ${bin} install -c "${cfg1}" -p p0 -V -f
+cd "${ddpath}" | ${bin} compare -c "${cfg1}" -p p0 -V
 
-[ ! -s ${tmpd}/abc ] && echo "abc not installed" && exit 1
-[ ! -s ${tmpd}/def ] && echo "def not installed" && exit 1
+[ ! -s "${tmpd}"/abc ] && echo "abc not installed" && exit 1
+[ ! -s "${tmpd}"/def ] && echo "def not installed" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/import-duplicate.sh b/tests-ng/import-duplicate.sh
index 4950334..dedcfff 100755
--- a/tests-ng/import-duplicate.sh
+++ b/tests-ng/import-duplicate.sh
@@ -5,65 +5,44 @@
 # test import duplicates
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the dotfile
-touch ${tmpd}/.colors
-mkdir -p ${tmpd}/.mutt
-touch ${tmpd}/.mutt/colors
+touch "${tmpd}"/.colors
+mkdir -p "${tmpd}"/.mutt
+touch "${tmpd}"/.mutt/colors
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -76,35 +55,35 @@ dotfiles:
   f_mutt_colors:
     src: abc
     dst: abc
-  f_`echo ${tmpd} | sed -e 's#^/\(.*\)$#\1#g' | sed 's#/#_#g' | tr '[:upper:]' '[:lower:]'`_colors:
+  f_$(echo "${tmpd}" | sed -e 's#^/\(.*\)$#\1#g' | sed 's#/#_#g' | tr '[:upper:]' '[:lower:]')_colors:
     src: abc
     dst: abc
-  f_`echo ${tmpd} | sed -e 's#^/tmp/\(.*\)$#\1#g' | sed 's#/#_#g' | tr '[:upper:]' '[:lower:]'`_colors:
+  f_$(echo "${tmpd}" | sed -e 's#^/tmp/\(.*\)$#\1#g' | sed 's#/#_#g' | tr '[:upper:]' '[:lower:]')_colors:
     src: abc
     dst: abc
-  f_`echo ${tmpd} | sed -e 's#^/\(.*\)$#\1#g' | sed 's#/#_#g' | tr '[:upper:]' '[:lower:]'`_mutt_colors:
+  f_$(echo "${tmpd}" | sed -e 's#^/\(.*\)$#\1#g' | sed 's#/#_#g' | tr '[:upper:]' '[:lower:]')_mutt_colors:
     src: abc
     dst: abc
-  f_`echo ${tmpd} | sed -e 's#^/tmp/\(.*\)$#\1#g' | sed 's#/#_#g' | tr '[:upper:]' '[:lower:]'`_mutt_colors:
+  f_$(echo "${tmpd}" | sed -e 's#^/tmp/\(.*\)$#\1#g' | sed 's#/#_#g' | tr '[:upper:]' '[:lower:]')_mutt_colors:
     src: abc
     dst: abc
 profiles:
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
 # import
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/.mutt/colors
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/.colors
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/.mutt/colors
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/.colors
 
-cat ${cfg}
+cat "${cfg}"
 
 # ensure exists and is not link
-[ ! -d ${tmps}/dotfiles/${tmpd}/.mutt ] && echo "not a directory" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/.mutt/colors ] && echo "not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/.colors ] && echo "not exist (2)" && exit 1
+[ ! -d "${tmps}"/dotfiles/"${tmpd}"/.mutt ] && echo "not a directory" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/.mutt/colors ] && echo "not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/.colors ] && echo "not exist (2)" && exit 1
 
-cat ${cfg} | grep ${tmpd}/.mutt/colors >/dev/null 2>&1
-cat ${cfg} | grep ${tmpd}/.colors >/dev/null 2>&1
+cat "${cfg}" | grep "${tmpd}"/.mutt/colors >/dev/null 2>&1
+cat "${cfg}" | grep "${tmpd}"/.colors >/dev/null 2>&1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/import-ignore.sh b/tests-ng/import-ignore.sh
index ea571ef..50be7bf 100755
--- a/tests-ng/import-ignore.sh
+++ b/tests-ng/import-ignore.sh
@@ -6,75 +6,47 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
-# $1 pattern
-# $2 path
-grep_or_fail()
-{
-  grep "${1}" "${2}" >/dev/null 2>&1 || (echo "pattern not found in ${2}" && exit 1)
-}
-
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmpd}
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmpd}"
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # dotdrop directory
-mkdir -p ${tmpd}/a/{b,c}
-echo 'a' > ${tmpd}/a/b/abfile
-echo 'a' > ${tmpd}/a/c/acfile
-echo 'a' > ${tmpd}/a/b/newfile
-mkdir -p ${tmpd}/a/newdir
-echo 'a' > ${tmpd}/a/newdir/newfile
+mkdir -p "${tmpd}"/a/{b,c}
+echo 'a' > "${tmpd}"/a/b/abfile
+echo 'a' > "${tmpd}"/a/c/acfile
+echo 'a' > "${tmpd}"/a/b/newfile
+mkdir -p "${tmpd}"/a/newdir
+echo 'a' > "${tmpd}"/a/newdir/newfile
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -90,11 +62,11 @@ _EOF
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -c ${cfg} -f --verbose --profile=p1 ${tmpd}/a
+cd "${ddpath}" | ${bin} import -c "${cfg}" -f --verbose --profile=p1 "${tmpd}"/a
 
-[ -d ${tmps}/dotfiles/newdir ] && echo "newdir not ignored" && exit 1
-[ -e ${tmps}/dotfiles/newdir/newfile ] && echo "newfile not ignored" && exit 1
-[ -e ${tmps}/dotfiles/a/b/newfile ] && echo "newfile not ignored" && exit 1
+[ -d "${tmps}"/dotfiles/newdir ] && echo "newdir not ignored" && exit 1
+[ -e "${tmps}"/dotfiles/newdir/newfile ] && echo "newfile not ignored" && exit 1
+[ -e "${tmps}"/dotfiles/a/b/newfile ] && echo "newfile not ignored" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/import-include.sh b/tests-ng/import-include.sh
index 0d0c2c4..76a6cc9 100755
--- a/tests-ng/import-include.sh
+++ b/tests-ng/import-include.sh
@@ -5,65 +5,44 @@
 # test import in profile which includes another
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the dotfile to import
-echo "file" > ${tmpd}/file
+echo "file" > "${tmpd}"/file
 
 # create the dotfiles already imported
-echo "already in" > ${tmps}/dotfiles/abc
+echo "already in" > "${tmps}"/dotfiles/abc
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -80,22 +59,22 @@ profiles:
     dotfiles:
     - f_abc
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
-cnt=`cd ${ddpath} | ${bin} files -c ${cfg} -p p0 | grep '^f_' | wc -l`
+cnt=$(cd "${ddpath}" | ${bin} files -c "${cfg}" -p p0 | grep '^f_' | wc -l)
 [ "${cnt}" != "1" ] && echo "this is bad" && exit 1
 
 # import
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p0 --verbose ${tmpd}/file
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p0 --verbose "${tmpd}"/file
 
-[ ! -e ${tmps}/dotfiles/${tmpd}/file ] && echo "file not imported" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/file ] && echo "file not imported" && exit 1
 
 # make sure file is in
-cnt=`cd ${ddpath} | ${bin} files -c ${cfg} -p p0 | grep '^f_file' | wc -l`
+cnt=$(cd "${ddpath}" | ${bin} files -c "${cfg}" -p p0 | grep '^f_file' | wc -l)
 [ "${cnt}" != "1" ] && echo "dotfiles not in config" && exit 1
 
 # count
-cnt=`cd ${ddpath} | ${bin} files -c ${cfg} -p p0 -b | grep '^f_' | wc -l`
+cnt=$(cd "${ddpath}" | ${bin} files -c "${cfg}" -p p0 -b | grep '^f_' | wc -l)
 [ "${cnt}" != "2" ] && echo "not enough dotfile" exit 1
 
 echo "OK"
diff --git a/tests-ng/import-link-children.sh b/tests-ng/import-link-children.sh
index 7eccba5..5cfea67 100755
--- a/tests-ng/import-link-children.sh
+++ b/tests-ng/import-link-children.sh
@@ -6,80 +6,59 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # dotpath
 dotpath="${tmps}/dotfiles"
-mkdir -p ${dotpath}
+mkdir -p "${dotpath}"
 
 # create the dotfile to import
 dt="${tmpd}/directory"
-mkdir -p ${dt}
+mkdir -p "${dt}"
 # subdir
 dtsub1="${dt}/sub1"
-mkdir -p ${dtsub1}
+mkdir -p "${dtsub1}"
 dtsub2="${dt}/sub2"
-mkdir -p ${dtsub2}
+mkdir -p "${dtsub2}"
 dtsub3="${dtsub1}/subsub1"
-mkdir -p ${dtsub3}
+mkdir -p "${dtsub3}"
 # files
 f1="${dt}/file"
 subf1="${dtsub1}/file"
 subf2="${dtsub2}/file"
 subf3="${dtsub3}/file"
-touch ${f1} ${subf1} ${subf2} ${subf3}
+touch "${f1}" "${subf1}" "${subf2}" "${subf3}"
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -89,42 +68,42 @@ profiles:
 _EOF
 
 # import
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V --link=link_children ${dt}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V --link=link_children "${dt}"
 
 # check is set to link_children
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "d_`basename ${dt}`" | grep ',link:link_children,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "d_$(basename "${dt}")" | grep ',link:link_children,'
 
 # checks file exists in dotpath
-[ ! -e ${dotpath}/${dt} ] && echo "dotfile not imported" && exit 1
-[ ! -e ${dotpath}/${dtsub1} ] && echo "sub1 not found in dotpath" && exit 1
-[ ! -e ${dotpath}/${dtsub2} ] && echo "sub2 not found in dotpath" && exit 1
-[ ! -e ${dotpath}/${dtsub3} ] && echo "sub3 not found in dotpath" && exit 1
-[ ! -e ${dotpath}/${f1} ] && echo "f1 not found in dotpath" && exit 1
-[ ! -e ${dotpath}/${subf1} ] && echo "subf1 not found in dotpath" && exit 1
-[ ! -e ${dotpath}/${subf2} ] && echo "subf2 not found in dotpath" && exit 1
-[ ! -e ${dotpath}/${subf3} ] && echo "subf3 not found in dotpath" && exit 1
+[ ! -e "${dotpath}"/"${dt}" ] && echo "dotfile not imported" && exit 1
+[ ! -e "${dotpath}"/"${dtsub1}" ] && echo "sub1 not found in dotpath" && exit 1
+[ ! -e "${dotpath}"/"${dtsub2}" ] && echo "sub2 not found in dotpath" && exit 1
+[ ! -e "${dotpath}"/"${dtsub3}" ] && echo "sub3 not found in dotpath" && exit 1
+[ ! -e "${dotpath}"/"${f1}" ] && echo "f1 not found in dotpath" && exit 1
+[ ! -e "${dotpath}"/"${subf1}" ] && echo "subf1 not found in dotpath" && exit 1
+[ ! -e "${dotpath}"/"${subf2}" ] && echo "subf2 not found in dotpath" && exit 1
+[ ! -e "${dotpath}"/"${subf3}" ] && echo "subf3 not found in dotpath" && exit 1
 
 # checks file exists in fs
-[ ! -e ${dt} ] && echo "dotfile not imported" && exit 1
-[ ! -e ${dtsub1} ] && echo "sub1 not found in fs" && exit 1
-[ ! -e ${dtsub2} ] && echo "sub2 not found in fs" && exit 1
-[ ! -e ${dtsub3} ] && echo "sub3 not found in fs" && exit 1
-[ ! -e ${f1} ] && echo "f1 not found in fs" && exit 1
-[ ! -e ${subf1} ] && echo "subf1 not found in fs" && exit 1
-[ ! -e ${subf2} ] && echo "subf2 not found in fs" && exit 1
-[ ! -e ${subf3} ] && echo "subf3 not found in fs" && exit 1
+[ ! -e "${dt}" ] && echo "dotfile not imported" && exit 1
+[ ! -e "${dtsub1}" ] && echo "sub1 not found in fs" && exit 1
+[ ! -e "${dtsub2}" ] && echo "sub2 not found in fs" && exit 1
+[ ! -e "${dtsub3}" ] && echo "sub3 not found in fs" && exit 1
+[ ! -e "${f1}" ] && echo "f1 not found in fs" && exit 1
+[ ! -e "${subf1}" ] && echo "subf1 not found in fs" && exit 1
+[ ! -e "${subf2}" ] && echo "subf2 not found in fs" && exit 1
+[ ! -e "${subf3}" ] && echo "subf3 not found in fs" && exit 1
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks file have correct type in fs
-[ ! -h ${f1} ] && echo "f1 is not a symlink" && exit 1
-[ -h ${subf1} ] && echo "subf1 is not a regular file" && exit 1
-[ -h ${subf2} ] && echo "subf2 is not a regular file" && exit 1
-[ -h ${subf3} ] && echo "subf3 is not a regular file" && exit 1
-[ ! -h ${dtsub1} ] && echo "dtsub1 is not a symlink" && exit 1
-[ ! -h ${dtsub2} ] && echo "dtsub2 is not a symlink" && exit 1
-[ -h ${dtsub3} ] && echo "dtsub3 is not a regular directory" && exit 1
+[ ! -h "${f1}" ] && echo "f1 is not a symlink" && exit 1
+[ -h "${subf1}" ] && echo "subf1 is not a regular file" && exit 1
+[ -h "${subf2}" ] && echo "subf2 is not a regular file" && exit 1
+[ -h "${subf3}" ] && echo "subf3 is not a regular file" && exit 1
+[ ! -h "${dtsub1}" ] && echo "dtsub1 is not a symlink" && exit 1
+[ ! -h "${dtsub2}" ] && echo "dtsub2 is not a symlink" && exit 1
+[ -h "${dtsub3}" ] && echo "dtsub3 is not a regular directory" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/import-negative-ignore.sh b/tests-ng/import-negative-ignore.sh
index ff1c073..d761381 100755
--- a/tests-ng/import-negative-ignore.sh
+++ b/tests-ng/import-negative-ignore.sh
@@ -5,75 +5,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-if [ $(uname) = Darwin ]; then
-  # Unfortunately, readlink works differently on macOS than it does on GNU/Linux
-  # (the -f option behaves differently) and the realpath command does not exist.
-  # Workarounds I find on the Internet suggest just using Homebrew to install coreutils
-  # so you can get the GNU coreutils on your Mac. But, I don't want this script to
-  # assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
-  # they then installed the GNU coreutils.
-  readlink() {
-    TARGET_FILE=$1
-
-    cd `dirname $TARGET_FILE`
-    TARGET_FILE=`basename $TARGET_FILE`
-
-    # Iterate down a (possible) chain of symlinks
-    while [ -L "$TARGET_FILE" ]; do
-      TARGET_FILE=`readlink $TARGET_FILE`
-      cd `dirname $TARGET_FILE`
-      TARGET_FILE=`basename $TARGET_FILE`
-    done
-
-    # Compute the canonicalized name by finding the physical path
-    # for the directory we're in and appending the target file.
-    PHYS_DIR=`pwd -P`
-    RESULT=$PHYS_DIR/$TARGET_FILE
-    echo $RESULT
-  }
-  rl="readlink"
-else
-  rl="readlink -f"
-  if ! ${rl} "${0}" >/dev/null 2>&1; then
-    rl="realpath"
-
-    if ! hash ${rl}; then
-      echo "\"${rl}\" not found !" && exit 1
-    fi
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ -n "${1}" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 # the dotfile source
-basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
-mkdir -p ${basedir}/dotfiles
+basedir=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
+mkdir -p "${basedir}"/dotfiles
 
 # the dotfile destination
-tmpd=`mkdir -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+tmpd=$(mkdir -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
@@ -81,36 +36,36 @@ clear_on_exit "${tmpd}"
 # dotdrop directory
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
-mkdir -p ${tmpd}/a/{b,c}
-echo 'a' > ${tmpd}/a/b/abfile1
-echo 'a' > ${tmpd}/a/b/abfile2
-echo 'a' > ${tmpd}/a/b/abfile3
-echo 'a' > ${tmpd}/a/c/acfile
-mkdir -p ${tmpd}/a/newdir/b
-touch ${tmpd}/a/newdir/b/{c,d}
+mkdir -p "${tmpd}"/a/{b,c}
+echo 'a' > "${tmpd}"/a/b/abfile1
+echo 'a' > "${tmpd}"/a/b/abfile2
+echo 'a' > "${tmpd}"/a/b/abfile3
+echo 'a' > "${tmpd}"/a/c/acfile
+mkdir -p "${tmpd}"/a/newdir/b
+touch "${tmpd}"/a/newdir/b/{c,d}
 
 # create the config file
 cfg="${basedir}/config.yaml"
 cfg2="${basedir}/config2.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 sed '/dotpath: dotfiles/a\
 \ \ impignore:\
 \ \ \ \ - "*/newdir/b/*"\
 \ \ \ \ - "!*/newdir/b/d"\
 \ \ \ \ - "*/abfile?"\
 \ \ \ \ - "!*/abfile3"
-' ${cfg} > ${cfg2}
+' "${cfg}" > "${cfg2}"
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg2} --verbose --profile=p1 ${tmpd}/a --as=~/a
+cd "${ddpath}" | ${bin} import -f -c "${cfg2}" --verbose --profile=p1 "${tmpd}"/a --as=~/a
 
 # check files haven't been imported
-[ -e ${basedir}/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been imported" && exit 1
-[ ! -e ${basedir}/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been imported" && exit 1
-[ -e ${basedir}/dotfiles/a/b/abfile1 ] && echo "abfile1 should not have been imported" && exit 1
-[ -e ${basedir}/dotfiles/a/b/abfile2 ] && echo "abfile2 should not have been imported" && exit 1
-[ ! -e ${basedir}/dotfiles/a/b/abfile3 ] && echo "abfile3 should have been imported" && exit 1
+[ -e "${basedir}"/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been imported" && exit 1
+[ ! -e "${basedir}"/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been imported" && exit 1
+[ -e "${basedir}"/dotfiles/a/b/abfile1 ] && echo "abfile1 should not have been imported" && exit 1
+[ -e "${basedir}"/dotfiles/a/b/abfile2 ] && echo "abfile2 should not have been imported" && exit 1
+[ ! -e "${basedir}"/dotfiles/a/b/abfile3 ] && echo "abfile3 should have been imported" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/import-non-existing.sh b/tests-ng/import-non-existing.sh
index 72b5e83..a9a21d1 100755
--- a/tests-ng/import-non-existing.sh
+++ b/tests-ng/import-non-existing.sh
@@ -5,63 +5,42 @@
 # test import not existing
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the dotfile
-echo "test" > ${tmps}/dotfiles/abc
+echo "test" > "${tmps}"/dotfiles/abc
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -90,9 +69,9 @@ _EOF
 #cat ${cfg}
 
 # dummy call
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -111,11 +90,11 @@ _EOF
 
 # dummy call
 set +e
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
 [ "$?" = "0" ] && echo "variables" && exit 1
 set -e
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -134,11 +113,11 @@ _EOF
 
 # dummy call
 set +e
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
 [ "$?" = "0" ] && echo "variables with separator" && exit 1
 set -e
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -157,11 +136,11 @@ _EOF
 
 # dummy call
 set +e
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
 [ "$?" = "0" ] && echo "variables glob" && exit 1
 set -e
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -180,11 +159,11 @@ _EOF
 
 # dummy call
 set +e
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
 [ "$?" = "0" ] && echo "actions" && exit 1
 set -e
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -203,11 +182,11 @@ _EOF
 
 # dummy call
 set +e
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
 [ "$?" = "0" ] && echo "actions with separator" && exit 1
 set -e
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -226,11 +205,11 @@ _EOF
 
 # dummy call
 set +e
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
 [ "$?" = "0" ] && echo "actions glob" && exit 1
 set -e
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -249,11 +228,11 @@ _EOF
 
 # dummy call
 set +e
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
 [ "$?" = "0" ] && echo "configs" && exit 1
 set -e
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -272,11 +251,11 @@ _EOF
 
 # dummy call
 set +e
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
 [ "$?" = "0" ] && echo "configs with separator" && exit 1
 set -e
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -295,7 +274,7 @@ _EOF
 
 # dummy call
 set +e
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
 [ "$?" = "0" ] && echo "configs glob" && exit 1
 set -e
 
diff --git a/tests-ng/import-profile-dotfiles.sh b/tests-ng/import-profile-dotfiles.sh
index bfd6528..212c3f0 100755
--- a/tests-ng/import-profile-dotfiles.sh
+++ b/tests-ng/import-profile-dotfiles.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 extdotfiles="${tmps}/df_p1.yaml"
 
 clear_on_exit "${tmps}"
@@ -62,7 +41,7 @@ dynextdotfiles="${tmps}/ext_${dynextdotfiles_name}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -87,42 +66,42 @@ profiles:
     dotfiles:
     - f_abc
     import:
-    - $(basename ${extdotfiles})
+    - $(basename "${extdotfiles}")
     - "ext_{{@@ d_uid @@}}"
 _EOF
 
 # create the external dotfile file
-cat > ${extdotfiles} << _EOF
+cat > "${extdotfiles}" << _EOF
 dotfiles:
   - f_def
   - f_xyz
 _EOF
 
-cat > ${dynextdotfiles} << _EOF
+cat > "${dynextdotfiles}" << _EOF
 dotfiles:
   - f_dyn
 _EOF
 
 # create the source
-mkdir -p ${tmps}/dotfiles/
-echo "abc" > ${tmps}/dotfiles/abc
-echo "def" > ${tmps}/dotfiles/def
-echo "xyz" > ${tmps}/dotfiles/xyz
-echo "dyn" > ${tmps}/dotfiles/dyn
+mkdir -p "${tmps}"/dotfiles/
+echo "abc" > "${tmps}"/dotfiles/abc
+echo "def" > "${tmps}"/dotfiles/def
+echo "xyz" > "${tmps}"/dotfiles/xyz
+echo "dyn" > "${tmps}"/dotfiles/dyn
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # checks
-[ ! -e ${tmpd}/abc ] && exit 1
-[ ! -e ${tmpd}/def ] && exit 1
-[ ! -e ${tmpd}/xyz ] && exit 1
-[ ! -e ${tmpd}/dyn ] && exit 1
+[ ! -e "${tmpd}"/abc ] && exit 1
+[ ! -e "${tmpd}"/def ] && exit 1
+[ ! -e "${tmpd}"/xyz ] && exit 1
+[ ! -e "${tmpd}"/dyn ] && exit 1
 echo 'file found'
-grep 'abc' ${tmpd}/abc >/dev/null 2>&1
-grep 'def' ${tmpd}/def >/dev/null 2>&1
-grep 'xyz' ${tmpd}/xyz >/dev/null 2>&1
-grep 'dyn' ${tmpd}/dyn >/dev/null 2>&1
+grep 'abc' "${tmpd}"/abc >/dev/null 2>&1
+grep 'def' "${tmpd}"/def >/dev/null 2>&1
+grep 'xyz' "${tmpd}"/xyz >/dev/null 2>&1
+grep 'dyn' "${tmpd}"/dyn >/dev/null 2>&1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/import-subfile.sh b/tests-ng/import-subfile.sh
index 38a6c01..bc3f55b 100755
--- a/tests-ng/import-subfile.sh
+++ b/tests-ng/import-subfile.sh
@@ -6,64 +6,43 @@
 # after having imported directory
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the dotfile
-mkdir -p ${tmpd}/adir
-echo "first" > ${tmpd}/adir/file1
+mkdir -p "${tmpd}"/adir
+echo "first" > "${tmpd}"/adir/file1
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -74,18 +53,18 @@ _EOF
 #cat ${cfg}
 
 # import dir
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/adir
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/adir
 
 # change the file
-echo "second" >> ${tmpd}/adir/file1
+echo "second" >> "${tmpd}"/adir/file1
 
 # import file
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/adir/file1
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/adir/file1
 
 # test
 #cat ${tmps}/dotfiles/${tmpd}/adir/file1
-[ ! -e ${tmps}/dotfiles/${tmpd}/adir/file1 ] && echo "not exist" && exit 1
-grep 'second' ${tmps}/dotfiles/${tmpd}/adir/file1 >/dev/null
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/adir/file1 ] && echo "not exist" && exit 1
+grep 'second' "${tmps}"/dotfiles/"${tmpd}"/adir/file1 >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/import-to-no-profile.sh b/tests-ng/import-to-no-profile.sh
index 1dbc3fa..82ff737 100755
--- a/tests-ng/import-to-no-profile.sh
+++ b/tests-ng/import-to-no-profile.sh
@@ -5,64 +5,43 @@
 # test import to no profile (using ALL keyword)
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the dotfile
-echo "file1" > ${tmpd}/file1
-echo "file2" > ${tmpd}/file2
+echo "file1" > "${tmpd}"/file1
+echo "file2" > "${tmpd}"/file2
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -76,57 +55,57 @@ noprofile="ALL"
 
 ##################################
 # import with profile from arg
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p "${noprofile}" -V ${tmpd}/file1
-cat ${cfg}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p "${noprofile}" -V "${tmpd}"/file1
+cat "${cfg}"
 
 # ensure exists and is not link
-[ ! -e ${tmps}/dotfiles/${tmpd}/file1 ] && echo "file not imported" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/file1 ] && echo "file not imported" && exit 1
 # ensure present in config
-cat ${cfg} | grep ${tmpd}/file1 >/dev/null 2>&1
+cat "${cfg}" | grep "${tmpd}"/file1 >/dev/null 2>&1
 
-nb=`cat ${cfg} | grep f_file1 | wc -l`
+nb=$(cat "${cfg}" | grep f_file1 | wc -l)
 [ "${nb}" != "1" ] && echo 'bad config' && exit 1
 
-cntpre=`find ${tmps}/dotfiles -type f | wc -l`
+cntpre=$(find "${tmps}"/dotfiles -type f | wc -l)
 
 # reimport
 set +e
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p "${noprofile}" -V ${tmpd}/file1
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p "${noprofile}" -V "${tmpd}"/file1
 set -e
-cat ${cfg}
+cat "${cfg}"
 
-cntpost=`find ${tmps}/dotfiles -type f | wc -l`
+cntpost=$(find "${tmps}"/dotfiles -type f | wc -l)
 [ "${cntpost}" != "${cntpre}" ] && echo "imported twice" && exit 1
 
-nb=`cat ${cfg} | grep "dst: ${tmpd}/file1" | wc -l`
+nb=$(cat "${cfg}" | grep "dst: ${tmpd}/file1" | wc -l)
 [ "${nb}" != "1" ] && echo 'imported twice in config' && exit 1
 
 ##################################
 # import with profile from env
 export DOTDROP_PROFILE="${noprofile}"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -V ${tmpd}/file2
-cat ${cfg}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -V "${tmpd}"/file2
+cat "${cfg}"
 
 # ensure exists and is not link
-[ ! -e ${tmps}/dotfiles/${tmpd}/file2 ] && echo "file not imported" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/file2 ] && echo "file not imported" && exit 1
 # ensure present in config
-cat ${cfg} | grep ${tmpd}/file2 >/dev/null 2>&1
+cat "${cfg}" | grep "${tmpd}"/file2 >/dev/null 2>&1
 
-nb=`cat ${cfg} | grep f_file2 | wc -l`
+nb=$(cat "${cfg}" | grep f_file2 | wc -l)
 [ "${nb}" != "1" ] && echo 'bad config' && exit 1
 
-cntpre=`find ${tmps}/dotfiles -type f | wc -l`
+cntpre=$(find "${tmps}"/dotfiles -type f | wc -l)
 
 # reimport
 set +e
-cd ${ddpath} | ${bin} import -f -c ${cfg} -V ${tmpd}/file2
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -V "${tmpd}"/file2
 set -e
-cat ${cfg}
+cat "${cfg}"
 
-cntpost=`find ${tmps}/dotfiles -type f | wc -l`
+cntpost=$(find "${tmps}"/dotfiles -type f | wc -l)
 [ "${cntpost}" != "${cntpre}" ] && echo "imported twice" && exit 1
 
-nb=`cat ${cfg} | grep "dst: ${tmpd}/file2" | wc -l`
+nb=$(cat "${cfg}" | grep "dst: ${tmpd}/file2" | wc -l)
 [ "${nb}" != "1" ] && echo 'imported twice in config' && exit 1
 
 echo "OK"
diff --git a/tests-ng/import-variables.sh b/tests-ng/import-variables.sh
new file mode 100755
index 0000000..2b68276
--- /dev/null
+++ b/tests-ng/import-variables.sh
@@ -0,0 +1,121 @@
+#!/usr/bin/env bash
+# author: deadc0de6 (https://github.com/deadc0de6)
+# Copyright (c) 2023, deadc0de6
+#
+# test import_variables
+# returns 1 in case of error
+# see issue 380
+#
+
+## start-cookie
+set -e
+cur=$(cd "$(dirname "${0}")" && pwd)
+ddpath="${cur}/../"
+export PYTHONPATH="${ddpath}:${PYTHONPATH}"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
+
+################################################################
+# this is the test
+################################################################
+
+# the dotfile source
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
+# the dotfile destination
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+
+clear_on_exit "${tmps}"
+clear_on_exit "${tmpd}"
+
+# create the config file
+cfg="${tmps}/config.yaml"
+cfgvar1="${tmps}/var1.yaml"
+cfgvar2="${tmps}/var2.yaml"
+
+cat << _EOF > "${tmps}/dotfiles/abc"
+var1: {{@@ var1 @@}}
+var2: {{@@ var2 @@}}
+var3: {{@@ var3 @@}}
+var4: {{@@ var4 @@}}
+var5: {{@@ var5 @@}}
+var6: {{@@ var6 @@}}
+_EOF
+
+cat > "${cfg}" << _EOF
+config:
+  backup: true
+  create: true
+  dotpath: dotfiles
+  import_variables:
+  - ${cfgvar1}
+  - ${cfgvar2}
+variables:
+  var1: "this is var1 from main config"
+  var2: "this is var2 from main config"
+  var3: "this is var3 from main config"
+dotfiles:
+  f_abc:
+    dst: ${tmpd}/abc
+    src: 'abc'
+profiles:
+  p1:
+    dotfiles:
+    - f_abc
+_EOF
+echo "main config: ${cfg}"
+cat "${cfg}"
+
+cat << _EOF > "${cfgvar1}"
+variables:
+  var2: "this is var2 from sub1"
+  var3: "this is var3 from sub1"
+  var4: "this is var4 from sub1"
+  var5: "this is var5 from sub1"
+_EOF
+echo "cfgvar1: ${cfgvar1}"
+cat "${cfgvar1}"
+
+cat << _EOF > "${cfgvar2}"
+variables:
+  var3: "this is var3 from sub2"
+  var4: "this is var4 from sub2"
+  var6: "this is var6 from sub2"
+_EOF
+echo "cfgvar2: ${cfgvar2}"
+cat "${cfgvar2}"
+
+# install
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 --verbose
+
+# test file existence
+[ -f "${tmpd}/abc" ] || {
+    echo 'Dotfile not installed'
+    exit 1
+}
+
+# test file content
+cat "${tmpd}"/abc
+echo "----------------------"
+grep '^var1: this is var1 from main config$' "${tmpd}"/abc >/dev/null
+echo "var1 ok"
+grep '^var2: this is var2 from sub1$' "${tmpd}"/abc >/dev/null
+echo "var2 ok"
+grep '^var3: this is var3 from sub2$' "${tmpd}"/abc >/dev/null
+echo "var3 ok"
+grep '^var4: this is var4 from sub2$' "${tmpd}"/abc >/dev/null
+echo "var4 ok"
+grep '^var5: this is var5 from sub1$' "${tmpd}"/abc >/dev/null
+echo "var5 ok"
+grep '^var6: this is var6 from sub2$' "${tmpd}"/abc >/dev/null
+echo "var6 ok"
+
+echo "OK"
+exit 0
diff --git a/tests-ng/import-with-empty.sh b/tests-ng/import-with-empty.sh
index 73bd1f3..8caeda4 100755
--- a/tests-ng/import-with-empty.sh
+++ b/tests-ng/import-with-empty.sh
@@ -6,63 +6,42 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 # the temp directory
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # create a dotfile
 dftoimport="${tmpd}/a_dotfile"
-echo 'some content' > ${dftoimport}
+echo 'some content' > "${dftoimport}"
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -96,15 +75,15 @@ profiles:
 _EOF
 
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 --verbose ${dftoimport}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 --verbose "${dftoimport}"
 [ "$?" != "0" ] && exit 1
 
 echo "[+] install"
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p1 --verbose | grep '^5 dotfile(s) installed.$'
-rm -f ${dftoimport}
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p1 --verbose | grep '^6 dotfile(s) installed.$'
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 --verbose | grep '^5 dotfile(s) installed.$'
+rm -f "${dftoimport}"
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 --verbose | grep '^6 dotfile(s) installed.$'
 
-nb=`cd ${ddpath} | ${bin} files -c ${cfg} -p p1 --verbose | grep '^[a-zA-Z]' | grep -v '^Dotfile(s)' | wc -l`
+nb=$(cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 --verbose | grep '^[a-zA-Z]' | grep -v '^Dotfile(s)' | wc -l)
 [ "${nb}" != "6" ] && echo "error in dotfile list (${nb} VS 6)" && exit 1
 
 #cat ${cfg}
diff --git a/tests-ng/import-with-trans.sh b/tests-ng/import-with-trans.sh
index bcc26ea..572b636 100755
--- a/tests-ng/import-with-trans.sh
+++ b/tests-ng/import-with-trans.sh
@@ -6,53 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-#set -v
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -61,7 +39,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 trans_read:
   base64: "cat {0} | base64 -d > {1}"
   decompress: "mkdir -p {1} && tar -xf {0} -C {1}"
@@ -85,10 +63,10 @@ tokend="compressed archive"
 tokenenc="encrypted"
 
 # create the dotfiles
-echo ${token} > ${tmpd}/abc
-mkdir -p ${tmpd}/def/a
-echo ${tokend} > ${tmpd}/def/a/file
-echo ${tokenenc} > ${tmpd}/ghi
+echo ${token} > "${tmpd}"/abc
+mkdir -p "${tmpd}"/def/a
+echo "${tokend}" > "${tmpd}"/def/a/file
+echo ${tokenenc} > "${tmpd}"/ghi
 
 ###########################
 # test import
@@ -96,73 +74,73 @@ echo ${tokenenc} > ${tmpd}/ghi
 
 echo "[+] run import"
 # import file (to base64)
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -b -V --transw=base64 --transr=base64 ${tmpd}/abc
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -b -V --transw=base64 --transr=base64 "${tmpd}"/abc
 # import directory (to compress)
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -b -V --transw=compress --transr=decompress ${tmpd}/def
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -b -V --transw=compress --transr=decompress "${tmpd}"/def
 # import file (to encrypt)
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -b -V --transw=encrypt --transr=decrypt ${tmpd}/ghi
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -b -V --transw=encrypt --transr=decrypt "${tmpd}"/ghi
 
 # check file imported in dotpath
-[ ! -e ${tmps}/dotfiles/${tmpd}/abc ] && echo "abc does not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/def ] && echo "def does not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/ghi ] && echo "ghi does not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/abc ] && echo "abc does not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/def ] && echo "def does not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/ghi ] && echo "ghi does not exist" && exit 1
 
 # check content in dotpath
 echo "checking content"
-file ${tmps}/dotfiles/${tmpd}/abc | grep -i 'text'
-cat ${tmpd}/abc | base64 > ${tmps}/test-abc
-diff ${tmps}/dotfiles/${tmpd}/abc ${tmps}/test-abc
+file "${tmps}"/dotfiles/"${tmpd}"/abc | grep -i 'text'
+cat "${tmpd}"/abc | base64 > "${tmps}"/test-abc
+diff "${tmps}"/dotfiles/"${tmpd}"/abc "${tmps}"/test-abc
 
-file ${tmps}/dotfiles/${tmpd}/def | grep -i 'tar'
-tar -cf ${tmps}/test-def -C ${tmpd}/def .
-diff ${tmps}/dotfiles/${tmpd}/def ${tmps}/test-def
+file "${tmps}"/dotfiles/"${tmpd}"/def | grep -i 'tar'
+tar -cf "${tmps}"/test-def -C "${tmpd}"/def .
+diff "${tmps}"/dotfiles/"${tmpd}"/def "${tmps}"/test-def
 
-file ${tmps}/dotfiles/${tmpd}/ghi | grep -i 'gpg symmetrically encrypted data'
-echo p1 | gpg -q --batch --yes --passphrase-fd 0 --no-tty -d ${tmps}/dotfiles/${tmpd}/ghi > ${tmps}/test-ghi
-diff ${tmps}/test-ghi ${tmpd}/ghi
+file "${tmps}"/dotfiles/"${tmpd}"/ghi | grep -i 'gpg symmetrically encrypted data'
+echo p1 | gpg -q --batch --yes --passphrase-fd 0 --no-tty -d "${tmps}"/dotfiles/"${tmpd}"/ghi > "${tmps}"/test-ghi
+diff "${tmps}"/test-ghi "${tmpd}"/ghi
 
 # check is imported in config
 echo "checking imported in config"
-cd ${ddpath} | ${bin} -p p1 -c ${cfg} files
-cd ${ddpath} | ${bin} -p p1 -c ${cfg} files | grep '^f_abc'
-cd ${ddpath} | ${bin} -p p1 -c ${cfg} files | grep '^d_def'
-cd ${ddpath} | ${bin} -p p1 -c ${cfg} files | grep '^f_ghi'
+cd "${ddpath}" | ${bin} -p p1 -c "${cfg}" files
+cd "${ddpath}" | ${bin} -p p1 -c "${cfg}" files | grep '^f_abc'
+cd "${ddpath}" | ${bin} -p p1 -c "${cfg}" files | grep '^d_def'
+cd "${ddpath}" | ${bin} -p p1 -c "${cfg}" files | grep '^f_ghi'
 
 # check has trans_write and trans_read in config
 echo "checking trans_write is set in config"
 echo "--------------"
-cat ${cfg}
+cat "${cfg}"
 echo "--------------"
-cat ${cfg} | grep -A 4 'f_abc:' | grep 'trans_write: base64'
-cat ${cfg} | grep -A 4 'd_def:' | grep 'trans_write: compress'
-cat ${cfg} | grep -A 4 'f_ghi:' | grep 'trans_write: encrypt'
+cat "${cfg}" | grep -A 4 'f_abc:' | grep 'trans_write: base64'
+cat "${cfg}" | grep -A 4 'd_def:' | grep 'trans_write: compress'
+cat "${cfg}" | grep -A 4 'f_ghi:' | grep 'trans_write: encrypt'
 
-cat ${cfg} | grep -A 4 'f_abc:' | grep 'trans_read: base64'
-cat ${cfg} | grep -A 4 'd_def:' | grep 'trans_read: decompress'
-cat ${cfg} | grep -A 4 'f_ghi:' | grep 'trans_read: decrypt'
+cat "${cfg}" | grep -A 4 'f_abc:' | grep 'trans_read: base64'
+cat "${cfg}" | grep -A 4 'd_def:' | grep 'trans_read: decompress'
+cat "${cfg}" | grep -A 4 'f_ghi:' | grep 'trans_read: decrypt'
 
 # install these
 echo "install and check"
-rm ${tmpd}/abc
-rm -r ${tmpd}/def
-rm ${tmpd}/ghi
+rm "${tmpd}"/abc
+rm -r "${tmpd}"/def
+rm "${tmpd}"/ghi
 
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 
 # test exist
 echo "check exist"
-[ ! -e ${tmpd}/abc ] && exit 1
-[ ! -d ${tmpd}/def/a ] && exit 1
-[ ! -e ${tmpd}/def/a/file ] && exit 1
-[ ! -e ${tmpd}/ghi ] && exit 1
+[ ! -e "${tmpd}"/abc ] && exit 1
+[ ! -d "${tmpd}"/def/a ] && exit 1
+[ ! -e "${tmpd}"/def/a/file ] && exit 1
+[ ! -e "${tmpd}"/ghi ] && exit 1
 
 # test content
 echo "check content"
-cat ${tmpd}/abc
-cat ${tmpd}/abc | grep "${token}"
-cat ${tmpd}/def/a/file
-cat ${tmpd}/def/a/file | grep "${tokend}"
-cat ${tmpd}/ghi | grep "${tokenenc}"
+cat "${tmpd}"/abc
+cat "${tmpd}"/abc | grep "${token}"
+cat "${tmpd}"/def/a/file
+cat "${tmpd}"/def/a/file | grep "${tokend}"
+cat "${tmpd}"/ghi | grep "${tokenenc}"
 
 echo "OK"
 exit 0
diff --git a/tests-ng/import.sh b/tests-ng/import.sh
index e6ffb92..ea7d4bd 100755
--- a/tests-ng/import.sh
+++ b/tests-ng/import.sh
@@ -5,66 +5,45 @@
 # test basic import
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the dotfile
-mkdir -p ${tmpd}/adir
-echo "adir/file1" > ${tmpd}/adir/file1
-echo "adir/fil2" > ${tmpd}/adir/file2
-echo "file3" > ${tmpd}/file3
+mkdir -p "${tmpd}"/adir
+echo "adir/file1" > "${tmpd}"/adir/file1
+echo "adir/fil2" > "${tmpd}"/adir/file2
+echo "file3" > "${tmpd}"/file3
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -75,39 +54,39 @@ _EOF
 #cat ${cfg}
 
 # import
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/adir
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/file3
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/adir
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/file3
 
-cat ${cfg}
+cat "${cfg}"
 
 # ensure exists and is not link
-[ ! -d ${tmps}/dotfiles/${tmpd}/adir ] && echo "not a directory" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/adir/file1 ] && echo "not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/adir/file2 ] && echo "not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/${tmpd}/file3 ] && echo "not a file" && exit 1
+[ ! -d "${tmps}"/dotfiles/"${tmpd}"/adir ] && echo "not a directory" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/adir/file1 ] && echo "not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/adir/file2 ] && echo "not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/file3 ] && echo "not a file" && exit 1
 
-cat ${cfg} | grep ${tmpd}/adir >/dev/null 2>&1
-cat ${cfg} | grep ${tmpd}/file3 >/dev/null 2>&1
+cat "${cfg}" | grep "${tmpd}"/adir >/dev/null 2>&1
+cat "${cfg}" | grep "${tmpd}"/file3 >/dev/null 2>&1
 
-nb=`cat ${cfg} | grep d_adir | wc -l`
+nb=$(cat "${cfg}" | grep d_adir | wc -l)
 [ "${nb}" != "2" ] && echo 'bad config1' && exit 1
-nb=`cat ${cfg} | grep f_file3 | wc -l`
+nb=$(cat "${cfg}" | grep f_file3 | wc -l)
 [ "${nb}" != "2" ] && echo 'bad config2' && exit 1
 
-cntpre=`find ${tmps}/dotfiles -type f | wc -l`
+cntpre=$(find "${tmps}"/dotfiles -type f | wc -l)
 
 # reimport
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/adir
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/file3
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/adir
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/file3
 
-cntpost=`find ${tmps}/dotfiles -type f | wc -l`
+cntpost=$(find "${tmps}"/dotfiles -type f | wc -l)
 
 [ "${cntpost}" != "${cntpre}" ] && echo "import issue" && exit 1
 
 #######################################
 # import directory with named pipe
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -118,20 +97,20 @@ _EOF
 
 # create the dotfile
 d="${tmpd}/with_named_pipe"
-mkdir -p ${d}
-echo "file1" > ${d}/file1
-echo "fil2" > ${d}/file2
-mkfifo ${d}/fifo
+mkdir -p "${d}"
+echo "file1" > "${d}"/file1
+echo "fil2" > "${d}"/file2
+mkfifo "${d}"/fifo
 
 # import
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p2 -V ${d}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p2 -V "${d}"
 
 # ensure exists and is not link
-[ ! -d ${tmps}/dotfiles/${d} ] && echo "not a directory" && exit 1
-[ ! -e ${tmps}/dotfiles/${d}/file1 ] && echo "not exist" && exit 1
-[ ! -e ${tmps}/dotfiles/${d}/file2 ] && echo "not exist" && exit 1
+[ ! -d "${tmps}"/dotfiles/"${d}" ] && echo "not a directory" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${d}"/file1 ] && echo "not exist" && exit 1
+[ ! -e "${tmps}"/dotfiles/"${d}"/file2 ] && echo "not exist" && exit 1
 
-cat ${cfg} | grep ${d} >/dev/null 2>&1
+cat "${cfg}" | grep "${d}" >/dev/null 2>&1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/imported-configs-variables.sh b/tests-ng/imported-configs-variables.sh
index 55093c6..37b7b23 100755
--- a/tests-ng/imported-configs-variables.sh
+++ b/tests-ng/imported-configs-variables.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -59,13 +38,13 @@ clear_on_exit "${tmpd}"
 # create the config file
 extcfg="${tmps}/ext-config.yaml"
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
   dotpath: dotfiles
   import_configs:
-  - $(basename ${extcfg})
+  - $(basename "${extcfg}")
 variables:
   varx: "test"
   provar: "local"
@@ -87,10 +66,10 @@ profiles:
       dvarx: echo dprofvarx
       dprovar: echo dprovar
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
 # create the external variables file
-cat > ${extcfg} << _EOF
+cat > "${extcfg}" << _EOF
 config:
 profiles:
   p2:
@@ -104,36 +83,36 @@ profiles:
       dprovar: echo extdprovar
 dotfiles:
 _EOF
-ls -l ${extcfg}
-cat ${extcfg}
+ls -l "${extcfg}"
+cat "${extcfg}"
 
 # create the dotfile
-echo "varx: {{@@ varx @@}}" > ${tmps}/dotfiles/abc
-echo "provar: {{@@ provar @@}}" >> ${tmps}/dotfiles/abc
-echo "dvarx: {{@@ dvarx @@}}" >> ${tmps}/dotfiles/abc
-echo "dprovar: {{@@ dprovar@@}}" >> ${tmps}/dotfiles/abc
+echo "varx: {{@@ varx @@}}" > "${tmps}"/dotfiles/abc
+echo "provar: {{@@ provar @@}}" >> "${tmps}"/dotfiles/abc
+echo "dvarx: {{@@ dvarx @@}}" >> "${tmps}"/dotfiles/abc
+echo "dprovar: {{@@ dprovar@@}}" >> "${tmps}"/dotfiles/abc
 
 #cat ${tmps}/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p2 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p2 -V
 
 echo "test1"
-cat ${tmpd}/abc
-grep '^varx: extprofvarx' ${tmpd}/abc >/dev/null
-grep '^provar: extprovar' ${tmpd}/abc >/dev/null
-grep '^dvarx: extdprofvarx' ${tmpd}/abc >/dev/null
-grep '^dprovar: extdprovar' ${tmpd}/abc >/dev/null
+cat "${tmpd}"/abc
+grep '^varx: extprofvarx' "${tmpd}"/abc >/dev/null
+grep '^provar: extprovar' "${tmpd}"/abc >/dev/null
+grep '^dvarx: extdprofvarx' "${tmpd}"/abc >/dev/null
+grep '^dprovar: extdprovar' "${tmpd}"/abc >/dev/null
 
-rm -f ${tmpd}/abc
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+rm -f "${tmpd}"/abc
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 echo "test2"
-cat ${tmpd}/abc
-grep '^varx: profvarx' ${tmpd}/abc >/dev/null
-grep '^provar: provar' ${tmpd}/abc >/dev/null
-grep '^dvarx: dprofvarx' ${tmpd}/abc >/dev/null
-grep '^dprovar: dprovar' ${tmpd}/abc >/dev/null
+cat "${tmpd}"/abc
+grep '^varx: profvarx' "${tmpd}"/abc >/dev/null
+grep '^provar: provar' "${tmpd}"/abc >/dev/null
+grep '^dvarx: dprofvarx' "${tmpd}"/abc >/dev/null
+grep '^dprovar: dprovar' "${tmpd}"/abc >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/imported-variables-from-config.sh b/tests-ng/imported-variables-from-config.sh
index 2cf6c88..9f078b1 100755
--- a/tests-ng/imported-variables-from-config.sh
+++ b/tests-ng/imported-variables-from-config.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -59,7 +38,7 @@ clear_on_exit "${tmpd}"
 cfg="${tmps}/config.yaml"
 subcfg="${tmps}/subconfig.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -75,10 +54,10 @@ profiles:
     dotfiles:
     - f_abc
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
 # create the subconfig file
-cat > ${subcfg} << _EOF
+cat > "${subcfg}" << _EOF
 config:
   backup: true
   create: true
@@ -92,13 +71,13 @@ profiles: []
 _EOF
 
 # create the dotfile
-dirname ${tmps}/dotfiles/abc | xargs mkdir -p
-cat > ${tmps}/dotfiles/abc << _EOF
+dirname "${tmps}"/dotfiles/abc | xargs mkdir -p
+cat > "${tmps}"/dotfiles/abc << _EOF
 Hell yeah
 _EOF
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # test file existence and content
 [ -f "${tmpd}/abc" ] || {
diff --git a/tests-ng/include-actions.sh b/tests-ng/include-actions.sh
index ffd4e36..7b7cbda 100755
--- a/tests-ng/include-actions.sh
+++ b/tests-ng/include-actions.sh
@@ -7,53 +7,32 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -62,7 +41,7 @@ clear_on_exit "${tmpa}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 actions:
   pre:
     preaction: echo 'pre' >> ${tmpa}/pre
@@ -103,109 +82,109 @@ profiles:
 _EOF
 
 # create the source
-mkdir -p ${tmps}/dotfiles/
-echo "test" > ${tmps}/dotfiles/abc
+mkdir -p "${tmps}"/dotfiles/
+echo "test" > "${tmps}"/dotfiles/abc
 
 # install
 echo "PROFILE p2"
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p2 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p2 -V
 
 # checks
-[ ! -e ${tmpa}/pre ] && echo "pre not found" && exit 1
-nb=`wc -l ${tmpa}/pre | awk '{print $1}'`
+[ ! -e "${tmpa}"/pre ] && echo "pre not found" && exit 1
+nb=$(wc -l "${tmpa}"/pre | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "pre executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/pre2 ] && echo "pre2 not found" && exit 1
-nb=`wc -l ${tmpa}/pre2 | awk '{print $1}'`
+[ ! -e "${tmpa}"/pre2 ] && echo "pre2 not found" && exit 1
+nb=$(wc -l "${tmpa}"/pre2 | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "pre2 executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/post ] && echo "post not found" && exit 1
-nb=`wc -l ${tmpa}/post | awk '{print $1}'`
+[ ! -e "${tmpa}"/post ] && echo "post not found" && exit 1
+nb=$(wc -l "${tmpa}"/post | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "post executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/post2 ] && echo "post2 not found" && exit 1
-nb=`wc -l ${tmpa}/post2 | awk '{print $1}'`
+[ ! -e "${tmpa}"/post2 ] && echo "post2 not found" && exit 1
+nb=$(wc -l "${tmpa}"/post2 | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "post2 executed multiple times" && exit 1
 
 # install
-rm -f ${tmpa}/pre ${tmpa}/pre2 ${tmpa}/post ${tmpa}/post2 ${tmpa}/naked
-rm -f ${tmpd}/abc
+rm -f "${tmpa}"/pre "${tmpa}"/pre2 "${tmpa}"/post "${tmpa}"/post2 "${tmpa}"/naked
+rm -f "${tmpd}"/abc
 echo "PROFILE p3"
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p3 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p3 -V
 
 # checks
-[ ! -e ${tmpa}/pre ] && echo "pre not found" && exit 1
-nb=`wc -l ${tmpa}/pre | awk '{print $1}'`
+[ ! -e "${tmpa}"/pre ] && echo "pre not found" && exit 1
+nb=$(wc -l "${tmpa}"/pre | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "pre executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/pre2 ] && echo "pre2 not found" && exit 1
-nb=`wc -l ${tmpa}/pre2 | awk '{print $1}'`
+[ ! -e "${tmpa}"/pre2 ] && echo "pre2 not found" && exit 1
+nb=$(wc -l "${tmpa}"/pre2 | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "pre2 executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/post ] && echo "post not found" && exit 1
-nb=`wc -l ${tmpa}/post | awk '{print $1}'`
+[ ! -e "${tmpa}"/post ] && echo "post not found" && exit 1
+nb=$(wc -l "${tmpa}"/post | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "post executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/post2 ] && echo "post2 not found" && exit 1
-nb=`wc -l ${tmpa}/post2 | awk '{print $1}'`
+[ ! -e "${tmpa}"/post2 ] && echo "post2 not found" && exit 1
+nb=$(wc -l "${tmpa}"/post2 | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "post2 executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/naked ] && echo "naked not found" && exit 1
-nb=`wc -l ${tmpa}/naked | awk '{print $1}'`
+[ ! -e "${tmpa}"/naked ] && echo "naked not found" && exit 1
+nb=$(wc -l "${tmpa}"/naked | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "naked executed multiple times" &&  exit 1
 
 # install
-rm -f ${tmpa}/pre ${tmpa}/pre2 ${tmpa}/post ${tmpa}/post2 ${tmpa}/naked
-rm -f ${tmpd}/abc
+rm -f "${tmpa}"/pre "${tmpa}"/pre2 "${tmpa}"/post "${tmpa}"/post2 "${tmpa}"/naked
+rm -f "${tmpd}"/abc
 echo "PROFILE p0"
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p0 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p0 -V
 
 # checks
-[ ! -e ${tmpa}/pre ] && echo "pre not found" && exit 1
-nb=`wc -l ${tmpa}/pre | awk '{print $1}'`
+[ ! -e "${tmpa}"/pre ] && echo "pre not found" && exit 1
+nb=$(wc -l "${tmpa}"/pre | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "pre executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/pre2 ] && echo "pre2 not found" && exit 1
-nb=`wc -l ${tmpa}/pre2 | awk '{print $1}'`
+[ ! -e "${tmpa}"/pre2 ] && echo "pre2 not found" && exit 1
+nb=$(wc -l "${tmpa}"/pre2 | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "pre2 executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/post ] && echo "post not found" && exit 1
-nb=`wc -l ${tmpa}/post | awk '{print $1}'`
+[ ! -e "${tmpa}"/post ] && echo "post not found" && exit 1
+nb=$(wc -l "${tmpa}"/post | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "post executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/post2 ] && echo "post2 not found" && exit 1
-nb=`wc -l ${tmpa}/post2 | awk '{print $1}'`
+[ ! -e "${tmpa}"/post2 ] && echo "post2 not found" && exit 1
+nb=$(wc -l "${tmpa}"/post2 | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "post2 executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/naked ] && echo "naked not found" && exit 1
-nb=`wc -l ${tmpa}/naked | awk '{print $1}'`
+[ ! -e "${tmpa}"/naked ] && echo "naked not found" && exit 1
+nb=$(wc -l "${tmpa}"/naked | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "naked executed multiple times" &&  exit 1
 
 # install without verbose
-rm -f ${tmpa}/pre ${tmpa}/pre2 ${tmpa}/post ${tmpa}/post2 ${tmpa}/naked
-rm -f ${tmpd}/abc
+rm -f "${tmpa}"/pre "${tmpa}"/pre2 "${tmpa}"/post "${tmpa}"/post2 "${tmpa}"/naked
+rm -f "${tmpd}"/abc
 echo "PROFILE p0 without verbose"
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p0
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p0
 
 # checks
-[ ! -e ${tmpa}/pre ] && echo "pre not found" && exit 1
-nb=`wc -l ${tmpa}/pre | awk '{print $1}'`
+[ ! -e "${tmpa}"/pre ] && echo "pre not found" && exit 1
+nb=$(wc -l "${tmpa}"/pre | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "pre executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/pre2 ] && echo "pre2 not found" && exit 1
-nb=`wc -l ${tmpa}/pre2 | awk '{print $1}'`
+[ ! -e "${tmpa}"/pre2 ] && echo "pre2 not found" && exit 1
+nb=$(wc -l "${tmpa}"/pre2 | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "pre2 executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/post ] && echo "post not found" && exit 1
-nb=`wc -l ${tmpa}/post | awk '{print $1}'`
+[ ! -e "${tmpa}"/post ] && echo "post not found" && exit 1
+nb=$(wc -l "${tmpa}"/post | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "post executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/post2 ] && echo "post2 not found" && exit 1
-nb=`wc -l ${tmpa}/post2 | awk '{print $1}'`
+[ ! -e "${tmpa}"/post2 ] && echo "post2 not found" && exit 1
+nb=$(wc -l "${tmpa}"/post2 | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "post2 executed multiple times" && exit 1
 
-[ ! -e ${tmpa}/naked ] && echo "naked not found" && exit 1
-nb=`wc -l ${tmpa}/naked | awk '{print $1}'`
+[ ! -e "${tmpa}"/naked ] && echo "naked not found" && exit 1
+nb=$(wc -l "${tmpa}"/naked | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "naked executed multiple times" &&  exit 1
 
 echo "OK"
diff --git a/tests-ng/include-order.sh b/tests-ng/include-order.sh
index 60978d1..f9435d0 100755
--- a/tests-ng/include-order.sh
+++ b/tests-ng/include-order.sh
@@ -7,53 +7,32 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # temporary
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -63,7 +42,7 @@ export DOTDROP_WORKERS=1
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -105,24 +84,24 @@ profiles:
 _EOF
 
 # create the source
-mkdir -p ${tmps}/dotfiles/
-echo "first" > ${tmps}/dotfiles/first
-echo "second" > ${tmps}/dotfiles/second
-echo "third" > ${tmps}/dotfiles/third
+mkdir -p "${tmps}"/dotfiles/
+echo "first" > "${tmps}"/dotfiles/first
+echo "second" > "${tmps}"/dotfiles/second
+echo "third" > "${tmps}"/dotfiles/third
 
 attempts="3"
-for ((i=0;i<${attempts};i++)); do
+for ((i=0;i<attempts;i++)); do
   # install
-  cd ${ddpath} | ${bin} install -w 1 -f -c ${cfg} -p p0 -V
+  cd "${ddpath}" | ${bin} install -w 1 -f -c "${cfg}" -p p0 -V
 
   # checks timestamp
-  echo "first timestamp: `stat -c %y ${tmpd}/first`"
-  echo "second timestamp: `stat -c %y ${tmpd}/second`"
-  echo "third timestamp: `stat -c %y ${tmpd}/third`"
+  echo "first timestamp: $(stat -c %y "${tmpd}"/first)"
+  echo "second timestamp: $(stat -c %y "${tmpd}"/second)"
+  echo "third timestamp: $(stat -c %y "${tmpd}"/third)"
 
-  ts_first=`date "+%s" -d "$(stat -c %y ${tmpd}/first)"`
-  ts_second=`date "+%s" -d "$(stat -c %y ${tmpd}/second)"`
-  ts_third=`date "+%s" -d "$(stat -c %y ${tmpd}/third)"`
+  ts_first=$(date "+%s" -d "$(stat -c %y "${tmpd}"/first)")
+  ts_second=$(date "+%s" -d "$(stat -c %y "${tmpd}"/second)")
+  ts_third=$(date "+%s" -d "$(stat -c %y "${tmpd}"/third)")
 
   #echo "first ts: ${ts_first}"
   #echo "second ts: ${ts_second}"
@@ -132,13 +111,13 @@ for ((i=0;i<${attempts};i++)); do
   [ "${ts_second}" -ge "${ts_third}" ] && echo "third created before second" && exit 1
 
   # check cookie
-  cat ${tmpa}/cookie
-  content=`cat ${tmpa}/cookie | xargs`
+  cat "${tmpa}"/cookie
+  content=$(cat "${tmpa}"/cookie | xargs)
   [ "${content}" != "first second third" ] && echo "bad cookie" && exit 1
 
   # clean
-  rm ${tmpa}/cookie
-  rm ${tmpd}/first ${tmpd}/second ${tmpd}/third
+  rm "${tmpa}"/cookie
+  rm "${tmpd}"/first "${tmpd}"/second "${tmpd}"/third
 done
 
 echo "OK"
diff --git a/tests-ng/include-variables.sh b/tests-ng/include-variables.sh
index 98919a7..fb46743 100755
--- a/tests-ng/include-variables.sh
+++ b/tests-ng/include-variables.sh
@@ -7,51 +7,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -59,7 +38,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -91,18 +70,18 @@ _EOF
 #cat ${cfg}
 
 # create the source
-mkdir -p ${tmps}/dotfiles/
-echo "head" > ${tmps}/dotfiles/abc
-echo "{{@@ var @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ dvar @@}}" >> ${tmps}/dotfiles/abc
-echo "tail" >> ${tmps}/dotfiles/abc
+mkdir -p "${tmps}"/dotfiles/
+echo "head" > "${tmps}"/dotfiles/abc
+echo "{{@@ var @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ dvar @@}}" >> "${tmps}"/dotfiles/abc
+echo "tail" >> "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p0 --verbose
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p0 --verbose
 
 #cat ${tmpd}/abc
-grep 'p0v' ${tmpd}/abc
-grep 'p0dv' ${tmpd}/abc
+grep 'p0v' "${tmpd}"/abc
+grep 'p0dv' "${tmpd}"/abc
 
 echo "OK"
 exit 0
diff --git a/tests-ng/include.sh b/tests-ng/include.sh
index 069b989..f120805 100755
--- a/tests-ng/include.sh
+++ b/tests-ng/include.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -58,7 +37,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -89,35 +68,35 @@ profiles:
     include:
     - p2
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
 # create the source
-mkdir -p ${tmps}/dotfiles/
-echo "test" > ${tmps}/dotfiles/abc
+mkdir -p "${tmps}"/dotfiles/
+echo "test" > "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p0 --verbose
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p0 --verbose
 
-[ ! -e ${tmpd}/action.pre ] && exit 1
-[ ! -e ${tmpd}/action.post ] && exit 1
+[ ! -e "${tmpd}"/action.pre ] && exit 1
+[ ! -e "${tmpd}"/action.post ] && exit 1
 
 # compare
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p2
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p3
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p0
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p2
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p3
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p0
 
 # list
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 | grep f_abc
-cd ${ddpath} | ${bin} files -c ${cfg} -p p2 | grep f_abc
-cd ${ddpath} | ${bin} files -c ${cfg} -p p3 | grep f_abc
-cd ${ddpath} | ${bin} files -c ${cfg} -p p0 | grep f_abc
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 | grep f_abc
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p2 | grep f_abc
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p3 | grep f_abc
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p0 | grep f_abc
 
-cnt=`cd ${ddpath} | ${bin} files -c ${cfg} -p p0 | grep f_abc | wc -l`
+cnt=$(cd "${ddpath}" | ${bin} files -c "${cfg}" -p p0 | grep f_abc | wc -l)
 [ "${cnt}" != "1" ] && echo "dotfiles displayed more than once" && exit 1
 
 # count
-cnt=`cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -b | grep '^f_' | wc -l`
+cnt=$(cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -b | grep '^f_' | wc -l)
 [ "${cnt}" != "1" ] && exit 1
 
 echo "OK"
diff --git a/tests-ng/inst-link-default.sh b/tests-ng/inst-link-default.sh
index 200eb5e..c5bee54 100755
--- a/tests-ng/inst-link-default.sh
+++ b/tests-ng/inst-link-default.sh
@@ -6,67 +6,46 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the dotfile
-mkdir -p ${tmps}/dotfiles/abc
-echo "test link_dotfile_default 1" > ${tmps}/dotfiles/abc/file1
-echo "test link_dotfile_default 2" > ${tmps}/dotfiles/abc/file2
-echo "should be linked" > ${tmps}/dotfiles/def
+mkdir -p "${tmps}"/dotfiles/abc
+echo "test link_dotfile_default 1" > "${tmps}"/dotfiles/abc/file1
+echo "test link_dotfile_default 2" > "${tmps}"/dotfiles/abc/file2
+echo "should be linked" > "${tmps}"/dotfiles/def
 
 # create a shell script
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -84,19 +63,19 @@ _EOF
 #cat ${cfg}
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 #cat ${cfg}
 
 # ensure exists and is not link
-[ ! -d ${tmpd}/abc ] && echo "not a directory" && exit 1
-[ -h ${tmpd}/abc ] && echo "not a regular file" && exit 1
-[ ! -e ${tmpd}/abc/file1 ] && echo "not exist" && exit 1
-[ -h ${tmpd}/abc/file1 ] && echo "not a regular file" && exit 1
-[ ! -e ${tmpd}/abc/file2 ] && echo "not exist" && exit 1
-[ -h ${tmpd}/abc/file2 ] && echo "not a regular file" && exit 1
-rm -rf ${tmpd}/abc
-
-cat > ${cfg} << _EOF
+[ ! -d "${tmpd}"/abc ] && echo "not a directory" && exit 1
+[ -h "${tmpd}"/abc ] && echo "not a regular file" && exit 1
+[ ! -e "${tmpd}"/abc/file1 ] && echo "not exist" && exit 1
+[ -h "${tmpd}"/abc/file1 ] && echo "not a regular file" && exit 1
+[ ! -e "${tmpd}"/abc/file2 ] && echo "not exist" && exit 1
+[ -h "${tmpd}"/abc/file2 ] && echo "not a regular file" && exit 1
+rm -rf "${tmpd}"/abc
+
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -117,23 +96,23 @@ profiles:
 _EOF
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 #cat ${cfg}
 
 # ensure exists and parent is a link
-[ ! -e ${tmpd}/abc ] && echo "not exist" && exit 1
-[ ! -h ${tmpd}/abc ] && echo "not a symlink" && exit 1
-[ ! -e ${tmpd}/abc/file1 ] && echo "not exist" && exit 1
-[ -h ${tmpd}/abc/file1 ] && echo "not a regular file" && exit 1
-[ ! -e ${tmpd}/abc/file2 ] && echo "not exist" && exit 1
-[ -h ${tmpd}/abc/file2 ] && echo "not a regular file" && exit 1
-rm -rf ${tmpd}/abc
-
-[ ! -e ${tmpd}/def ] && echo "not exist" && exit 1
-[ ! -h ${tmpd}/def ] && echo "not a symlink" && exit 1
-rm -f ${tmpd}/def
-
-cat > ${cfg} << _EOF
+[ ! -e "${tmpd}"/abc ] && echo "not exist" && exit 1
+[ ! -h "${tmpd}"/abc ] && echo "not a symlink" && exit 1
+[ ! -e "${tmpd}"/abc/file1 ] && echo "not exist" && exit 1
+[ -h "${tmpd}"/abc/file1 ] && echo "not a regular file" && exit 1
+[ ! -e "${tmpd}"/abc/file2 ] && echo "not exist" && exit 1
+[ -h "${tmpd}"/abc/file2 ] && echo "not a regular file" && exit 1
+rm -rf "${tmpd}"/abc
+
+[ ! -e "${tmpd}"/def ] && echo "not exist" && exit 1
+[ ! -h "${tmpd}"/def ] && echo "not a symlink" && exit 1
+rm -f "${tmpd}"/def
+
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -150,17 +129,17 @@ profiles:
 _EOF
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 #cat ${cfg}
 
 # ensure exists and children are links
-[ ! -e ${tmpd}/abc ] && echo "not exist" && exit 1
-[ -h ${tmpd}/abc ] && echo "not a regular file" && exit 1
-[ ! -e ${tmpd}/abc/file1 ] && echo "not exist" && exit 1
-[ ! -h ${tmpd}/abc/file1 ] && echo "not a symlink" && exit 1
-[ ! -e ${tmpd}/abc/file2 ] && echo "not exist" && exit 1
-[ ! -h ${tmpd}/abc/file2 ] && echo "not a symlink" && exit 1
-rm -rf ${tmpd}/abc
+[ ! -e "${tmpd}"/abc ] && echo "not exist" && exit 1
+[ -h "${tmpd}"/abc ] && echo "not a regular file" && exit 1
+[ ! -e "${tmpd}"/abc/file1 ] && echo "not exist" && exit 1
+[ ! -h "${tmpd}"/abc/file1 ] && echo "not a symlink" && exit 1
+[ ! -e "${tmpd}"/abc/file2 ] && echo "not exist" && exit 1
+[ ! -h "${tmpd}"/abc/file2 ] && echo "not a symlink" && exit 1
+rm -rf "${tmpd}"/abc
 
 echo "OK"
 exit 0
diff --git a/tests-ng/install-empty.sh b/tests-ng/install-empty.sh
index 34ce1c9..8addee6 100755
--- a/tests-ng/install-empty.sh
+++ b/tests-ng/install-empty.sh
@@ -6,48 +6,27 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
@@ -55,7 +34,7 @@ clear_on_exit "${basedir}"
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -89,7 +68,7 @@ profiles:
 _EOF
 
 echo "[+] install"
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p1 --verbose | grep '^5 dotfile(s) installed.$'
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 --verbose | grep '^5 dotfile(s) installed.$'
 [ "$?" != "0" ] && exit 1
 
 echo "OK"
diff --git a/tests-ng/install-ignore.sh b/tests-ng/install-ignore.sh
index 3395f8d..ce46cb7 100755
--- a/tests-ng/install-ignore.sh
+++ b/tests-ng/install-ignore.sh
@@ -6,127 +6,109 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 tmps="${basedir}"
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # some files
-mkdir -p ${tmpd}/{program,config,vscode}
-echo "some data" > ${tmpd}/program/a
-echo "some data" > ${tmpd}/config/a
-echo "some data" > ${tmpd}/vscode/extensions.txt
-echo "some data" > ${tmpd}/vscode/keybindings.json
+mkdir -p "${tmpd}"/{program,config,vscode}
+echo "some data" > "${tmpd}"/program/a
+echo "some data" > "${tmpd}"/config/a
+echo "some data" > "${tmpd}"/vscode/extensions.txt
+echo "some data" > "${tmpd}"/vscode/keybindings.json
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/config
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/vscode
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/program
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/config
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/vscode
 
 # add files on filesystem
 echo "[+] add files"
-echo "new data" > ${basedir}/dotfiles/${tmpd}/README.md
-echo "new data" > ${basedir}/dotfiles/${tmpd}/vscode/README.md
-echo "new data" > ${basedir}/dotfiles/${tmpd}/program/README.md
-mkdir -p ${basedir}/dotfiles/${tmpd}/readmes
-echo "new data" > ${basedir}/dotfiles/${tmpd}/readmes/README.md
+echo "new data" > "${basedir}"/dotfiles/"${tmpd}"/README.md
+echo "new data" > "${basedir}"/dotfiles/"${tmpd}"/vscode/README.md
+echo "new data" > "${basedir}"/dotfiles/"${tmpd}"/program/README.md
+mkdir -p "${basedir}"/dotfiles/"${tmpd}"/readmes
+echo "new data" > "${basedir}"/dotfiles/"${tmpd}"/readmes/README.md
 
 # install
-rm -rf ${tmpd}
+rm -rf "${tmpd}"
 echo "[+] install normal"
-cd ${ddpath} | ${bin} install --showdiff -c ${cfg} --verbose -f
+cd "${ddpath}" | ${bin} install --showdiff -c "${cfg}" --verbose -f
 [ "$?" != "0" ] && exit 1
-nb=`find ${tmpd} -iname 'README.md' | wc -l`
+nb=$(find "${tmpd}" -iname 'README.md' | wc -l)
 echo "(1) found ${nb} README.md file(s)"
 [ "${nb}" != "2" ] && exit 1
 
 # adding ignore in dotfile
 cfg2="${basedir}/config2.yaml"
-sed '/d_program:/a \ \ \ \ instignore:\n\ \ \ \ - "README.md"' ${cfg} > ${cfg2}
-cat ${cfg2}
+sed '/d_program:/a \ \ \ \ instignore:\n\ \ \ \ - "README.md"' "${cfg}" > "${cfg2}"
+cat "${cfg2}"
 
 # install
-rm -rf ${tmpd}
+rm -rf "${tmpd}"
 echo "[+] install with ignore in dotfile"
-cd ${ddpath} | ${bin} install -c ${cfg2} --verbose -f
+cd "${ddpath}" | ${bin} install -c "${cfg2}" --verbose -f
 [ "$?" != "0" ] && exit 1
-nb=`find ${tmpd} -iname 'README.md' | wc -l`
+nb=$(find "${tmpd}" -iname 'README.md' | wc -l)
 echo "(2) found ${nb} README.md file(s)"
 [ "${nb}" != "1" ] && exit 1
 
 # adding ignore in config
 cfg2="${basedir}/config2.yaml"
-sed '/^config:/a \ \ instignore:\n\ \ - "README.md"' ${cfg} > ${cfg2}
-cat ${cfg2}
+sed '/^config:/a \ \ instignore:\n\ \ - "README.md"' "${cfg}" > "${cfg2}"
+cat "${cfg2}"
 
 # install
-rm -rf ${tmpd}
+rm -rf "${tmpd}"
 echo "[+] install with ignore in config"
-cd ${ddpath} | ${bin} install -c ${cfg2} --verbose -f
+cd "${ddpath}" | ${bin} install -c "${cfg2}" --verbose -f
 [ "$?" != "0" ] && exit 1
-nb=`find ${tmpd} -iname 'README.md' | wc -l`
+nb=$(find "${tmpd}" -iname 'README.md' | wc -l)
 echo "(3) found ${nb} README.md file(s)"
 [ "${nb}" != "0" ] && exit 1
 
 ## reinstall to trigger showdiff
-echo "showdiff" > ${tmpd}/program/a
-cd ${ddpath} | echo "y" | ${bin} install --showdiff -c ${cfg} --verbose -f
-[ "$?" != "0" ] && exit 1
+echo "showdiff" > "${tmpd}"/program/a
+(
+  cd "${ddpath}"
+  printf "y\n" | ${bin} install --showdiff -c "${cfg}" --verbose -f
+  exit $?
+)
 
 # test templated subdir
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -135,52 +117,52 @@ dotfiles:
 profiles:
 _EOF
 
-mkdir -p ${tmpd}/nvim
-mkdir -p ${tmpd}/nvim/dir1
-echo "f1" > ${tmpd}/nvim/dir1/file1
-mkdir -p ${tmpd}/nvim/dir2
-echo "f1" > ${tmpd}/nvim/dir2/file2
-echo "ftop" > ${tmpd}/nvim/ftop
+mkdir -p "${tmpd}"/nvim
+mkdir -p "${tmpd}"/nvim/dir1
+echo "f1" > "${tmpd}"/nvim/dir1/file1
+mkdir -p "${tmpd}"/nvim/dir2
+echo "f1" > "${tmpd}"/nvim/dir2/file2
+echo "ftop" > "${tmpd}"/nvim/ftop
 
 echo "[+] import top"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -l link_children -p p1 ${tmpd}/nvim
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -l link_children -p p1 "${tmpd}"/nvim
 
 # add sub dir
-mkdir -p ${tmpd}/nvim/templated
-echo "noprofile" > ${tmpd}/nvim/templated/ftemplated
-echo "noprofile" > ${tmpd}/nvim/template
+mkdir -p "${tmpd}"/nvim/templated
+echo "noprofile" > "${tmpd}"/nvim/templated/ftemplated
+echo "noprofile" > "${tmpd}"/nvim/template
 
 echo "[+] import sub"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 ${tmpd}/nvim/templated
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 ${tmpd}/nvim/template
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 "${tmpd}"/nvim/templated
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 "${tmpd}"/nvim/template
 
 cfg2="${basedir}/config2.yaml"
-sed '/d_nvim:/a \ \ \ \ instignore:\n\ \ \ \ - "*template*"' ${cfg} > ${cfg2}
-cat ${cfg2}
+sed '/d_nvim:/a \ \ \ \ instignore:\n\ \ \ \ - "*template*"' "${cfg}" > "${cfg2}"
+cat "${cfg2}"
 
 ## clean destination files
-rm -rf ${tmpd}/nvim
+rm -rf "${tmpd}"/nvim
 ## patch template file
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/${tmpd}/nvim/templated/ftemplated
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/${tmpd}/nvim/template
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/"${tmpd}"/nvim/templated/ftemplated
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/"${tmpd}"/nvim/template
 
 echo "[+] install link_children"
-cd ${ddpath} | ${bin} install -f -c ${cfg2} -p p1 -V d_nvim
+cd "${ddpath}" | ${bin} install -f -c "${cfg2}" -p p1 -V d_nvim
 
-[ -d ${tmpd}/nvim/templated ] && echo "templated should not be installed" && exit 1
-[ -e ${tmpd}/nvim/templated/ftemplated ] && echo "templated file should not be installed" && exit 1
-[ -e ${tmpd}/nvim/template ] && echo "template file should not be installed" && exit 1
+[ -d "${tmpd}"/nvim/templated ] && echo "templated should not be installed" && exit 1
+[ -e "${tmpd}"/nvim/templated/ftemplated ] && echo "templated file should not be installed" && exit 1
+[ -e "${tmpd}"/nvim/template ] && echo "template file should not be installed" && exit 1
 
 echo "[+] install sub"
-cd ${ddpath} | ${bin} install -f -c ${cfg2} -p p1 -V d_templated
+cd "${ddpath}" | ${bin} install -f -c "${cfg2}" -p p1 -V d_templated
 echo "[+] install template"
-cd ${ddpath} | ${bin} install -f -c ${cfg2} -p p1 -V f_template
+cd "${ddpath}" | ${bin} install -f -c "${cfg2}" -p p1 -V f_template
 
-[ ! -d ${tmpd}/nvim/templated ] && echo "templated not installed" && exit 1
-[ ! -e ${tmpd}/nvim/templated/ftemplated ] && echo "templated file not installed" && exit 1
-[ ! -e ${tmpd}/nvim/template ] && echo "template file not installed" && exit 1
-grep 'p1' ${tmpd}/nvim/templated/ftemplated
-grep 'p1' ${tmpd}/nvim/template
+[ ! -d "${tmpd}"/nvim/templated ] && echo "templated not installed" && exit 1
+[ ! -e "${tmpd}"/nvim/templated/ftemplated ] && echo "templated file not installed" && exit 1
+[ ! -e "${tmpd}"/nvim/template ] && echo "template file not installed" && exit 1
+grep 'p1' "${tmpd}"/nvim/templated/ftemplated
+grep 'p1' "${tmpd}"/nvim/template
 
 echo "OK"
 exit 0
diff --git a/tests-ng/install-link-children.sh b/tests-ng/install-link-children.sh
index b2f0146..f6b03b8 100755
--- a/tests-ng/install-link-children.sh
+++ b/tests-ng/install-link-children.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -59,7 +38,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -80,34 +59,34 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-mkdir ${tmps}/dotfiles/dir1
-mkdir ${tmps}/dotfiles/dir1/empty
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir1/empty/this.ignore
-mkdir ${tmps}/dotfiles/dir1/not-empty
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir1/not-empty/file
-mkdir ${tmps}/dotfiles/dir1/sub
-mkdir ${tmps}/dotfiles/dir1/sub/empty
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir1/sub/empty/that.ignore
+mkdir "${tmps}"/dotfiles/dir1
+mkdir "${tmps}"/dotfiles/dir1/empty
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dir1/empty/this.ignore
+mkdir "${tmps}"/dotfiles/dir1/not-empty
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dir1/not-empty/file
+mkdir "${tmps}"/dotfiles/dir1/sub
+mkdir "${tmps}"/dotfiles/dir1/sub/empty
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/dir1/sub/empty/that.ignore
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 #cat ${cfg}
 
 # check normal
-[ ! -d ${tmpd}/dir1 ] && exit 1
-[ -d ${tmpd}/dir1/empty ] && exit 1
-[ -d ${tmpd}/dir1/sub ] && exit 1
-[ -d ${tmpd}/dir1/sub/empty ] && exit 1
-[ ! -d ${tmpd}/dir1/not-empty ] && exit 1
+[ ! -d "${tmpd}"/dir1 ] && exit 1
+[ -d "${tmpd}"/dir1/empty ] && exit 1
+[ -d "${tmpd}"/dir1/sub ] && exit 1
+[ -d "${tmpd}"/dir1/sub/empty ] && exit 1
+[ ! -d "${tmpd}"/dir1/not-empty ] && exit 1
 
-[ ! -e ${tmpd}/dir1/not-empty/file ] && exit 1
+[ ! -e "${tmpd}"/dir1/not-empty/file ] && exit 1
 
 # ignored files
-[ -e ${tmpd}/dir1/empty/this.ignore ] && exit 1
-[ -e ${tmpd}/dir1/sub/empty/that.ignore ] && exit 1
+[ -e "${tmpd}"/dir1/empty/this.ignore ] && exit 1
+[ -e "${tmpd}"/dir1/sub/empty/that.ignore ] && exit 1
 
-cat ${tmpd}/dir1/not-empty/file
-grep "p1" ${tmpd}/dir1/not-empty/file
+cat "${tmpd}"/dir1/not-empty/file
+grep "p1" "${tmpd}"/dir1/not-empty/file
 
 echo "OK"
 exit 0
diff --git a/tests-ng/install-negative-ignore.sh b/tests-ng/install-negative-ignore.sh
index 961d242..95b87c0 100755
--- a/tests-ng/install-negative-ignore.sh
+++ b/tests-ng/install-negative-ignore.sh
@@ -5,94 +5,49 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-if [ $(uname) = Darwin ]; then
-  # Unfortunately, readlink works differently on macOS than it does on GNU/Linux
-  # (the -f option behaves differently) and the realpath command does not exist.
-  # Workarounds I find on the Internet suggest just using Homebrew to install coreutils
-  # so you can get the GNU coreutils on your Mac. But, I don't want this script to
-  # assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
-  # they then installed the GNU coreutils.
-  readlink() {
-    TARGET_FILE=$1
-
-    cd `dirname $TARGET_FILE`
-    TARGET_FILE=`basename $TARGET_FILE`
-
-    # Iterate down a (possible) chain of symlinks
-    while [ -L "$TARGET_FILE" ]; do
-      TARGET_FILE=`readlink $TARGET_FILE`
-      cd `dirname $TARGET_FILE`
-      TARGET_FILE=`basename $TARGET_FILE`
-    done
-
-    # Compute the canonicalized name by finding the physical path
-    # for the directory we're in and appending the target file.
-    PHYS_DIR=`pwd -P`
-    RESULT=$PHYS_DIR/$TARGET_FILE
-    echo $RESULT
-  }
-  rl="readlink"
-else
-  rl="readlink -f"
-  if ! ${rl} "${0}" >/dev/null 2>&1; then
-    rl="realpath"
-
-    if ! hash ${rl}; then
-      echo "\"${rl}\" not found !" && exit 1
-    fi
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ -n "${1}" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # some files
-mkdir -p ${tmpd}/program/ignore_me
-echo "some data" > ${tmpd}/program/a
-echo "some data" > ${tmpd}/program/ignore_me/b
-echo "some data" > ${tmpd}/program/ignore_me/c
+mkdir -p "${tmpd}"/program/ignore_me
+echo "some data" > "${tmpd}"/program/a
+echo "some data" > "${tmpd}"/program/ignore_me/b
+echo "some data" > "${tmpd}"/program/ignore_me/c
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/program
 
 # adding ignore in dotfile
 cfg2="${basedir}/config2.yaml"
@@ -100,12 +55,12 @@ sed '/d_program:/a\
 \ \ \ \ instignore:\
 \ \ \ \ - "*/ignore_me/*"\
 \ \ \ \ - "!*/ignore_me/c"
-' ${cfg} > ${cfg2}
+' "${cfg}" > "${cfg2}"
 
 # install
-rm -rf ${tmpd}
+rm -rf "${tmpd}"
 echo "[+] install with negative ignore in dotfile"
-cd ${ddpath} | ${bin} install -c ${cfg2} --verbose
+cd "${ddpath}" | ${bin} install -c "${cfg2}" --verbose
 [ "$?" != "0" ] && exit 1
 echo '(1) expect structure to be
 .
@@ -114,11 +69,11 @@ echo '(1) expect structure to be
  └── ignore_me
     └── c'
 
-[[ -n "$(find ${tmpd}/program -name a)" ]] || exit 1
+[[ -n "$(find "${tmpd}"/program -name a)" ]] || exit 1
 echo "(1) found program/a ... good"
-[[ -n "$(find ${tmpd}/program/ignore_me -name b)" ]] && exit 1
+[[ -n "$(find "${tmpd}"/program/ignore_me -name b)" ]] && exit 1
 echo "(1) didn't find program/b ... good"
-[[ -n "$(find ${tmpd}/program/ignore_me -name c)" ]] || exit 1
+[[ -n "$(find "${tmpd}"/program/ignore_me -name c)" ]] || exit 1
 echo "(1) found program/c ... good"
 
 echo "OK"
diff --git a/tests-ng/install-to-temp.sh b/tests-ng/install-to-temp.sh
index 831970a..c8069f6 100755
--- a/tests-ng/install-to-temp.sh
+++ b/tests-ng/install-to-temp.sh
@@ -6,50 +6,29 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${basedir}/dotfiles
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${basedir}"/dotfiles
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
@@ -58,7 +37,7 @@ clear_on_exit "${tmpd}"
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -82,19 +61,19 @@ profiles:
     - f_z
 _EOF
 
-echo 'test_x' > ${basedir}/dotfiles/x
-echo 'test_y' > ${basedir}/dotfiles/y
-echo "00000000  01 02 03 04 05" | xxd -r - ${basedir}/dotfiles/z
+echo 'test_x' > "${basedir}"/dotfiles/x
+echo 'test_y' > "${basedir}"/dotfiles/y
+echo "00000000  01 02 03 04 05" | xxd -r - "${basedir}"/dotfiles/z
 
 echo "[+] install"
 log="${basedir}/log"
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 --showdiff --verbose --temp > ${log}
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 --showdiff --verbose --temp > "${log}"
 
-tmpfile=`cat ${basedir}/log | grep 'installed to tmp ' | sed 's/^.*to tmp "\(.*\)"./\1/'`
+tmpfile=$(cat "${basedir}"/log | grep 'installed to tmp ' | sed 's/^.*to tmp "\(.*\)"./\1/')
 echo "tmpfile: ${tmpfile}"
 clear_on_exit "${tmpfile}"
 
-cat ${log} | grep '^3 dotfile(s) installed.$'
+cat "${log}" | grep '^3 dotfile(s) installed.$'
 [ "$?" != "0" ] && exit 1
 
 echo "OK"
diff --git a/tests-ng/install.sh b/tests-ng/install.sh
index 5164330..21bf8ed 100755
--- a/tests-ng/install.sh
+++ b/tests-ng/install.sh
@@ -6,41 +6,20 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -48,8 +27,9 @@ echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
 
 get_file_mode()
 {
-  u=`umask`
-  u=`echo ${u} | sed 's/^0*//'`
+  u=$(umask)
+  # shellcheck disable=SC2001
+  u=$(echo "${u}" | sed 's/^0*//')
   v=$((666 - u))
   echo "${v}"
 }
@@ -59,27 +39,28 @@ get_file_mode()
 has_rights()
 {
   echo "testing ${1} is ${2}"
-  [ ! -e "$1" ] && echo "`basename $1` does not exist" && exit 1
-  local mode=`stat -L -c '%a' "$1"`
-  [ "${mode}" != "$2" ] && echo "bad mode for `basename $1` (${mode} VS expected ${2})" && exit 1
+  [ ! -e "$1" ] && echo "$(basename "$1") does not exist" && exit 1
+  local mode
+  mode=$(stat -L -c '%a' "$1")
+  [ "${mode}" != "$2" ] && echo "bad mode for $(basename "$1") (${mode} VS expected ${2})" && exit 1
   true
 }
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${basedir}/dotfiles
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${basedir}"/dotfiles
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
-echo "content" > ${basedir}/dotfiles/x
+echo "content" > "${basedir}"/dotfiles/x
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -95,31 +76,37 @@ profiles:
 _EOF
 
 echo "[+] install"
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p1 --verbose | grep '^1 dotfile(s) installed.$'
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 --verbose | grep '^1 dotfile(s) installed.$'
 [ "$?" != "0" ] && exit 1
 
-[ ! -e ${tmpd}/x ] && echo "f_x not installed" && exit 1
+[ ! -e "${tmpd}"/x ] && echo "f_x not installed" && exit 1
 
 # update chmod
-chmod 666 ${tmpd}/x
-cd ${ddpath} | ${bin} update -c ${cfg} -f -p p1 --verbose ${tmpd}/x
+chmod 666 "${tmpd}"/x
+cd "${ddpath}" | ${bin} update -c "${cfg}" -f -p p1 --verbose "${tmpd}"/x
 
 # chmod updated
-cat ${cfg} | grep "chmod: '666'"
+cat "${cfg}" | grep "chmod: '666'"
 
-chmod 644 ${tmpd}/x
+chmod 644 "${tmpd}"/x
 
-mode=`get_file_mode ${tmpd}/x`
+mode=$(get_file_mode "${tmpd}"/x)
 echo "[+] re-install with no"
-cd ${ddpath} | printf "N\n" | ${bin} install -c ${cfg} -p p1 --verbose
-[ "$?" != "0" ] && exit 1
+(
+  cd "${ddpath}"
+  printf "N\n" | ${bin} install -c "${cfg}" -p p1 --verbose
+  exit ${?}
+)
 
 # if user answers N, chmod should not be done
 has_rights "${tmpd}/x" "${mode}"
 
 echo "[+] re-install with yes"
-cd ${ddpath} | printf "y\n" | ${bin} install -c ${cfg} -p p1 --verbose
-[ "$?" != "0" ] && exit 1
+(
+  cd "${ddpath}"
+  printf "y\n" | ${bin} install -c "${cfg}" -p p1 --verbose
+  exit ${?}
+)
 
 has_rights "${tmpd}/x" "666"
 
diff --git a/tests-ng/jhelpers.sh b/tests-ng/jhelpers.sh
index c2067b1..86c54a2 100755
--- a/tests-ng/jhelpers.sh
+++ b/tests-ng/jhelpers.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -59,7 +38,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -80,25 +59,25 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "this is the test dotfile" > ${tmps}/dotfiles/abc
+echo "this is the test dotfile" > "${tmps}"/dotfiles/abc
 
 # test exists
-echo "{%@@ if exists('/dev/null') @@%}" >> ${tmps}/dotfiles/abc
-echo "this should exist" >> ${tmps}/dotfiles/abc
-echo "{%@@ endif @@%}" >> ${tmps}/dotfiles/abc
+echo "{%@@ if exists('/dev/null') @@%}" >> "${tmps}"/dotfiles/abc
+echo "this should exist" >> "${tmps}"/dotfiles/abc
+echo "{%@@ endif @@%}" >> "${tmps}"/dotfiles/abc
 
-echo "{%@@ if exists('/dev/abcdef') @@%}" >> ${tmps}/dotfiles/abc
-echo "this should not exist" >> ${tmps}/dotfiles/abc
-echo "{%@@ endif @@%}" >> ${tmps}/dotfiles/abc
+echo "{%@@ if exists('/dev/abcdef') @@%}" >> "${tmps}"/dotfiles/abc
+echo "this should not exist" >> "${tmps}"/dotfiles/abc
+echo "{%@@ endif @@%}" >> "${tmps}"/dotfiles/abc
 
 # test exists_in_path
-cat >> ${tmps}/dotfiles/abc << _EOF
+cat >> "${tmps}"/dotfiles/abc << _EOF
 {%@@ if exists_in_path('cat') @@%}
 this should exist too
 {%@@ endif @@%}
 _EOF
 
-cat >> ${tmps}/dotfiles/abc << _EOF
+cat >> "${tmps}"/dotfiles/abc << _EOF
 {%@@ if exists_in_path('a_name_that_is_unlikely_to_be_chosen_for_an_executable') @@%}
 this should not exist either
 {%@@ endif @@%}
@@ -106,16 +85,16 @@ _EOF
 
 #cat ${tmps}/dotfiles/abc
 
-echo "this is def" > ${tmps}/dotfiles/def
+echo "this is def" > "${tmps}"/dotfiles/def
 
 # test basename
-cat >> ${tmps}/dotfiles/def << _EOF
+cat >> "${tmps}"/dotfiles/def << _EOF
 {%@@ set dotfile_filename = basename( _dotfile_abs_dst ) @@%}
 dotfile dst filename: {{@@ dotfile_filename @@}}
 _EOF
 
 # test dirname
-cat >> ${tmps}/dotfiles/def << _EOF
+cat >> "${tmps}"/dotfiles/def << _EOF
 {%@@ set dotfile_dirname= dirname( _dotfile_abs_dst ) @@%}
 dotfile dst dirname: {{@@ dotfile_dirname @@}}
 _EOF
@@ -123,22 +102,22 @@ _EOF
 #cat ${tmps}/dotfiles/def
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 #cat ${tmpd}/abc
 
-grep '^this should exist' ${tmpd}/abc >/dev/null
-grep '^this should exist too' ${tmpd}/abc >/dev/null
+grep '^this should exist' "${tmpd}"/abc >/dev/null
+grep '^this should exist too' "${tmpd}"/abc >/dev/null
 set +e
-grep '^this should not exist' ${tmpd}/abc >/dev/null && exit 1
-grep '^this should not exist either' ${tmpd}/abc >/dev/null && exit 1
+grep '^this should not exist' "${tmpd}"/abc >/dev/null && exit 1
+grep '^this should not exist either' "${tmpd}"/abc >/dev/null && exit 1
 set -e
 
 #cat ${tmpd}/abc
 
 # test def
-grep "dotfile dst filename: `basename ${tmpd}/def`" ${tmpd}/def
-grep "dotfile dst dirname: `dirname ${tmpd}/def`" ${tmpd}/def
+grep "dotfile dst filename: $(basename "${tmpd}"/def)" "${tmpd}"/def
+grep "dotfile dst dirname: $(dirname "${tmpd}"/def)" "${tmpd}"/def
 
 echo "OK"
 exit 0
diff --git a/tests-ng/key-prefix-sep.sh b/tests-ng/key-prefix-sep.sh
index 35a6c31..67df4aa 100755
--- a/tests-ng/key-prefix-sep.sh
+++ b/tests-ng/key-prefix-sep.sh
@@ -5,67 +5,46 @@
 # test key_prefix and key_separator
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the dotfile
-mkdir -p ${tmpd}/top
-touch ${tmpd}/top/.colors
-mkdir -p ${tmpd}/.mutt/sub
-touch ${tmpd}/.mutt/sub/colors
+mkdir -p "${tmpd}"/top
+touch "${tmpd}"/top/.colors
+mkdir -p "${tmpd}"/.mutt/sub
+touch "${tmpd}"/.mutt/sub/colors
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
 # normal behavior
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -78,19 +57,19 @@ profiles:
 _EOF
 
 # import
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/top/.colors
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/.mutt/sub
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/top/.colors
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/.mutt/sub
 
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | cut -f1 -d',' | grep -q '_top_colors'
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | cut -f1 -d',' | grep -q '_mutt_sub'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | cut -f1 -d',' | grep -q '_top_colors'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | cut -f1 -d',' | grep -q '_mutt_sub'
 
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | cut -f1 -d',' | grep '_top_colors' | grep -q 'f_'
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | cut -f1 -d',' | grep '_mutt_sub' | grep -q 'd_'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | cut -f1 -d',' | grep '_top_colors' | grep -q 'f_'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | cut -f1 -d',' | grep '_mutt_sub' | grep -q 'd_'
 
 # pimping
-rm -rf ${tmps}/*
+rm -rf "${tmps:?}"/*
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -103,17 +82,17 @@ profiles:
 _EOF
 
 # import
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/top/.colors
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/.mutt/sub
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/top/.colors
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/.mutt/sub
 
-cat ${cfg}
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G
+cat "${cfg}"
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G
 
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | cut -f1 -d',' | grep -q '+top+colors'
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | cut -f1 -d',' | grep -q '+mutt+sub'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | cut -f1 -d',' | grep -q '+top+colors'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | cut -f1 -d',' | grep -q '+mutt+sub'
 
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | cut -f1 -d',' | grep '+top+colors' | grep -qv 'f_'
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -G | cut -f1 -d',' | grep '+mutt+sub' | grep -qv 'd_'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | cut -f1 -d',' | grep '+top+colors' | grep -qv 'f_'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -G | cut -f1 -d',' | grep '+mutt+sub' | grep -qv 'd_'
 
 echo "OK"
 exit 0
diff --git a/tests-ng/link-import-default.sh b/tests-ng/link-import-default.sh
index e792848..72769cf 100755
--- a/tests-ng/link-import-default.sh
+++ b/tests-ng/link-import-default.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -59,10 +38,10 @@ clear_on_exit "${tmpd}"
 cfg="${tmps}/config.yaml"
 
 # create the source
-echo "abc" > ${tmpd}/abc
+echo "abc" > "${tmpd}"/abc
 
 # import with nolink by default
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -73,18 +52,18 @@ profiles:
 _EOF
 
 # import
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/abc
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/abc
 
 # checks
 inside="${tmps}/dotfiles/${tmpd}/abc"
-[ ! -e ${inside} ] && exit 1
+[ ! -e "${inside}" ] && exit 1
 
 set +e
-cat ${cfg} | grep 'link:' && exit 1
+cat "${cfg}" | grep 'link:' && exit 1
 set -e
 
 # import with parent by default
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -95,14 +74,14 @@ profiles:
 _EOF
 
 # import
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/abc
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/abc
 
 # checks
 inside="${tmps}/dotfiles/${tmpd}/abc"
-[ ! -e ${inside} ] && exit 1
+[ ! -e "${inside}" ] && exit 1
 
-cat ${cfg}
-cat ${cfg} | grep 'link: absolute' >/dev/null
+cat "${cfg}"
+cat "${cfg}" | grep 'link: absolute' >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/link-templates-dir-home.sh b/tests-ng/link-templates-dir-home.sh
index b1bb603..60224cf 100755
--- a/tests-ng/link-templates-dir-home.sh
+++ b/tests-ng/link-templates-dir-home.sh
@@ -6,55 +6,34 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d -p ${HOME} --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d -p "${HOME}" --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 # the workdir
-tmpw=`mktemp -d -p ${HOME} --suffix='-dotdrop-tests' || mktemp -d`
+tmpw=$(mktemp -d -p "${HOME}" --suffix='-dotdrop-tests' || mktemp -d)
 export DOTDROP_WORKDIR="${tmpw}"
 echo "workdir: ${tmpw}"
 
@@ -65,7 +44,7 @@ clear_on_exit "${tmpw}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -84,21 +63,21 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-mkdir -p ${tmps}/dotfiles/abc
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/abc/template
-echo "blabla" >> ${tmps}/dotfiles/abc/template
-echo "blabla" > ${tmps}/dotfiles/abc/nottemplate
+mkdir -p "${tmps}"/dotfiles/abc
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/abc/template
+echo "blabla" >> "${tmps}"/dotfiles/abc/template
+echo "blabla" > "${tmps}"/dotfiles/abc/nottemplate
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 
 # checks
-[ ! -d ${tmpd}/abc ] && echo "[ERROR] dotfile not installed" && exit 1
-[ ! -h ${tmpd}/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
+[ ! -d "${tmpd}"/abc ] && echo "[ERROR] dotfile not installed" && exit 1
+[ ! -h "${tmpd}"/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
 #cat ${tmpd}/abc/template
 #tree -a ${tmpd}/abc/
 set +e
-grep '{{@@' ${tmpd}/abc/template >/dev/null 2>&1 && echo "[ERROR] template in dir not replace" && exit 1
+grep '{{@@' "${tmpd}"/abc/template >/dev/null 2>&1 && echo "[ERROR] template in dir not replace" && exit 1
 set -e
 
 echo "OK"
diff --git a/tests-ng/link-templates-dir.sh b/tests-ng/link-templates-dir.sh
index 77b8d5a..65d9dcb 100755
--- a/tests-ng/link-templates-dir.sh
+++ b/tests-ng/link-templates-dir.sh
@@ -6,55 +6,34 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 # the workdir
-tmpw=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpw=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 export DOTDROP_WORKDIR="${tmpw}"
 echo "workdir: ${tmpw}"
 
@@ -65,7 +44,7 @@ clear_on_exit "${tmpw}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -84,21 +63,21 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-mkdir -p ${tmps}/dotfiles/abc
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/abc/template
-echo "blabla" >> ${tmps}/dotfiles/abc/template
-echo "blabla" > ${tmps}/dotfiles/abc/nottemplate
+mkdir -p "${tmps}"/dotfiles/abc
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/abc/template
+echo "blabla" >> "${tmps}"/dotfiles/abc/template
+echo "blabla" > "${tmps}"/dotfiles/abc/nottemplate
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 
 # checks
-[ ! -d ${tmpd}/abc ] && echo "[ERROR] dotfile not installed" && exit 1
-[ ! -h ${tmpd}/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
+[ ! -d "${tmpd}"/abc ] && echo "[ERROR] dotfile not installed" && exit 1
+[ ! -h "${tmpd}"/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
 #cat ${tmpd}/abc/template
 #tree -a ${tmpd}/abc/
 set +e
-grep '{{@@' ${tmpd}/abc/template >/dev/null 2>&1 && echo "[ERROR] template in dir not replace" && exit 1
+grep '{{@@' "${tmpd}"/abc/template >/dev/null 2>&1 && echo "[ERROR] template in dir not replace" && exit 1
 set -e
 
 echo "OK"
diff --git a/tests-ng/link-templates.sh b/tests-ng/link-templates.sh
index 8a74a45..fb63fdf 100755
--- a/tests-ng/link-templates.sh
+++ b/tests-ng/link-templates.sh
@@ -6,55 +6,34 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 # the workdir
-tmpw=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpw=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 export DOTDROP_WORKDIR="${tmpw}"
 echo "workdir: ${tmpw}"
 
@@ -65,7 +44,7 @@ clear_on_exit "${tmpw}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -84,15 +63,15 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/abc
-echo "blabla" >> ${tmps}/dotfiles/abc
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/abc
+echo "blabla" >> "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 
 # checks
-[ ! -e ${tmpd}/abc ] && echo "[ERROR] dotfile not installed" && exit 1
-[ ! -h ${tmpd}/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
+[ ! -e "${tmpd}"/abc ] && echo "[ERROR] dotfile not installed" && exit 1
+[ ! -h "${tmpd}"/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/link-value-tests.sh b/tests-ng/link-value-tests.sh
index cdc40ea..682be82 100755
--- a/tests-ng/link-value-tests.sh
+++ b/tests-ng/link-value-tests.sh
@@ -7,51 +7,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -62,13 +41,13 @@ cfg="${tmps}/config.yaml"
 # ----------------------------------------------------------
 echo -e "\n======> import with all default"
 # create the source
-rm -rf ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert
+rm -rf "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -79,28 +58,28 @@ _EOF
 
 # import
 df="${tmpd}/qwert"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 ${df} -V
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 "${df}" -V
 
 # checks
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "f_`basename ${df}`" | head -1 | grep ',link:nolink,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "f_$(basename "${df}")" | head -1 | grep ',link:nolink,'
 
 # try to install
-rm -rf ${tmpd}/qwert
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ ! -e ${df} ] && echo "does not exist" && exit 1
-[ -h ${df} ] && echo "is symlink" && exit 1
+rm -rf "${tmpd}"/qwert
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ ! -e "${df}" ] && echo "does not exist" && exit 1
+[ -h "${df}" ] && echo "is symlink" && exit 1
 
 # ----------------------------------------------------------
 echo -e "\n======> import with link_on_import=nolink and link_dotfile_default=nolink"
 # create the source
-rm -rf ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert
+rm -rf "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -113,28 +92,28 @@ _EOF
 
 # import
 df="${tmpd}/qwert"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 ${df} -V
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 "${df}" -V
 
 # checks
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "f_`basename ${df}`" | head -1 | grep ',link:nolink,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "f_$(basename "${df}")" | head -1 | grep ',link:nolink,'
 
 # try to install
-rm -rf ${tmpd}/qwert
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ ! -e ${df} ] && echo "does not exist" && exit 1
-[ -h ${df} ] && echo "is symlink" && exit 1
+rm -rf "${tmpd}"/qwert
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ ! -e "${df}" ] && echo "does not exist" && exit 1
+[ -h "${df}" ] && echo "is symlink" && exit 1
 
 # ----------------------------------------------------------
 echo -e "\n======> import with link_on_import=nolink and link_dotfile_default=nolink and --link=nolink"
 # create the source
-rm -rf ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert
+rm -rf "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -147,28 +126,28 @@ _EOF
 
 # import
 df="${tmpd}/qwert"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 ${df} -V --link=nolink
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 "${df}" -V --link=nolink
 
 # checks
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "f_`basename ${df}`" | head -1 | grep ',link:nolink,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "f_$(basename "${df}")" | head -1 | grep ',link:nolink,'
 
 # try to install
-rm -rf ${tmpd}/qwert
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ ! -e ${df} ] && echo "does not exist" && exit 1
-[ -h ${df} ] && echo "is symlink" && exit 1
+rm -rf "${tmpd}"/qwert
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ ! -e "${df}" ] && echo "does not exist" && exit 1
+[ -h "${df}" ] && echo "is symlink" && exit 1
 
 # ----------------------------------------------------------
 echo -e "\n======> import with link_on_import=nolink and link_dotfile_default=nolink and --link=link"
 # create the source
-rm -rf ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert
+rm -rf "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -181,28 +160,28 @@ _EOF
 
 # import
 df="${tmpd}/qwert"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 ${df} -V --link=absolute
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 "${df}" -V --link=absolute
 
 # checks
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "f_`basename ${df}`" | head -1 | grep ',link:absolute,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "f_$(basename "${df}")" | head -1 | grep ',link:absolute,'
 
 # try to install
-rm -rf ${tmpd}/qwert
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ ! -e ${df} ] && echo "does not exist" && exit 1
-[ ! -h ${df} ] && echo "not symlink" && exit 1
+rm -rf "${tmpd}"/qwert
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ ! -e "${df}" ] && echo "does not exist" && exit 1
+[ ! -h "${df}" ] && echo "not symlink" && exit 1
 
 # ----------------------------------------------------------
 echo -e "\n======> import with link_on_import=link and link_dotfile_default=nolink"
 # create the source
-rm -rf ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert
+rm -rf "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -215,28 +194,28 @@ _EOF
 
 # import
 df="${tmpd}/qwert"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 ${df} -V
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 "${df}" -V
 
 # checks
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "f_`basename ${df}`" | head -1 | grep ',link:absolute,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "f_$(basename "${df}")" | head -1 | grep ',link:absolute,'
 
 # try to install
-rm -rf ${tmpd}/qwert
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ ! -e ${df} ] && echo "does not exist" && exit 1
-[ ! -h ${df} ] && echo "not symlink" && exit 1
+rm -rf "${tmpd}"/qwert
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ ! -e "${df}" ] && echo "does not exist" && exit 1
+[ ! -h "${df}" ] && echo "not symlink" && exit 1
 
 # ----------------------------------------------------------
 echo -e "\n======> import with link_on_import=link and link_dotfile_default=nolink and --link=nolink"
 # create the source
-rm -rf ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert
+rm -rf "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -249,28 +228,28 @@ _EOF
 
 # import
 df="${tmpd}/qwert"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 ${df} -V --link=nolink
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 "${df}" -V --link=nolink
 
 # checks
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "f_`basename ${df}`" | head -1 | grep ',link:nolink,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "f_$(basename "${df}")" | head -1 | grep ',link:nolink,'
 
 # try to install
-rm -rf ${tmpd}/qwert
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ ! -e ${df} ] && echo "does not exist" && exit 1
-[ -h ${df} ] && echo "is symlink" && exit 1
+rm -rf "${tmpd}"/qwert
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ ! -e "${df}" ] && echo "does not exist" && exit 1
+[ -h "${df}" ] && echo "is symlink" && exit 1
 
 # ----------------------------------------------------------
 echo -e "\n======> import with link_on_import=nolink and link_dotfile_default=link"
 # create the source
-rm -rf ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert
+rm -rf "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -283,28 +262,28 @@ _EOF
 
 # import
 df="${tmpd}/qwert"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 ${df} -V --link=nolink
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 "${df}" -V --link=nolink
 
 # checks
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "f_`basename ${df}`" | head -1 | grep ',link:nolink,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "f_$(basename "${df}")" | head -1 | grep ',link:nolink,'
 
 # try to install
-rm -rf ${tmpd}/qwert
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ ! -e ${df} ] && echo "does not exist" && exit 1
-[ -h ${df} ] && echo "is symlink" && exit 1
+rm -rf "${tmpd}"/qwert
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ ! -e "${df}" ] && echo "does not exist" && exit 1
+[ -h "${df}" ] && echo "is symlink" && exit 1
 
 # ----------------------------------------------------------
 echo -e "\n======> import with link_on_import=link and link_dotfile_default=nolink and --link=nolink"
 # create the source
-rm -rf ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert
+rm -rf "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -317,28 +296,28 @@ _EOF
 
 # import
 df="${tmpd}/qwert"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 ${df} -V --link=nolink
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 "${df}" -V --link=nolink
 
 # checks
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "f_`basename ${df}`" | head -1 | grep ',link:nolink,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "f_$(basename "${df}")" | head -1 | grep ',link:nolink,'
 
 # try to install
-rm -rf ${tmpd}/qwert
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ ! -e ${df} ] && echo "does not exist" && exit 1
-[ -h ${df} ] && echo "is symlink" && exit 1
+rm -rf "${tmpd}"/qwert
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ ! -e "${df}" ] && echo "does not exist" && exit 1
+[ -h "${df}" ] && echo "is symlink" && exit 1
 
 # ----------------------------------------------------------
 echo -e "\n======> import with all default and --link=link"
 # create the source
-rm -rf ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert
+rm -rf "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -349,28 +328,28 @@ _EOF
 
 # import
 df="${tmpd}/qwert"
-cd ${ddpath} | ${bin} import -f -c ${cfg} --link=absolute -p p1 ${df} -V
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" --link=absolute -p p1 "${df}" -V
 
 # checks
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "f_`basename ${df}`" | head -1 | grep ',link:absolute,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "f_$(basename "${df}")" | head -1 | grep ',link:absolute,'
 
 # try to install
-rm -rf ${tmpd}/qwert
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ ! -e ${df} ] && echo "does not exist" && exit 1
-[ ! -h ${df} ] && echo "not a symlink" && exit 1
+rm -rf "${tmpd}"/qwert
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ ! -e "${df}" ] && echo "does not exist" && exit 1
+[ ! -h "${df}" ] && echo "not a symlink" && exit 1
 
 # ----------------------------------------------------------
 echo -e "\n======> import with all default and --link=link_children"
 # create the source
-rm -rf ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert
+rm -rf "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -382,24 +361,24 @@ _EOF
 # import
 df="${tmpd}/qwert"
 set +e
-cd ${ddpath} | ${bin} import -f -c ${cfg} --link=link_children -p p1 ${df} -V
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" --link=link_children -p p1 "${df}" -V
 [ "$?" = "0" ] && echo "link_children with file should fail" && exit 1
 set -e
 
 # ----------------------------------------------------------
 echo -e "\n======> import with all default and --link=link_children"
 # create the source
-rm -rf ${tmpd}/qwert
-mkdir -p ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert/file
-mkdir -p ${tmpd}/qwert/directory
-echo "test" > ${tmpd}/qwert/directory/file
+rm -rf "${tmpd}"/qwert
+mkdir -p "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert/file
+mkdir -p "${tmpd}"/qwert/directory
+echo "test" > "${tmpd}"/qwert/directory/file
 
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -410,34 +389,34 @@ _EOF
 
 # import
 df="${tmpd}/qwert"
-cd ${ddpath} | ${bin} import -f -c ${cfg} --link=link_children -p p1 ${df} -V
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" --link=link_children -p p1 "${df}" -V
 
 # checks
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "d_`basename ${df}`" | head -1 | grep ',link:link_children,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "d_$(basename "${df}")" | head -1 | grep ',link:link_children,'
 
 # try to install
-rm -rf ${tmpd}/qwert
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ ! -e ${df} ] && echo "does not exist" && exit 1
-[ -h ${df} ] && echo "is a symlink" && exit 1
-[ ! -h ${df}/file ] && echo "file is not a symlink" && exit 1
-[ ! -h ${df}/directory ] && echo "directory is not a symlink" && exit 1
-[ -h ${df}/directory/file ] && echo "directory/file is a symlink" && exit 1
+rm -rf "${tmpd}"/qwert
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ ! -e "${df}" ] && echo "does not exist" && exit 1
+[ -h "${df}" ] && echo "is a symlink" && exit 1
+[ ! -h "${df}"/file ] && echo "file is not a symlink" && exit 1
+[ ! -h "${df}"/directory ] && echo "directory is not a symlink" && exit 1
+[ -h "${df}"/directory/file ] && echo "directory/file is a symlink" && exit 1
 
 echo -e "\n======> import with link_on_import=link_children and link_dotfile_default=nolink"
 # create the source
-rm -rf ${tmpd}/qwert
-mkdir -p ${tmpd}/qwert
-echo "test" > ${tmpd}/qwert/file
-mkdir -p ${tmpd}/qwert/directory
-echo "test" > ${tmpd}/qwert/directory/file
+rm -rf "${tmpd}"/qwert
+mkdir -p "${tmpd}"/qwert
+echo "test" > "${tmpd}"/qwert/file
+mkdir -p "${tmpd}"/qwert/directory
+echo "test" > "${tmpd}"/qwert/directory/file
 
 # clean
-rm -rf ${tmps}/dotfiles
-mkdir -p ${tmps}/dotfiles
+rm -rf "${tmps}"/dotfiles
+mkdir -p "${tmps}"/dotfiles
 # config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -450,20 +429,20 @@ _EOF
 
 # import
 df="${tmpd}/qwert"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 ${df} -V
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 "${df}" -V
 
 # checks
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V -G | grep "d_`basename ${df}`" | head -1 | grep ',link:link_children,'
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p1 -V -G | grep "d_$(basename "${df}")" | head -1 | grep ',link:link_children,'
 
 # try to install
-rm -rf ${tmpd}/qwert
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
-[ ! -e ${df} ] && echo "does not exist" && exit 1
-[ -h ${df} ] && echo "is a symlink" && exit 1
-[ ! -h ${df}/file ] && echo "file is not a symlink" && exit 1
-[ ! -h ${df}/directory ] && echo "directory is not a symlink" && exit 1
-[ -h ${df}/directory/file ] && echo "directory/file is a symlink" && exit 1
+rm -rf "${tmpd}"/qwert
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
+[ ! -e "${df}" ] && echo "does not exist" && exit 1
+[ -h "${df}" ] && echo "is a symlink" && exit 1
+[ ! -h "${df}"/file ] && echo "file is not a symlink" && exit 1
+[ ! -h "${df}"/directory ] && echo "directory is not a symlink" && exit 1
+[ -h "${df}"/directory/file ] && echo "directory/file is a symlink" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/macro-with-globals.sh b/tests-ng/macro-with-globals.sh
index d03e14f..7c4446e 100755
--- a/tests-ng/macro-with-globals.sh
+++ b/tests-ng/macro-with-globals.sh
@@ -5,51 +5,30 @@
 # import variables from file
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -57,7 +36,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -76,27 +55,27 @@ variables:
 _EOF
 
 # create the source
-mkdir -p ${tmps}/dotfiles/
+mkdir -p "${tmps}"/dotfiles/
 
-cat > ${tmps}/dotfiles/macro_file << _EOF
+cat > "${tmps}"/dotfiles/macro_file << _EOF
 {%@@ macro macro(var) @@%}
 {{@@ global @@}}
 {{@@ var @@}}
 {%@@ endmacro @@%}
 _EOF
 
-cat > ${tmps}/dotfiles/abc << _EOF
+cat > "${tmps}"/dotfiles/abc << _EOF
 {%@@ from 'macro_file' import macro with context @@%}
 {{@@ macro(local) @@}}
 _EOF
 
 # install
-cd ${ddpath} | ${bin} install -c ${cfg} -p p0 -V -f
+cd "${ddpath}" | ${bin} install -c "${cfg}" -p p0 -V -f
 
 # test file content
-cat ${tmpd}/abc
-grep 'global_var' ${tmpd}/abc >/dev/null 2>&1
-grep 'local_var' ${tmpd}/abc >/dev/null 2>&1
+cat "${tmpd}"/abc
+grep 'global_var' "${tmpd}"/abc >/dev/null 2>&1
+grep 'local_var' "${tmpd}"/abc >/dev/null 2>&1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/minversion.sh b/tests-ng/minversion.sh
index 616005a..21c44ef 100755
--- a/tests-ng/minversion.sh
+++ b/tests-ng/minversion.sh
@@ -4,57 +4,36 @@
 #
 # test minversion
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -71,20 +50,20 @@ profiles:
 _EOF
 
 # create the source
-mkdir -p ${tmps}/dotfiles/
-echo "abc" > ${tmps}/dotfiles/abc
-ln -s ${tmps}/dotfiles/abc ${tmpd}/abc
+mkdir -p "${tmps}"/dotfiles/
+echo "abc" > "${tmps}"/dotfiles/abc
+ln -s "${tmps}"/dotfiles/abc "${tmpd}"/abc
 
 # compare
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -V
 
 # ensure minversion is present
-cat ${cfg}
-grep 'link: absolute' ${cfg}
-grep 'minversion' ${cfg}
+cat "${cfg}"
+grep 'link: absolute' "${cfg}"
+grep 'minversion' "${cfg}"
 
 # fake a higher version
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -103,12 +82,12 @@ _EOF
 
 # compare
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -V
 [ "$?" != "1" ] && echo "minversion not working" && exit 1
 set -e
 
 # all clean
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -124,11 +103,11 @@ profiles:
 _EOF
 
 # compare
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -V
 
 # test
-cat ${cfg}
-grep 'minversion' ${cfg} && echo "minversion added, not needed" && exit 1
+cat "${cfg}"
+grep 'minversion' "${cfg}" && echo "minversion added, not needed" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/misc.sh b/tests-ng/misc.sh
new file mode 100755
index 0000000..281dcb0
--- /dev/null
+++ b/tests-ng/misc.sh
@@ -0,0 +1,112 @@
+#!/usr/bin/env bash
+# author: deadc0de6 (https://github.com/deadc0de6)
+# Copyright (c) 2023, deadc0de6
+#
+# test misc stuff
+# returns 1 in case of error
+#
+
+## start-cookie
+set -e
+cur=$(cd "$(dirname "${0}")" && pwd)
+ddpath="${cur}/../"
+export PYTHONPATH="${ddpath}:${PYTHONPATH}"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
+
+################################################################
+# this is the test
+################################################################
+
+# dotdrop directory
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${basedir}"/dotfiles
+echo "[+] dotdrop dir: ${basedir}"
+echo "[+] dotpath dir: ${basedir}/dotfiles"
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+
+clear_on_exit "${basedir}"
+clear_on_exit "${tmpd}"
+
+echo "content" > "${basedir}"/dotfiles/x
+
+# create the config file
+cfg="${basedir}/config.yaml"
+cat > "${cfg}" << _EOF
+config:
+  backup: true
+  create: true
+  dotpath: dotfiles
+dotfiles:
+  f_x:
+    src: x
+    dst: ${tmpd}/x
+  f_fake:
+    src:
+    dst:
+profiles:
+  p1:
+    dotfiles:
+    - f_x
+  p2:
+    dotfiles:
+  p3:
+    dotfiles:
+    - f_fake
+_EOF
+
+echo "[+] compare - does not exist on dst"
+set +e
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 --verbose
+[ "$?" = "0" ] && exit 1
+set -e
+
+echo "[+] install - no dotfiles"
+set +e
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p2 --verbose
+[ "$?" = "0" ] && exit 1
+set -e
+
+echo "[+] compare - no dotfiles"
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p2 --verbose
+[ "$?" != "0" ] && exit 1
+
+echo "[+] compare - fake dotfile"
+cd "${ddpath}" | ${bin} compare -w1 -c "${cfg}" -p p3 --verbose
+[ "$?" != "0" ] && exit 1
+
+echo "[+] compare - fake dotfile"
+cd "${ddpath}" | ${bin} compare -w3 -c "${cfg}" -p p3 --verbose
+[ "$?" != "0" ] && exit 1
+
+set +e
+echo "[+] update - bad profile"
+cd "${ddpath}" | ${bin} update -c "${cfg}" -p p4 --verbose
+[ "$?" = "0" ] && exit 1
+set -e
+
+echo "[+] grepable profiles"
+cd "${ddpath}" | ${bin} profiles -c "${cfg}" --grepable --verbose
+[ "$?" != "0" ] && exit 1
+
+echo "[+] files - bad profile but return 0"
+cd "${ddpath}" | ${bin} files -c "${cfg}" -p p10 --verbose
+[ "$?" != "0" ] && exit 1
+
+echo "[+] detail - bad profile but return 0"
+cd "${ddpath}" | ${bin} detail -c "${cfg}" -p p10 --verbose
+[ "$?" != "0" ] && exit 1
+
+echo "[+] remove - no dotfiles"
+cd "${ddpath}" | ${bin} remove -c "${cfg}" -p p2 --verbose
+[ "$?" != "0" ] && exit 1
+
+echo "OK"
+exit 0
diff --git a/tests-ng/negative-ignore-no-match.sh b/tests-ng/negative-ignore-no-match.sh
index e0ca76b..14b05b0 100755
--- a/tests-ng/negative-ignore-no-match.sh
+++ b/tests-ng/negative-ignore-no-match.sh
@@ -6,110 +6,65 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-if [ $(uname) = Darwin ]; then
-  # Unfortunately, readlink works differently on macOS than it does on GNU/Linux
-  # (the -f option behaves differently) and the realpath command does not exist.
-  # Workarounds I find on the Internet suggest just using Homebrew to install coreutils
-  # so you can get the GNU coreutils on your Mac. But, I don't want this script to
-  # assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
-  # they then installed the GNU coreutils.
-  readlink() {
-    TARGET_FILE=$1
-
-    cd `dirname $TARGET_FILE`
-    TARGET_FILE=`basename $TARGET_FILE`
-
-    # Iterate down a (possible) chain of symlinks
-    while [ -L "$TARGET_FILE" ]; do
-      TARGET_FILE=`readlink $TARGET_FILE`
-      cd `dirname $TARGET_FILE`
-      TARGET_FILE=`basename $TARGET_FILE`
-    done
-
-    # Compute the canonicalized name by finding the physical path
-    # for the directory we're in and appending the target file.
-    PHYS_DIR=`pwd -P`
-    RESULT=$PHYS_DIR/$TARGET_FILE
-    echo $RESULT
-  }
-  rl="readlink"
-else
-  rl="readlink -f"
-  if ! ${rl} "${0}" >/dev/null 2>&1; then
-    rl="realpath"
-
-    if ! hash ${rl}; then
-      echo "\"${rl}\" not found !" && exit 1
-    fi
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ -n "${1}" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # some files
-mkdir -p ${tmpd}/program/ignore_me
-echo "some data" > ${tmpd}/program/a
-echo "some data" > ${tmpd}/program/ignore_me/b
-echo "some data" > ${tmpd}/program/ignore_me/c
+mkdir -p "${tmpd}"/program/ignore_me
+echo "some data" > "${tmpd}"/program/a
+echo "some data" > "${tmpd}"/program/ignore_me/b
+echo "some data" > "${tmpd}"/program/ignore_me/c
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/program
 
 # adding ignore in dotfile
 cfg2="${basedir}/config2.yaml"
 sed '/d_program:/a\
 \ \ \ \ instignore:\
 \ \ \ \ - "!*/ignore_me/c"
-' ${cfg} > ${cfg2}
+' "${cfg}" > "${cfg2}"
 
 # install
-rm -rf ${tmpd}
+rm -rf "${tmpd}"
 echo "[+] install with negative ignore in dotfile"
 echo '(1) expect dotdrop install to warn when negative ignore pattern does not match an already-ignored file'
 
 patt="[WARN] no files that are currently being ignored match \"*/ignore_me/c\". In order for a negative ignore
 pattern to work, it must match a file that is being ignored by a previous ignore pattern."
-cd ${ddpath} | ${bin} install -c ${cfg2} --verbose 2>&1 >/dev/null | grep -F "${patt}" ||
+cd "${ddpath}" | ${bin} install -c "${cfg2}" --verbose 2>&1 >/dev/null | grep -F "${patt}" ||
   (echo "dotdrop did not warn when negative ignore pattern did not match an already-ignored file" && exit 1)
 
 echo "OK"
diff --git a/tests-ng/notemplate.sh b/tests-ng/notemplate.sh
index e8bb451..7f5b6ae 100755
--- a/tests-ng/notemplate.sh
+++ b/tests-ng/notemplate.sh
@@ -6,52 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 #echo "dotfile source: ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -61,7 +40,7 @@ clear_on_exit "${tmpd}"
 cfg="${tmps}/config.yaml"
 
 # globally
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -103,93 +82,93 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "before" > ${tmps}/dotfiles/f1
-echo "{#@@ should not be stripped @@#}" >> ${tmps}/dotfiles/f1
-echo "{{@@ header() @@}}" >> ${tmps}/dotfiles/f1
-echo "after" >> ${tmps}/dotfiles/f1
+echo "before" > "${tmps}"/dotfiles/f1
+echo "{#@@ should not be stripped @@#}" >> "${tmps}"/dotfiles/f1
+echo "{{@@ header() @@}}" >> "${tmps}"/dotfiles/f1
+echo "after" >> "${tmps}"/dotfiles/f1
 
 # create the directory
-mkdir -p ${tmps}/dotfiles/dir1/d1
-echo "{{@@ header() @@}}" > ${tmps}/dotfiles/dir1/d1/f2
+mkdir -p "${tmps}"/dotfiles/dir1/d1
+echo "{{@@ header() @@}}" > "${tmps}"/dotfiles/dir1/d1/f2
 
 # create the linked directory
-mkdir -p ${tmps}/dotfiles/dir2/d1
-echo "{{@@ header() @@}}" > ${tmps}/dotfiles/dir2/d1/f2
+mkdir -p "${tmps}"/dotfiles/dir2/d1
+echo "{{@@ header() @@}}" > "${tmps}"/dotfiles/dir2/d1/f2
 
 # create the link_children directory
-mkdir -p ${tmps}/dotfiles/dir3/{s1,s2,s3}
-echo "{{@@ header() @@}}" > ${tmps}/dotfiles/dir3/s1/f1
-echo "{{@@ header() @@}}" > ${tmps}/dotfiles/dir3/s2/f2
+mkdir -p "${tmps}"/dotfiles/dir3/{s1,s2,s3}
+echo "{{@@ header() @@}}" > "${tmps}"/dotfiles/dir3/s1/f1
+echo "{{@@ header() @@}}" > "${tmps}"/dotfiles/dir3/s2/f2
 
 # create the linked dotfile
-echo "{{@@ header() @@}}" > ${tmps}/dotfiles/fl
+echo "{{@@ header() @@}}" > "${tmps}"/dotfiles/fl
 
 # create the normal dotfile
-echo "before" > ${tmps}/dotfiles/fn
-echo "{#@@ should be stripped @@#}" >> ${tmps}/dotfiles/fn
-echo "after" >> ${tmps}/dotfiles/fn
+echo "before" > "${tmps}"/dotfiles/fn
+echo "{#@@ should be stripped @@#}" >> "${tmps}"/dotfiles/fn
+echo "after" >> "${tmps}"/dotfiles/fn
 
 # install
 echo "installing"
-cd ${ddpath} | ${bin} install -f --showdiff -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f --showdiff -c "${cfg}" -p p1 -V
 echo "comparing"
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -V
 
 # simple file
 echo "doing globally"
 echo "* test simple file"
-[ ! -e ${tmpd}/f1 ] && echo 'not installed1' && exit 1
-grep 'header' ${tmpd}/f1 || (echo "header stripped" && exit 1)
-grep 'should not be stripped' ${tmpd}/f1 || (echo "comment stripped" && exit 1)
+[ ! -e "${tmpd}"/f1 ] && echo 'not installed1' && exit 1
+grep 'header' "${tmpd}"/f1 || (echo "header stripped" && exit 1)
+grep 'should not be stripped' "${tmpd}"/f1 || (echo "comment stripped" && exit 1)
 
 # directory
 echo "* test directory"
-[ ! -d ${tmpd}/dir1 ] && echo 'not installed1' && exit 1
-[ ! -d ${tmpd}/dir1/d1 ] && echo 'not installed2' && exit 1
-[ ! -e ${tmpd}/dir1/d1/f2 ] && echo 'not installed3' && exit 1
-grep 'header' ${tmpd}/dir1/d1/f2 || (echo "header stripped" && exit 1)
+[ ! -d "${tmpd}"/dir1 ] && echo 'not installed1' && exit 1
+[ ! -d "${tmpd}"/dir1/d1 ] && echo 'not installed2' && exit 1
+[ ! -e "${tmpd}"/dir1/d1/f2 ] && echo 'not installed3' && exit 1
+grep 'header' "${tmpd}"/dir1/d1/f2 || (echo "header stripped" && exit 1)
 
 # linked directory
 echo "* test linked directory"
-[ ! -h ${tmpd}/dir2 ] && echo 'not installed1' && exit 1
-[ ! -d ${tmpd}/dir2/d1 ] && echo 'not installed2' && exit 1
-[ ! -e ${tmpd}/dir2/d1/f2 ] && echo 'not installed3' && exit 1
-grep 'header' ${tmpd}/dir2/d1/f2 || (echo "header stripped" && exit 1)
+[ ! -h "${tmpd}"/dir2 ] && echo 'not installed1' && exit 1
+[ ! -d "${tmpd}"/dir2/d1 ] && echo 'not installed2' && exit 1
+[ ! -e "${tmpd}"/dir2/d1/f2 ] && echo 'not installed3' && exit 1
+grep 'header' "${tmpd}"/dir2/d1/f2 || (echo "header stripped" && exit 1)
 
 # children_link directory
 echo "* test link_children directory"
-[ ! -d ${tmpd}/dir3 ] && echo 'not installed1' && exit 1
-[ ! -h ${tmpd}/dir3/s1 ] && echo 'not installed2' && exit 1
-[ ! -h ${tmpd}/dir3/s2 ] && echo 'not installed3' && exit 1
-[ ! -h ${tmpd}/dir3/s3 ] && echo 'not installed4' && exit 1
-[ ! -e ${tmpd}/dir3/s1/f1 ] && echo 'not installed5' && exit 1
-[ ! -e ${tmpd}/dir3/s2/f2 ] && echo 'not installed6' && exit 1
-grep 'header' ${tmpd}/dir3/s1/f1 || (echo "header stripped" && exit 1)
-grep 'header' ${tmpd}/dir3/s2/f2 || (echo "header stripped" && exit 1)
+[ ! -d "${tmpd}"/dir3 ] && echo 'not installed1' && exit 1
+[ ! -h "${tmpd}"/dir3/s1 ] && echo 'not installed2' && exit 1
+[ ! -h "${tmpd}"/dir3/s2 ] && echo 'not installed3' && exit 1
+[ ! -h "${tmpd}"/dir3/s3 ] && echo 'not installed4' && exit 1
+[ ! -e "${tmpd}"/dir3/s1/f1 ] && echo 'not installed5' && exit 1
+[ ! -e "${tmpd}"/dir3/s2/f2 ] && echo 'not installed6' && exit 1
+grep 'header' "${tmpd}"/dir3/s1/f1 || (echo "header stripped" && exit 1)
+grep 'header' "${tmpd}"/dir3/s2/f2 || (echo "header stripped" && exit 1)
 
 # linked file
 echo "* test linked file"
-[ ! -h ${tmpd}/fl ] && echo 'not installed' && exit 1
-grep 'header' ${tmpd}/f1 || (echo "header stripped" && exit 1)
+[ ! -h "${tmpd}"/fl ] && echo 'not installed' && exit 1
+grep 'header' "${tmpd}"/f1 || (echo "header stripped" && exit 1)
 
 # normal dotfile
 echo "* normal dotfile"
-[ ! -e ${tmpd}/fn ] && echo 'not installed' && exit 1
-grep 'should be stripped' ${tmpd}/fn && echo "not templated" && exit 1
+[ ! -e "${tmpd}"/fn ] && echo 'not installed' && exit 1
+grep 'should be stripped' "${tmpd}"/fn && echo "not templated" && exit 1
 
 # test backup done
-echo "before" > ${tmps}/dotfiles/f1
-cd ${ddpath} | ${bin} install -f --showdiff -c ${cfg} -p p1 -V
-[ ! -e ${tmpd}/f1.dotdropbak ] && echo "backup not done" && exit 1
+echo "before" > "${tmps}"/dotfiles/f1
+cd "${ddpath}" | ${bin} install -f --showdiff -c "${cfg}" -p p1 -V
+[ ! -e "${tmpd}"/f1.dotdropbak ] && echo "backup not done" && exit 1
 
 # re-create the dotfile
-echo "before" > ${tmps}/dotfiles/f1
-echo "{#@@ should not be stripped @@#}" >> ${tmps}/dotfiles/f1
-echo "{{@@ header() @@}}" >> ${tmps}/dotfiles/f1
-echo "after" >> ${tmps}/dotfiles/f1
+echo "before" > "${tmps}"/dotfiles/f1
+echo "{#@@ should not be stripped @@#}" >> "${tmps}"/dotfiles/f1
+echo "{{@@ header() @@}}" >> "${tmps}"/dotfiles/f1
+echo "after" >> "${tmps}"/dotfiles/f1
 
 # through the dotfile
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -235,53 +214,53 @@ _EOF
 #cat ${cfg}
 
 # clean destination
-rm -rf ${tmpd}/*
+rm -rf "${tmpd:?}"/*
 
 # install
-cd ${ddpath} | ${bin} install -f --showdiff -c ${cfg} -p p1 -V
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f --showdiff -c "${cfg}" -p p1 -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -V
 
 # simple file
 echo "doing specifically"
 echo "* test simple file"
-[ ! -e ${tmpd}/f1 ] && echo 'not installed1' && exit 1
-grep 'header' ${tmpd}/f1 || (echo "header stripped" && exit 1)
-grep 'should not be stripped' ${tmpd}/f1 || (echo "comment stripped" && exit 1)
+[ ! -e "${tmpd}"/f1 ] && echo 'not installed1' && exit 1
+grep 'header' "${tmpd}"/f1 || (echo "header stripped" && exit 1)
+grep 'should not be stripped' "${tmpd}"/f1 || (echo "comment stripped" && exit 1)
 
 # directory
 echo "* test directory"
-[ ! -d ${tmpd}/dir1 ] && echo 'not installed1' && exit 1
-[ ! -d ${tmpd}/dir1/d1 ] && echo 'not installed2' && exit 1
-[ ! -e ${tmpd}/dir1/d1/f2 ] && echo 'not installed3' && exit 1
-grep 'header' ${tmpd}/dir1/d1/f2 || (echo "header stripped" && exit 1)
+[ ! -d "${tmpd}"/dir1 ] && echo 'not installed1' && exit 1
+[ ! -d "${tmpd}"/dir1/d1 ] && echo 'not installed2' && exit 1
+[ ! -e "${tmpd}"/dir1/d1/f2 ] && echo 'not installed3' && exit 1
+grep 'header' "${tmpd}"/dir1/d1/f2 || (echo "header stripped" && exit 1)
 
 # linked directory
 echo "* test linked directory"
-[ ! -h ${tmpd}/dir2 ] && echo 'not installed1' && exit 1
-[ ! -d ${tmpd}/dir2/d1 ] && echo 'not installed2' && exit 1
-[ ! -e ${tmpd}/dir2/d1/f2 ] && echo 'not installed3' && exit 1
-grep 'header' ${tmpd}/dir2/d1/f2 || (echo "header stripped" && exit 1)
+[ ! -h "${tmpd}"/dir2 ] && echo 'not installed1' && exit 1
+[ ! -d "${tmpd}"/dir2/d1 ] && echo 'not installed2' && exit 1
+[ ! -e "${tmpd}"/dir2/d1/f2 ] && echo 'not installed3' && exit 1
+grep 'header' "${tmpd}"/dir2/d1/f2 || (echo "header stripped" && exit 1)
 
 # children_link directory
 echo "* test link_children directory"
-[ ! -d ${tmpd}/dir3 ] && echo 'not installed1' && exit 1
-[ ! -h ${tmpd}/dir3/s1 ] && echo 'not installed2' && exit 1
-[ ! -h ${tmpd}/dir3/s2 ] && echo 'not installed3' && exit 1
-[ ! -h ${tmpd}/dir3/s3 ] && echo 'not installed4' && exit 1
-[ ! -e ${tmpd}/dir3/s1/f1 ] && echo 'not installed5' && exit 1
-[ ! -e ${tmpd}/dir3/s2/f2 ] && echo 'not installed6' && exit 1
-grep 'header' ${tmpd}/dir3/s1/f1 || (echo "header stripped" && exit 1)
-grep 'header' ${tmpd}/dir3/s2/f2 || (echo "header stripped" && exit 1)
+[ ! -d "${tmpd}"/dir3 ] && echo 'not installed1' && exit 1
+[ ! -h "${tmpd}"/dir3/s1 ] && echo 'not installed2' && exit 1
+[ ! -h "${tmpd}"/dir3/s2 ] && echo 'not installed3' && exit 1
+[ ! -h "${tmpd}"/dir3/s3 ] && echo 'not installed4' && exit 1
+[ ! -e "${tmpd}"/dir3/s1/f1 ] && echo 'not installed5' && exit 1
+[ ! -e "${tmpd}"/dir3/s2/f2 ] && echo 'not installed6' && exit 1
+grep 'header' "${tmpd}"/dir3/s1/f1 || (echo "header stripped" && exit 1)
+grep 'header' "${tmpd}"/dir3/s2/f2 || (echo "header stripped" && exit 1)
 
 # linked file
 echo "* test linked file"
-[ ! -h ${tmpd}/fl ] && echo 'not installed' && exit 1
-grep 'header' ${tmpd}/f1 || (echo "header stripped" && exit 1)
+[ ! -h "${tmpd}"/fl ] && echo 'not installed' && exit 1
+grep 'header' "${tmpd}"/f1 || (echo "header stripped" && exit 1)
 
 # normal dotfile
 echo "* normal dotfile"
-[ ! -e ${tmpd}/fn ] && echo 'not installed' && exit 1
-grep 'should not be stripped' ${tmpd}/fn && echo "no templated" && exit 1
+[ ! -e "${tmpd}"/fn ] && echo 'not installed' && exit 1
+grep 'should not be stripped' "${tmpd}"/fn && echo "no templated" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/profile-actions.sh b/tests-ng/profile-actions.sh
index c050efe..5d78809 100755
--- a/tests-ng/profile-actions.sh
+++ b/tests-ng/profile-actions.sh
@@ -6,54 +6,33 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 # the action temp
-tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpa=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -62,7 +41,7 @@ clear_on_exit "${tmpa}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -99,40 +78,40 @@ _EOF
 #cat ${cfg}
 
 # list profiles
-cd ${ddpath} | ${bin} profiles -c ${cfg} -V
+cd "${ddpath}" | ${bin} profiles -c "${cfg}" -V
 
 # create the dotfile
-echo "test" > ${tmps}/dotfiles/abc
-echo "test" > ${tmps}/dotfiles/def
-echo "test" > ${tmps}/dotfiles/ghi
+echo "test" > "${tmps}"/dotfiles/abc
+echo "test" > "${tmps}"/dotfiles/def
+echo "test" > "${tmps}"/dotfiles/ghi
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p0 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p0 -V
 
 # check actions executed
-[ ! -e ${tmpa}/pre2 ] && echo 'action not executed' && exit 1
-[ ! -e ${tmpa}/post2 ] && echo 'action not executed' && exit 1
-[ ! -e ${tmpa}/naked ] && echo 'action not executed' && exit 1
+[ ! -e "${tmpa}"/pre2 ] && echo 'action not executed' && exit 1
+[ ! -e "${tmpa}"/post2 ] && echo 'action not executed' && exit 1
+[ ! -e "${tmpa}"/naked ] && echo 'action not executed' && exit 1
 
-grep pre2 ${tmpa}/pre2
-nb=`wc -l ${tmpa}/pre2 | awk '{print $1}'`
+grep pre2 "${tmpa}"/pre2
+nb=$(wc -l "${tmpa}"/pre2 | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "profile action executed multiple times" && exit 1
 
-grep post2 ${tmpa}/post2
-nb=`wc -l ${tmpa}/post2 | awk '{print $1}'`
+grep post2 "${tmpa}"/post2
+nb=$(wc -l "${tmpa}"/post2 | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "profile action executed multiple times" && exit 1
 
-grep naked ${tmpa}/naked
-nb=`wc -l ${tmpa}/naked | awk '{print $1}'`
+grep naked "${tmpa}"/naked
+nb=$(wc -l "${tmpa}"/naked | awk '{print $1}')
 [ "${nb}" != "1" ] && echo "profile action executed multiple times" && exit 1
 
 # install again
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p0 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p0 -V
 
 # check actions not executed twice
-nb=`wc -l ${tmpa}/post2 | awk '{print $1}'`
+nb=$(wc -l "${tmpa}"/post2 | awk '{print $1}')
 [ "${nb}" -gt "1" ] && echo "action post2 executed twice" && exit 1
-nb=`wc -l ${tmpa}/naked | awk '{print $1}'`
+nb=$(wc -l "${tmpa}"/naked | awk '{print $1}')
 [ "${nb}" -gt "1" ] && echo "action naked executed twice" && exit 1
 
 echo "OK"
diff --git a/tests-ng/profile-dyninclude.sh b/tests-ng/profile-dyninclude.sh
index 94bd7c8..239d515 100755
--- a/tests-ng/profile-dyninclude.sh
+++ b/tests-ng/profile-dyninclude.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -59,7 +38,7 @@ clear_on_exit "${tmpd}"
 cfg="${tmps}/config.yaml"
 cfg2="${tmps}/sub.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   dotpath: dotfiles
   import_configs:
@@ -85,7 +64,7 @@ profiles:
 _EOF
 #cat ${cfg}
 
-cat > ${cfg2} << _EOF
+cat > "${cfg2}" << _EOF
 config:
 dotfiles:
   f_abc:
@@ -120,26 +99,26 @@ _EOF
 #cat ${cfg2}
 
 # create the dotfile
-echo "start" > ${tmps}/dotfiles/abc
-echo "{{@@ mainvar @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ maindyn @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ subdyn @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ subvar @@}}" >> ${tmps}/dotfiles/abc
-echo "end" >> ${tmps}/dotfiles/abc
+echo "start" > "${tmps}"/dotfiles/abc
+echo "{{@@ mainvar @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ maindyn @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ subdyn @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ subvar @@}}" >> "${tmps}"/dotfiles/abc
+echo "end" >> "${tmps}"/dotfiles/abc
 #cat ${tmps}/dotfiles/abc
-echo "ghi content" > ${tmps}/dotfiles/ghi
+echo "ghi content" > "${tmps}"/dotfiles/ghi
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p profile_1 --verbose
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p profile_1 --verbose
 
 # check dotfile exists
-[ ! -e ${tmpd}/abc ] && exit 1
-grep 'maincontent' ${tmpd}/abc >/dev/null || (echo "variables 1 not resolved" && exit 1)
-grep 'maindyncontent' ${tmpd}/abc >/dev/null || (echo "dynvariables 1 not resolved"  && exit 1)
-grep 'subcontent' ${tmpd}/abc >/dev/null || (echo "variables 2 not resolved" && exit 1)
-grep 'subdyncontent' ${tmpd}/abc >/dev/null || (echo "dynvariables 2 not resolved" && exit 1)
+[ ! -e "${tmpd}"/abc ] && exit 1
+grep 'maincontent' "${tmpd}"/abc >/dev/null || (echo "variables 1 not resolved" && exit 1)
+grep 'maindyncontent' "${tmpd}"/abc >/dev/null || (echo "dynvariables 1 not resolved"  && exit 1)
+grep 'subcontent' "${tmpd}"/abc >/dev/null || (echo "variables 2 not resolved" && exit 1)
+grep 'subdyncontent' "${tmpd}"/abc >/dev/null || (echo "dynvariables 2 not resolved" && exit 1)
 #cat ${tmpd}/abc
-[ ! -e ${tmpd}/ghi ] && exit 1
+[ ! -e "${tmpd}"/ghi ] && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/profile-dynvariables.sh b/tests-ng/profile-dynvariables.sh
index b7323ae..5ed42db 100755
--- a/tests-ng/profile-dynvariables.sh
+++ b/tests-ng/profile-dynvariables.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -58,14 +37,14 @@ clear_on_exit "${tmpd}"
 
 # create a shell script
 export TESTENV="this is my global testenv"
-scr=`mktemp --suffix='-dotdrop-tests' || mktemp -d`
-chmod +x ${scr}
-echo -e "#!/bin/bash\necho $TESTENV\n" >> ${scr}
+scr=$(mktemp --suffix='-dotdrop-tests' || mktemp -d)
+chmod +x "${scr}"
+echo -e "#!/bin/bash\necho $TESTENV\n" >> "${scr}"
 
 export TESTENV2="this is my profile testenv"
-scr2=`mktemp --suffix='-dotdrop-tests' || mktemp -d`
-chmod +x ${scr2}
-echo -e "#!/bin/bash\necho $TESTENV2\n" >> ${scr2}
+scr2=$(mktemp --suffix='-dotdrop-tests' || mktemp -d)
+chmod +x "${scr2}"
+echo -e "#!/bin/bash\necho $TESTENV2\n" >> "${scr2}"
 
 clear_on_exit "${scr}"
 clear_on_exit "${scr2}"
@@ -73,7 +52,7 @@ clear_on_exit "${scr2}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -103,30 +82,30 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "===================" > ${tmps}/dotfiles/abc
-echo "{{@@ gvar1 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ gvar2 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ gdvar1 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ gdvar2 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ gdvar3 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ lvar1 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ pdvar1 @@}}" >> ${tmps}/dotfiles/abc
-echo "===================" >> ${tmps}/dotfiles/abc
+echo "===================" > "${tmps}"/dotfiles/abc
+echo "{{@@ gvar1 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ gvar2 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ gdvar1 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ gdvar2 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ gdvar3 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ lvar1 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ pdvar1 @@}}" >> "${tmps}"/dotfiles/abc
+echo "===================" >> "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
-cat ${tmpd}/abc
+cat "${tmpd}"/abc
 
 # test variables
-grep '^local1' ${tmpd}/abc >/dev/null
-grep '^global2' ${tmpd}/abc >/dev/null
-grep '^local2' ${tmpd}/abc >/dev/null
+grep '^local1' "${tmpd}"/abc >/dev/null
+grep '^global2' "${tmpd}"/abc >/dev/null
+grep '^local2' "${tmpd}"/abc >/dev/null
 # test dynvariables
-grep "^# author: deadc0de6" ${tmpd}/abc >/dev/null
-grep '^tset,emos,si,siht' ${tmpd}/abc >/dev/null
-grep "^${TESTENV2}" ${tmpd}/abc > /dev/null
-grep "^cba" ${tmpd}/abc >/dev/null
+grep "^# shellcheck" "${tmpd}"/abc >/dev/null
+grep '^tset,emos,si,siht' "${tmpd}"/abc >/dev/null
+grep "^${TESTENV2}" "${tmpd}"/abc > /dev/null
+grep "^cba" "${tmpd}"/abc >/dev/null
 
 #cat ${tmpd}/abc
 
diff --git a/tests-ng/profile-import-dotfiles.sh b/tests-ng/profile-import-dotfiles.sh
index d0fa00b..8101bbf 100755
--- a/tests-ng/profile-import-dotfiles.sh
+++ b/tests-ng/profile-import-dotfiles.sh
@@ -7,51 +7,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -64,7 +43,7 @@ src="dotdrop-test"
 dst=".dotdrop-test"
 clear_on_exit "${HOME}/${dst}"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   dotpath: dotfiles
 dotfiles:
@@ -81,32 +60,32 @@ profiles:
     dotfiles:
     - f_abc
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
-cat > ${cfg2} << _EOF
+cat > "${cfg2}" << _EOF
 dotfiles:
   - f_def
 _EOF
 #cat ${cfg2}
 
 # create the dotfile
-echo "abc" > ${tmps}/dotfiles/abc
-echo "abc" > ${tmpd}/abc
-echo "def" > ${tmps}/dotfiles/${src}
-echo "def" > ${HOME}/${dst}
+echo "abc" > "${tmps}"/dotfiles/abc
+echo "abc" > "${tmpd}"/abc
+echo "def" > "${tmps}"/dotfiles/${src}
+echo "def" > "${HOME}"/${dst}
 
 # import
 ## this is a special case since the dotfile must
 ## be in home (because it is strip)
-echo ${ddpath}
-echo ${bin}
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 --verbose ~/${dst}
+echo "${ddpath}"
+echo "${bin}"
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 --verbose ~/${dst}
 
-cat ${cfg}
+cat "${cfg}"
 echo '----------'
-cat ${cfg2}
+cat "${cfg2}"
 
-cnt=$(cd ${ddpath} | ${bin} files -G -c ${cfg} -p p1 | grep '^f_def' | wc -l)
+cnt=$(cd "${ddpath}" | ${bin} files -G -c "${cfg}" -p p1 | grep '^f_def' | wc -l)
 [ "${cnt}" != "1" ] && echo "imported twice! (${cnt})" && exit 1
 
 echo "OK"
diff --git a/tests-ng/profile-undefined-variables.sh b/tests-ng/profile-undefined-variables.sh
index 0e6cf23..a1f7d72 100755
--- a/tests-ng/profile-undefined-variables.sh
+++ b/tests-ng/profile-undefined-variables.sh
@@ -7,51 +7,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -60,7 +39,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -96,29 +75,29 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "main" > ${tmps}/dotfiles/abc
-echo "alt" > ${tmps}/dotfiles/def
+echo "main" > "${tmps}"/dotfiles/abc
+echo "alt" > "${tmps}"/dotfiles/def
 
 # install pmain
 echo "install pmain"
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p pmain -V
-[ ! -e ${tmpd}/abc ] && echo "dotfile not installed" && exit 1
-grep main ${tmpd}/abc
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p pmain -V
+[ ! -e "${tmpd}"/abc ] && echo "dotfile not installed" && exit 1
+grep main "${tmpd}"/abc
 
 # install pall
 echo "install pall"
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p pall -V
-[ ! -e ${tmpd}/abcall ] && echo "dotfile not installed" && exit 1
-grep main ${tmpd}/abcall
-[ ! -e ${tmpd}/defall ] && echo "dotfile not installed" && exit 1
-grep alt ${tmpd}/defall
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p pall -V
+[ ! -e "${tmpd}"/abcall ] && echo "dotfile not installed" && exit 1
+grep main "${tmpd}"/abcall
+[ ! -e "${tmpd}"/defall ] && echo "dotfile not installed" && exit 1
+grep alt "${tmpd}"/defall
 
 # install pinclude
 echo "install pinclude"
-rm -f ${tmpd}/abc
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p pinclude -V
-[ ! -e ${tmpd}/abc ] && echo "dotfile not installed" && exit 1
-grep main ${tmpd}/abc
+rm -f "${tmpd}"/abc
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p pinclude -V
+[ ! -e "${tmpd}"/abc ] && echo "dotfile not installed" && exit 1
+grep main "${tmpd}"/abc
 
 echo "OK"
 exit 0
diff --git a/tests-ng/re-import.sh b/tests-ng/re-import.sh
index 1bd7c6c..6a7a5f9 100755
--- a/tests-ng/re-import.sh
+++ b/tests-ng/re-import.sh
@@ -5,64 +5,43 @@
 # test re-importing file
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
-clear_on_exit "~/.dotdrop-test"
+clear_on_exit "${HOME}/.dotdrop-test"
 
 # create the dotfile
-echo "original" > ${tmpd}/testfile
+echo "original" > "${tmpd}"/testfile
 
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -74,39 +53,39 @@ _EOF
 
 # import
 echo "[+] import file"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/testfile
-cat ${cfg}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/testfile
+cat "${cfg}"
 
 # ensure exists and is not link
-[ ! -e ${tmps}/dotfiles/${tmpd}/testfile ] && echo "does not exist" && exit 1
-cat ${cfg} | grep ${tmpd}/testfile >/dev/null 2>&1
-grep 'original' ${tmps}/dotfiles/${tmpd}/testfile
-nb=`cat ${cfg} | grep ${tmpd}/testfile | wc -l`
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/testfile ] && echo "does not exist" && exit 1
+cat "${cfg}" | grep "${tmpd}"/testfile >/dev/null 2>&1
+grep 'original' "${tmps}"/dotfiles/"${tmpd}"/testfile
+nb=$(cat "${cfg}" | grep "${tmpd}"/testfile | wc -l)
 [ "${nb}" != "1" ] && echo 'not 1 entry' && exit 1
 
 # re-import without changing
 echo "[+] re-import without changes"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/testfile
-cat ${cfg}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/testfile
+cat "${cfg}"
 
 # test is only once
-[ ! -e ${tmps}/dotfiles/${tmpd}/testfile ] && echo "does not exist" && exit 1
-cat ${cfg} | grep ${tmpd}/testfile >/dev/null 2>&1
-grep 'original' ${tmps}/dotfiles/${tmpd}/testfile
-nb=`cat ${cfg} | grep ${tmpd}/testfile | wc -l`
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/testfile ] && echo "does not exist" && exit 1
+cat "${cfg}" | grep "${tmpd}"/testfile >/dev/null 2>&1
+grep 'original' "${tmps}"/dotfiles/"${tmpd}"/testfile
+nb=$(cat "${cfg}" | grep "${tmpd}"/testfile | wc -l)
 [ "${nb}" != "1" ] && echo 'two entries!' && exit 1
 
 # re-import with changes
 echo "[+] re-import with changes"
-echo 'modified' > ${tmpd}/testfile
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ${tmpd}/testfile
-cat ${cfg}
+echo 'modified' > "${tmpd}"/testfile
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V "${tmpd}"/testfile
+cat "${cfg}"
 
 # test is only once
-[ ! -e ${tmps}/dotfiles/${tmpd}/testfile ] && echo "does not exist" && exit 1
-cat ${cfg} | grep ${tmpd}/testfile >/dev/null 2>&1
-grep 'modified' ${tmps}/dotfiles/${tmpd}/testfile
-nb=`cat ${cfg} | grep ${tmpd}/testfile | wc -l`
+[ ! -e "${tmps}"/dotfiles/"${tmpd}"/testfile ] && echo "does not exist" && exit 1
+cat "${cfg}" | grep "${tmpd}"/testfile >/dev/null 2>&1
+grep 'modified' "${tmps}"/dotfiles/"${tmpd}"/testfile
+nb=$(cat "${cfg}" | grep "${tmpd}"/testfile | wc -l)
 [ "${nb}" != "1" ] && echo 'two entries!' && exit 1
 
 # ###################################################
@@ -114,39 +93,45 @@ nb=`cat ${cfg} | grep ${tmpd}/testfile | wc -l`
 echo 'original' > "${HOME}/.dotdrop.test"
 # import in home
 echo "[+] import file in home"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ~/.dotdrop.test
-cat ${cfg}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V ~/.dotdrop.test
+cat "${cfg}"
 
 # ensure exists and is not link
 [ ! -e "${tmps}/dotfiles/dotdrop.test" ] && echo "does not exist" && exit 1
-cat ${cfg} | grep "~/.dotdrop.test" >/dev/null 2>&1
-grep 'original' ${tmps}/dotfiles/dotdrop.test
-nb=`cat ${cfg} | grep "~/.dotdrop.test" | wc -l`
+# shellcheck disable=SC2088
+cat "${cfg}" | grep '~/.dotdrop.test'
+grep 'original' "${tmps}"/dotfiles/dotdrop.test
+# shellcheck disable=SC2088
+nb=$(cat "${cfg}" | grep '~/.dotdrop.test' | wc -l)
 [ "${nb}" != "1" ] && echo 'not 1 entry' && exit 1
 
 # re-import without changing
 echo "[+] re-import without changes in home"
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ~/.dotdrop.test
-cat ${cfg}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V ~/.dotdrop.test
+cat "${cfg}"
 
 # test is only once
 [ ! -e "${tmps}/dotfiles/dotdrop.test" ] && echo "does not exist" && exit 1
-cat ${cfg} | grep "~/.dotdrop.test" >/dev/null 2>&1
-grep 'original' ${tmps}/dotfiles/dotdrop.test
-nb=`cat ${cfg} | grep "~/.dotdrop.test" | wc -l`
+# shellcheck disable=SC2088
+cat "${cfg}" | grep '~/.dotdrop.test' >/dev/null 2>&1
+grep 'original' "${tmps}"/dotfiles/dotdrop.test
+# shellcheck disable=SC2088
+nb=$(cat "${cfg}" | grep '~/.dotdrop.test' | wc -l)
 [ "${nb}" != "1" ] && echo 'two entries!' && exit 1
 
 # re-import with changes
 echo "[+] re-import with changes in home"
 echo 'modified' > ~/.dotdrop.test
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -V ~/.dotdrop.test
-cat ${cfg}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -V ~/.dotdrop.test
+cat "${cfg}"
 
 # test is only once
 [ ! -e "${tmps}/dotfiles/dotdrop.test" ] && echo "does not exist" && exit 1
-cat ${cfg} | grep "~/.dotdrop.test" >/dev/null 2>&1
-grep 'modified' ${tmps}/dotfiles/dotdrop.test
-nb=`cat ${cfg} | grep "~/.dotdrop.test" | wc -l`
+# shellcheck disable=SC2088
+cat "${cfg}" | grep '~/.dotdrop.test' >/dev/null 2>&1
+grep 'modified' "${tmps}"/dotfiles/dotdrop.test
+# shellcheck disable=SC2088
+nb=$(cat "${cfg}" | grep '~/.dotdrop.test' | wc -l)
 [ "${nb}" != "1" ] && echo 'two entries!' && exit 1
 
 echo "OK"
diff --git a/tests-ng/recinclude.sh b/tests-ng/recinclude.sh
index 5cf2b55..08cf851 100755
--- a/tests-ng/recinclude.sh
+++ b/tests-ng/recinclude.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -58,7 +37,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -85,26 +64,26 @@ profiles:
 _EOF
 
 # create the source
-mkdir -p ${tmps}/dotfiles/
+mkdir -p "${tmps}"/dotfiles/
 content_abc="testrecinclude_abc"
-echo "${content_abc}" > ${tmps}/dotfiles/abc
+echo "${content_abc}" > "${tmps}"/dotfiles/abc
 content_def="testrecinclude_def"
-echo "${content_def}" > ${tmps}/dotfiles/def
+echo "${content_def}" > "${tmps}"/dotfiles/def
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p host -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p host -V
 
 # checks
-[ ! -e ${tmpd}/abc ] && echo "abc not installed" && exit 1
+[ ! -e "${tmpd}"/abc ] && echo "abc not installed" && exit 1
 echo "abc installed"
-grep ${content_abc} ${tmpd}/abc
+grep ${content_abc} "${tmpd}"/abc
 
-[ ! -e ${tmpd}/def ] && echo "def not installed" && exit 1
+[ ! -e "${tmpd}"/def ] && echo "def not installed" && exit 1
 echo "def installed"
-grep ${content_def} ${tmpd}/def
+grep ${content_def} "${tmpd}"/def
 
 # test cyclic include
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -134,7 +113,7 @@ _EOF
 
 # install
 set +e
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p host -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p host -V
 [ "$?" = 0 ] && exit 1
 set -e
 
diff --git a/tests-ng/recvariables.sh b/tests-ng/recvariables.sh
index c1c7369..d90d7a2 100755
--- a/tests-ng/recvariables.sh
+++ b/tests-ng/recvariables.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -59,7 +38,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -86,22 +65,22 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "var3: {{@@ var3 @@}}" > ${tmps}/dotfiles/abc
-echo "dvar3: {{@@ dvar3 @@}}" >> ${tmps}/dotfiles/abc
-echo "var4: {{@@ var4 @@}}" >> ${tmps}/dotfiles/abc
-echo "dvar4: {{@@ dvar4 @@}}" >> ${tmps}/dotfiles/abc
+echo "var3: {{@@ var3 @@}}" > "${tmps}"/dotfiles/abc
+echo "dvar3: {{@@ dvar3 @@}}" >> "${tmps}"/dotfiles/abc
+echo "var4: {{@@ var4 @@}}" >> "${tmps}"/dotfiles/abc
+echo "dvar4: {{@@ dvar4 @@}}" >> "${tmps}"/dotfiles/abc
 
 #cat ${tmps}/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 #cat ${tmpd}/abc
 
-grep '^var3: var1 var2 var3' ${tmpd}/abc >/dev/null
-grep '^dvar3: dvar1 dvar2 dvar3' ${tmpd}/abc >/dev/null
-grep '^var4: echo var1 var2 var3' ${tmpd}/abc >/dev/null
-grep '^dvar4: var1 var2 var3' ${tmpd}/abc >/dev/null
+grep '^var3: var1 var2 var3' "${tmpd}"/abc >/dev/null
+grep '^dvar3: dvar1 dvar2 dvar3' "${tmpd}"/abc >/dev/null
+grep '^var4: echo var1 var2 var3' "${tmpd}"/abc >/dev/null
+grep '^dvar4: var1 var2 var3' "${tmpd}"/abc >/dev/null
 
 #cat ${tmpd}/abc
 
diff --git a/tests-ng/remove.sh b/tests-ng/remove.sh
index 854f047..1d15233 100755
--- a/tests-ng/remove.sh
+++ b/tests-ng/remove.sh
@@ -6,58 +6,37 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -85,44 +64,44 @@ profiles:
     - f_last
 _EOF
 cfgbak="${tmps}/config.yaml.bak"
-cp ${cfg} ${cfgbak}
+cp "${cfg}" "${cfgbak}"
 
 # create the dotfile
-echo "abc" > ${tmps}/dotfiles/abc
-echo "abc" > ${tmpd}/abc
+echo "abc" > "${tmps}"/dotfiles/abc
+echo "abc" > "${tmpd}"/abc
 
-echo "def" > ${tmps}/dotfiles/def
-echo "def" > ${tmpd}/def
+echo "def" > "${tmps}"/dotfiles/def
+echo "def" > "${tmpd}"/def
 
 # remove with bad profile
-cd ${ddpath} | ${bin} remove -f -k -p empty -c ${cfg} f_abc -V
-[ ! -e ${tmps}/dotfiles/abc ] && echo "dotfile in dotpath deleted" && exit 1
-[ ! -e ${tmpd}/abc ] && echo "source dotfile deleted" && exit 1
-[ ! -e ${tmps}/dotfiles/def ] && echo "dotfile in dotpath deleted" && exit 1
-[ ! -e ${tmpd}/def ] && echo "source dotfile deleted" && exit 1
+cd "${ddpath}" | ${bin} remove -f -k -p empty -c "${cfg}" f_abc -V
+[ ! -e "${tmps}"/dotfiles/abc ] && echo "dotfile in dotpath deleted" && exit 1
+[ ! -e "${tmpd}"/abc ] && echo "source dotfile deleted" && exit 1
+[ ! -e "${tmps}"/dotfiles/def ] && echo "dotfile in dotpath deleted" && exit 1
+[ ! -e "${tmpd}"/def ] && echo "source dotfile deleted" && exit 1
 # ensure config not altered
-diff ${cfg} ${cfgbak}
+diff "${cfg}" "${cfgbak}"
 
 # remove by key
 echo "[+] remove f_abc by key"
-cd ${ddpath} | ${bin} remove -p p1 -f -k -c ${cfg} f_abc -V
-cat ${cfg}
+cd "${ddpath}" | ${bin} remove -p p1 -f -k -c "${cfg}" f_abc -V
+cat "${cfg}"
 echo "[+] remove f_def by key"
-cd ${ddpath} | ${bin} remove -p p2 -f -k -c ${cfg} f_def -V
-cat ${cfg}
+cd "${ddpath}" | ${bin} remove -p p2 -f -k -c "${cfg}" f_def -V
+cat "${cfg}"
 
 # checks
-[ -e ${tmps}/dotfiles/abc ] && echo "dotfile in dotpath not deleted" && exit 1
-[ ! -e ${tmpd}/abc ] && echo "source dotfile deleted" && exit 1
+[ -e "${tmps}"/dotfiles/abc ] && echo "dotfile in dotpath not deleted" && exit 1
+[ ! -e "${tmpd}"/abc ] && echo "source dotfile deleted" && exit 1
 
-[ -e ${tmps}/dotfiles/def ] && echo "dotfile in dotpath not deleted" && exit 1
-[ ! -e ${tmpd}/def ] && echo "source dotfile deleted" && exit 1
+[ -e "${tmps}"/dotfiles/def ] && echo "dotfile in dotpath not deleted" && exit 1
+[ ! -e "${tmpd}"/def ] && echo "source dotfile deleted" && exit 1
 
 echo "[+] ========="
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -149,32 +128,32 @@ profiles:
     dotfiles:
     - f_last
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
 # create the dotfile
-echo "abc" > ${tmps}/dotfiles/abc
-echo "abc" > ${tmpd}/abc
+echo "abc" > "${tmps}"/dotfiles/abc
+echo "abc" > "${tmpd}"/abc
 
-echo "def" > ${tmps}/dotfiles/def
-echo "def" > ${tmpd}/def
+echo "def" > "${tmps}"/dotfiles/def
+echo "def" > "${tmpd}"/def
 
 # remove by key
 echo "[+] remove f_abc by path"
-cd ${ddpath} | ${bin} remove -p p1 -f -c ${cfg} ${tmpd}/abc -V
-cat ${cfg}
+cd "${ddpath}" | ${bin} remove -p p1 -f -c "${cfg}" "${tmpd}"/abc -V
+cat "${cfg}"
 echo "[+] remove f_def by path"
-cd ${ddpath} | ${bin} remove -p p2 -f -c ${cfg} ${tmpd}/def -V
-cat ${cfg}
+cd "${ddpath}" | ${bin} remove -p p2 -f -c "${cfg}" "${tmpd}"/def -V
+cat "${cfg}"
 
 # checks
-[ -e ${tmps}/dotfiles/abc ] && echo "(2) dotfile in dotpath not deleted" && exit 1
-[ ! -e ${tmpd}/abc ] && echo "(2) source dotfile deleted" && exit 1
+[ -e "${tmps}"/dotfiles/abc ] && echo "(2) dotfile in dotpath not deleted" && exit 1
+[ ! -e "${tmpd}"/abc ] && echo "(2) source dotfile deleted" && exit 1
 
-[ -e ${tmps}/dotfiles/def ] && echo "(2) dotfile in dotpath not deleted" && exit 1
-[ ! -e ${tmpd}/def ] && echo "(2) source dotfile deleted" && exit 1
+[ -e "${tmps}"/dotfiles/def ] && echo "(2) dotfile in dotpath not deleted" && exit 1
+[ ! -e "${tmpd}"/def ] && echo "(2) source dotfile deleted" && exit 1
 
 
-cat ${cfg}
+cat "${cfg}"
 
 echo "OK"
 exit 0
diff --git a/tests-ng/symlink-relative.sh b/tests-ng/symlink-relative.sh
index 8534d3a..aaf53ec 100755
--- a/tests-ng/symlink-relative.sh
+++ b/tests-ng/symlink-relative.sh
@@ -5,53 +5,32 @@
 # test relative symlink
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
-tmpw=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpw=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 export DOTDROP_WORKDIR="${tmpw}"
 
 clear_on_exit "${tmps}"
@@ -62,16 +41,16 @@ clear_on_exit "${tmpw}"
 # test symlink directory
 ##################################################
 # create the file
-echo "file1" > ${tmps}/dotfiles/abc
-mkdir -p ${tmps}/dotfiles/def
-echo 'file2' > ${tmps}/dotfiles/def/afile
-echo '{{@@ header() @@}}' > ${tmps}/dotfiles/ghi
-mkdir -p ${tmps}/dotfiles/jkl
-echo '{{@@ header() @@}}' > ${tmps}/dotfiles/jkl/anotherfile
+echo "file1" > "${tmps}"/dotfiles/abc
+mkdir -p "${tmps}"/dotfiles/def
+echo 'file2' > "${tmps}"/dotfiles/def/afile
+echo '{{@@ header() @@}}' > "${tmps}"/dotfiles/ghi
+mkdir -p "${tmps}"/dotfiles/jkl
+echo '{{@@ header() @@}}' > "${tmps}"/dotfiles/jkl/anotherfile
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -111,54 +90,58 @@ _EOF
 #cat ${cfg}
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # ensure exists and is link
-[ ! -h ${tmpd}/abc ] && echo "not a symlink" && exit 1
-[ ! -h ${tmpd}/abc2 ] && echo "not a symlink" && exit 1
-[ ! -h ${tmpd}/def ] && echo "not a symlink" && exit 1
-[ ! -d ${tmpd}/def ] && echo "not a symlink" && exit 1
-[ ! -h ${tmpd}/ghi ] && echo "not a symlink" && exit 1
-[ ! -h ${tmpd}/jkl ] && echo "not a symlink" && exit 1
-[ ! -d ${tmpd}/jkl ] && echo "not a symlink" && exit 1
-
-ls -l ${tmpd}/abc | grep '\.\.' || exit 1
-ls -l ${tmpd}/abc2
-ls -l ${tmpd}/def | grep '\.\.' || exit 1
-ls -l ${tmpd}/ghi | grep '\.\.' || exit 1
-ls -l ${tmpd}/jkl | grep '\.\.' || exit 1
-
-grep 'file1' ${tmpd}/abc
-grep 'file1' ${tmpd}/abc2
-grep 'file2' ${tmpd}/def/afile
-grep 'This dotfile is managed using dotdrop' ${tmpd}/ghi
-grep 'This dotfile is managed using dotdrop' ${tmpd}/jkl/anotherfile
-
-[[ $(realpath --relative-base="${tmpw}" -- "$(realpath ${tmpd}/ghi)") =~ "^/" ]] && echo "ghi not subpath of workdir" && exit 1
-[[ $(realpath --relative-base="${tmpw}" -- "$(realpath ${tmpd}/jkl)") =~ ^/ ]] && echo "jkl not subpath of workdir" && exit 1
+[ ! -h "${tmpd}"/abc ] && echo "not a symlink" && exit 1
+[ ! -h "${tmpd}"/abc2 ] && echo "not a symlink" && exit 1
+[ ! -h "${tmpd}"/def ] && echo "not a symlink" && exit 1
+[ ! -d "${tmpd}"/def ] && echo "not a symlink" && exit 1
+[ ! -h "${tmpd}"/ghi ] && echo "not a symlink" && exit 1
+[ ! -h "${tmpd}"/jkl ] && echo "not a symlink" && exit 1
+[ ! -d "${tmpd}"/jkl ] && echo "not a symlink" && exit 1
+
+# shellcheck disable=SC2010
+ls -l "${tmpd}"/abc | grep '\.\.' || exit 1
+ls -l "${tmpd}"/abc2
+# shellcheck disable=SC2010
+ls -l "${tmpd}"/def | grep '\.\.' || exit 1
+# shellcheck disable=SC2010
+ls -l "${tmpd}"/ghi | grep '\.\.' || exit 1
+# shellcheck disable=SC2010
+ls -l "${tmpd}"/jkl | grep '\.\.' || exit 1
+
+grep 'file1' "${tmpd}"/abc
+grep 'file1' "${tmpd}"/abc2
+grep 'file2' "${tmpd}"/def/afile
+grep 'This dotfile is managed using dotdrop' "${tmpd}"/ghi
+grep 'This dotfile is managed using dotdrop' "${tmpd}"/jkl/anotherfile
+
+[[ $(realpath --relative-base="${tmpw}" -- "$(realpath "${tmpd}"/ghi)") =~ "^/" ]] && echo "ghi not subpath of workdir" && exit 1
+[[ $(realpath --relative-base="${tmpw}" -- "$(realpath "${tmpd}"/jkl)") =~ ^/ ]] && echo "jkl not subpath of workdir" && exit 1
 
 
 #############################################################################################################################
 
-rm -rf ${tmps} ${tmpd} ${tmpw}
+rm -rf "${tmps}" "${tmpd}" "${tmpw}"
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 tmpd="${tmps}"
-mkdir -p ${tmpd}
+mkdir -p "${tmpd}"
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the file
-echo "file1" > ${tmps}/dotfiles/abc
-mkdir -p ${tmps}/dotfiles/def
-echo 'file2' > ${tmps}/dotfiles/def/afile
+echo "file1" > "${tmps}"/dotfiles/abc
+mkdir -p "${tmps}"/dotfiles/def
+echo 'file2' > "${tmps}"/dotfiles/def/afile
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -188,17 +171,17 @@ _EOF
 #cat ${cfg}
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
 # ensure exists and is link
-[ ! -h ${tmpd}/abc ] && echo "not a symlink" && exit 1
-[ ! -h ${tmpd}/abc2 ] && echo "not a symlink" && exit 1
-[ ! -h ${tmpd}/def ] && echo "not a symlink" && exit 1
-[ ! -d ${tmpd}/def ] && echo "not a symlink" && exit 1
-
-grep 'file1' ${tmpd}/abc
-grep 'file1' ${tmpd}/abc2
-grep 'file2' ${tmpd}/def/afile
+[ ! -h "${tmpd}"/abc ] && echo "not a symlink" && exit 1
+[ ! -h "${tmpd}"/abc2 ] && echo "not a symlink" && exit 1
+[ ! -h "${tmpd}"/def ] && echo "not a symlink" && exit 1
+[ ! -d "${tmpd}"/def ] && echo "not a symlink" && exit 1
+
+grep 'file1' "${tmpd}"/abc
+grep 'file1' "${tmpd}"/abc2
+grep 'file2' "${tmpd}"/def/afile
 
 echo "OK"
 exit 0
diff --git a/tests-ng/symlink.sh b/tests-ng/symlink.sh
index 8f8b8c1..5f0a374 100755
--- a/tests-ng/symlink.sh
+++ b/tests-ng/symlink.sh
@@ -5,51 +5,30 @@
 # test symlinking dotfiles
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -59,15 +38,15 @@ clear_on_exit "${tmpd}"
 # test symlink directory
 ##################################################
 # create the dotfile
-mkdir -p ${tmps}/dotfiles/abc
-echo "file1" > ${tmps}/dotfiles/abc/file1
-echo "file2" > ${tmps}/dotfiles/abc/file2
+mkdir -p "${tmps}"/dotfiles/abc
+echo "file1" > "${tmps}"/dotfiles/abc/file1
+echo "file2" > "${tmps}"/dotfiles/abc/file2
 
 # create a shell script
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -86,29 +65,29 @@ _EOF
 #cat ${cfg}
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 #cat ${cfg}
 
 # ensure exists and is link
-[ ! -h ${tmpd}/abc ] && echo "not a symlink" && exit 1
-[ ! -e ${tmpd}/abc/file1 ] && echo "does not exist" && exit 1
-[ ! -e ${tmpd}/abc/file2 ] && echo "does not exist" && exit 1
+[ ! -h "${tmpd}"/abc ] && echo "not a symlink" && exit 1
+[ ! -e "${tmpd}"/abc/file1 ] && echo "does not exist" && exit 1
+[ ! -e "${tmpd}"/abc/file2 ] && echo "does not exist" && exit 1
 
 ##################################################
 # test symlink files
 ##################################################
 # clean
-rm -rf ${tmps}/dotfiles ${tmpd}/abc
+rm -rf "${tmps}"/dotfiles "${tmpd}"/abc
 
 # create the dotfiles
-mkdir -p ${tmps}/dotfiles/
-echo "abc" > ${tmps}/dotfiles/abc
+mkdir -p "${tmps}"/dotfiles/
+echo "abc" > "${tmps}"/dotfiles/abc
 
 # create a shell script
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -127,28 +106,28 @@ _EOF
 #cat ${cfg}
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 #cat ${cfg}
 
 # ensure exists and is link
-[ ! -h ${tmpd}/abc ] && echo "not a symlink" && exit 1
+[ ! -h "${tmpd}"/abc ] && echo "not a symlink" && exit 1
 
 ##################################################
 # test link_children
 ##################################################
 # clean
-rm -rf ${tmps}/dotfiles ${tmpd}/abc
+rm -rf "${tmps}"/dotfiles "${tmpd}"/abc
 
 # create the dotfile
-mkdir -p ${tmps}/dotfiles/abc
-echo "file1" > ${tmps}/dotfiles/abc/file1
-echo "file2" > ${tmps}/dotfiles/abc/file2
+mkdir -p "${tmps}"/dotfiles/abc
+echo "file1" > "${tmps}"/dotfiles/abc/file1
+echo "file2" > "${tmps}"/dotfiles/abc/file2
 
 # create a shell script
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -167,30 +146,30 @@ _EOF
 #cat ${cfg}
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 #cat ${cfg}
 
 # ensure exists and is link
-[ ! -d ${tmpd}/abc ] && echo "not a symlink" && exit 1
-[ ! -h ${tmpd}/abc/file1 ] && echo "does not exist" && exit 1
-[ ! -h ${tmpd}/abc/file2 ] && echo "does not exist" && exit 1
+[ ! -d "${tmpd}"/abc ] && echo "not a symlink" && exit 1
+[ ! -h "${tmpd}"/abc/file1 ] && echo "does not exist" && exit 1
+[ ! -h "${tmpd}"/abc/file2 ] && echo "does not exist" && exit 1
 
 ##################################################
 # test link_children with templates
 ##################################################
 # clean
-rm -rf ${tmps}/dotfiles ${tmpd}/abc
+rm -rf "${tmps}"/dotfiles "${tmpd}"/abc
 
 # create the dotfile
-mkdir -p ${tmps}/dotfiles/abc
-echo "{{@@ profile @@}}" > ${tmps}/dotfiles/abc/file1
-echo "file2" > ${tmps}/dotfiles/abc/file2
+mkdir -p "${tmps}"/dotfiles/abc
+echo "{{@@ profile @@}}" > "${tmps}"/dotfiles/abc/file1
+echo "file2" > "${tmps}"/dotfiles/abc/file2
 
 # create a shell script
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -209,14 +188,14 @@ _EOF
 #cat ${cfg}
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 #cat ${cfg}
 
 # ensure exists and is link
-[ ! -d ${tmpd}/abc ] && echo "not a symlink" && exit 1
-[ ! -h ${tmpd}/abc/file1 ] && echo "does not exist" && exit 1
-[ ! -h ${tmpd}/abc/file2 ] && echo "does not exist" && exit 1
-grep '^p1$' ${tmpd}/abc/file1
+[ ! -d "${tmpd}"/abc ] && echo "not a symlink" && exit 1
+[ ! -h "${tmpd}"/abc/file1 ] && echo "does not exist" && exit 1
+[ ! -h "${tmpd}"/abc/file2 ] && echo "does not exist" && exit 1
+grep '^p1$' "${tmpd}"/abc/file1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/template-dotpath.sh b/tests-ng/template-dotpath.sh
index ed4b283..5dfa857 100755
--- a/tests-ng/template-dotpath.sh
+++ b/tests-ng/template-dotpath.sh
@@ -6,41 +6,20 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -49,22 +28,22 @@ echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
 dotpath="xyz"
 
 # dotdrop directory
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/${dotpath}
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/${dotpath}
 echo "[+] dotdrop dir: ${tmps}"
 echo "[+] dotpath dir: ${tmps}/${dotpath}"
 
 # dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
-echo "content" > ${tmps}/${dotpath}/abc
+echo "content" > "${tmps}"/${dotpath}/abc
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -81,16 +60,16 @@ _EOF
 
 echo "[+] install"
 export DOTDROP_DOTPATH=${dotpath}
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p1 --verbose | grep '^1 dotfile(s) installed.$'
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 --verbose | grep '^1 dotfile(s) installed.$'
 [ "$?" != "0" ] && exit 1
 
-[ ! -e ${tmpd}/abc ] && echo "f_abc not installed" && exit 1
+[ ! -e "${tmpd}"/abc ] && echo "f_abc not installed" && exit 1
 
 # clean
-rm ${tmpd}/abc
+rm "${tmpd}"/abc
 
 # create the config file
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -108,10 +87,10 @@ profiles:
 _EOF
 
 echo "[+] install"
-cd ${ddpath} | ${bin} install -c ${cfg} -f -p p1 --verbose | grep '^1 dotfile(s) installed.$'
+cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 --verbose | grep '^1 dotfile(s) installed.$'
 [ "$?" != "0" ] && exit 1
 
-[ ! -e ${tmpd}/abc ] && echo "f_abc not installed" && exit 1
+[ ! -e "${tmpd}"/abc ] && echo "f_abc not installed" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/template-link-value.sh b/tests-ng/template-link-value.sh
index 63e5a96..5aaa7dd 100755
--- a/tests-ng/template-link-value.sh
+++ b/tests-ng/template-link-value.sh
@@ -6,52 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -60,7 +39,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -115,38 +94,38 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "filea" > ${tmps}/dotfiles/a
-echo "fileb" > ${tmps}/dotfiles/b
-echo "filec" > ${tmps}/dotfiles/c
-echo "filed" > ${tmps}/dotfiles/d
-mkdir -p ${tmps}/dotfiles/e/{1,2,3}
-echo filee > ${tmps}/dotfiles/e/1/file
-echo filee > ${tmps}/dotfiles/e/2/file
-echo filee > ${tmps}/dotfiles/e/3/file
-mkdir -p ${tmps}/dotfiles/f/{1,2,3}
-echo filee > ${tmps}/dotfiles/f/1/file
-echo filee > ${tmps}/dotfiles/f/2/file
-echo filee > ${tmps}/dotfiles/f/3/file
+echo "filea" > "${tmps}"/dotfiles/a
+echo "fileb" > "${tmps}"/dotfiles/b
+echo "filec" > "${tmps}"/dotfiles/c
+echo "filed" > "${tmps}"/dotfiles/d
+mkdir -p "${tmps}"/dotfiles/e/{1,2,3}
+echo filee > "${tmps}"/dotfiles/e/1/file
+echo filee > "${tmps}"/dotfiles/e/2/file
+echo filee > "${tmps}"/dotfiles/e/3/file
+mkdir -p "${tmps}"/dotfiles/f/{1,2,3}
+echo filee > "${tmps}"/dotfiles/f/1/file
+echo filee > "${tmps}"/dotfiles/f/2/file
+echo filee > "${tmps}"/dotfiles/f/3/file
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 
 # checks
-[ ! -e ${tmpd}/a ] && echo "[ERROR] dotfile a not linked" && exit 1
-[ ! -h ${tmpd}/b ] && echo "[ERROR] dotfile b linked" && exit 1
-[ ! -e ${tmpd}/c ] && echo "[ERROR] dotfile c not linked" && exit 1
-[ ! -h ${tmpd}/d ] && echo "[ERROR] dotfile d linked" && exit 1
+[ ! -e "${tmpd}"/a ] && echo "[ERROR] dotfile a not linked" && exit 1
+[ ! -h "${tmpd}"/b ] && echo "[ERROR] dotfile b linked" && exit 1
+[ ! -e "${tmpd}"/c ] && echo "[ERROR] dotfile c not linked" && exit 1
+[ ! -h "${tmpd}"/d ] && echo "[ERROR] dotfile d linked" && exit 1
 
 # link_children
-[ ! -d ${tmpd}/e ] && echo "[ERROR] dir e does not exist" && exit 1
-[ ! -h ${tmpd}/e/1 ] && echo "[ERROR] children e/1 not linked" && exit 1
-[ ! -h ${tmpd}/e/2 ] && echo "[ERROR] children e/2 not linked" && exit 1
-[ ! -h ${tmpd}/e/3 ] && echo "[ERROR] children e/3 not linked" && exit 1
-
-[ ! -d ${tmpd}/f ] && echo "[ERROR] dir f does not exist" && exit 1
-[ ! -h ${tmpd}/f/1 ] && echo "[ERROR] children f/1 not linked" && exit 1
-[ ! -h ${tmpd}/f/2 ] && echo "[ERROR] children f/2 not linked" && exit 1
-[ ! -h ${tmpd}/f/3 ] && echo "[ERROR] children f/3 not linked" && exit 1
+[ ! -d "${tmpd}"/e ] && echo "[ERROR] dir e does not exist" && exit 1
+[ ! -h "${tmpd}"/e/1 ] && echo "[ERROR] children e/1 not linked" && exit 1
+[ ! -h "${tmpd}"/e/2 ] && echo "[ERROR] children e/2 not linked" && exit 1
+[ ! -h "${tmpd}"/e/3 ] && echo "[ERROR] children e/3 not linked" && exit 1
+
+[ ! -d "${tmpd}"/f ] && echo "[ERROR] dir f does not exist" && exit 1
+[ ! -h "${tmpd}"/f/1 ] && echo "[ERROR] children f/1 not linked" && exit 1
+[ ! -h "${tmpd}"/f/2 ] && echo "[ERROR] children f/2 not linked" && exit 1
+[ ! -h "${tmpd}"/f/3 ] && echo "[ERROR] children f/3 not linked" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/tests-launcher.py b/tests-ng/tests_launcher.py
similarity index 95%
rename from tests-ng/tests-launcher.py
rename to tests-ng/tests_launcher.py
index 010e20f..bdb231f 100755
--- a/tests-ng/tests-launcher.py
+++ b/tests-ng/tests_launcher.py
@@ -14,7 +14,7 @@ from concurrent import futures
 from halo import Halo
 
 
-LOG_FILE = '/tmp/dotdrop-tests-launcher.log'
+LOG_FILE = '/tmp/dotdrop-tests_launcher.log'
 GITHUB_ENV = 'GITHUB_WORKFLOW'
 
 
@@ -32,6 +32,7 @@ def run_test(logfd, path):
     if logfd:
         logfd.write(f'starting test \"{path}\"\n')
         logfd.flush()
+    # pylint: disable=R1732
     proc = subprocess.Popen(path, shell=False,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT,
@@ -73,6 +74,7 @@ def main():
 
     logfd = sys.stdout
     if not is_cicd():
+        # pylint: disable=R1732
         logfd = open(LOG_FILE, 'w', encoding='utf-8')
     if max_jobs:
         logfd.write(f'run tests with {max_jobs} parallel job(s)\n')
@@ -95,6 +97,7 @@ def main():
         for test in futures.as_completed(wait_for.keys()):
             try:
                 ret, reason, name, log = test.result()
+            # pylint: disable=W0703
             except Exception as exc:
                 print()
                 print(f'test \"{wait_for[test]}\" failed: {exc}')
diff --git a/tests-ng/toml.sh b/tests-ng/toml.sh
index 4354cfb..3a99c00 100755
--- a/tests-ng/toml.sh
+++ b/tests-ng/toml.sh
@@ -6,50 +6,29 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmp=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmp=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 tmpf="${tmp}/dotfiles"
-mkdir -p ${tmpf}
+mkdir -p "${tmpf}"
 echo "dotfiles source (dotpath): ${tmpf}"
 
 # create the config file
@@ -57,14 +36,14 @@ cfg="${tmp}/config.toml"
 echo "config file: ${cfg}"
 
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmp}"
 clear_on_exit "${tmpd}"
 
 ## RELATIVE
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 [config]
 backup = true
 create = true
@@ -81,23 +60,23 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "{{@@ profile @@}}" > ${tmpf}/abc
-echo "{{@@ profile @@}}" > ${tmpd}/def
+echo "{{@@ profile @@}}" > "${tmpf}"/abc
+echo "{{@@ profile @@}}" > "${tmpd}"/def
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
-[ ! -e ${tmpd}/abc ] && echo "[ERROR] dotfile not installed" && exit 1
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
+[ ! -e "${tmpd}"/abc ] && echo "[ERROR] dotfile not installed" && exit 1
 
 # import
-cd ${ddpath} | ${bin} import -f -c ${cfg} -p p1 -b -V ${tmpd}/def
-[ ! -e ${tmpf}${tmpd}/def ] && echo "[ERROR] dotfile not imported" && exit 1
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" -p p1 -b -V "${tmpd}"/def
+[ ! -e "${tmpf}""${tmpd}"/def ] && echo "[ERROR] dotfile not imported" && exit 1
 
 # checks
-cnt=$(cd ${ddpath} | ${bin} files -G -c ${cfg} -p p1 -V | grep '^f_' | wc -l)
+cnt=$(cd "${ddpath}" | ${bin} files -G -c "${cfg}" -p p1 -V | grep '^f_' | wc -l)
 [ "${cnt}" != "2" ] && echo "[ERROR]" && exit 1
 
 ## CLEANING
-rm -rf ${tmp} ${tmpd}
+rm -rf "${tmp}" "${tmpd}"
 
 echo "OK"
 exit 0
diff --git a/tests-ng/transformations-template.sh b/tests-ng/transformations-template.sh
index 04f9a78..b249af9 100755
--- a/tests-ng/transformations-template.sh
+++ b/tests-ng/transformations-template.sh
@@ -5,53 +5,31 @@
 # test transformations using templates
 #
 
-# exit on first error
+## start-cookie
 set -e
-#set -v
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -60,7 +38,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 trans_read:
   r_echo_abs_src: echo "\$(cat {0}); {{@@ _dotfile_abs_src @@}}" > {1}
   r_echo_var: echo "\$(cat {0}); {{@@ r_var @@}}" > {1}
@@ -104,48 +82,48 @@ _EOF
 #cat ${cfg}
 
 # create the dotfiles
-echo 'abc' > ${tmps}/dotfiles/abc
-echo 'marker' > ${tmps}/dotfiles/def
-echo 'ghi' > ${tmps}/dotfiles/ghi
-echo '{{@@ profile @@}}' | rev > ${tmps}/dotfiles/rev
+echo 'abc' > "${tmps}"/dotfiles/abc
+echo 'marker' > "${tmps}"/dotfiles/def
+echo 'ghi' > "${tmps}"/dotfiles/ghi
+echo '{{@@ profile @@}}' | rev > "${tmps}"/dotfiles/rev
 
 ###########################
 # test install and compare
 ###########################
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 
 # check dotfile
-[ ! -e ${tmpd}/def ] && exit 1
-[ ! -e ${tmpd}/abc ] && exit 1
-[ ! -e ${tmpd}/ghi ] && exit 1
-[ ! -e ${tmpd}/rev ] && exit 1
-grep marker ${tmpd}/def
-cat ${tmpd}/abc
-grep "^abc; ${tmps}/dotfiles/abc$" ${tmpd}/abc
-cat ${tmpd}/ghi
-grep "^ghi; readvar$" ${tmpd}/ghi
-cat ${tmpd}/rev
-grep "^p1$" ${tmpd}/rev
+[ ! -e "${tmpd}"/def ] && exit 1
+[ ! -e "${tmpd}"/abc ] && exit 1
+[ ! -e "${tmpd}"/ghi ] && exit 1
+[ ! -e "${tmpd}"/rev ] && exit 1
+grep marker "${tmpd}"/def
+cat "${tmpd}"/abc
+grep "^abc; ${tmps}/dotfiles/abc$" "${tmpd}"/abc
+cat "${tmpd}"/ghi
+grep "^ghi; readvar$" "${tmpd}"/ghi
+cat "${tmpd}"/rev
+grep "^p1$" "${tmpd}"/rev
 
 ###########################
 # test update
 ###########################
 
 # update single file
-cd ${ddpath} | ${bin} update -f -k -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} update -f -k -c "${cfg}" -p p1 -b -V
 
 # checks
-[ ! -e ${tmps}/dotfiles/def ] && exit 1
-[ ! -e ${tmps}/dotfiles/abc ] && exit 1
-[ ! -e ${tmps}/dotfiles/ghi ] && exit 1
-[ ! -e ${tmps}/dotfiles/rev ] && exit 1
-grep marker ${tmps}/dotfiles/def
-cat ${tmps}/dotfiles/abc
-grep "^abc; ${tmps}/dotfiles/abc; f_abc$" ${tmps}/dotfiles/abc
-cat ${tmps}/dotfiles/ghi
-grep "^ghi; readvar; writevar$" ${tmps}/dotfiles/ghi
+[ ! -e "${tmps}"/dotfiles/def ] && exit 1
+[ ! -e "${tmps}"/dotfiles/abc ] && exit 1
+[ ! -e "${tmps}"/dotfiles/ghi ] && exit 1
+[ ! -e "${tmps}"/dotfiles/rev ] && exit 1
+grep marker "${tmps}"/dotfiles/def
+cat "${tmps}"/dotfiles/abc
+grep "^abc; ${tmps}/dotfiles/abc; f_abc$" "${tmps}"/dotfiles/abc
+cat "${tmps}"/dotfiles/ghi
+grep "^ghi; readvar; writevar$" "${tmps}"/dotfiles/ghi
 
 echo "OK"
 exit 0
diff --git a/tests-ng/transformations-with-args.sh b/tests-ng/transformations-with-args.sh
index 20bda59..b8cee89 100755
--- a/tests-ng/transformations-with-args.sh
+++ b/tests-ng/transformations-with-args.sh
@@ -5,53 +5,31 @@
 # test transformations with args and templates
 #
 
-# exit on first error
+## start-cookie
 set -e
-#set -v
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -60,7 +38,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 trans_read:
   r_echo_abs_src: echo "\$(cat {0}); {{@@ _dotfile_abs_src @@}}; {2}" > {1}
   r_echo_var: echo "\$(cat {0}); {{@@ r_var @@}}; {2}" > {1}
@@ -98,43 +76,43 @@ _EOF
 #cat ${cfg}
 
 # create the dotfiles
-echo 'abc' > ${tmps}/dotfiles/abc
-echo 'marker' > ${tmps}/dotfiles/def
-echo 'ghi' > ${tmps}/dotfiles/ghi
+echo 'abc' > "${tmps}"/dotfiles/abc
+echo 'marker' > "${tmps}"/dotfiles/def
+echo 'ghi' > "${tmps}"/dotfiles/ghi
 
 ###########################
 # test install and compare
 ###########################
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 
 # check dotfile
-[ ! -e ${tmpd}/def ] && exit 1
-[ ! -e ${tmpd}/abc ] && exit 1
-[ ! -e ${tmpd}/ghi ] && exit 1
-grep marker ${tmpd}/def
-cat ${tmpd}/abc
-grep "^abc; ${tmps}/dotfiles/abc; arg1$" ${tmpd}/abc
-cat ${tmpd}/ghi
-grep "^ghi; readvar; p1$" ${tmpd}/ghi
+[ ! -e "${tmpd}"/def ] && exit 1
+[ ! -e "${tmpd}"/abc ] && exit 1
+[ ! -e "${tmpd}"/ghi ] && exit 1
+grep marker "${tmpd}"/def
+cat "${tmpd}"/abc
+grep "^abc; ${tmps}/dotfiles/abc; arg1$" "${tmpd}"/abc
+cat "${tmpd}"/ghi
+grep "^ghi; readvar; p1$" "${tmpd}"/ghi
 
 ###########################
 # test update
 ###########################
 
 # update single file
-cd ${ddpath} | ${bin} update -f -k -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} update -f -k -c "${cfg}" -p p1 -b -V
 
 # checks
-[ ! -e ${tmps}/dotfiles/def ] && exit 1
-[ ! -e ${tmps}/dotfiles/abc ] && exit 1
-[ ! -e ${tmps}/dotfiles/ghi ] && exit 1
-grep marker ${tmps}/dotfiles/def
-cat ${tmps}/dotfiles/abc
-grep "^abc; ${tmps}/dotfiles/abc; arg1; f_abc; arg2$" ${tmps}/dotfiles/abc
-cat ${tmps}/dotfiles/ghi
-grep "^ghi; readvar; p1; writevar; f_ghi$" ${tmps}/dotfiles/ghi
+[ ! -e "${tmps}"/dotfiles/def ] && exit 1
+[ ! -e "${tmps}"/dotfiles/abc ] && exit 1
+[ ! -e "${tmps}"/dotfiles/ghi ] && exit 1
+grep marker "${tmps}"/dotfiles/def
+cat "${tmps}"/dotfiles/abc
+grep "^abc; ${tmps}/dotfiles/abc; arg1; f_abc; arg2$" "${tmps}"/dotfiles/abc
+cat "${tmps}"/dotfiles/ghi
+grep "^ghi; readvar; p1; writevar; f_ghi$" "${tmps}"/dotfiles/ghi
 
 echo "OK"
 exit 0
diff --git a/tests-ng/transformations.sh b/tests-ng/transformations.sh
index 80f0d5e..68a02cf 100755
--- a/tests-ng/transformations.sh
+++ b/tests-ng/transformations.sh
@@ -7,53 +7,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-#set -v
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -67,7 +45,7 @@ token="test-base64"
 tokend="compressed archive"
 touched="touched"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 trans_read:
   base64: cat {0} | base64 -d > {1}
   uncompress: mkdir -p {1} && tar -xf {0} -C {1}
@@ -103,30 +81,30 @@ _EOF
 #cat ${cfg}
 
 # create the base64 dotfile
-tmpf=`mktemp --suffix='-dotdrop-tests' || mktemp -d`
-echo ${token} > ${tmpf}
-cat ${tmpf} | base64 > ${tmps}/dotfiles/abc
-rm -f ${tmpf}
+tmpf=$(mktemp --suffix='-dotdrop-tests' || mktemp -d)
+echo ${token} > "${tmpf}"
+cat "${tmpf}" | base64 > "${tmps}"/dotfiles/abc
+rm -f "${tmpf}"
 
 # create the canary dotfile
-echo 'marker' > ${tmps}/dotfiles/def
+echo 'marker' > "${tmps}"/dotfiles/def
 
 # create the compressed dotfile
-tmpx=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpx=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 clear_on_exit "${tmpx}"
-mkdir -p ${tmpx}/{a,b,c}
-mkdir -p ${tmpx}/a/{dir1,dir2}
+mkdir -p "${tmpx}"/{a,b,c}
+mkdir -p "${tmpx}"/a/{dir1,dir2}
 # ambiguous redirect ??
 #echo ${tokend} > ${tmpd}/{a,b,c}/somefile
-echo ${tokend} > ${tmpx}/a/somefile
-echo ${tokend} > ${tmpx}/b/somefile
-echo ${tokend} > ${tmpx}/c/somefile
-echo ${tokend} > ${tmpx}/a/dir1/otherfile
+echo "${tokend}" > "${tmpx}"/a/somefile
+echo "${tokend}" > "${tmpx}"/b/somefile
+echo "${tokend}" > "${tmpx}"/c/somefile
+echo "${tokend}" > "${tmpx}"/a/dir1/otherfile
 # create a fake file to ensure dir is created
-echo ${tokend} > ${tmpx}/a/dir2/token
-tar -cf ${tmps}/dotfiles/ghi -C ${tmpx} .
-rm -rf ${tmpx}
-tar -tf ${tmps}/dotfiles/ghi
+echo "${tokend}" > "${tmpx}"/a/dir2/token
+tar -cf "${tmps}"/dotfiles/ghi -C "${tmpx}" .
+rm -rf "${tmpx}"
+tar -tf "${tmps}"/dotfiles/ghi
 
 ###########################
 # test install and compare
@@ -134,40 +112,40 @@ tar -tf ${tmps}/dotfiles/ghi
 
 echo "[+] run install"
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 
 # check canary dotfile
-[ ! -e ${tmpd}/def ] && echo "def does not exist" && exit 1
+[ ! -e "${tmpd}"/def ] && echo "def does not exist" && exit 1
 
 # check base64 dotfile
-[ ! -e ${tmpd}/abc ] && echo "abc does not exist" && exit 1
-content=`cat ${tmpd}/abc`
+[ ! -e "${tmpd}"/abc ] && echo "abc does not exist" && exit 1
+content=$(cat "${tmpd}"/abc)
 [ "${content}" != "${token}" ] && echo "bad content for abc" && exit 1
 
 # check directory dotfile
-[ ! -e ${tmpd}/ghi/a/dir1/otherfile ] && echo "otherfile does not exist" && exit 1
-content=`cat ${tmpd}/ghi/a/somefile`
+[ ! -e "${tmpd}"/ghi/a/dir1/otherfile ] && echo "otherfile does not exist" && exit 1
+content=$(cat "${tmpd}"/ghi/a/somefile)
 [ "${content}" != "${tokend}" ] && echo "bad content for somefile" && exit 1
-content=`cat ${tmpd}/ghi/a/dir1/otherfile`
+content=$(cat "${tmpd}"/ghi/a/dir1/otherfile)
 [ "${content}" != "${tokend}" ] && echo "bad content for otherfile" && exit 1
 
 # compare
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -b -V
 [ "$?" != "0" ] && echo "compare failed (0)" && exit 1
 set -e
 
 # change base64 deployed file
-echo ${touched} > ${tmpd}/abc
+echo ${touched} > "${tmpd}"/abc
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -b -V
 [ "$?" != "1" ] && echo "compare failed (1)" && exit 1
 set -e
 
 # change uncompressed deployed dotfile
-echo ${touched} > ${tmpd}/ghi/a/somefile
+echo ${touched} > "${tmpd}"/ghi/a/somefile
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -b -V
 [ "$?" != "1" ] && echo "compare failed (2)" && exit 1
 set -e
 
@@ -176,46 +154,46 @@ set -e
 ###########################
 
 # update single file
-echo 'update' > ${tmpd}/def
+echo 'update' > "${tmpd}"/def
 set +e
-cd ${ddpath} | ${bin} update -f -k -c ${cfg} -p p1 -b -V f_def
+cd "${ddpath}" | ${bin} update -f -k -c "${cfg}" -p p1 -b -V f_def
 [ "$?" != "0" ] && echo "update failed (1)" && exit 1
 set -e
-[ ! -e  ${tmpd}/def ] && echo 'dotfile in FS removed' && exit 1
-[ ! -e  ${tmps}/dotfiles/def ] && echo 'dotfile in dotpath removed' && exit 1
+[ ! -e  "${tmpd}"/def ] && echo 'dotfile in FS removed' && exit 1
+[ ! -e  "${tmps}"/dotfiles/def ] && echo 'dotfile in dotpath removed' && exit 1
 
 # update single file
 set +e
-cd ${ddpath} | ${bin} update -f -k -c ${cfg} -p p1 -b -V f_abc
+cd "${ddpath}" | ${bin} update -f -k -c "${cfg}" -p p1 -b -V f_abc
 [ "$?" != "0" ] && echo "update failed (2)" && exit 1
 set -e
 
 # test updated file
-[ ! -e ${tmps}/dotfiles/abc ] && echo "abc does not exist" && exit 1
-content=`cat ${tmps}/dotfiles/abc`
-bcontent=`echo ${touched} | base64`
+[ ! -e "${tmps}"/dotfiles/abc ] && echo "abc does not exist" && exit 1
+content=$(cat "${tmps}"/dotfiles/abc)
+bcontent=$(echo ${touched} | base64)
 [ "${content}" != "${bcontent}" ] && echo "bad content for abc" && exit 1
 
 # update directory
-echo ${touched} > ${tmpd}/ghi/b/newfile
-rm -r ${tmpd}/ghi/c
-cd ${ddpath} | ${bin} update -f -k -c ${cfg} -p p1 -b -V d_ghi
+echo ${touched} > "${tmpd}"/ghi/b/newfile
+rm -r "${tmpd}"/ghi/c
+cd "${ddpath}" | ${bin} update -f -k -c "${cfg}" -p p1 -b -V d_ghi
 [ "$?" != "0" ] && echo "update failed" && exit 1
 
 # test updated directory
 set +e
-tar -tf ${tmps}/dotfiles/ghi | grep './b/newfile' || (echo "newfile not found in tar" && exit 1)
-tar -tf ${tmps}/dotfiles/ghi | grep './a/dir1/otherfile' || (echo "otherfile not found in tar" && exit 1)
+tar -tf "${tmps}"/dotfiles/ghi | grep './b/newfile' || (echo "newfile not found in tar" && exit 1)
+tar -tf "${tmps}"/dotfiles/ghi | grep './a/dir1/otherfile' || (echo "otherfile not found in tar" && exit 1)
 set -e
 
-tmpy=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpy=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 clear_on_exit "${tmpy}"
-tar -xf ${tmps}/dotfiles/ghi -C ${tmpy}
-content=`cat ${tmpy}/a/somefile`
+tar -xf "${tmps}"/dotfiles/ghi -C "${tmpy}"
+content=$(cat "${tmpy}"/a/somefile)
 [ "${content}" != "${touched}" ] && echo "bad content" && exit 1
 
 # check canary dotfile
-[ ! -e ${tmps}/dotfiles/def ] && echo "def not found" && exit 1
+[ ! -e "${tmps}"/dotfiles/def ] && echo "def not found" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/update-ignore-missing.sh b/tests-ng/update-ignore-missing.sh
index df1fbe9..d4c4e03 100755
--- a/tests-ng/update-ignore-missing.sh
+++ b/tests-ng/update-ignore-missing.sh
@@ -6,66 +6,43 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
-# $1 pattern
-# $2 path
-grep_or_fail()
-{
-  grep "${1}" "${2}" >/dev/null 2>&1 || (echo "pattern not found in ${2}" && exit 1)
-}
-
 # dotdrop directory
-tmps=`mktemp -d --suffix='-dotdrop-tests-source' || mktemp -d`
+tmps=$(mktemp -d --suffix='-dotdrop-tests-source' || mktemp -d)
 dt="${tmps}/dotfiles"
-mkdir -p ${dt}/folder
-touch ${dt}/folder/a
+mkdir -p "${dt}"/folder
+touch "${dt}"/folder/a
 
 # fs dotfiles
-tmpd=`mktemp -d --suffix='-dotdrop-tests-dest' || mktemp -d`
-cp -r ${dt}/folder ${tmpd}/
-touch ${tmpd}/folder/b
-mkdir ${tmpd}/folder/c
+tmpd=$(mktemp -d --suffix='-dotdrop-tests-dest' || mktemp -d)
+cp -r "${dt}"/folder "${tmpd}"/
+touch "${tmpd}"/folder/b
+mkdir "${tmpd}"/folder/c
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -89,14 +66,14 @@ _EOF
 
 # file b / folder c SHOULD be copied
 echo "[+] test with no ignore-missing setting"
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key thedotfile
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=p1 --key thedotfile
 
-[ ! -e ${dt}/folder/b ] && echo "should have been updated" && exit 1
-[ ! -e ${dt}/folder/c ] && echo "should have been updated" && exit 1
+[ ! -e "${dt}"/folder/b ] && echo "should have been updated" && exit 1
+[ ! -e "${dt}"/folder/c ] && echo "should have been updated" && exit 1
 
 # Reset
-rm ${dt}/folder/b
-rmdir ${dt}/folder/c
+rm "${dt}"/folder/b
+rmdir "${dt}"/folder/c
 
 #
 # Test with command-line flag
@@ -104,16 +81,16 @@ rmdir ${dt}/folder/c
 
 # file b / folder c should NOT be copied
 echo "[+] test with command-line flag"
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key thedotfile --ignore-missing
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=p1 --key thedotfile --ignore-missing
 
-[ -e ${dt}/folder/b ] && echo "should not have been updated" && exit 1
-[ -e ${dt}/folder/c ] && echo "should not have been updated" && exit 1
+[ -e "${dt}"/folder/b ] && echo "should not have been updated" && exit 1
+[ -e "${dt}"/folder/c ] && echo "should not have been updated" && exit 1
 
 #
 # Test with global option
 #
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -131,16 +108,16 @@ _EOF
 
 # file b / folder c should NOT be copied
 echo "[+] test global option"
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key thedotfile
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=p1 --key thedotfile
 
-[ -e ${dt}/folder/b ] && echo "should not have been updated" && exit 1
-[ -e ${dt}/folder/c ] && echo "should not have been updated" && exit 1
+[ -e "${dt}"/folder/b ] && echo "should not have been updated" && exit 1
+[ -e "${dt}"/folder/c ] && echo "should not have been updated" && exit 1
 
 #
 # Test with dotfile option
 #
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -157,10 +134,10 @@ profiles:
 _EOF
 # file b / folder c should NOT be copied
 echo "[+] test dotfile option"
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key thedotfile
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=p1 --key thedotfile
 
-[ -e ${dt}/folder/b ] && echo "should not have been updated" && exit 1
-[ -e ${dt}/folder/c ] && echo "should not have been updated" && exit 1
+[ -e "${dt}"/folder/b ] && echo "should not have been updated" && exit 1
+[ -e "${dt}"/folder/c ] && echo "should not have been updated" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/update-ignore-relative.sh b/tests-ng/update-ignore-relative.sh
index 93db333..56c56bb 100755
--- a/tests-ng/update-ignore-relative.sh
+++ b/tests-ng/update-ignore-relative.sh
@@ -6,65 +6,44 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 dt="${tmps}/dotfiles"
-mkdir -p ${dt}
-mkdir -p ${dt}/a/{b,c}
-echo 'a' > ${dt}/a/b/abfile
-echo 'a' > ${dt}/a/c/acfile
+mkdir -p "${dt}"
+mkdir -p "${dt}"/a/{b,c}
+echo 'a' > "${dt}"/a/b/abfile
+echo 'a' > "${dt}"/a/c/acfile
 
 # fs dotfiles
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
-cp -r ${dt}/a ${tmpd}/
+cp -r "${dt}"/a "${tmpd}"/
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -88,22 +67,22 @@ _EOF
 
 # edit/add files
 echo "[+] edit/add files"
-touch ${tmpd}/a/newfile
-echo 'b' > ${tmpd}/a/c/acfile
-mkdir -p ${tmpd}/a/newdir/b
-touch ${tmpd}/a/newdir/b/c
+touch "${tmpd}"/a/newfile
+echo 'b' > "${tmpd}"/a/c/acfile
+mkdir -p "${tmpd}"/a/newdir/b
+touch "${tmpd}"/a/newdir/b/c
 
 #tree ${tmpd}/a
 
 # update
 echo "[+] update"
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key f_abc
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=p1 --key f_abc
 
 #tree ${dt}
 
 # check files haven't been updated
-grep 'b' ${dt}/a/c/acfile >/dev/null || (echo "b not found" && exit 1)
-[ -e ${dt}/a/newfile ] && echo "new file does not exist" && exit 1
+grep 'b' "${dt}"/a/c/acfile >/dev/null || (echo "b not found" && exit 1)
+[ -e "${dt}"/a/newfile ] && echo "new file does not exist" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/update-ignore.sh b/tests-ng/update-ignore.sh
index 167c94b..8852ea6 100755
--- a/tests-ng/update-ignore.sh
+++ b/tests-ng/update-ignore.sh
@@ -6,41 +6,20 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -54,24 +33,24 @@ grep_or_fail()
 }
 
 # dotdrop directory
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 dt="${tmps}/dotfiles"
-mkdir -p ${dt}
-mkdir -p ${dt}/a/{b,c}
-echo 'a' > ${dt}/a/b/abfile
-echo 'a' > ${dt}/a/c/acfile
+mkdir -p "${dt}"
+mkdir -p "${dt}"/a/{b,c}
+echo 'a' > "${dt}"/a/b/abfile
+echo 'a' > "${dt}"/a/c/acfile
 
 # fs dotfiles
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
-cp -r ${dt}/a ${tmpd}/
+cp -r "${dt}"/a "${tmpd}"/
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -95,18 +74,18 @@ _EOF
 
 # edit/add files
 echo "[+] edit/add files"
-touch ${tmpd}/a/newfile
-echo 'b' > ${tmpd}/a/c/acfile
-mkdir -p ${tmpd}/a/newdir/b
-touch ${tmpd}/a/newdir/b/c
+touch "${tmpd}"/a/newfile
+echo 'b' > "${tmpd}"/a/c/acfile
+mkdir -p "${tmpd}"/a/newdir/b
+touch "${tmpd}"/a/newdir/b/c
 
 # update
 echo "[+] update"
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key f_abc
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=p1 --key f_abc
 
 # check files haven't been updated
 grep_or_fail 'b' "${dt}/a/c/acfile"
-[ -e ${dt}/a/newfile ] && echo "should not have been updated" && exit 1
+[ -e "${dt}"/a/newfile ] && echo "should not have been updated" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/update-negative-ignore-relative.sh b/tests-ng/update-negative-ignore-relative.sh
index cc67836..cb9995a 100755
--- a/tests-ng/update-negative-ignore-relative.sh
+++ b/tests-ng/update-negative-ignore-relative.sh
@@ -1,95 +1,50 @@
 #!/usr/bin/env bash
 # author: jtt9340 (https://github.com/jtt9340)
-# 
+#
 # test ignore update negative relative pattern
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-if [ $(uname) = Darwin ]; then
-  # Unfortunately, readlink works differently on macOS than it does on GNU/Linux
-  # (the -f option behaves differently) and the realpath command does not exist.
-  # Workarounds I find on the Internet suggest just using Homebrew to install coreutils
-  # so you can get the GNU coreutils on your Mac. But, I don't want this script to
-  # assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
-  # they then installed the GNU coreutils.
-  readlink() {
-    TARGET_FILE=$1
-
-    cd `dirname $TARGET_FILE`
-    TARGET_FILE=`basename $TARGET_FILE`
-
-    # Iterate down a (possible) chain of symlinks
-    while [ -L "$TARGET_FILE" ]; do
-      TARGET_FILE=`readlink $TARGET_FILE`
-      cd `dirname $TARGET_FILE`
-      TARGET_FILE=`basename $TARGET_FILE`
-    done
-
-    # Compute the canonicalized name by finding the physical path
-    # for the directory we're in and appending the target file.
-    PHYS_DIR=`pwd -P`
-    RESULT=$PHYS_DIR/$TARGET_FILE
-    echo $RESULT
-  }
-  rl="readlink"
-else
-  rl="readlink -f"
-  if ! ${rl} "${0}" >/dev/null 2>&1; then
-    rl="realpath"
-
-    if ! hash ${rl}; then
-      echo "\"${rl}\" not found !" && exit 1
-    fi
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ -n "${1}" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
-mkdir -p ${basedir}/dotfiles/a/{b,c}
-echo 'a' > ${basedir}/dotfiles/a/b/abfile1
-echo 'a' > ${basedir}/dotfiles/a/b/abfile2
-echo 'a' > ${basedir}/dotfiles/a/b/abfile3
-echo 'a' > ${basedir}/dotfiles/a/c/acfile
+mkdir -p "${basedir}"/dotfiles/a/{b,c}
+echo 'a' > "${basedir}"/dotfiles/a/b/abfile1
+echo 'a' > "${basedir}"/dotfiles/a/b/abfile2
+echo 'a' > "${basedir}"/dotfiles/a/b/abfile3
+echo 'a' > "${basedir}"/dotfiles/a/c/acfile
 
 # the dotfile to be updated
-tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
-cp -r ${basedir}/dotfiles/a ${tmpd}/
+cp -r "${basedir}"/dotfiles/a "${tmpd}"/
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -111,26 +66,26 @@ _EOF
 
 # edit/add files
 echo "[+] edit/add files"
-mkdir -p ${tmpd}/a/newdir/b
-echo 'b' > ${tmpd}/a/b/abfile1
-echo 'b' > ${tmpd}/a/b/abfile2
-echo 'b' > ${tmpd}/a/b/abfile3
-echo 'b' > ${tmpd}/a/b/abfile4
-touch ${tmpd}/a/newdir/b/{c,d}
+mkdir -p "${tmpd}"/a/newdir/b
+echo 'b' > "${tmpd}"/a/b/abfile1
+echo 'b' > "${tmpd}"/a/b/abfile2
+echo 'b' > "${tmpd}"/a/b/abfile3
+echo 'b' > "${tmpd}"/a/b/abfile4
+touch "${tmpd}"/a/newdir/b/{c,d}
 
 # update
 echo "[+] update"
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key f_abc
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=p1 --key f_abc
 
 # check files haven't been updated
 set +e
-grep a ${basedir}/dotfiles/a/b/abfile1 >/dev/null 2>&1 || (echo "abfile1 should not have been updated" && exit 1)
-grep a ${basedir}/dotfiles/a/b/abfile2 >/dev/null 2>&1 || (echo "abfile2 should not have been updated" && exit 1)
-grep b ${basedir}/dotfiles/a/b/abfile3 >/dev/null 2>&1 || (echo "abfile3 should have been updated" && exit 1)
+grep a "${basedir}"/dotfiles/a/b/abfile1 >/dev/null 2>&1 || (echo "abfile1 should not have been updated" && exit 1)
+grep a "${basedir}"/dotfiles/a/b/abfile2 >/dev/null 2>&1 || (echo "abfile2 should not have been updated" && exit 1)
+grep b "${basedir}"/dotfiles/a/b/abfile3 >/dev/null 2>&1 || (echo "abfile3 should have been updated" && exit 1)
 set -e
-[ -e ${basedir}/dotfiles/a/b/abfile4 ] && echo "abfile4 should not have been updated" && exit 1
-[ -e ${basedir}/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been updated" && exit 1
-[ ! -e ${basedir}/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been updated" && exit 1
+[ -e "${basedir}"/dotfiles/a/b/abfile4 ] && echo "abfile4 should not have been updated" && exit 1
+[ -e "${basedir}"/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been updated" && exit 1
+[ ! -e "${basedir}"/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been updated" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/update-negative-ignore.sh b/tests-ng/update-negative-ignore.sh
index efb18f4..a426943 100755
--- a/tests-ng/update-negative-ignore.sh
+++ b/tests-ng/update-negative-ignore.sh
@@ -5,70 +5,20 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-if [ $(uname) = Darwin ]; then
-  # Unfortunately, readlink works differently on macOS than it does on GNU/Linux
-  # (the -f option behaves differently) and the realpath command does not exist.
-  # Workarounds I find on the Internet suggest just using Homebrew to install coreutils
-  # so you can get the GNU coreutils on your Mac. But, I don't want this script to
-  # assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
-  # they then installed the GNU coreutils.
-  readlink() {
-    TARGET_FILE=$1
-
-    cd `dirname $TARGET_FILE`
-    TARGET_FILE=`basename $TARGET_FILE`
-
-    # Iterate down a (possible) chain of symlinks
-    while [ -L "$TARGET_FILE" ]; do
-      TARGET_FILE=`readlink $TARGET_FILE`
-      cd `dirname $TARGET_FILE`
-      TARGET_FILE=`basename $TARGET_FILE`
-    done
-
-    # Compute the canonicalized name by finding the physical path
-    # for the directory we're in and appending the target file.
-    PHYS_DIR=`pwd -P`
-    RESULT=$PHYS_DIR/$TARGET_FILE
-    echo $RESULT
-  }
-  rl="readlink"
-else
-  rl="readlink -f"
-  if ! ${rl} "${0}" >/dev/null 2>&1; then
-    rl="realpath"
-
-    if ! hash ${rl}; then
-      echo "\"${rl}\" not found !" && exit 1
-    fi
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ -n "${1}" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && exho "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -82,26 +32,26 @@ grep_or_fail()
 }
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
-mkdir -p ${basedir}/dotfiles/a/{b,c}
-echo 'a' > ${basedir}/dotfiles/a/b/abfile1
-echo 'a' > ${basedir}/dotfiles/a/b/abfile2
-echo 'a' > ${basedir}/dotfiles/a/b/abfile3
-echo 'a' > ${basedir}/dotfiles/a/c/acfile
+mkdir -p "${basedir}"/dotfiles/a/{b,c}
+echo 'a' > "${basedir}"/dotfiles/a/b/abfile1
+echo 'a' > "${basedir}"/dotfiles/a/b/abfile2
+echo 'a' > "${basedir}"/dotfiles/a/b/abfile3
+echo 'a' > "${basedir}"/dotfiles/a/c/acfile
 
 # the dotfile to be updated
-tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
-cp -r ${basedir}/dotfiles/a ${tmpd}/
+cp -r "${basedir}"/dotfiles/a "${tmpd}"/
 
 # create the config file
 cfg="${basedir}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -123,24 +73,24 @@ _EOF
 
 # edit/add files
 echo "[+] edit/add files"
-mkdir -p ${tmpd}/a/newdir/b
-echo 'b' > ${tmpd}/a/b/abfile1
-echo 'b' > ${tmpd}/a/b/abfile2
-echo 'b' > ${tmpd}/a/b/abfile3
-echo 'b' > ${tmpd}/a/b/abfile4
-touch ${tmpd}/a/newdir/b/{c,d}
+mkdir -p "${tmpd}"/a/newdir/b
+echo 'b' > "${tmpd}"/a/b/abfile1
+echo 'b' > "${tmpd}"/a/b/abfile2
+echo 'b' > "${tmpd}"/a/b/abfile3
+echo 'b' > "${tmpd}"/a/b/abfile4
+touch "${tmpd}"/a/newdir/b/{c,d}
 
 # update
 echo "[+] update"
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key f_abc
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=p1 --key f_abc
 
 # check files haven't been updated
-grep_or_fail a ${basedir}/dotfiles/a/b/abfile1
-grep_or_fail a ${basedir}/dotfiles/a/b/abfile2
-grep_or_fail b ${basedir}/dotfiles/a/b/abfile3
-[ -e ${basedir}/dotfiles/a/b/abfile4 ] && echo "abfile4 should not have been updated" && exit 1
-[ -e ${basedir}/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been updated" && exit 1
-[ ! -e ${basedir}/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been updated" && exit 1
+grep_or_fail a "${basedir}"/dotfiles/a/b/abfile1
+grep_or_fail a "${basedir}"/dotfiles/a/b/abfile2
+grep_or_fail b "${basedir}"/dotfiles/a/b/abfile3
+[ -e "${basedir}"/dotfiles/a/b/abfile4 ] && echo "abfile4 should not have been updated" && exit 1
+[ -e "${basedir}"/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been updated" && exit 1
+[ ! -e "${basedir}"/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been updated" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/update-profile-check.sh b/tests-ng/update-profile-check.sh
index 02f1e11..7755b11 100755
--- a/tests-ng/update-profile-check.sh
+++ b/tests-ng/update-profile-check.sh
@@ -6,36 +6,20 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -49,25 +33,25 @@ grep_or_fail()
 }
 
 # dotdrop directory
-tmps=`mktemp -d --suffix='-dotdrop-tests-source' || mktemp -d`
+tmps=$(mktemp -d --suffix='-dotdrop-tests-source' || mktemp -d)
 dt="${tmps}/dotfiles"
-mkdir -p ${dt}
+mkdir -p "${dt}"
 
 xori="profile x"
-xori="profile y"
-echo "${xori}" > ${dt}/file_x
-echo "${yori}" > ${dt}/file_y
+yori="profile y"
+echo "${xori}" > "${dt}"/file_x
+echo "${yori}" > "${dt}"/file_y
 
 # fs dotfiles
-tmpd=`mktemp -d --suffix='-dotdrop-tests-dest' || mktemp -d`
-touch ${tmpd}/file
+tmpd=$(mktemp -d --suffix='-dotdrop-tests-dest' || mktemp -d)
+touch "${tmpd}"/file
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
 
 # create the config file
 cfg="${tmps}/config.yaml"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: false
   create: true
@@ -87,81 +71,81 @@ profiles:
     dotfiles:
     - f_file_y
 _EOF
-cat ${cfg}
+cat "${cfg}"
 
 # reset
-echo "${xori}" > ${dt}/file_x
-echo "${yori}" > ${dt}/file_y
+echo "${xori}" > "${dt}"/file_x
+echo "${yori}" > "${dt}"/file_y
 
 # test with key
 echo "test update x from key"
 n="patched content for X"
-echo "${n}" > ${tmpd}/file
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=x --key f_file_x
+echo "${n}" > "${tmpd}"/file
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=x --key f_file_x
 grep_or_fail "${n}" "${dt}/file_x"
 grep_or_fail "${yori}" "${dt}/file_y"
 
 # reset
-echo "${xori}" > ${dt}/file_x
-echo "${yori}" > ${dt}/file_y
+echo "${xori}" > "${dt}"/file_x
+echo "${yori}" > "${dt}"/file_y
 
 # test with key
 echo "test update y from key"
 n="patched content for Y"
-echo "${n}" > ${tmpd}/file
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=y --key f_file_y
+echo "${n}" > "${tmpd}"/file
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=y --key f_file_y
 grep_or_fail "${n}" "${dt}/file_y"
 grep_or_fail "${xori}" "${dt}/file_x"
 
 # reset
-echo "${xori}" > ${dt}/file_x
-echo "${yori}" > ${dt}/file_y
+echo "${xori}" > "${dt}"/file_x
+echo "${yori}" > "${dt}"/file_y
 
 # test with path
 echo "test update x from path"
 n="patched content for X"
-echo "${n}" > ${tmpd}/file
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=x "${tmpd}/file"
+echo "${n}" > "${tmpd}"/file
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=x "${tmpd}/file"
 grep_or_fail "${n}" "${dt}/file_x"
 grep_or_fail "${yori}" "${dt}/file_y"
 
 # reset
-echo "${xori}" > ${dt}/file_x
-echo "${yori}" > ${dt}/file_y
+echo "${xori}" > "${dt}"/file_x
+echo "${yori}" > "${dt}"/file_y
 
 # test with path
 echo "test update y from path"
 n="patched content for Y"
-echo "${n}" > ${tmpd}/file
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=y "${tmpd}/file"
+echo "${n}" > "${tmpd}"/file
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=y "${tmpd}/file"
 grep_or_fail "${n}" "${dt}/file_y"
 grep_or_fail "${xori}" "${dt}/file_x"
 
 ## make sure it fails when wrong dotfile
 # reset
-echo "${xori}" > ${dt}/file_x
-echo "${yori}" > ${dt}/file_y
+echo "${xori}" > "${dt}"/file_x
+echo "${yori}" > "${dt}"/file_y
 
 # test with key
 echo "test wrong key for x"
 n="patched content for X"
-echo "${n}" > ${tmpd}/file
+echo "${n}" > "${tmpd}"/file
 set +e
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=x --key f_file_y
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=x --key f_file_y
 set -e
 grep_or_fail "${xori}" "${dt}/file_x"
 grep_or_fail "${yori}" "${dt}/file_y"
 
 # reset
-echo "${xori}" > ${dt}/file_x
-echo "${yori}" > ${dt}/file_y
+echo "${xori}" > "${dt}"/file_x
+echo "${yori}" > "${dt}"/file_y
 
 # test with key
 echo "test wrong key for y"
 n="patched content for Y"
-echo "${n}" > ${tmpd}/file
+echo "${n}" > "${tmpd}"/file
 set +e
-cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=y --key f_file_x
+cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=y --key f_file_x
 set -e
 grep_or_fail "${xori}" "${dt}/file_x"
 grep_or_fail "${yori}" "${dt}/file_y"
diff --git a/tests-ng/update-rights.sh b/tests-ng/update-rights.sh
index c214982..c29210c 100755
--- a/tests-ng/update-rights.sh
+++ b/tests-ng/update-rights.sh
@@ -6,97 +6,76 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile directory to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 # the dotfile file to be imported
-tmpf=`mktemp`
+tmpf=$(mktemp)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # single file
-echo 'file' > ${tmpf}
+echo 'file' > "${tmpf}"
 
-mkdir ${tmpd}/dir1
-echo 'dir1file1' > ${tmpd}/dir1/file1
-echo 'dir1file2' > ${tmpd}/dir1/file2
+mkdir "${tmpd}"/dir1
+echo 'dir1file1' > "${tmpd}"/dir1/file1
+echo 'dir1file2' > "${tmpd}"/dir1/file2
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import dir1
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpf}
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpf}"
 
 # change file
-chmod +x ${tmpf}
+chmod +x "${tmpf}"
 
 # update
 echo "[+] updating"
-cd ${ddpath} | ${bin} update -c ${cfg} -f --verbose ${tmpf}
+cd "${ddpath}" | ${bin} update -c "${cfg}" -f --verbose "${tmpf}"
 
 # test change applied
-[ "`stat -c '%a' ${tmpf}`" != "`stat -c '%a' ${basedir}/dotfiles/${tmpf}`" ] && exit 1
+[ "$(stat -c '%a' "${tmpf}")" != "$(stat -c '%a' "${basedir}"/dotfiles/"${tmpf}")" ] && exit 1
 
 # change file
-chmod +x ${tmpd}/dir1/file2
-echo 'test' > ${tmpd}/dir1/newfile
-chmod +x ${tmpd}/dir1/newfile
+chmod +x "${tmpd}"/dir1/file2
+echo 'test' > "${tmpd}"/dir1/newfile
+chmod +x "${tmpd}"/dir1/newfile
 
 # update
 echo "[+] updating"
-cd ${ddpath} | ${bin} update -c ${cfg} -f --verbose ${tmpd}
+cd "${ddpath}" | ${bin} update -c "${cfg}" -f --verbose "${tmpd}"
 
 # test change applied
-[ "`stat -c '%a' ${tmpd}/dir1/newfile`" != "`stat -c '%a' ${basedir}/dotfiles/${tmpd}/dir1/newfile`" ] && exit 1
-[ "`stat -c '%a' ${tmpd}/dir1/file2`" != "`stat -c '%a' ${basedir}/dotfiles/${tmpd}/dir1/file2`" ] && exit 1
+[ "$(stat -c '%a' "${tmpd}"/dir1/newfile)" != "$(stat -c '%a' "${basedir}"/dotfiles/"${tmpd}"/dir1/newfile)" ] && exit 1
+[ "$(stat -c '%a' "${tmpd}"/dir1/file2)" != "$(stat -c '%a' "${basedir}"/dotfiles/"${tmpd}"/dir1/file2)" ] && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/update-templates.sh b/tests-ng/update-templates.sh
index aaec60e..ec7678f 100755
--- a/tests-ng/update-templates.sh
+++ b/tests-ng/update-templates.sh
@@ -6,55 +6,34 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 echo "dotfiles source (dotpath): ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 # the workdir
-tmpw=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpw=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 export DOTDROP_WORKDIR="${tmpw}"
 echo "workdir: ${tmpw}"
 
@@ -65,7 +44,7 @@ clear_on_exit "${tmpw}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -83,27 +62,28 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "head" > ${tmps}/dotfiles/abc
-echo '{%@@ if profile == "p1" @@%}' >> ${tmps}/dotfiles/abc
-echo "is p1" >> ${tmps}/dotfiles/abc
-echo '{%@@ else @@%}' >> ${tmps}/dotfiles/abc
-echo "is not p1" >> ${tmps}/dotfiles/abc
-echo '{%@@ endif @@%}' >> ${tmps}/dotfiles/abc
-echo "tail" >> ${tmps}/dotfiles/abc
+echo "head" > "${tmps}"/dotfiles/abc
+echo '{%@@ if profile == "p1" @@%}' >> "${tmps}"/dotfiles/abc
+echo "is p1" >> "${tmps}"/dotfiles/abc
+echo '{%@@ else @@%}' >> "${tmps}"/dotfiles/abc
+echo "is not p1" >> "${tmps}"/dotfiles/abc
+echo '{%@@ endif @@%}' >> "${tmps}"/dotfiles/abc
+echo "tail" >> "${tmps}"/dotfiles/abc
 
 # create the installed dotfile
-echo "head" > ${tmpd}/abc
-echo "is p1" >> ${tmpd}/abc
-echo "tail" >> ${tmpd}/abc
+echo "head" > "${tmpd}"/abc
+echo "is p1" >> "${tmpd}"/abc
+echo "tail" >> "${tmpd}"/abc
 
 # update
 #cat ${tmps}/dotfiles/abc
 set +e
-patch=`cd ${ddpath} | ${bin} update -P -p p1 -k f_abc --cfg ${cfg} 2>&1 | grep 'try patching with' | sed 's/"//g'`
+patch=$(cd "${ddpath}" | ${bin} update -P -p p1 -k f_abc --cfg "${cfg}" 2>&1 | grep 'try patching with' | sed 's/"//g')
 set -e
-patch=`echo ${patch} | sed 's/^.*: //g'`
+# shellcheck disable=SC2001
+patch=$(echo "${patch}" | sed 's/^.*: //g')
 echo "patching with: ${patch}"
-eval ${patch}
+eval "${patch}"
 #cat ${tmps}/dotfiles/abc
 
 echo "OK"
diff --git a/tests-ng/update-with-key.sh b/tests-ng/update-with-key.sh
index 17363bc..6b40942 100755
--- a/tests-ng/update-with-key.sh
+++ b/tests-ng/update-with-key.sh
@@ -6,100 +6,77 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # originally imported directory
-echo 'unique' > ${tmpd}/uniquefile
+echo 'unique' > "${tmpd}"/uniquefile
 uniquefile_key="f_uniquefile"
-echo 'unique2' > ${tmpd}/uniquefile2
-uniquefile2_key="f_uniquefile2"
-mkdir ${tmpd}/dir1
-touch ${tmpd}/dir1/dir1f1
-mkdir ${tmpd}/dir1/dir1dir1
-dir1_key="d_dir1"
+echo 'unique2' > "${tmpd}"/uniquefile2
+mkdir "${tmpd}"/dir1
+touch "${tmpd}"/dir1/dir1f1
+mkdir "${tmpd}"/dir1/dir1dir1
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import dir1
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/dir1
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/uniquefile
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/uniquefile2
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/dir1
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/uniquefile
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/uniquefile2
 
 # make some modification
 echo "[+] modify"
-echo 'changed' > ${tmpd}/uniquefile
-echo 'changed' > ${tmpd}/uniquefile2
-echo 'new' > ${tmpd}/dir1/dir1dir1/new
+echo 'changed' > "${tmpd}"/uniquefile
+echo 'changed' > "${tmpd}"/uniquefile2
+echo 'new' > "${tmpd}"/dir1/dir1dir1/new
 
 # update by key
 echo "[+] updating single key"
-cd ${ddpath} | ${bin} update -c ${cfg} -k -f --verbose ${uniquefile_key}
+cd "${ddpath}" | ${bin} update -c "${cfg}" -k -f --verbose ${uniquefile_key}
 
 # ensure changes applied correctly (only to uniquefile)
-diff ${tmpd}/uniquefile ${basedir}/dotfiles/${tmpd}/uniquefile # should be same
+diff "${tmpd}"/uniquefile "${basedir}"/dotfiles/"${tmpd}"/uniquefile # should be same
 set +e
-diff ${tmpd}/uniquefile2 ${basedir}/dotfiles/${tmpd}/uniquefile2 # should be different
+diff "${tmpd}"/uniquefile2 "${basedir}"/dotfiles/"${tmpd}"/uniquefile2 # should be different
 [ "${?}" != "1" ] && exit 1
 set -e
 
 # update all keys
 echo "[+] updating all keys"
-cd ${ddpath} | ${bin} update -c ${cfg} -k -f --verbose
+cd "${ddpath}" | ${bin} update -c "${cfg}" -k -f --verbose
 
 # ensure all changes applied
-diff ${tmpd} ${basedir}/dotfiles/${tmpd}
+diff "${tmpd}" "${basedir}"/dotfiles/"${tmpd}"
 
 echo "OK"
 exit 0
diff --git a/tests-ng/update.sh b/tests-ng/update.sh
index 3a6a1b1..527b243 100755
--- a/tests-ng/update.sh
+++ b/tests-ng/update.sh
@@ -6,111 +6,90 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # dotdrop directory
-basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "[+] dotdrop dir: ${basedir}"
 echo "[+] dotpath dir: ${basedir}/dotfiles"
 
 # the dotfile to be imported
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${basedir}"
 clear_on_exit "${tmpd}"
 
 # single file
-echo 'unique' > ${tmpd}/uniquefile
+echo 'unique' > "${tmpd}"/uniquefile
 
 # hierarchy from https://pymotw.com/2/filecmp/
 # create the hierarchy
 # for dir1 (originally imported directory))))
-mkdir ${tmpd}/dir1
-touch ${tmpd}/dir1/file_only_in_dir1
-mkdir -p ${tmpd}/dir1/dir_only_in_dir1
-mkdir -p ${tmpd}/dir1/common_dir
-echo 'this file is the same' > ${tmpd}/dir1/common_file
-echo 'in dir1' > ${tmpd}/dir1/not_the_same
-echo 'This is a file in dir1' > ${tmpd}/dir1/file_in_dir1
-mkdir -p ${tmpd}/dir1/sub/sub2
-mkdir -p ${tmpd}/dir1/notindir2/notindir2
-echo 'first' > ${tmpd}/dir1/sub/sub2/different
+mkdir "${tmpd}"/dir1
+touch "${tmpd}"/dir1/file_only_in_dir1
+mkdir -p "${tmpd}"/dir1/dir_only_in_dir1
+mkdir -p "${tmpd}"/dir1/common_dir
+echo 'this file is the same' > "${tmpd}"/dir1/common_file
+echo 'in dir1' > "${tmpd}"/dir1/not_the_same
+echo 'This is a file in dir1' > "${tmpd}"/dir1/file_in_dir1
+mkdir -p "${tmpd}"/dir1/sub/sub2
+mkdir -p "${tmpd}"/dir1/notindir2/notindir2
+echo 'first' > "${tmpd}"/dir1/sub/sub2/different
 #tree ${tmpd}/dir1
 
 # create the hierarchy
 # for dir2 (modified original for update)
-mkdir ${tmpd}/dir2
-touch ${tmpd}/dir2/file_only_in_dir2
-mkdir -p ${tmpd}/dir2/dir_only_in_dir2
-mkdir -p ${tmpd}/dir2/common_dir
-echo 'this file is the same' > ${tmpd}/dir2/common_file
-echo 'in dir2' > ${tmpd}/dir2/not_the_same
-mkdir -p ${tmpd}/dir2/file_in_dir1
-mkdir -p ${tmpd}/dir2/sub/sub2
-echo 'modified' > ${tmpd}/dir2/sub/sub2/different
-mkdir -p ${tmpd}/dir2/new/new2
-mkdir -p ${tmpd}/dir2/sub1/sub2/sub3/
-touch ${tmpd}/dir2/sub1/sub2/sub3/file
+mkdir "${tmpd}"/dir2
+touch "${tmpd}"/dir2/file_only_in_dir2
+mkdir -p "${tmpd}"/dir2/dir_only_in_dir2
+mkdir -p "${tmpd}"/dir2/common_dir
+echo 'this file is the same' > "${tmpd}"/dir2/common_file
+echo 'in dir2' > "${tmpd}"/dir2/not_the_same
+mkdir -p "${tmpd}"/dir2/file_in_dir1
+mkdir -p "${tmpd}"/dir2/sub/sub2
+echo 'modified' > "${tmpd}"/dir2/sub/sub2/different
+mkdir -p "${tmpd}"/dir2/new/new2
+mkdir -p "${tmpd}"/dir2/sub1/sub2/sub3/
+touch "${tmpd}"/dir2/sub1/sub2/sub3/file
 #tree ${tmpd}/dir2
 
 # create the config file
 cfg="${basedir}/config.yaml"
-create_conf ${cfg} # sets token
+create_conf "${cfg}" # sets token
 
 # import dir1
 echo "[+] import"
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/dir1
-cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/uniquefile
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/dir1
+cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/uniquefile
 
 # let's see the dotpath
 #tree ${basedir}/dotfiles
 
 # change dir1 to dir2 in deployed
 echo "[+] change dir"
-rm -rf ${tmpd}/dir1
-mv ${tmpd}/dir2 ${tmpd}/dir1
+rm -rf "${tmpd}"/dir1
+mv "${tmpd}"/dir2 "${tmpd}"/dir1
 #tree ${tmpd}/dir1
 
 # change unique file
-echo 'changed' > ${tmpd}/uniquefile
+echo 'changed' > "${tmpd}"/uniquefile
 
 # compare
 #echo "[+] comparing"
@@ -118,16 +97,16 @@ echo 'changed' > ${tmpd}/uniquefile
 
 # update
 echo "[+] updating"
-cd ${ddpath} | ${bin} update -c ${cfg} -f --verbose ${tmpd}/uniquefile ${tmpd}/dir1
+cd "${ddpath}" | ${bin} update -c "${cfg}" -f --verbose "${tmpd}"/uniquefile "${tmpd}"/dir1
 
 # manually update
-rm ${basedir}/dotfiles/${tmpd}/dir1/file_in_dir1
-mkdir -p ${basedir}/dotfiles/${tmpd}/dir1/file_in_dir1
+rm "${basedir}"/dotfiles/"${tmpd}"/dir1/file_in_dir1
+mkdir -p "${basedir}"/dotfiles/"${tmpd}"/dir1/file_in_dir1
 
 # ensure changes applied correctly
-diff ${tmpd}/dir1 ${basedir}/dotfiles/${tmpd}/dir1
-diff ${tmpd}/uniquefile ${basedir}/dotfiles/${tmpd}/uniquefile
-[ ! -e ${basedir}/dotfiles/${tmpd}/dir1/sub1/sub2/sub3/file ] && echo "sub does not exist" && exit 1
+diff "${tmpd}"/dir1 "${basedir}"/dotfiles/"${tmpd}"/dir1
+diff "${tmpd}"/uniquefile "${basedir}"/dotfiles/"${tmpd}"/uniquefile
+[ ! -e "${basedir}"/dotfiles/"${tmpd}"/dir1/sub1/sub2/sub3/file ] && echo "sub does not exist" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-ng/uservariables.sh b/tests-ng/uservariables.sh
index 7f4e6d2..f6ab82e 100755
--- a/tests-ng/uservariables.sh
+++ b/tests-ng/uservariables.sh
@@ -6,51 +6,30 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -59,7 +38,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -87,27 +66,31 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "var1: {{@@ var1 @@}}" > ${tmps}/dotfiles/abc
-echo "var2: {{@@ var2 @@}}" >> ${tmps}/dotfiles/abc
-echo "var3: {{@@ var3 @@}}" >> ${tmps}/dotfiles/abc
-echo "var4: {{@@ var4 @@}}" >> ${tmps}/dotfiles/abc
+echo "var1: {{@@ var1 @@}}" > "${tmps}"/dotfiles/abc
+echo "var2: {{@@ var2 @@}}" >> "${tmps}"/dotfiles/abc
+echo "var3: {{@@ var3 @@}}" >> "${tmps}"/dotfiles/abc
+echo "var4: {{@@ var4 @@}}" >> "${tmps}"/dotfiles/abc
 
 # install
 echo "step 1"
-cd ${ddpath} | echo -e 'var1contentxxx\nvar2contentyyy\nvar3\nvar4\n' | ${bin} install -f -c ${cfg} -p p1 -V
+(
+  cd "${ddpath}"
+  printf 'var1contentxxx\nvar2contentyyy\nvar3\nvar4\n' | ${bin} install -f -c "${cfg}" -p p1 -V
+  exit ${?}
+)
 
-cat ${tmpd}/abc
+cat "${tmpd}"/abc
 
-grep '^var1: var1contentxxx$' ${tmpd}/abc >/dev/null
-grep '^var2: var2contentyyy$' ${tmpd}/abc >/dev/null
-grep '^var3: dynvariables_var3$' ${tmpd}/abc >/dev/null
-grep '^var4: variables_var4$' ${tmpd}/abc >/dev/null
+grep '^var1: var1contentxxx$' "${tmpd}"/abc >/dev/null
+grep '^var2: var2contentyyy$' "${tmpd}"/abc >/dev/null
+grep '^var3: dynvariables_var3$' "${tmpd}"/abc >/dev/null
+grep '^var4: variables_var4$' "${tmpd}"/abc >/dev/null
 
 [ ! -e "${tmps}/uservariables.yaml" ] && exit 1
 
-grep '^variables:' ${tmps}/uservariables.yaml >/dev/null
-grep '^  var1: var1contentxxx$' ${tmps}/uservariables.yaml >/dev/null
-grep '^  var2: var2contentyyy$' ${tmps}/uservariables.yaml >/dev/null
+grep '^variables:' "${tmps}"/uservariables.yaml >/dev/null
+grep '^  var1: var1contentxxx$' "${tmps}"/uservariables.yaml >/dev/null
+grep '^  var2: var2contentyyy$' "${tmps}"/uservariables.yaml >/dev/null
 
 cat > "${tmps}/uservariables.yaml" << _EOF
 variables:
@@ -116,12 +99,12 @@ variables:
 _EOF
 
 echo "step 2"
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -V
 
-grep '^var1: editedvar1$' ${tmpd}/abc >/dev/null
-grep '^var2: editedvar2$' ${tmpd}/abc >/dev/null
-grep '^var3: dynvariables_var3$' ${tmpd}/abc >/dev/null
-grep '^var4: variables_var4$' ${tmpd}/abc >/dev/null
+grep '^var1: editedvar1$' "${tmpd}"/abc >/dev/null
+grep '^var2: editedvar2$' "${tmpd}"/abc >/dev/null
+grep '^var3: dynvariables_var3$' "${tmpd}"/abc >/dev/null
+grep '^var4: variables_var4$' "${tmpd}"/abc >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/variables-enrich.sh b/tests-ng/variables-enrich.sh
index 3a45ed9..9a359e0 100755
--- a/tests-ng/variables-enrich.sh
+++ b/tests-ng/variables-enrich.sh
@@ -6,52 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 clear_on_exit "${tmps}"
 clear_on_exit "${tmpd}"
@@ -60,7 +39,7 @@ clear_on_exit "${tmpd}"
 cfg="${tmps}/config.yaml"
 export dotdrop_test_dst="${tmpd}/def"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -77,14 +56,14 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "os={{@@ os @@}}" > ${tmps}/dotfiles/abc
-echo "release={{@@ release @@}}" >> ${tmps}/dotfiles/abc
-echo "distro_id={{@@ distro_id @@}}" >> ${tmps}/dotfiles/abc
-echo "distro_like={{@@ distro_like @@}}" >> ${tmps}/dotfiles/abc
-echo "distro_version={{@@ distro_version @@}}" >> ${tmps}/dotfiles/abc
+echo "os={{@@ os @@}}" > "${tmps}"/dotfiles/abc
+echo "release={{@@ release @@}}" >> "${tmps}"/dotfiles/abc
+echo "distro_id={{@@ distro_id @@}}" >> "${tmps}"/dotfiles/abc
+echo "distro_like={{@@ distro_like @@}}" >> "${tmps}"/dotfiles/abc
+echo "distro_version={{@@ distro_version @@}}" >> "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 --verbose
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 --verbose
 
 pybin="python3"
 real_os=$(${pybin} -c 'import platform; print(platform.system().lower())')
@@ -94,17 +73,17 @@ real_distro_like=$(${pybin} -c 'import distro; print(distro.like().lower())')
 real_distro_version=$(${pybin} -c 'import distro; print(distro.version().lower())')
 
 # tests
-[ ! -e ${tmpd}/abc ] && echo "abc not installed" && exit 1
+[ ! -e "${tmpd}"/abc ] && echo "abc not installed" && exit 1
 cat "${tmpd}/abc"
   ## only test this on CI/CD
-grep "^os=${real_os}" ${tmpd}/abc >/dev/null
-grep "^release=${real_release}" ${tmpd}/abc >/dev/null
-grep "^distro_id=${real_distro_id}" ${tmpd}/abc >/dev/null
-grep "^distro_like=${real_distro_like}" ${tmpd}/abc >/dev/null
-grep "^distro_version=${real_distro_version}" ${tmpd}/abc >/dev/null
+grep "^os=${real_os}" "${tmpd}"/abc >/dev/null
+grep "^release=${real_release}" "${tmpd}"/abc >/dev/null
+grep "^distro_id=${real_distro_id}" "${tmpd}"/abc >/dev/null
+grep "^distro_like=${real_distro_like}" "${tmpd}"/abc >/dev/null
+grep "^distro_version=${real_distro_version}" "${tmpd}"/abc >/dev/null
 
 # already defined variables
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -127,16 +106,16 @@ _EOF
 rm -f "${tmpd}/abc"
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 --verbose
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 --verbose
 
 # tests
-[ ! -e ${tmpd}/abc ] && echo "abc not installed" && exit 1
+[ ! -e "${tmpd}"/abc ] && echo "abc not installed" && exit 1
 cat "${tmpd}/abc"
-grep '^os=abc$' ${tmpd}/abc >/dev/null
-grep '^release=def$' ${tmpd}/abc >/dev/null
-grep '^distro_id=ghi$' ${tmpd}/abc >/dev/null
-grep '^distro_like=jkl$' ${tmpd}/abc >/dev/null
-grep '^distro_version=mno$' ${tmpd}/abc >/dev/null
+grep '^os=abc$' "${tmpd}"/abc >/dev/null
+grep '^release=def$' "${tmpd}"/abc >/dev/null
+grep '^distro_id=ghi$' "${tmpd}"/abc >/dev/null
+grep '^distro_like=jkl$' "${tmpd}"/abc >/dev/null
+grep '^distro_version=mno$' "${tmpd}"/abc >/dev/null
 
 echo "OK"
 exit 0
diff --git a/tests-ng/variables-include.sh b/tests-ng/variables-include.sh
index ac11738..a389143 100755
--- a/tests-ng/variables-include.sh
+++ b/tests-ng/variables-include.sh
@@ -6,52 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 #echo "dotfile source: ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -60,7 +39,7 @@ clear_on_exit "${tmpd}"
 # create the config file
 cfg="${tmps}/config.yaml"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -88,26 +67,26 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "{{@@ var1 @@}}" > ${tmps}/dotfiles/abc
-echo "{{@@ var2 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ var3 @@}}" >> ${tmps}/dotfiles/abc
-echo "test" >> ${tmps}/dotfiles/abc
+echo "{{@@ var1 @@}}" > "${tmps}"/dotfiles/abc
+echo "{{@@ var2 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ var3 @@}}" >> "${tmps}"/dotfiles/abc
+echo "test" >> "${tmps}"/dotfiles/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1
 
-cat ${tmpd}/abc
-grep '^this is some sub-test' ${tmpd}/abc >/dev/null
-grep '^12' ${tmpd}/abc >/dev/null
-grep '^another test' ${tmpd}/abc >/dev/null
+cat "${tmpd}"/abc
+grep '^this is some sub-test' "${tmpd}"/abc >/dev/null
+grep '^12' "${tmpd}"/abc >/dev/null
+grep '^another test' "${tmpd}"/abc >/dev/null
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p2
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p2
 
-cat ${tmpd}/abc
-grep '^this is some sub-test' ${tmpd}/abc >/dev/null
-grep '^42' ${tmpd}/abc >/dev/null
-grep '^another test' ${tmpd}/abc >/dev/null
+cat "${tmpd}"/abc
+grep '^this is some sub-test' "${tmpd}"/abc >/dev/null
+grep '^42' "${tmpd}"/abc >/dev/null
+grep '^another test' "${tmpd}"/abc >/dev/null
 
 #cat ${tmpd}/abc
 
diff --git a/tests-ng/variables-nested.sh b/tests-ng/variables-nested.sh
new file mode 100755
index 0000000..9ed3a0b
--- /dev/null
+++ b/tests-ng/variables-nested.sh
@@ -0,0 +1,87 @@
+#!/usr/bin/env bash
+# author: deadc0de6 (https://github.com/deadc0de6)
+# Copyright (c) 2023, deadc0de6
+#
+# test nested variables (see #383)
+# returns 1 in case of error
+#
+
+## start-cookie
+set -e
+cur=$(cd "$(dirname "${0}")" && pwd)
+ddpath="${cur}/../"
+export PYTHONPATH="${ddpath}:${PYTHONPATH}"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
+
+################################################################
+# this is the test
+################################################################
+
+# the dotfile source
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
+# the dotfile destination
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+
+clear_on_exit "${tmps}"
+clear_on_exit "${tmpd}"
+
+# create the config file
+cfg="${tmps}/config.yaml"
+
+cat > "${cfg}" << _EOF
+config:
+  backup: true
+  create: true
+  dotpath: dotfiles
+variables:
+  hello:
+    k: "hello1"
+  wow1: "{{@@ hello.k @@}}"
+  hello2: "hello2"
+  z2:
+    wow2: "{{@@ hello2 @@}}"
+  a:
+    suba:
+      subsuba: "submarine"
+  b:
+    subb:
+      subsubb:
+dotfiles:
+  f_abc:
+    dst: ${tmpd}/abc
+    src: abc
+profiles:
+  p1:
+    dotfiles:
+    - f_abc
+_EOF
+#cat ${cfg}
+
+# create the dotfile
+echo "wow1={{@@ wow1 @@}}" > "${tmps}"/dotfiles/abc
+echo "wow2={{@@ z2.wow2 @@}}" >> "${tmps}"/dotfiles/abc
+echo "subsuba={{@@ a.suba.subsuba @@}}" >> "${tmps}"/dotfiles/abc
+echo "subsubb={{@@ b.subb.subsubb @@}}" >> "${tmps}"/dotfiles/abc
+
+# install
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 --verbose
+
+cat "${tmpd}"/abc
+
+[ ! -e "${tmpd}"/abc ] && echo "abc not installed" && exit 1
+grep '^wow1=hello1' "${tmpd}"/abc >/dev/null
+grep '^wow2=hello2' "${tmpd}"/abc >/dev/null
+grep '^subsuba=submarine' "${tmpd}"/abc >/dev/null
+grep '^subsubb=None' "${tmpd}"/abc >/dev/null
+
+echo "OK"
+exit 0
diff --git a/tests-ng/variables.sh b/tests-ng/variables.sh
index 94f6e60..92d1c77 100755
--- a/tests-ng/variables.sh
+++ b/tests-ng/variables.sh
@@ -6,52 +6,31 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 
 # the dotfile source
-tmps=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
-mkdir -p ${tmps}/dotfiles
+tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
+mkdir -p "${tmps}"/dotfiles
 #echo "dotfile source: ${tmps}"
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 #echo "dotfile destination: ${tmpd}"
 
 clear_on_exit "${tmps}"
@@ -61,7 +40,7 @@ clear_on_exit "${tmpd}"
 cfg="${tmps}/config.yaml"
 export dotdrop_test_dst="${tmpd}/def"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -87,23 +66,23 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "{{@@ var1 @@}}" > ${tmps}/dotfiles/abc
-echo "{{@@ var2 @@}}" >> ${tmps}/dotfiles/abc
-echo "{{@@ var3 @@}}" >> ${tmps}/dotfiles/abc
-echo "test" >> ${tmps}/dotfiles/abc
+echo "{{@@ var1 @@}}" > "${tmps}"/dotfiles/abc
+echo "{{@@ var2 @@}}" >> "${tmps}"/dotfiles/abc
+echo "{{@@ var3 @@}}" >> "${tmps}"/dotfiles/abc
+echo "test" >> "${tmps}"/dotfiles/abc
 
-echo "test_def" > ${tmps}/dotfiles/def
+echo "test_def" > "${tmps}"/dotfiles/def
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 --verbose
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 --verbose
 
-[ ! -e ${tmpd}/abc ] && echo "abc not installed" && exit 1
-grep '^this is some test' ${tmpd}/abc >/dev/null
-grep '^12' ${tmpd}/abc >/dev/null
-grep '^another test' ${tmpd}/abc >/dev/null
+[ ! -e "${tmpd}"/abc ] && echo "abc not installed" && exit 1
+grep '^this is some test' "${tmpd}"/abc >/dev/null
+grep '^12' "${tmpd}"/abc >/dev/null
+grep '^another test' "${tmpd}"/abc >/dev/null
 
-[ ! -e ${tmpd}/def ] && echo "def not installed" && exit 1
-grep '^test_def' ${tmpd}/def >/dev/null
+[ ! -e "${tmpd}"/def ] && echo "def not installed" && exit 1
+grep '^test_def' "${tmpd}"/def >/dev/null
 
 #cat ${tmpd}/abc
 
diff --git a/tests-ng/workdir-compare.sh b/tests-ng/workdir-compare.sh
index 5251268..4696f17 100755
--- a/tests-ng/workdir-compare.sh
+++ b/tests-ng/workdir-compare.sh
@@ -6,58 +6,36 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
 ################################################################
 unset DOTDROP_WORKDIR
-string="blabla"
 
 # the dotfile source
-tmp=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmp=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 tmpf="${tmp}/dotfiles"
 tmpw="${tmp}/workdir"
 export DOTDROP_WORKDIR="${tmpw}"
 
-mkdir -p ${tmpf}
+mkdir -p "${tmpf}"
 echo "dotfiles source (dotpath): ${tmpf}"
-mkdir -p ${tmpw}
+mkdir -p "${tmpw}"
 echo "workdir: ${tmpw}"
 
 # create the config file
@@ -65,13 +43,13 @@ cfg="${tmp}/config.yaml"
 echo "config file: ${cfg}"
 
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmp}"
 clear_on_exit "${tmpd}"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -101,67 +79,67 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "{{@@ profile @@}}" > ${tmpf}/a
-echo "{{@@ profile @@}}" > ${tmpf}/b
-mkdir -p ${tmpf}/c
-echo "{{@@ profile @@}}" > ${tmpf}/c/a
-echo "{{@@ profile @@}}" > ${tmpf}/c/b
-mkdir ${tmpf}/c/x
-echo "{{@@ profile @@}}" > ${tmpf}/c/x/a
-echo "{{@@ profile @@}}" > ${tmpf}/c/x/b
+echo "{{@@ profile @@}}" > "${tmpf}"/a
+echo "{{@@ profile @@}}" > "${tmpf}"/b
+mkdir -p "${tmpf}"/c
+echo "{{@@ profile @@}}" > "${tmpf}"/c/a
+echo "{{@@ profile @@}}" > "${tmpf}"/c/b
+mkdir "${tmpf}"/c/x
+echo "{{@@ profile @@}}" > "${tmpf}"/c/x/a
+echo "{{@@ profile @@}}" > "${tmpf}"/c/x/b
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b
 
 # compare (no diff)
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -b -V
 
 # add file
-touch ${tmpw}/untrack
+touch "${tmpw}"/untrack
 
 # compare (one diff)
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -b -V
 [ "$?" != "1" ] && echo "not found untracked file in workdir (1)" && exit 1
 set -e
 
 # clean
-rm ${tmpw}/untrack
+rm "${tmpw}"/untrack
 # add sub file
-touch ${tmpw}/${tmpd}/c/x/untrack
+touch "${tmpw}"/"${tmpd}"/c/x/untrack
 
 # compare (two diff)
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -b -V
 [ "$?" != "1" ] && echo "not found untracked file in workdir (2)" && exit 1
 set -e
 
 # clean
-rm ${tmpw}/${tmpd}/c/x/untrack
+rm "${tmpw}"/"${tmpd}"/c/x/untrack
 # add dir
-mkdir ${tmpw}/d_untrack
-touch ${tmpw}/d_untrack/untrack
+mkdir "${tmpw}"/d_untrack
+touch "${tmpw}"/d_untrack/untrack
 
 # compare (three diffs)
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -b -V
 [ "$?" != "1" ] && echo "not found untracked file in workdir (3)" && exit 1
 set -e
 
 # clean
-rm -r ${tmpw}/d_untrack
+rm -r "${tmpw}"/d_untrack
 # add sub dir
-mkdir ${tmpw}/${tmpd}/c/x/d_untrack
-touch ${tmpw}/${tmpd}/c/x/d_untrack/untrack
+mkdir "${tmpw}"/"${tmpd}"/c/x/d_untrack
+touch "${tmpw}"/"${tmpd}"/c/x/d_untrack/untrack
 
 # compare
 set +e
-cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -b -V
 [ "$?" != "1" ] && echo "not found untracked file in workdir (4)" && exit 1
 set -e
 
 ## CLEANING
-rm -rf ${tmp} ${tmpd}
+rm -rf "${tmp}" "${tmpd}"
 
 echo "OK"
 exit 0
diff --git a/tests-ng/workdir.sh b/tests-ng/workdir.sh
index 763bc04..be741ff 100755
--- a/tests-ng/workdir.sh
+++ b/tests-ng/workdir.sh
@@ -6,41 +6,20 @@
 # returns 1 in case of error
 #
 
-# exit on first error
+## start-cookie
 set -e
-
-# all this crap to get current path
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found !" && exit 1
-  fi
-fi
-cur=$(dirname "$(${rl} "${0}")")
-
-#hash dotdrop >/dev/null 2>&1
-#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
-
-#echo "called with ${1}"
-
-# dotdrop path can be pass as argument
+cur=$(cd "$(dirname "${0}")" && pwd)
 ddpath="${cur}/../"
-[ "${1}" != "" ] && ddpath="${1}"
-[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
-
 export PYTHONPATH="${ddpath}:${PYTHONPATH}"
-bin="python3 -m dotdrop.dotdrop"
-hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true
-
-echo "dotdrop path: ${ddpath}"
-echo "pythonpath: ${PYTHONPATH}"
-
-# get the helpers
-source ${cur}/helpers
-
-echo -e "$(tput setaf 6)==> RUNNING $(basename $BASH_SOURCE) <==$(tput sgr0)"
+altbin="python3 -m dotdrop.dotdrop"
+if hash coverage 2>/dev/null; then
+  altbin="coverage run -p --source=dotdrop -m dotdrop.dotdrop"
+fi
+bin="${DT_BIN:-${altbin}}"
+# shellcheck source=tests-ng/helpers
+source "${cur}"/helpers
+echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
+## end-cookie
 
 ################################################################
 # this is the test
@@ -49,15 +28,15 @@ unset DOTDROP_WORKDIR
 string="blabla"
 
 # the dotfile source
-tmp=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmp=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 tmpf="${tmp}/dotfiles"
 tmpw="${tmp}/workdir"
 export DOTDROP_WORKDIR="${tmpw}"
 
-mkdir -p ${tmpf}
+mkdir -p "${tmpf}"
 echo "dotfiles source (dotpath): ${tmpf}"
-mkdir -p ${tmpw}
+mkdir -p "${tmpw}"
 echo "workdir: ${tmpw}"
 
 # create the config file
@@ -65,7 +44,7 @@ cfg="${tmp}/config.yaml"
 echo "config file: ${cfg}"
 
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmp}"
@@ -73,12 +52,12 @@ clear_on_exit "${tmpd}"
 
 ## RELATIVE
 echo "RUNNING RELATIVE"
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
   dotpath: dotfiles
-  workdir: `echo ${tmpw} | sed 's/^.*\///g'`
+  workdir: $(echo "${tmpw}" | sed 's/^.*\///g')
 dotfiles:
   f_abc:
     dst: ${tmpd}/abc
@@ -92,33 +71,33 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "{{@@ profile @@}}" > ${tmpf}/abc
-echo "${string}" >> ${tmpf}/abc
+echo "{{@@ profile @@}}" > "${tmpf}"/abc
+echo "${string}" >> "${tmpf}"/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 
 # checks
-grep -r p1 ${tmpw} >/dev/null
-grep -r ${string} ${tmpw} >/dev/null
-[ ! -e ${tmpd}/abc ] && echo "[ERROR] dotfile not installed" && exit 1
-[ ! -h ${tmpd}/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
+grep -r p1 "${tmpw}" >/dev/null
+grep -r ${string} "${tmpw}" >/dev/null
+[ ! -e "${tmpd}"/abc ] && echo "[ERROR] dotfile not installed" && exit 1
+[ ! -h "${tmpd}"/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
 
 ## CLEANING
-rm -rf ${tmp} ${tmpd}
+rm -rf "${tmp}" "${tmpd}"
 
 ## ABSOLUTE
 echo "RUNNING ABSOLUTE"
 # the dotfile source
-tmp=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmp=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 tmpf="${tmp}/dotfiles"
 tmpw="${tmp}/workdir"
 export DOTDROP_WORKDIR="${tmpw}"
 
-mkdir -p ${tmpf}
+mkdir -p "${tmpf}"
 echo "dotfiles source (dotpath): ${tmpf}"
-mkdir -p ${tmpw}
+mkdir -p "${tmpw}"
 echo "workdir: ${tmpw}"
 
 # create the config file
@@ -126,13 +105,13 @@ cfg="${tmp}/config.yaml"
 echo "config file: ${cfg}"
 
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmp}"
 clear_on_exit "${tmpd}"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -151,29 +130,29 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "{{@@ profile @@}}" > ${tmpf}/abc
-echo "${string}" >> ${tmpf}/abc
+echo "{{@@ profile @@}}" > "${tmpf}"/abc
+echo "${string}" >> "${tmpf}"/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 
 # checks
-grep -r p1 ${tmpw} >/dev/null
-grep -r ${string} ${tmpw} >/dev/null
-[ ! -e ${tmpd}/abc ] && echo "[ERROR] dotfile not installed" && exit 1
-[ ! -h ${tmpd}/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
+grep -r p1 "${tmpw}" >/dev/null
+grep -r ${string} "${tmpw}" >/dev/null
+[ ! -e "${tmpd}"/abc ] && echo "[ERROR] dotfile not installed" && exit 1
+[ ! -h "${tmpd}"/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
 
 ## CLEANING
-rm -rf ${tmp} ${tmpd}
+rm -rf "${tmp}" "${tmpd}"
 
 ## NONE
 echo "RUNNING UNDEFINED WORKDIR"
 # the dotfile source
-tmp=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmp=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 
 tmpf="${tmp}/dotfiles"
 
-mkdir -p ${tmpf}
+mkdir -p "${tmpf}"
 echo "dotfiles source (dotpath): ${tmpf}"
 
 # create the config file
@@ -181,13 +160,13 @@ cfg="${tmp}/config.yaml"
 echo "config file: ${cfg}"
 
 # the dotfile destination
-tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
+tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
 echo "dotfiles destination: ${tmpd}"
 
 clear_on_exit "${tmp}"
 clear_on_exit "${tmpd}"
 
-cat > ${cfg} << _EOF
+cat > "${cfg}" << _EOF
 config:
   backup: true
   create: true
@@ -205,17 +184,17 @@ _EOF
 #cat ${cfg}
 
 # create the dotfile
-echo "{{@@ profile @@}}" > ${tmpf}/abc
-echo "${string}" >> ${tmpf}/abc
+echo "{{@@ profile @@}}" > "${tmpf}"/abc
+echo "${string}" >> "${tmpf}"/abc
 
 # install
-cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
+cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1 -b -V
 
 # checks
 #grep -r p1 ${tmpw} >/dev/null
 #grep -r ${string} ${tmpw} >/dev/null
-[ ! -e ${tmpd}/abc ] && echo "[ERROR] dotfile not installed" && exit 1
-[ ! -h ${tmpd}/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
+[ ! -e "${tmpd}"/abc ] && echo "[ERROR] dotfile not installed" && exit 1
+[ ! -h "${tmpd}"/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
 
 echo "OK"
 exit 0
diff --git a/tests-requirements.txt b/tests-requirements.txt
index b1f2e91..d496cec 100644
--- a/tests-requirements.txt
+++ b/tests-requirements.txt
@@ -1,8 +1,9 @@
 pycodestyle; python_version > '3.5'
-nose2; python_version > '3.5'
+pytest; python_version > '3.5'
 coverage; python_version > '3.5'
 coveralls; python_version > '3.5'
 pyflakes; python_version > '3.5'
 pylint; python_version > '3.5'
 halo; python_version > '3.5'
-distro; python_version > '3.5'
\ No newline at end of file
+distro; python_version > '3.5'
+urllib3; python_version > '3.5'
\ No newline at end of file
diff --git a/tests.sh b/tests.sh
index dfaba10..c855d38 100755
--- a/tests.sh
+++ b/tests.sh
@@ -6,15 +6,7 @@
 #set -ev
 set -e
 
-rl="readlink -f"
-if ! ${rl} "${0}" >/dev/null 2>&1; then
-  rl="realpath"
-
-  if ! hash ${rl}; then
-    echo "\"${rl}\" not found!" && exit 1
-  fi
-fi
-cur=`dirname $(${rl} "${0}")`
+cur=$(cd "$(dirname "${0}")" && pwd)
 
 # make sure both version.py and manpage dotdrop.1 are in sync
 dotdrop_version=$(grep version dotdrop/version.py | sed 's/^.*= .\(.*\).$/\1/g')
@@ -23,23 +15,29 @@ if [ "${dotdrop_version}" != "${man_version}" ]; then
   echo "ERROR version.py (${dotdrop_version}) and manpage (${man_version}) differ!"
   exit 1
 fi
-echo "current version ${dotdrop_version}"
+echo "current dotdrop version ${dotdrop_version}"
+
+echo "=> python version:"
+python3 --version
 
 # test syntax
 echo "checking syntax..."
-${cur}/test-syntax.sh
+"${cur}"/scripts/check-syntax.sh
 
 # test doc
 echo "checking documentation..."
-${cur}/test-doc.sh
+"${cur}"/scripts/check-doc.sh
 
 # unittest
 echo "unittest..."
-${cur}/test-unittest.sh
+"${cur}"/scripts/check-unittests.sh
 
 # tests-ng
 echo "tests-ng..."
-${cur}/test-ng.sh
+"${cur}"/scripts/check-tests-ng.sh
+
+# merge coverage
+coverage combine
 
 ## done
 echo "All tests finished successfully"
diff --git a/tests/dummy.py b/tests/dummy.py
index b85de83..1c4b939 100644
--- a/tests/dummy.py
+++ b/tests/dummy.py
@@ -10,11 +10,13 @@ import dotdrop
 
 
 class TestDummy(unittest.TestCase):
+    """test case"""
 
     dotdrop.main()
 
 
 def main():
+    """entry point"""
     unittest.main()
 
 
diff --git a/tests/helpers.py b/tests/helpers.py
index 8b604ff..ac58e7f 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -21,27 +21,30 @@ TMPSUFFIX = '-dotdrop-tests'
 
 
 class SubsetTestCase(TestCase):
-    def assertIsSubset(self, sub, sup):
-        for subKey, subValue in sub.items():
-            self.assertIn(subKey, sup)
-            supValue = sup[subKey]
+    """test case"""
 
-            if isinstance(subValue, str):
-                self.assertEqual(subValue, supValue)
+    def assert_is_subset(self, sub, sup):
+        """ensure it's a subset"""
+        for sub_key, sub_val in sub.items():
+            self.assertIn(sub_key, sup)
+            subvalue = sup[sub_key]
+
+            if isinstance(sub_val, str):
+                self.assertEqual(sub_val, subvalue)
                 continue
 
-            if isinstance(subValue, dict):
-                self.assertIsSubset(subValue, supValue)
+            if isinstance(sub_val, dict):
+                self.assert_is_subset(sub_val, subvalue)
                 continue
 
             try:
-                iter(subValue)
+                iter(sub_val)
                 self.assertTrue(all(
-                    subItem in supValue
-                    for subItem in subValue
+                    subItem in subvalue
+                    for subItem in sub_val
                 ))
             except TypeError:
-                self.assertEqual(subValue, supValue)
+                self.assertEqual(sub_val, subvalue)
 
 
 def clean(path):
@@ -60,7 +63,7 @@ def get_string(length):
     """Get a random string of length 'length'"""
     alpha = string.ascii_uppercase + string.digits
     temp = ''.join(random.choice(alpha) for _ in range(length))
-    return 'tmp.{}{}'.format(temp, TMPSUFFIX)
+    return f'tmp.{temp}{TMPSUFFIX}'
 
 
 def get_tempdir():
@@ -82,15 +85,16 @@ def create_random_file(directory, content=None,
             pre = bytes()
             if template:
                 pre = bytes('{{@@ header() @@}}\n', 'ascii')
-            content = bytes('{}{}\n'.format(pre, get_string(100)), 'ascii')
+            content = bytes(f'{pre}{get_string(100)}\n', 'ascii')
         else:
             pre = ''
             if template:
                 pre = '{{@@ header() @@}}\n'
-            content = '{}{}\n'.format(pre, get_string(100))
+            content = f'{pre}{get_string(100)}\n'
     path = os.path.join(directory, fname)
-    with open(path, mode) as f:
-        f.write(content)
+    # pylint: disable=W1514
+    with open(path, mode) as file:
+        file.write(content)
     return path, content
 
 
@@ -99,8 +103,9 @@ def edit_content(path, newcontent, binary=False):
     mode = 'w'
     if binary:
         mode = 'wb'
-    with open(path, mode) as f:
-        f.write(newcontent)
+    # pylint: disable=W1514
+    with open(path, mode) as file:
+        file.write(newcontent)
 
 
 def create_dir(path):
@@ -112,7 +117,7 @@ def create_dir(path):
 
 def _fake_args():
     args = {}
-    args['--verbose'] = False
+    args['--verbose'] = True
     args['--no-banner'] = False
     args['--dry'] = False
     args['--force'] = False
@@ -159,15 +164,16 @@ def load_options(confpath, profile):
     args['--profile'] = profile
     args['--verbose'] = True
     # and get the options
-    o = Options(args=args)
-    o.profile = profile
-    o.dry = False
-    o.safe = False
-    o.install_diff = True
-    o.import_link = LinkTypes.NOLINK
-    o.install_showdiff = True
-    o.debug = True
-    return o
+    opt = Options(args=args)
+    opt.profile = profile
+    opt.dry = False
+    opt.safe = False
+    opt.install_diff = True
+    opt.import_link = LinkTypes.NOLINK
+    opt.install_showdiff = True
+    opt.debug = True
+    opt.dotpath = os.path.join(os.path.dirname(confpath), 'dotfiles')
+    return opt
 
 
 def get_path_strip_version(path):
@@ -192,7 +198,9 @@ def get_dotfile_from_yaml(dic, path):
 
 
 def yaml_dashed_list(items, indent=0):
-    return ('\n'.join('{}- {}'.format(' ' * indent, item) for item in items)
+    """yaml dashed list"""
+    ind = ' ' * indent
+    return ('\n'.join(f'{ind}- {item}' for item in items)
             + '\n')
 
 
@@ -203,28 +211,29 @@ def create_fake_config(directory, configname='config.yaml',
     """Create a fake config file"""
     path = os.path.join(directory, configname)
     workdir = os.path.join(directory, 'workdir')
-    with open(path, 'w') as f:
-        f.write('config:\n')
-        f.write('  backup: {}\n'.format(str(backup)))
-        f.write('  create: {}\n'.format(str(create)))
-        f.write('  dotpath: {}\n'.format(dotpath))
-        f.write('  workdir: {}\n'.format(workdir))
+    with open(path, 'w', encoding='utf-8') as file:
+        file.write('config:\n')
+        file.write(f'  backup: {backup}\n')
+        file.write(f'  create: {create}\n')
+        file.write(f'  dotpath: {dotpath}\n')
+        file.write(f'  workdir: {workdir}\n')
         if import_actions:
-            f.write('  import_actions:\n')
-            f.write(yaml_dashed_list(import_actions, 4))
+            file.write('  import_actions:\n')
+            file.write(yaml_dashed_list(import_actions, 4))
         if import_configs:
-            f.write('  import_configs:\n')
-            f.write(yaml_dashed_list(import_configs, 4))
+            file.write('  import_configs:\n')
+            file.write(yaml_dashed_list(import_configs, 4))
         if import_variables:
-            f.write('  import_variables:\n')
-            f.write(yaml_dashed_list(import_variables, 4))
-        f.write('dotfiles:\n')
-        f.write('profiles:\n')
-        f.write('actions:\n')
+            file.write('  import_variables:\n')
+            file.write(yaml_dashed_list(import_variables, 4))
+        file.write('dotfiles:\n')
+        file.write('profiles:\n')
+        file.write('actions:\n')
     return path
 
 
 def create_yaml_keyval(pairs, parent_dir=None, top_key=None):
+    """create key val for yaml"""
     if top_key:
         pairs = {top_key: pairs}
     if not parent_dir:
@@ -235,6 +244,7 @@ def create_yaml_keyval(pairs, parent_dir=None, top_key=None):
     return file_name
 
 
+# pylint: disable=W0102
 def populate_fake_config(config, dotfiles={}, profiles={}, actions={},
                          trans={}, trans_write={}, variables={},
                          dynvariables={}):
@@ -267,14 +277,14 @@ def file_in_yaml(yaml_file, path, link=False):
 
     dotfiles = yaml_conf['dotfiles'].values()
 
-    in_src = any([x['src'].endswith(strip) for x in dotfiles])
+    in_src = any(x['src'].endswith(strip) for x in dotfiles)
     in_dst = path in (os.path.expanduser(x['dst']) for x in dotfiles)
 
     if link:
-        df = get_dotfile_from_yaml(yaml_conf, path)
+        dotfile = get_dotfile_from_yaml(yaml_conf, path)
         has_link = False
-        if df:
-            has_link = 'link' in df
+        if dotfile:
+            has_link = 'link' in dotfile
         else:
             return False
         return in_src and in_dst and has_link
@@ -282,15 +292,17 @@ def file_in_yaml(yaml_file, path, link=False):
 
 
 def yaml_load(path):
-    with open(path, 'r') as f:
-        content = yaml(typ='safe').load(f)
+    """load yaml"""
+    with open(path, 'r', encoding='utf-8') as file:
+        content = yaml(typ='safe').load(file)
     return content
 
 
 def yaml_dump(content, path):
-    with open(path, 'w') as f:
-        y = yaml()
-        y.default_flow_style = False
-        y.indent = 2
-        y.typ = 'safe'
-        y.dump(content, f)
+    """dump yaml"""
+    with open(path, 'w', encoding='utf-8') as file:
+        cont = yaml()
+        cont.default_flow_style = False
+        cont.indent = 2
+        cont.typ = 'safe'
+        cont.dump(content, file)
diff --git a/tests/test_compare.py b/tests/test_compare.py
index b436c92..e4521d5 100644
--- a/tests/test_compare.py
+++ b/tests/test_compare.py
@@ -20,24 +20,26 @@ from tests.helpers import create_dir, get_string, get_tempdir, clean, \
 
 
 class TestCompare(unittest.TestCase):
+    """test case"""
 
     CONFIG_BACKUP = False
     CONFIG_CREATE = True
     CONFIG_DOTPATH = 'dotfiles'
     CONFIG_NAME = 'config.yaml'
 
-    def compare(self, o, tmp, nbdotfiles):
-        dotfiles = o.dotfiles
+    def compare(self, opt, tmp, nbdotfiles):
+        """compare"""
+        dotfiles = opt.dotfiles
         self.assertTrue(len(dotfiles) == nbdotfiles)
-        t = Templategen(base=o.dotpath, debug=True)
-        inst = Installer(create=o.create, backup=o.backup,
-                         dry=o.dry, base=o.dotpath, debug=o.debug)
+        templ = Templategen(base=opt.dotpath, debug=True)
+        inst = Installer(create=opt.create, backup=opt.backup,
+                         dry=opt.dry, base=opt.dotpath, debug=opt.debug)
         comp = Comparator()
         results = {}
         for dotfile in dotfiles:
             path = os.path.expanduser(dotfile.dst)
-            ret, err, insttmp = inst.install_to_temp(t, tmp, dotfile.src,
-                                                     dotfile.dst)
+            ret, _, insttmp = inst.install_to_temp(templ, tmp, dotfile.src,
+                                                   dotfile.dst)
             if not ret:
                 results[path] = False
                 continue
@@ -47,9 +49,10 @@ class TestCompare(unittest.TestCase):
         return results
 
     def test_none(self):
-        t = Templategen(base=self.CONFIG_DOTPATH,
-                        debug=True, variables=None)
-        self.assertTrue(t is not None)
+        """test none"""
+        templ = Templategen(base=self.CONFIG_DOTPATH,
+                            debug=True, variables=None)
+        self.assertTrue(templ is not None)
 
     def test_compare(self):
         """Test the compare function"""
@@ -74,33 +77,33 @@ class TestCompare(unittest.TestCase):
         self.addCleanup(clean, dotfilespath)
 
         # create the dotfiles to test
-        d1, c1 = create_random_file(fold_config)
-        self.assertTrue(os.path.exists(d1))
-        self.addCleanup(clean, d1)
+        df1, _ = create_random_file(fold_config)
+        self.assertTrue(os.path.exists(df1))
+        self.addCleanup(clean, df1)
 
-        d2, c2 = create_random_file(fold_subcfg)
-        self.assertTrue(os.path.exists(d2))
-        self.addCleanup(clean, d2)
+        df2, _ = create_random_file(fold_subcfg)
+        self.assertTrue(os.path.exists(df2))
+        self.addCleanup(clean, df2)
 
-        d3, c3 = create_random_file(fold_tmp)
-        self.assertTrue(os.path.exists(d3))
-        self.addCleanup(clean, d3)
+        df3, _ = create_random_file(fold_tmp)
+        self.assertTrue(os.path.exists(df3))
+        self.addCleanup(clean, df3)
 
-        d4, c4 = create_random_file(fold_tmp, binary=True)
-        self.assertTrue(os.path.exists(d4))
-        self.addCleanup(clean, d4)
+        df4, _ = create_random_file(fold_tmp, binary=True)
+        self.assertTrue(os.path.exists(df4))
+        self.addCleanup(clean, df4)
 
-        d5 = get_tempdir()
-        self.assertTrue(os.path.exists(d5))
-        self.addCleanup(clean, d5)
+        df5 = get_tempdir()
+        self.assertTrue(os.path.exists(df5))
+        self.addCleanup(clean, df5)
 
-        d6, _ = create_random_file(d5)
-        self.assertTrue(os.path.exists(d6))
+        df6, _ = create_random_file(df5)
+        self.assertTrue(os.path.exists(df6))
 
-        d9 = get_tempdir()
-        self.assertTrue(os.path.exists(d9))
-        self.addCleanup(clean, d9)
-        d9sub = os.path.join(d9, get_string(5))
+        df9 = get_tempdir()
+        self.assertTrue(os.path.exists(df9))
+        self.addCleanup(clean, df9)
+        d9sub = os.path.join(df9, get_string(5))
         create_dir(d9sub)
         d9f1, _ = create_random_file(d9sub)
 
@@ -112,69 +115,70 @@ class TestCompare(unittest.TestCase):
                                       backup=self.CONFIG_BACKUP,
                                       create=self.CONFIG_CREATE)
         self.assertTrue(os.path.exists(confpath))
-        o = load_options(confpath, profile)
-        o.longkey = True
-        o.debug = True
-        dfiles = [d1, d2, d3, d4, d5, d9]
+        opt = load_options(confpath, profile)
+        opt.longkey = True
+        opt.debug = True
+        dfiles = [df1, df2, df3, df4, df5, df9]
 
         # import the files
-        o.import_path = dfiles
-        cmd_importer(o)
-        o = load_options(confpath, profile)
+        opt.import_path = dfiles
+        cmd_importer(opt)
+        opt = load_options(confpath, profile)
 
         # compare the files
-        expected = {d1: True, d2: True, d3: True, d4: True,
-                    d5: True, d9: True}
-        results = self.compare(o, tmp, len(dfiles))
+        expected = {df1: True, df2: True, df3: True, df4: True,
+                    df5: True, df9: True}
+        results = self.compare(opt, tmp, len(dfiles))
         self.assertTrue(results == expected)
 
         # modify file
-        edit_content(d1, get_string(20))
-        expected = {d1: False, d2: True, d3: True, d4: True,
-                    d5: True, d9: True}
-        results = self.compare(o, tmp, len(dfiles))
+        edit_content(df1, get_string(20))
+        expected = {df1: False, df2: True, df3: True, df4: True,
+                    df5: True, df9: True}
+        results = self.compare(opt, tmp, len(dfiles))
         self.assertTrue(results == expected)
 
         # modify binary file
-        edit_content(d4, bytes(get_string(20), 'ascii'), binary=True)
-        expected = {d1: False, d2: True, d3: True, d4: False,
-                    d5: True, d9: True}
-        results = self.compare(o, tmp, len(dfiles))
+        edit_content(df4, bytes(get_string(20), 'ascii'), binary=True)
+        expected = {df1: False, df2: True, df3: True, df4: False,
+                    df5: True, df9: True}
+        results = self.compare(opt, tmp, len(dfiles))
         self.assertTrue(results == expected)
 
         # add file in directory
-        d7, _ = create_random_file(d5)
-        self.assertTrue(os.path.exists(d7))
-        expected = {d1: False, d2: True, d3: True, d4: False,
-                    d5: False, d9: True}
-        results = self.compare(o, tmp, len(dfiles))
+        df7, _ = create_random_file(df5)
+        self.assertTrue(os.path.exists(df7))
+        expected = {df1: False, df2: True, df3: True, df4: False,
+                    df5: False, df9: True}
+        results = self.compare(opt, tmp, len(dfiles))
         self.assertTrue(results == expected)
 
         # modify all files
-        edit_content(d2, get_string(20))
-        edit_content(d3, get_string(21))
-        expected = {d1: False, d2: False, d3: False, d4: False,
-                    d5: False, d9: True}
-        results = self.compare(o, tmp, len(dfiles))
+        edit_content(df2, get_string(20))
+        edit_content(df3, get_string(21))
+        expected = {df1: False, df2: False, df3: False, df4: False,
+                    df5: False, df9: True}
+        results = self.compare(opt, tmp, len(dfiles))
         self.assertTrue(results == expected)
 
         # edit sub file
         edit_content(d9f1, get_string(12))
-        expected = {d1: False, d2: False, d3: False, d4: False,
-                    d5: False, d9: False}
-        results = self.compare(o, tmp, len(dfiles))
+        expected = {df1: False, df2: False, df3: False, df4: False,
+                    df5: False, df9: False}
+        results = self.compare(opt, tmp, len(dfiles))
         self.assertTrue(results == expected)
 
         # test compare from dotdrop
-        self.assertFalse(cmd_compare(o, tmp))
+        self.assertFalse(cmd_compare(opt, tmp))
         # test focus
-        o.compare_focus = [d4]
-        self.assertFalse(cmd_compare(o, tmp))
-        o.compare_focus = ['/tmp/fake']
-        self.assertFalse(cmd_compare(o, tmp))
+        opt.compare_focus = [df4]
+        self.assertFalse(cmd_compare(opt, tmp))
+        opt.compare_focus = ['/tmp/fake']
+        self.assertFalse(cmd_compare(opt, tmp))
 
 
 def main():
+    """entry point"""
     unittest.main()
 
 
diff --git a/tests/test_import.py b/tests/test_import.py
index 186382a..539eba3 100644
--- a/tests/test_import.py
+++ b/tests/test_import.py
@@ -22,6 +22,7 @@ from tests.helpers import (clean, create_dir, create_fake_config,
 
 
 class TestImport(unittest.TestCase):
+    """test case"""
 
     CONFIG_BACKUP = False
     CONFIG_CREATE = True
@@ -33,11 +34,11 @@ class TestImport(unittest.TestCase):
         self.assertTrue(os.path.exists(path))
         return yaml_load(path)
 
-    def assert_file(self, path, o, profile):
+    def assert_file(self, path, opt, _profile):
         """Make sure path has been inserted in conf for profile"""
         strip = get_path_strip_version(path)
-        self.assertTrue(any(x.src.endswith(strip) for x in o.dotfiles))
-        dsts = (os.path.expanduser(x.dst) for x in o.dotfiles)
+        self.assertTrue(any(x.src.endswith(strip) for x in opt.dotfiles))
+        dsts = (os.path.expanduser(x.dst) for x in opt.dotfiles)
         self.assertTrue(path in dsts)
 
     def assert_in_yaml(self, path, dic, link=False):
@@ -63,12 +64,12 @@ class TestImport(unittest.TestCase):
                                       backup=self.CONFIG_BACKUP,
                                       create=self.CONFIG_CREATE)
         self.assertTrue(os.path.exists(confpath))
-        o = load_options(confpath, profile)
+        opt = load_options(confpath, profile)
 
         # create some random dotfiles
-        dotfile1, content1 = create_random_file(src)
+        dotfile1, _ = create_random_file(src)
         self.addCleanup(clean, dotfile1)
-        dotfile2, content2 = create_random_file(os.path.expanduser('~'))
+        dotfile2, _ = create_random_file(os.path.expanduser('~'))
         self.addCleanup(clean, dotfile2)
         homeconf = os.path.join(os.path.expanduser('~'), '.config')
         if not os.path.exists(homeconf):
@@ -77,8 +78,8 @@ class TestImport(unittest.TestCase):
         dotconfig = os.path.join(homeconf, get_string(5))
         create_dir(dotconfig)
         self.addCleanup(clean, dotconfig)
-        dotfile3, content3 = create_random_file(dotconfig)
-        dotfile4, content3 = create_random_file(homeconf)
+        dotfile3, _ = create_random_file(dotconfig)
+        dotfile4, _ = create_random_file(homeconf)
         self.addCleanup(clean, dotfile4)
 
         # fake a directory containing dotfiles
@@ -89,7 +90,7 @@ class TestImport(unittest.TestCase):
         sub2, _ = create_random_file(dotfile5)
 
         # fake a file for symlink
-        dotfile6, content6 = create_random_file(dotconfig)
+        dotfile6, _ = create_random_file(dotconfig)
         self.addCleanup(clean, dotfile6)
 
         # fake a directory for symlink
@@ -101,37 +102,37 @@ class TestImport(unittest.TestCase):
 
         # import the dotfiles
         dfiles = [dotfile1, dotfile2, dotfile3, dotfile4, dotfile5]
-        o.import_path = dfiles
-        cmd_importer(o)
+        opt.import_path = dfiles
+        cmd_importer(opt)
         # import symlink
-        o.import_link = LinkTypes.LINK
+        opt.import_link = LinkTypes.LINK
         sfiles = [dotfile6, dotfile7]
-        o.import_path = sfiles
-        cmd_importer(o)
-        o.import_link = LinkTypes.NOLINK
+        opt.import_path = sfiles
+        cmd_importer(opt)
+        opt.import_link = LinkTypes.NOLINK
 
         # reload the config
-        o = load_options(confpath, profile)
+        opt = load_options(confpath, profile)
 
         # test dotfiles in config class
-        self.assertTrue(profile in [p.key for p in o.profiles])
-        self.assert_file(dotfile1, o, profile)
-        self.assert_file(dotfile2, o, profile)
-        self.assert_file(dotfile3, o, profile)
-        self.assert_file(dotfile4, o, profile)
-        self.assert_file(dotfile5, o, profile)
-        self.assert_file(dotfile6, o, profile)
-        self.assert_file(dotfile7, o, profile)
+        self.assertTrue(profile in [p.key for p in opt.profiles])
+        self.assert_file(dotfile1, opt, profile)
+        self.assert_file(dotfile2, opt, profile)
+        self.assert_file(dotfile3, opt, profile)
+        self.assert_file(dotfile4, opt, profile)
+        self.assert_file(dotfile5, opt, profile)
+        self.assert_file(dotfile6, opt, profile)
+        self.assert_file(dotfile7, opt, profile)
 
         # test dotfiles in yaml file
-        y = self.load_yaml(confpath)
-        self.assert_in_yaml(dotfile1, y)
-        self.assert_in_yaml(dotfile2, y)
-        self.assert_in_yaml(dotfile3, y)
-        self.assert_in_yaml(dotfile4, y)
-        self.assert_in_yaml(dotfile5, y)
-        self.assert_in_yaml(dotfile6, y, link=True)
-        self.assert_in_yaml(dotfile7, y, link=True)
+        cont2 = self.load_yaml(confpath)
+        self.assert_in_yaml(dotfile1, cont2)
+        self.assert_in_yaml(dotfile2, cont2)
+        self.assert_in_yaml(dotfile3, cont2)
+        self.assert_in_yaml(dotfile4, cont2)
+        self.assert_in_yaml(dotfile5, cont2)
+        self.assert_in_yaml(dotfile6, cont2, link=True)
+        self.assert_in_yaml(dotfile7, cont2, link=True)
 
         # test have been imported in dotdrop dotpath directory
         indt1 = os.path.join(dotfilespath,
@@ -154,16 +155,16 @@ class TestImport(unittest.TestCase):
                              self.CONFIG_DOTPATH,
                              get_path_strip_version(dotfile5))
         self.assertTrue(os.path.exists(indt5))
-        s1 = os.path.join(dotfilespath,
-                          self.CONFIG_DOTPATH,
-                          get_path_strip_version(dotfile6),
-                          sub1)
-        self.assertTrue(os.path.exists(s1))
-        s2 = os.path.join(dotfilespath,
-                          self.CONFIG_DOTPATH,
-                          get_path_strip_version(dotfile6),
-                          sub2)
-        self.assertTrue(os.path.exists(s2))
+        fsb1 = os.path.join(dotfilespath,
+                            self.CONFIG_DOTPATH,
+                            get_path_strip_version(dotfile6),
+                            sub1)
+        self.assertTrue(os.path.exists(fsb1))
+        fsb2 = os.path.join(dotfilespath,
+                            self.CONFIG_DOTPATH,
+                            get_path_strip_version(dotfile6),
+                            sub2)
+        self.assertTrue(os.path.exists(fsb2))
         indt6 = os.path.join(dotfilespath,
                              self.CONFIG_DOTPATH,
                              get_path_strip_version(dotfile6))
@@ -172,29 +173,31 @@ class TestImport(unittest.TestCase):
                              self.CONFIG_DOTPATH,
                              get_path_strip_version(dotfile7))
         self.assertTrue(os.path.exists(indt7))
-        s3 = os.path.join(dotfilespath,
-                          self.CONFIG_DOTPATH,
-                          get_path_strip_version(dotfile7),
-                          sub3)
-        self.assertTrue(os.path.exists(s3))
-        s4 = os.path.join(dotfilespath,
-                          self.CONFIG_DOTPATH,
-                          get_path_strip_version(dotfile7),
-                          sub4)
-        self.assertTrue(os.path.exists(s4))
-
-        cmd_list_profiles(o)
-        cmd_files(o)
+        fsb3 = os.path.join(dotfilespath,
+                            self.CONFIG_DOTPATH,
+                            get_path_strip_version(dotfile7),
+                            sub3)
+        self.assertTrue(os.path.exists(fsb3))
+        fsb4 = os.path.join(dotfilespath,
+                            self.CONFIG_DOTPATH,
+                            get_path_strip_version(dotfile7),
+                            sub4)
+        self.assertTrue(os.path.exists(fsb4))
+
+        cmd_list_profiles(opt)
+        cmd_files(opt)
 
         # fake test update
         editcontent = 'edited'
         edit_content(dotfile1, editcontent)
-        o.safe = False
-        o.update_path = [dotfile1]
-        o.debug = True
-        cmd_update(o)
-        c2 = open(indt1, 'r').read()
-        self.assertTrue(editcontent == c2)
+        opt.safe = False
+        opt.update_path = [dotfile1]
+        opt.debug = True
+        cmd_update(opt)
+        cont = ''
+        with open(indt1, 'r', encoding='utf-8') as file:
+            cont = file.read()
+        self.assertTrue(editcontent == cont)
 
     def test_ext_config_yaml_not_mix(self):
         """Test whether the import_configs mixes yaml files upon importing."""
@@ -311,37 +314,37 @@ class TestImport(unittest.TestCase):
         })
 
         # import the dotfiles
-        o = load_options(imported_path, 'host1')
-        o.import_path = dotfiles_ed
-        cmd_importer(o)
+        opt = load_options(imported_path, 'host1')
+        opt.import_path = dotfiles_ed
+        cmd_importer(opt)
 
-        o = load_options(importing_path, 'host2')
-        o.import_path = dotfiles_ing
-        cmd_importer(o)
+        opt = load_options(importing_path, 'host2')
+        opt.import_path = dotfiles_ing
+        cmd_importer(opt)
 
         # reload the config
-        o = load_options(importing_path, 'host2')
+        opt = load_options(importing_path, 'host2')
 
         # test imported config
-        y = self.load_yaml(imported_path)
+        ycont = self.load_yaml(imported_path)
 
         # testing dotfiles
-        self.assertTrue(all(file_in_yaml(y, df)
+        self.assertTrue(all(file_in_yaml(ycont, df)
                             for df in dotfiles_ed))
-        self.assertFalse(any(file_in_yaml(y, df)
+        self.assertFalse(any(file_in_yaml(ycont, df)
                              for df in dotfiles_ing))
 
         # testing profiles
-        profiles = y['profiles'].keys()
+        profiles = ycont['profiles'].keys()
         self.assertTrue('host1' in profiles)
         self.assertFalse('host2' in profiles)
 
         # testing actions
-        actions = y['actions']['pre']
-        actions.update(y['actions']['post'])
+        actions = ycont['actions']['pre']
+        actions.update(ycont['actions']['post'])
         actions.update({
             k: v
-            for k, v in y['actions'].items()
+            for k, v in ycont['actions'].items()
             if k not in ('pre', 'post')
         })
         actions = actions.keys()
@@ -349,41 +352,41 @@ class TestImport(unittest.TestCase):
         self.assertFalse(any(a.endswith('ing') for a in actions))
 
         # testing transformations
-        transformations = y['trans_read'].keys()
+        transformations = ycont['trans_read'].keys()
         self.assertTrue(all(t.endswith('ed') for t in transformations))
         self.assertFalse(any(t.endswith('ing') for t in transformations))
-        transformations = y['trans_write'].keys()
+        transformations = ycont['trans_write'].keys()
         self.assertTrue(all(t.endswith('ed') for t in transformations))
         self.assertFalse(any(t.endswith('ing') for t in transformations))
 
         # testing variables
-        variables = self._remove_priv_vars(y['variables'].keys())
+        variables = _remove_priv_vars(ycont['variables'].keys())
         self.assertTrue(all(v.endswith('ed') for v in variables))
         self.assertFalse(any(v.endswith('ing') for v in variables))
-        dyn_variables = y['dynvariables'].keys()
+        dyn_variables = ycont['dynvariables'].keys()
         self.assertTrue(all(dv.endswith('ed') for dv in dyn_variables))
         self.assertFalse(any(dv.endswith('ing') for dv in dyn_variables))
 
         # test importing config
-        y = self.load_yaml(importing_path)
+        ycont = self.load_yaml(importing_path)
 
         # testing dotfiles
-        self.assertTrue(all(file_in_yaml(y, df)
+        self.assertTrue(all(file_in_yaml(ycont, df)
                             for df in dotfiles_ing))
-        self.assertFalse(any(file_in_yaml(y, df)
+        self.assertFalse(any(file_in_yaml(ycont, df)
                              for df in dotfiles_ed))
 
         # testing profiles
-        profiles = y['profiles'].keys()
+        profiles = ycont['profiles'].keys()
         self.assertTrue('host2' in profiles)
         self.assertFalse('host1' in profiles)
 
         # testing actions
-        actions = y['actions']['pre']
-        actions.update(y['actions']['post'])
+        actions = ycont['actions']['pre']
+        actions.update(ycont['actions']['post'])
         actions.update({
             k: v
-            for k, v in y['actions'].items()
+            for k, v in ycont['actions'].items()
             if k not in ('pre', 'post')
         })
         actions = actions.keys()
@@ -391,29 +394,31 @@ class TestImport(unittest.TestCase):
         self.assertFalse(any(action.endswith('ed') for action in actions))
 
         # testing transformations
-        transformations = y['trans_read'].keys()
+        transformations = ycont['trans_read'].keys()
         self.assertTrue(all(t.endswith('ing') for t in transformations))
         self.assertFalse(any(t.endswith('ed') for t in transformations))
-        transformations = y['trans_write'].keys()
+        transformations = ycont['trans_write'].keys()
         self.assertTrue(all(t.endswith('ing') for t in transformations))
         self.assertFalse(any(t.endswith('ed') for t in transformations))
 
         # testing variables
-        variables = self._remove_priv_vars(y['variables'].keys())
+        variables = _remove_priv_vars(ycont['variables'].keys())
         self.assertTrue(all(v.endswith('ing') for v in variables))
         self.assertFalse(any(v.endswith('ed') for v in variables))
-        dyn_variables = y['dynvariables'].keys()
+        dyn_variables = ycont['dynvariables'].keys()
         self.assertTrue(all(dv.endswith('ing') for dv in dyn_variables))
         self.assertFalse(any(dv.endswith('ed') for dv in dyn_variables))
 
-    def _remove_priv_vars(self, variables_keys):
-        variables = [v for v in variables_keys if not v.startswith('_')]
-        if 'profile' in variables:
-            variables.remove('profile')
-        return variables
+
+def _remove_priv_vars(variables_keys):
+    variables = [v for v in variables_keys if not v.startswith('_')]
+    if 'profile' in variables:
+        variables.remove('profile')
+    return variables
 
 
 def main():
+    """entry point"""
     unittest.main()
 
 
diff --git a/tests/test_install.py b/tests/test_install.py
index 6e640ed..2edf4f5 100644
--- a/tests/test_install.py
+++ b/tests/test_install.py
@@ -8,11 +8,10 @@ import os
 import unittest
 from unittest.mock import MagicMock
 import filecmp
-
-from dotdrop.cfg_aggregator import CfgAggregator as Cfg
 from tests.helpers import (clean, create_dir, create_fake_config,
                            create_random_file, get_string, get_tempdir,
                            load_options, populate_fake_config)
+from dotdrop.cfg_aggregator import CfgAggregator as Cfg
 from dotdrop.dotfile import Dotfile
 from dotdrop.installer import Installer
 from dotdrop.action import Action
@@ -22,7 +21,44 @@ from dotdrop.utils import header
 from dotdrop.linktypes import LinkTypes
 
 
+def fake_config(path, dotfiles, profile,
+                dotpath, actions, transs):
+    """Create a fake config file"""
+    with open(path, 'w', encoding='utf-8') as file:
+        file.write('actions:\n')
+        for action in actions:
+            file.write(f'  {action.key}: {action.action}\n')
+        file.write('trans:\n')
+        for trans in transs:
+            file.write(f'  {trans.key}: {trans.action}\n')
+        file.write('config:\n')
+        file.write('  backup: true\n')
+        file.write('  create: true\n')
+        file.write(f'  dotpath: {dotpath}\n')
+        file.write('dotfiles:\n')
+        for dotfile in dotfiles:
+            linkval = dotfile.link.name.lower()
+            file.write(f'  {dotfile.key}:\n')
+            file.write(f'    dst: {dotfile.dst}\n')
+            file.write(f'    src: {dotfile.src}\n')
+            file.write(f'    link: {linkval}\n')
+            if len(dotfile.actions) > 0:
+                file.write('    actions:\n')
+                for action in dotfile.actions:
+                    file.write(f'      - {action.key}\n')
+            if dotfile.trans_r:
+                for trans in dotfile.trans_r:
+                    file.write(f'    trans_read: {trans.key}\n')
+        file.write('profiles:\n')
+        file.write(f'  {profile}:\n')
+        file.write('    dotfiles:\n')
+        for dotfile in dotfiles:
+            file.write(f'    - {dotfile.key}\n')
+    return path
+
+
 class TestInstall(unittest.TestCase):
+    """test case"""
 
     CONFIG_NAME = 'config.yaml'
 
@@ -39,40 +75,6 @@ exec bspwm
 exec bspwm
 '''
 
-    def fake_config(self, path, dotfiles, profile,
-                    dotpath, actions, trans):
-        """Create a fake config file"""
-        with open(path, 'w') as f:
-            f.write('actions:\n')
-            for action in actions:
-                f.write('  {}: {}\n'.format(action.key, action.action))
-            f.write('trans:\n')
-            for tr in trans:
-                f.write('  {}: {}\n'.format(tr.key, tr.action))
-            f.write('config:\n')
-            f.write('  backup: true\n')
-            f.write('  create: true\n')
-            f.write('  dotpath: {}\n'.format(dotpath))
-            f.write('dotfiles:\n')
-            for d in dotfiles:
-                f.write('  {}:\n'.format(d.key))
-                f.write('    dst: {}\n'.format(d.dst))
-                f.write('    src: {}\n'.format(d.src))
-                f.write('    link: {}\n'.format(d.link.name.lower()))
-                if len(d.actions) > 0:
-                    f.write('    actions:\n')
-                    for action in d.actions:
-                        f.write('      - {}\n'.format(action.key))
-                if d.trans_r:
-                    for tr in d.trans_r:
-                        f.write('    trans_read: {}\n'.format(tr.key))
-            f.write('profiles:\n')
-            f.write('  {}:\n'.format(profile))
-            f.write('    dotfiles:\n')
-            for d in dotfiles:
-                f.write('    - {}\n'.format(d.key))
-        return path
-
     def test_install(self):
         """Test the install function"""
 
@@ -87,40 +89,43 @@ exec bspwm
         self.addCleanup(clean, dst)
 
         # create the dotfile in dotdrop
-        f1, c1 = create_random_file(tmp)
+        fcontent1, _ = create_random_file(tmp)
         dst1 = os.path.join(dst, get_string(6))
-        d1 = Dotfile(get_string(5), dst1, os.path.basename(f1))
+        dotfile1 = Dotfile(get_string(5), dst1, os.path.basename(fcontent1))
         # fake a __str__
-        self.assertTrue(str(d1) != '')
-        f2, c2 = create_random_file(tmp)
+        self.assertTrue(str(dotfile1) != '')
+        fcontent2, _ = create_random_file(tmp)
         dst2 = os.path.join(dst, get_string(6))
-        d2 = Dotfile(get_string(5), dst2, os.path.basename(f2))
-        with open(f2, 'w') as f:
-            f.write(self.TEMPLATE)
-        f3, _ = create_random_file(tmp, binary=True)
+        dotfile2 = Dotfile(get_string(5), dst2, os.path.basename(fcontent2))
+        with open(fcontent2, 'w', encoding='utf-8') as file:
+            file.write(self.TEMPLATE)
+        fcontent3, _ = create_random_file(tmp, binary=True)
         dst3 = os.path.join(dst, get_string(6))
-        d3 = Dotfile(get_string(5), dst3, os.path.basename(f3))
+        dotfile3 = Dotfile(get_string(5), dst3, os.path.basename(fcontent3))
 
         # create a directory dotfile
         dir1 = os.path.join(tmp, 'somedir')
         create_dir(dir1)
-        fd, _ = create_random_file(dir1)
+        fildfd, _ = create_random_file(dir1)
         dstd = os.path.join(dst, get_string(6))
         ddot = Dotfile(get_string(5), dstd, os.path.basename(dir1))
 
         # to test backup
-        f4, c4 = create_random_file(tmp)
+        fcontent4, _ = create_random_file(tmp)
         dst4 = os.path.join(dst, get_string(6))
-        d4 = Dotfile(key=get_string(6), dst=dst4, src=os.path.basename(f4))
-        with open(dst4, 'w') as f:
-            f.write(get_string(16))
+        dotfile4 = Dotfile(key=get_string(6),
+                           dst=dst4,
+                           src=os.path.basename(fcontent4))
+        with open(dst4, 'w',
+                  encoding='utf-8') as file:
+            file.write(get_string(16))
 
         # to test link
-        f5, c5 = create_random_file(tmp)
+        fcontent5, _ = create_random_file(tmp)
         dst5 = os.path.join(dst, get_string(6))
         self.addCleanup(clean, dst5)
-        d5 = Dotfile(get_string(6), dst5,
-                     os.path.basename(f5), link=LinkTypes.LINK)
+        dotfile5 = Dotfile(get_string(6), dst5,
+                           os.path.basename(fcontent5), link=LinkTypes.LINK)
 
         # create the dotfile directories in dotdrop
         dir1 = create_dir(os.path.join(tmp, get_string(6)))
@@ -133,7 +138,7 @@ exec bspwm
         sub2, _ = create_random_file(dir1)
         self.assertTrue(os.path.exists(sub2))
         # make up the dotfile
-        d6 = Dotfile(get_string(6), dst6, os.path.basename(dir1))
+        dotfile6 = Dotfile(get_string(6), dst6, os.path.basename(dir1))
 
         # to test symlink directories
         dir2 = create_dir(os.path.join(tmp, get_string(6)))
@@ -146,47 +151,52 @@ exec bspwm
         sub4, _ = create_random_file(dir2)
         self.assertTrue(os.path.exists(sub4))
         # make up the dotfile
-        d7 = Dotfile(get_string(6), dst7,
-                     os.path.basename(dir2), link=LinkTypes.LINK)
+        dotfile7 = Dotfile(get_string(6), dst7,
+                           os.path.basename(dir2), link=LinkTypes.LINK)
 
         # to test actions
         value = get_string(12)
         fact = '/tmp/action'
         self.addCleanup(clean, fact)
-        act1 = Action('testaction', 'post', 'echo "{}" > {}'.format(value,
-                                                                    fact))
-        f8, c8 = create_random_file(tmp)
+        act1 = Action('testaction', 'post', f'echo "{value}" > {fact}')
+        fcontent8, _ = create_random_file(tmp)
         dst8 = os.path.join(dst, get_string(6))
-        d8 = Dotfile(get_string(6), dst8, os.path.basename(f8), actions=[act1])
+        dotfile8 = Dotfile(get_string(6), dst8, os.path.basename(fcontent8),
+                           actions=[act1])
 
         # to test transformations
         trans1 = 'trans1'
         trans2 = 'trans2'
+        # pylint: disable=C0209
         cmd = 'cat {0} | sed \'s/%s/%s/g\' > {1}' % (trans1, trans2)
-        tr = Action('testtrans', 'post', cmd)
-        f9, c9 = create_random_file(tmp, content=trans1)
+        self.addCleanup(clean, trans2)
+        the_trans = Action('testtrans', 'post', cmd)
+        fcontent9, _ = create_random_file(tmp, content=trans1)
         dst9 = os.path.join(dst, get_string(6))
-        d9 = Dotfile(get_string(6), dst9, os.path.basename(f9), trans_r=[tr])
+        dotfile9 = Dotfile(get_string(6), dst9, os.path.basename(fcontent9),
+                           trans_r=[the_trans])
 
         # to test template
         f10, _ = create_random_file(tmp, content='{{@@ header() @@}}')
         dst10 = os.path.join(dst, get_string(6))
-        d10 = Dotfile(get_string(6), dst10, os.path.basename(f10))
+        dotfile10 = Dotfile(get_string(6), dst10, os.path.basename(f10))
 
         # generate the config and stuff
         profile = get_string(5)
         confpath = os.path.join(tmp, self.CONFIG_NAME)
-        dotfiles = [d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, ddot]
-        self.fake_config(confpath, dotfiles,
-                         profile, tmp, [act1], [tr])
+        dotfiles = [dotfile1, dotfile2, dotfile3, dotfile4,
+                    dotfile5, dotfile6, dotfile7, dotfile8,
+                    dotfile9, dotfile10, ddot]
+        fake_config(confpath, dotfiles,
+                    profile, tmp, [act1], [the_trans])
         conf = Cfg(confpath, profile, debug=True)
         self.assertTrue(conf is not None)
 
         # install them
-        o = load_options(confpath, profile)
-        o.safe = False
-        o.install_showdiff = True
-        cmd_install(o)
+        opt = load_options(confpath, profile)
+        opt.safe = False
+        opt.install_showdiff = True
+        cmd_install(opt)
 
         # now compare the generated files
         self.assertTrue(os.path.exists(dst1))
@@ -197,39 +207,47 @@ exec bspwm
         self.assertTrue(os.path.exists(dst7))
         self.assertTrue(os.path.exists(dst8))
         self.assertTrue(os.path.exists(dst10))
-        self.assertTrue(os.path.exists(fd))
+        self.assertTrue(os.path.exists(fildfd))
 
         # check if 'dst5' is a link whose target is 'f5'
         self.assertTrue(os.path.islink(dst5))
-        self.assertTrue(os.path.realpath(dst5) == os.path.realpath(f5))
+        self.assertTrue(os.path.realpath(dst5) == os.path.realpath(fcontent5))
 
         # check if 'dst7' is a link whose target is 'dir2'
         self.assertTrue(os.path.islink(dst7))
         self.assertTrue(os.path.realpath(dst7) == os.path.realpath(dir2))
 
         # make sure backup is there
-        b = dst4 + BACKUP_SUFFIX
-        self.assertTrue(os.path.exists(b))
+        backupf = dst4 + BACKUP_SUFFIX
+        self.assertTrue(os.path.exists(backupf))
 
-        self.assertTrue(filecmp.cmp(f1, dst1, shallow=True))
-        f2content = open(dst2, 'r').read()
+        self.assertTrue(filecmp.cmp(fcontent1, dst1, shallow=True))
+        f2content = ''
+        with open(dst2, 'r', encoding='utf-8') as file:
+            f2content = file.read()
         self.assertTrue(f2content == self.RESULT)
-        self.assertTrue(filecmp.cmp(f3, dst3, shallow=True))
+        self.assertTrue(filecmp.cmp(fcontent3, dst3, shallow=True))
 
         # test action has been executed
         self.assertTrue(os.path.exists(fact))
         self.assertTrue(str(act1) != '')
-        actcontent = open(fact, 'r').read().rstrip()
+        actcontent = ''
+        with open(fact, 'r', encoding='utf-8') as file:
+            actcontent = file.read().rstrip()
         self.assertTrue(actcontent == value)
 
         # test transformation has been done
         self.assertTrue(os.path.exists(dst9))
-        transcontent = open(dst9, 'r').read().rstrip()
+        transcontent = ''
+        with open(dst9, 'r', encoding='utf-8') as file:
+            transcontent = file.read().rstrip()
         self.assertTrue(transcontent == trans2)
 
         # test template has been remplaced
         self.assertTrue(os.path.exists(dst10))
-        tempcontent = open(dst10, 'r').read().rstrip()
+        tempcontent = ''
+        with open(dst10, 'r', encoding='utf-8') as file:
+            tempcontent = file.read().rstrip()
         self.assertTrue(tempcontent == header())
 
     def test_install_import_configs(self):
@@ -251,7 +269,7 @@ exec bspwm
         imported_dotfile, _ = create_random_file(os.path.join(tmp, 'imported'))
         imported_dotfile = {
             'dst': os.path.join(dst, imported_dotfile),
-            'key': 'f_{}'.format(imported_dotfile),
+            'key': f'f_{imported_dotfile}',
             'name': imported_dotfile,
             'src': os.path.join(tmp, 'imported', imported_dotfile),
         }
@@ -259,7 +277,7 @@ exec bspwm
             create_random_file(os.path.join(tmp, 'importing'))
         importing_dotfile = {
             'dst': os.path.join(dst, importing_dotfile),
-            'key': 'f_{}'.format(importing_dotfile),
+            'key': f'f_{importing_dotfile}',
             'name': importing_dotfile,
             'src': os.path.join(tmp, 'imported', importing_dotfile),
         }
@@ -323,11 +341,11 @@ exec bspwm
         })
 
         # install them
-        o = load_options(importing_path, 'host2')
-        o.safe = False
-        o.install_showdiff = True
-        o.variables = {}
-        cmd_install(o)
+        opt = load_options(importing_path, 'host2')
+        opt.safe = False
+        opt.install_showdiff = True
+        opt.variables = {}
+        cmd_install(opt)
 
         # now compare the generated files
         self.assertTrue(os.path.exists(importing_dotfile['dst']))
@@ -355,8 +373,8 @@ exec bspwm
 
         # Ensure all destination files point to source
         for src in srcs:
-            dst = os.path.join(dst_dir, src)
-            self.assertEqual(os.path.realpath(dst), os.path.realpath(src))
+            xyz = os.path.join(dst_dir, src)
+            self.assertEqual(os.path.realpath(xyz), os.path.realpath(src))
 
     def test_fails_without_src(self):
         """test fails without src"""
@@ -372,8 +390,8 @@ exec bspwm
                                      actionexec=None)
 
         self.assertFalse(res)
-        e = 'source dotfile does not exist: {}'.format(src)
-        self.assertEqual(err, e)
+        exp = f'source dotfile does not exist: {src}'
+        self.assertEqual(err, exp)
 
     def test_fails_when_src_file(self):
         """test fails when src file"""
@@ -397,8 +415,8 @@ exec bspwm
 
         # ensure nothing performed
         self.assertFalse(res)
-        e = 'source dotfile is not a directory: {}'.format(src)
-        self.assertEqual(err, e)
+        exp = f'source dotfile is not a directory: {src}'
+        self.assertEqual(err, exp)
 
     def test_creates_dst(self):
         """test creates dst"""
@@ -435,7 +453,7 @@ exec bspwm
 
         # Create destination file to be replaced
         dst = os.path.join(dst_dir, get_string(6))
-        with open(dst, 'w'):
+        with open(dst, 'w', encoding='utf=8'):
             pass
         self.assertTrue(os.path.isfile(dst))
 
@@ -457,8 +475,7 @@ exec bspwm
 
         # ensure prompted
         ask.assert_called_with(
-            'Remove regular file {} and replace with empty directory?'
-            .format(dst))
+            f'Remove regular file {dst} and replace with empty directory?')
 
     def test_runs_templater(self):
         """test runs templater"""
@@ -484,15 +501,16 @@ exec bspwm
                           linktype=LinkTypes.LINK_CHILDREN, actionexec=None)
 
         for src in srcs:
-            dst = os.path.join(dst_dir, os.path.basename(src))
+            xyz = os.path.join(dst_dir, os.path.basename(src))
 
             # ensure dst is link
-            self.assertTrue(os.path.islink(dst))
+            self.assertTrue(os.path.islink(xyz))
             # ensure dst not directly linked to src
-            self.assertNotEqual(os.path.realpath(dst), src)
+            self.assertNotEqual(os.path.realpath(xyz), src)
 
 
 def main():
+    """entry point"""
     unittest.main()
 
 
diff --git a/tests/test_jhelpers.py b/tests/test_jhelpers.py
index 114d9bb..00d07bf 100644
--- a/tests/test_jhelpers.py
+++ b/tests/test_jhelpers.py
@@ -6,16 +6,34 @@ basic unittest for jhelpers
 
 import os
 import unittest
-
-from dotdrop.cfg_aggregator import CfgAggregator
 from tests.helpers import (clean,
                            create_random_file, get_string, get_tempdir,
                            load_options)
+from dotdrop.cfg_aggregator import CfgAggregator
 from dotdrop.dotfile import Dotfile
 from dotdrop.dotdrop import cmd_install
 
 
+def fake_config(path, dotfile, profile, dotpath):
+    """Create a fake config file"""
+    with open(path, 'w', encoding='utf-8') as file:
+        file.write('config:\n')
+        file.write('  backup: true\n')
+        file.write('  create: true\n')
+        file.write(f'  dotpath: {dotpath}\n')
+        file.write('dotfiles:\n')
+        file.write(f'  {dotfile.key}:\n')
+        file.write(f'    dst: {dotfile.dst}\n')
+        file.write(f'    src: {dotfile.src}\n')
+        file.write('profiles:\n')
+        file.write(f'  {profile}:\n')
+        file.write('    dotfiles:\n')
+        file.write(f'    - {dotfile.key}\n')
+    return path
+
+
 class TestJhelpers(unittest.TestCase):
+    """test case"""
 
     CONFIG_NAME = 'config.yaml'
 
@@ -56,23 +74,6 @@ basename: c
 dirname: /tmp/a/b
 '''
 
-    def fake_config(self, path, dotfile, profile, dotpath):
-        """Create a fake config file"""
-        with open(path, 'w') as f:
-            f.write('config:\n')
-            f.write('  backup: true\n')
-            f.write('  create: true\n')
-            f.write('  dotpath: {}\n'.format(dotpath))
-            f.write('dotfiles:\n')
-            f.write('  {}:\n'.format(dotfile.key))
-            f.write('    dst: {}\n'.format(dotfile.dst))
-            f.write('    src: {}\n'.format(dotfile.src))
-            f.write('profiles:\n')
-            f.write('  {}:\n'.format(profile))
-            f.write('    dotfiles:\n')
-            f.write('    - {}\n'.format(dotfile.key))
-        return path
-
     def test_jhelpers(self):
         """Test the install function"""
 
@@ -87,34 +88,37 @@ dirname: /tmp/a/b
         self.addCleanup(clean, dst)
 
         # create the dotfile in dotdrop
-        f1, c1 = create_random_file(tmp)
-        with open(f1, 'w') as f:
-            f.write(self.TEMPLATE)
+        file1, _ = create_random_file(tmp)
+        with open(file1, 'w', encoding='utf-8') as file:
+            file.write(self.TEMPLATE)
         dst1 = os.path.join(dst, get_string(6))
-        d1 = Dotfile(get_string(5), dst1, os.path.basename(f1))
+        dotfile1 = Dotfile(get_string(5), dst1, os.path.basename(file1))
 
         # generate the config and stuff
         profile = get_string(5)
         confpath = os.path.join(tmp, self.CONFIG_NAME)
-        self.fake_config(confpath, d1, profile, tmp)
+        fake_config(confpath, dotfile1, profile, tmp)
         conf = CfgAggregator(confpath, profile, debug=True)
         self.assertTrue(conf is not None)
 
         # install them
-        o = load_options(confpath, profile)
-        o.safe = False
-        o.install_showdiff = True
-        o.variables = {}
-        o.debug = True
-        cmd_install(o)
+        opt = load_options(confpath, profile)
+        opt.safe = False
+        opt.install_showdiff = True
+        opt.variables = {}
+        opt.debug = True
+        cmd_install(opt)
 
         # now compare the generated files
         self.assertTrue(os.path.exists(dst1))
-        f1content = open(dst1, 'r').read()
+        f1content = ''
+        with open(dst1, 'r', encoding='utf-8') as file:
+            f1content = file.read()
         self.assertTrue(f1content == self.RESULT)
 
 
 def main():
+    """entry point"""
     unittest.main()
 
 
diff --git a/tests/test_listings.py b/tests/test_listings.py
index e568ad7..a81cbf5 100644
--- a/tests/test_listings.py
+++ b/tests/test_listings.py
@@ -49,23 +49,23 @@ class TestListings(unittest.TestCase):
         self.addCleanup(clean, dotfilespath)
 
         # create the dotfiles to test
-        d1, c1 = create_random_file(fold_config)
-        self.assertTrue(os.path.exists(d1))
-        self.addCleanup(clean, d1)
-        d2, c2 = create_random_file(fold_subcfg)
-        self.assertTrue(os.path.exists(d2))
-        self.addCleanup(clean, d2)
-        d3, c3 = create_random_file(fold_tmp)
-        self.assertTrue(os.path.exists(d3))
-        self.addCleanup(clean, d3)
-        d4, c4 = create_random_file(fold_tmp, binary=True)
-        self.assertTrue(os.path.exists(d4))
-        self.addCleanup(clean, d4)
-        d5 = get_tempdir()
-        self.assertTrue(os.path.exists(d5))
-        self.addCleanup(clean, d5)
-        d6, _ = create_random_file(d5)
-        self.assertTrue(os.path.exists(d6))
+        file1, _ = create_random_file(fold_config)
+        self.assertTrue(os.path.exists(file1))
+        self.addCleanup(clean, file1)
+        file2, _ = create_random_file(fold_subcfg)
+        self.assertTrue(os.path.exists(file2))
+        self.addCleanup(clean, file2)
+        file3, _ = create_random_file(fold_tmp)
+        self.assertTrue(os.path.exists(file3))
+        self.addCleanup(clean, file3)
+        file4, _ = create_random_file(fold_tmp, binary=True)
+        self.assertTrue(os.path.exists(file4))
+        self.addCleanup(clean, file4)
+        file5 = get_tempdir()
+        self.assertTrue(os.path.exists(file5))
+        self.addCleanup(clean, file5)
+        file6, _ = create_random_file(file5)
+        self.assertTrue(os.path.exists(file6))
 
         # create the config file
         profile = get_string(5)
@@ -75,29 +75,30 @@ class TestListings(unittest.TestCase):
                                       backup=self.CONFIG_BACKUP,
                                       create=self.CONFIG_CREATE)
         self.assertTrue(os.path.exists(confpath))
-        o = load_options(confpath, profile)
-        dfiles = [d1, d2, d3, d4, d5]
+        opt = load_options(confpath, profile)
+        dfiles = [file1, file2, file3, file4, file5]
 
         # import the files
-        o.import_path = dfiles
-        cmd_importer(o)
-        o = load_options(confpath, profile)
+        opt.import_path = dfiles
+        cmd_importer(opt)
+        opt = load_options(confpath, profile)
 
         # files
-        cmd_list_profiles(o)
+        cmd_list_profiles(opt)
 
         # list files
-        o.files_templateonly = False
-        cmd_files(o)
-        o.files_templateonly = True
-        cmd_files(o)
+        opt.files_templateonly = False
+        cmd_files(opt)
+        opt.files_templateonly = True
+        cmd_files(opt)
 
         # details
-        o.detail_keys = None
-        cmd_detail(o)
+        opt.detail_keys = None
+        cmd_detail(opt)
 
 
 def main():
+    """entry point"""
     unittest.main()
 
 
diff --git a/tests/test_misc.py b/tests/test_misc.py
new file mode 100644
index 0000000..483ca5d
--- /dev/null
+++ b/tests/test_misc.py
@@ -0,0 +1,64 @@
+"""
+author: deadc0de6 (https://github.com/deadc0de6)
+Copyright (c) 2023, deadc0de6
+basic unittest for misc stuff
+"""
+
+# pylint: disable=R0903
+# pylint: disable=W0231
+# pylint: disable=W0212
+
+import unittest
+from dotdrop.profile import Profile
+from dotdrop.linktypes import LinkTypes
+
+
+class TestLinkTypes(unittest.TestCase):
+    """test case"""
+
+    def test_exc(self):
+        """test exception"""
+        with self.assertRaises(ValueError):
+            LinkTypes.get('whatever')
+        with self.assertRaises(ValueError):
+            LinkTypes.get('whatever', default="something-else")
+
+
+class TestProfile(unittest.TestCase):
+    """test case"""
+
+    def test_hash(self):
+        """test profile hash"""
+        pro = Profile('some-profile')
+        self.assertIsNotNone(hash(pro))
+
+    def test_repr(self):
+        """test profile repr"""
+        name = 'profile-name'
+        pro = Profile(name)
+        expected = f'profile(key:"{name}")'
+        self.assertEqual(repr(pro), expected)
+
+    def test_eq(self):
+        """test profile eq"""
+        p1_name = 'profile-1'
+        pro1 = Profile(p1_name, dotfiles=['abc'])
+        p2_name = 'profile-2'
+        pro2 = Profile(p2_name)
+        p3_name = p1_name
+        pro3 = Profile(p3_name, dotfiles=['abc'])
+        p4_name = p1_name
+        pro4 = Profile(p4_name, dotfiles=['ab'])
+        self.assertNotEqual(pro1, pro2)
+        self.assertEqual(pro1, pro3)
+        self.assertNotEqual(pro1, pro4)
+        self.assertNotEqual(pro3, pro4)
+
+
+def main():
+    """entry point"""
+    unittest.main()
+
+
+if __name__ == '__main__':
+    main()
diff --git a/tests/test_options.py b/tests/test_options.py
new file mode 100644
index 0000000..27d3fc2
--- /dev/null
+++ b/tests/test_options.py
@@ -0,0 +1,239 @@
+"""
+author: deadc0de6 (https://github.com/deadc0de6)
+Copyright (c) 2017, deadc0de6
+basic unittest for the install function
+"""
+
+# pylint: disable=R0903
+# pylint: disable=W0231
+# pylint: disable=W0212
+
+import os
+import unittest
+from unittest.mock import patch
+from dotdrop.options import Options, Logger
+from dotdrop.exceptions import YamlException
+
+
+class FakeOptions(Options):
+    """fake Options class"""
+
+    def __init__(self, args):
+        """init"""
+        self.args = args
+        self.log = Logger(debug=True)
+
+
+def clean_setup():
+    """clean stuff"""
+    if 'DOTDROP_CONFIG' in os.environ:
+        del os.environ['DOTDROP_CONFIG']
+    if 'XDG_CONFIG_HOME' in os.environ:
+        del os.environ['XDG_CONFIG_HOME']
+
+
+def get_args(more):
+    """return args dict"""
+    args = {
+        '--dry': False,
+        '--verbose': True,
+        '--cfg': '',
+    }
+    for k, val in more.items():
+        args[k] = val
+    return args
+
+
+def side_effect(valid=''):
+    """side effect for os.path.exists"""
+    def inner(filename):
+        print(f'checking if {filename} exists')
+        if filename == valid:
+            return True
+        return False
+    return inner
+
+
+class TestOptions(unittest.TestCase):
+    """test case"""
+
+    def test_get_path_from_cli(self):
+        """from --cli"""
+        clean_setup()
+        expected = 'fakepath'
+        args = {}
+        args['--cfg'] = expected
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    def test_get_path_from_env(self):
+        """from env"""
+        clean_setup()
+        expected = 'envpath'
+        os.environ['DOTDROP_CONFIG'] = expected
+        args = get_args({'--cfg': ''})
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_from_yaml(self, mock_exists):
+        """from yaml"""
+        clean_setup()
+        mock_exists.return_value = True
+        expected = 'config.yaml'
+        args = get_args({'--cfg': ''})
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_from_toml(self, mock_exists):
+        """from toml"""
+        clean_setup()
+        expected = 'config.toml'
+        args = get_args({'--cfg': ''})
+        mock_exists.side_effect = side_effect(valid=expected)
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_xdg_yaml(self, mock_exists):
+        """from xdg"""
+        clean_setup()
+        home = os.path.expanduser('~/.config')
+        expected = f'{home}/dotdrop/config.yaml'
+        mock_exists.side_effect = side_effect(valid=expected)
+        args = get_args({'--cfg': ''})
+        os.environ['XDG_CONFIG_HOME'] = home
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_xdg_toml(self, mock_exists):
+        """from xdg toml"""
+        clean_setup()
+        home = os.path.expanduser('~/.config')
+        expected = f'{home}/dotdrop/config.toml'
+        mock_exists.side_effect = side_effect(valid=expected)
+        args = get_args({'--cfg': ''})
+        os.environ['XDG_CONFIG_HOME'] = home
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_fs_xdg_yaml(self, mock_exists):
+        """from fs yaml"""
+        clean_setup()
+        home = os.path.expanduser('~/.config')
+        expected = f'{home}/dotdrop/config.yaml'
+        mock_exists.side_effect = side_effect(valid=expected)
+        args = get_args({'--cfg': ''})
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_fs_xdg_etc_yaml(self, mock_exists):
+        """from fs xdg"""
+        clean_setup()
+        home = os.path.expanduser('/etc/xdg')
+        expected = f'{home}/dotdrop/config.yaml'
+        mock_exists.side_effect = side_effect(valid=expected)
+        args = get_args({'--cfg': ''})
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_fs_etc_dotdrop_yaml(self, mock_exists):
+        """from fs etc"""
+        clean_setup()
+        home = os.path.expanduser('/etc')
+        expected = f'{home}/dotdrop/config.yaml'
+        mock_exists.side_effect = side_effect(valid=expected)
+        args = get_args({'--cfg': ''})
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_fs_etc_xdg_yaml(self, mock_exists):
+        """from fs etc/xdg"""
+        clean_setup()
+        home = os.path.expanduser('/etc/xdg')
+        expected = f'{home}/dotdrop/config.yaml'
+        mock_exists.side_effect = side_effect(valid=expected)
+        args = get_args({'--cfg': ''})
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_fs_xdg_toml(self, mock_exists):
+        """from fs toml"""
+        clean_setup()
+        home = os.path.expanduser('~/.config')
+        expected = f'{home}/dotdrop/config.toml'
+        mock_exists.side_effect = side_effect(valid=expected)
+        args = get_args({'--cfg': ''})
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_fs_xdg_etc_toml(self, mock_exists):
+        """from fs xdg"""
+        clean_setup()
+        home = os.path.expanduser('/etc/xdg')
+        expected = f'{home}/dotdrop/config.toml'
+        mock_exists.side_effect = side_effect(valid=expected)
+        args = get_args({'--cfg': ''})
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_fs_etc_dotdrop_toml(self, mock_exists):
+        """from fs etc"""
+        clean_setup()
+        home = os.path.expanduser('/etc')
+        expected = f'{home}/dotdrop/config.toml'
+        mock_exists.side_effect = side_effect(valid=expected)
+        args = get_args({'--cfg': ''})
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_fs_etc_xdg_toml(self, mock_exists):
+        """from fs etc/xdg"""
+        clean_setup()
+        home = os.path.expanduser('/etc/xdg')
+        expected = f'{home}/dotdrop/config.toml'
+        mock_exists.side_effect = side_effect(valid=expected)
+        args = get_args({'--cfg': ''})
+        fake = FakeOptions(args)
+        self.assertEqual(fake._get_config_path(), expected)
+
+    @patch('os.path.exists')
+    def test_get_path_none(self, mock_exists):
+        """path is none"""
+        clean_setup()
+        mock_exists.return_value = False
+        args = get_args({})
+        fake = FakeOptions(args)
+        self.assertEqual(None, fake._get_config_path())
+
+    @patch('os.path.exists')
+    def test_options_debug(self, mock_exists):
+        """test debug"""
+        mock_exists.return_value = False
+        args = {
+            '--verbose': True,
+            '--dry': False,
+            '--cfg': 'path',
+            '--profile': 'profile',
+        }
+        with self.assertRaises(YamlException):
+            Options(args)
+
+
+def main():
+    """entry point"""
+    unittest.main()
+
+
+if __name__ == '__main__':
+    main()
diff --git a/tests/test_remove.py b/tests/test_remove.py
index 2c8d262..d287058 100644
--- a/tests/test_remove.py
+++ b/tests/test_remove.py
@@ -15,6 +15,7 @@ from tests.helpers import (clean, create_dir,
 
 
 class TestRemove(unittest.TestCase):
+    """test case"""
 
     def load_yaml(self, path):
         """Load yaml to dict"""
@@ -68,13 +69,13 @@ class TestRemove(unittest.TestCase):
         }
 
         yaml_dump(configdic, confpath)
-        o = load_options(confpath, 'host1')
-        o.remove_path = ['f_test1']
-        o.remove_iskey = True
-        o.debug = True
-        o.safe = False
+        opt = load_options(confpath, 'host1')
+        opt.remove_path = ['f_test1']
+        opt.remove_iskey = True
+        opt.debug = True
+        opt.safe = False
         # by key
-        cmd_remove(o)
+        cmd_remove(opt)
 
         # ensure file is deleted
         self.assertFalse(os.path.exists(df1))
@@ -82,48 +83,49 @@ class TestRemove(unittest.TestCase):
         self.assertTrue(os.path.exists(df3))
 
         # load dict
-        y = yaml_load(confpath)
+        cont = yaml_load(confpath)
 
         # ensure not present
-        self.assertTrue('f_test1' not in y['dotfiles'])
-        self.assertTrue('f_test1' not in y['profiles']['host1']['dotfiles'])
-        self.assertTrue('host2' not in y['profiles'])
+        self.assertTrue('f_test1' not in cont['dotfiles'])
+        self.assertTrue('f_test1' not in cont['profiles']['host1']['dotfiles'])
+        self.assertTrue('host2' not in cont['profiles'])
 
         # assert rest is intact
-        self.assertTrue('f_test2' in y['dotfiles'].keys())
-        self.assertTrue('f_test3' in y['dotfiles'].keys())
-        self.assertTrue('f_test2' in y['profiles']['host1']['dotfiles'])
-        self.assertTrue('f_test3' in y['profiles']['host1']['dotfiles'])
-        self.assertTrue(y['profiles']['host3']['dotfiles'] == ['f_test2'])
-
-        o = load_options(confpath, 'host1')
-        o.remove_path = ['/tmp/some-fake-path']
-        o.remove_iskey = False
-        o.debug = True
-        o.safe = False
+        self.assertTrue('f_test2' in cont['dotfiles'].keys())
+        self.assertTrue('f_test3' in cont['dotfiles'].keys())
+        self.assertTrue('f_test2' in cont['profiles']['host1']['dotfiles'])
+        self.assertTrue('f_test3' in cont['profiles']['host1']['dotfiles'])
+        self.assertTrue(cont['profiles']['host3']['dotfiles'] == ['f_test2'])
+
+        opt = load_options(confpath, 'host1')
+        opt.remove_path = ['/tmp/some-fake-path']
+        opt.remove_iskey = False
+        opt.debug = True
+        opt.safe = False
         # by path
-        cmd_remove(o)
+        cmd_remove(opt)
 
         # ensure file is deleted
         self.assertTrue(os.path.exists(df2))
         self.assertFalse(os.path.exists(df3))
 
         # load dict
-        y = yaml_load(confpath)
+        cont = yaml_load(confpath)
 
         # ensure not present
-        self.assertTrue('f_test3' not in y['dotfiles'])
-        self.assertTrue('f_test3' not in y['profiles']['host1']['dotfiles'])
+        self.assertTrue('f_test3' not in cont['dotfiles'])
+        self.assertTrue('f_test3' not in cont['profiles']['host1']['dotfiles'])
 
         # assert rest is intact
-        self.assertTrue('host1' in y['profiles'].keys())
-        self.assertFalse('host2' in y['profiles'].keys())
-        self.assertTrue('host3' in y['profiles'].keys())
-        self.assertTrue(y['profiles']['host1']['dotfiles'] == ['f_test2'])
-        self.assertTrue(y['profiles']['host3']['dotfiles'] == ['f_test2'])
+        self.assertTrue('host1' in cont['profiles'].keys())
+        self.assertFalse('host2' in cont['profiles'].keys())
+        self.assertTrue('host3' in cont['profiles'].keys())
+        self.assertTrue(cont['profiles']['host1']['dotfiles'] == ['f_test2'])
+        self.assertTrue(cont['profiles']['host3']['dotfiles'] == ['f_test2'])
 
 
 def main():
+    """entry point"""
     unittest.main()
 
 
diff --git a/tests/test_update.py b/tests/test_update.py
index a9f102c..834b683 100644
--- a/tests/test_update.py
+++ b/tests/test_update.py
@@ -17,6 +17,7 @@ from tests.helpers import create_dir, get_string, get_tempdir, clean, \
 
 
 class TestUpdate(unittest.TestCase):
+    """unit test"""
 
     CONFIG_BACKUP = False
     CONFIG_CREATE = True
@@ -46,16 +47,16 @@ class TestUpdate(unittest.TestCase):
         self.addCleanup(clean, dotfilespath)
 
         # create the dotfiles to test
-        d1, c1 = create_random_file(fold_config)
-        self.assertTrue(os.path.exists(d1))
-        self.addCleanup(clean, d1)
+        dotfilefile1, _ = create_random_file(fold_config)
+        self.assertTrue(os.path.exists(dotfilefile1))
+        self.addCleanup(clean, dotfilefile1)
 
-        d2, c2 = create_random_file(fold_config)
-        self.assertTrue(os.path.exists(d2))
-        self.addCleanup(clean, d2)
+        dotfilefile2, _ = create_random_file(fold_config)
+        self.assertTrue(os.path.exists(dotfilefile2))
+        self.addCleanup(clean, dotfilefile2)
 
         # template
-        d3t, c3t = create_random_file(fold_config)
+        d3t, _ = create_random_file(fold_config)
         self.assertTrue(os.path.exists(d3t))
         self.addCleanup(clean, d3t)
 
@@ -74,9 +75,9 @@ class TestUpdate(unittest.TestCase):
         dir1sub2str = 'sub2'
         sub2 = os.path.join(dir1, dir1sub2str)
         create_dir(sub2)
-        f1s1, f1s1c1 = create_random_file(sub1)
+        f1s1, _ = create_random_file(sub1)
         self.assertTrue(os.path.exists(f1s1))
-        f1s2, f1s2c1 = create_random_file(sub2)
+        f1s2, _ = create_random_file(sub2)
         self.assertTrue(os.path.exists(f1s2))
 
         # create the directory to test
@@ -93,38 +94,38 @@ class TestUpdate(unittest.TestCase):
                                       backup=self.CONFIG_BACKUP,
                                       create=self.CONFIG_CREATE)
         self.assertTrue(os.path.exists(confpath))
-        o = load_options(confpath, profile)
-        o.update_showpatch = True
-        dfiles = [d1, dir1, d2, d3t, dsubstmp]
+        opt = load_options(confpath, profile)
+        opt.update_showpatch = True
+        dfiles = [dotfilefile1, dir1, dotfilefile2, d3t, dsubstmp]
 
         # import the files
-        o.import_path = dfiles
-        cmd_importer(o)
+        opt.import_path = dfiles
+        cmd_importer(opt)
 
         # get new config
-        o = load_options(confpath, profile)
-        o.safe = False
-        o.update_showpatch = True
-        o.debug = True
+        opt = load_options(confpath, profile)
+        opt.safe = False
+        opt.update_showpatch = True
+        opt.debug = True
         trans = Transform('trans', 'cp -r {0} {1}')
         d3tb = os.path.basename(d3t)
-        for dotfile in o.dotfiles:
+        for dotfile in opt.dotfiles:
             if os.path.basename(dotfile.dst) == d3tb:
                 # patch the template
-                src = os.path.join(o.dotpath, dotfile.src)
+                src = os.path.join(opt.dotpath, dotfile.src)
                 src = os.path.expanduser(src)
                 edit_content(src, '{{@@ profile @@}}')
             left = os.path.realpath(os.path.basename(dotfile.dst))
             right = os.path.realpath(dirsubs)
             if left == right:
                 # retrieve the path of the sub in the dotpath
-                d1indotpath = os.path.join(o.dotpath, dotfile.src)
+                d1indotpath = os.path.join(opt.dotpath, dotfile.src)
                 d1indotpath = os.path.expanduser(d1indotpath)
             dotfile.trans_w = trans
 
         # update template
-        o.update_path = [d3t]
-        self.assertFalse(cmd_update(o))
+        opt.update_path = [d3t]
+        self.assertFalse(cmd_update(opt))
 
         # update sub dirs
         gone = os.path.join(d1indotpath, dir1string)
@@ -132,16 +133,16 @@ class TestUpdate(unittest.TestCase):
         self.assertTrue(os.path.exists(gone))
         clean(sub1)  # dir1sub1str
         self.assertTrue(os.path.exists(gone))
-        o.update_path = [dsubstmp]
-        cmd_update(o)
+        opt.update_path = [dsubstmp]
+        cmd_update(opt)
         self.assertFalse(os.path.exists(gone))
 
         # edit the files
-        edit_content(d1, 'newcontent')
+        edit_content(dotfilefile1, 'newcontent')
         edit_content(dirf1, 'newcontent')
 
         # add more file
-        dirf2, _ = create_random_file(dpath)
+        _, _ = create_random_file(dpath)
 
         # add more dirs
         dpath = os.path.join(dpath, get_string(5))
@@ -149,36 +150,43 @@ class TestUpdate(unittest.TestCase):
         create_random_file(dpath)
 
         # update it
-        o.update_path = [d1, dir1]
-        cmd_update(o)
+        opt.update_path = [dotfilefile1, dir1]
+        cmd_update(opt)
 
         # test content
-        newcontent = open(d1, 'r').read()
+        newcontent = ''
+        with open(dotfilefile1, 'r', encoding='utf-8') as file:
+            newcontent = file.read()
         self.assertTrue(newcontent == 'newcontent')
-        newcontent = open(dirf1, 'r').read()
+        newcontent = ''
+        with open(dirf1, 'r', encoding='utf-8') as file:
+            newcontent = file.read()
         self.assertTrue(newcontent == 'newcontent')
 
-        edit_content(d2, 'newcontentbykey')
+        edit_content(dotfilefile2, 'newcontentbykey')
 
         # update it by key
-        dfiles = o.dotfiles
+        dfiles = opt.dotfiles
         d2key = ''
-        for ds in dfiles:
-            t = os.path.expanduser(ds.dst)
-            if t == d2:
-                d2key = ds.key
+        for dotfile in dfiles:
+            src = os.path.expanduser(dotfile.dst)
+            if src == dotfilefile2:
+                d2key = dotfile.key
                 break
         self.assertTrue(d2key != '')
-        o.update_path = [d2key]
-        o.update_iskey = True
-        cmd_update(o)
+        opt.update_path = [d2key]
+        opt.update_iskey = True
+        cmd_update(opt)
 
         # test content
-        newcontent = open(d2, 'r').read()
+        newcontent = ''
+        with open(dotfilefile2, 'r', encoding='utf-8') as file:
+            newcontent = file.read()
         self.assertTrue(newcontent == 'newcontentbykey')
 
 
 def main():
+    """entry point"""
     unittest.main()
 
 
diff --git a/tests/test_yamlcfg.py b/tests/test_yamlcfg.py
index 2713ef7..d436df9 100644
--- a/tests/test_yamlcfg.py
+++ b/tests/test_yamlcfg.py
@@ -19,6 +19,7 @@ from tests.helpers import (SubsetTestCase, _fake_args, clean,
 
 
 class TestConfig(SubsetTestCase):
+    """test case"""
 
     CONFIG_BACKUP = False
     CONFIG_CREATE = True
@@ -51,7 +52,29 @@ class TestConfig(SubsetTestCase):
         self.assertTrue(dpath == self.CONFIG_DOTPATH)
         self.assertTrue(conf.dump() != '')
 
+    def test_raises(self):
+        """test raises on not existing path"""
+        with self.assertRaises(YamlException):
+            Cfg('path', debug=True)
+
+    def test_resolve_link(self):
+        """test bad link value"""
+        tmp = get_tempdir()
+        self.assertTrue(os.path.exists(tmp))
+        self.addCleanup(clean, tmp)
+        confpath = create_fake_config(tmp,
+                                      configname=self.CONFIG_NAME,
+                                      dotpath=self.CONFIG_DOTPATH,
+                                      backup=self.CONFIG_BACKUP,
+                                      create=self.CONFIG_CREATE)
+        cfg = Cfg(confpath, debug=True)
+        with self.assertRaises(YamlException):
+            # pylint: disable=W0212
+            cfg._resolve_dotfile_link('fake')
+
     def test_def_link(self):
+        """unittest"""
+        # pylint: disable=E1120
         self._test_link_import('nolink', LinkTypes.ABSOLUTE, 'absolute')
         self._test_link_import('nolink', LinkTypes.RELATIVE, 'relative')
         self._test_link_import('nolink', LinkTypes.NOLINK, 'nolink')
@@ -75,7 +98,7 @@ class TestConfig(SubsetTestCase):
     @patch('dotdrop.cfg_yaml.os.path.exists', create=True)
     def _test_link_import(self, cfgstring, expected,
                           cliargs, mock_exists, mock_open):
-        data = '''
+        data = f'''
 config:
   backup: true
   create: true
@@ -83,11 +106,11 @@ config:
   banner: true
   longkey: false
   keepdot: false
-  link_on_import: {}
+  link_on_import: {cfgstring}
   link_dotfile_default: nolink
 dotfiles:
 profiles:
-        '''.format(cfgstring)
+        '''
 
         mock_open.side_effect = [
                 unittest.mock.mock_open(read_data=data).return_value,
@@ -100,14 +123,14 @@ profiles:
         args['--cfg'] = 'mocked'
         args['--link'] = cliargs
         args['--verbose'] = True
-        o = Options(args=args)
+        opt = Options(args=args)
 
-        self.assertTrue(o.import_link == expected)
+        self.assertTrue(opt.import_link == expected)
 
     @patch('dotdrop.cfg_yaml.open', create=True)
     @patch('dotdrop.cfg_yaml.os.path.exists', create=True)
     def _test_link_import_fail(self, value, mock_exists, mock_open):
-        data = '''
+        data = f'''
 config:
   backup: true
   create: true
@@ -115,11 +138,11 @@ config:
   banner: true
   longkey: false
   keepdot: false
-  link_on_import: {}
+  link_on_import: {value}
   link_dotfile_default: nolink
 dotfiles:
 profiles:
-        '''.format(value)
+        '''
 
         mock_open.side_effect = [
                 unittest.mock.mock_open(read_data=data).return_value
@@ -132,10 +155,11 @@ profiles:
         args['--verbose'] = True
 
         with self.assertRaises(YamlException):
-            o = Options(args=args)
-            print(o.import_link)
+            opt = Options(args=args)
+            print(opt.import_link)
 
     def test_include(self):
+        """unittest"""
         tmp = get_tempdir()
         self.assertTrue(os.path.exists(tmp))
         self.addCleanup(clean, tmp)
@@ -358,32 +382,32 @@ profiles:
         self.assertIsNotNone(imported_cfg)
 
         # test profiles
-        self.assertIsSubset(imported_cfg.profiles,
-                            importing_cfg.profiles)
+        self.assert_is_subset(imported_cfg.profiles,
+                              importing_cfg.profiles)
 
         # test dotfiles
-        self.assertIsSubset(imported_cfg.dotfiles, importing_cfg.dotfiles)
+        self.assert_is_subset(imported_cfg.dotfiles, importing_cfg.dotfiles)
 
         # test actions
         pre_ed = post_ed = pre_ing = post_ing = {}
-        for k, v in imported_cfg.actions.items():
-            kind, _ = v
+        for k, val in imported_cfg.actions.items():
+            kind, _ = val
             if kind == 'pre':
-                pre_ed[k] = v
+                pre_ed[k] = val
             elif kind == 'post':
-                post_ed[k] = v
-        for k, v in importing_cfg.actions.items():
-            kind, _ = v
+                post_ed[k] = val
+        for k, val in importing_cfg.actions.items():
+            kind, _ = val
             if kind == 'pre':
-                pre_ing[k] = v
+                pre_ing[k] = val
             elif kind == 'post':
-                post_ing[k] = v
-        self.assertIsSubset(pre_ed, pre_ing)
-        self.assertIsSubset(post_ed, post_ing)
+                post_ing[k] = val
+        self.assert_is_subset(pre_ed, pre_ing)
+        self.assert_is_subset(post_ed, post_ing)
 
         # test transactions
-        self.assertIsSubset(imported_cfg.trans_r, importing_cfg.trans_r)
-        self.assertIsSubset(imported_cfg.trans_w, importing_cfg.trans_w)
+        self.assert_is_subset(imported_cfg.trans_r, importing_cfg.trans_r)
+        self.assert_is_subset(imported_cfg.trans_w, importing_cfg.trans_w)
 
         # test variables
         imported_vars = {
@@ -396,10 +420,10 @@ profiles:
             for k, v in importing_cfg.variables.items()
             if not k.startswith('_')
         }
-        self.assertIsSubset(imported_vars, importing_vars)
+        self.assert_is_subset(imported_vars, importing_vars)
 
         # test prodots
-        self.assertIsSubset(imported_cfg.profiles, importing_cfg.profiles)
+        self.assert_is_subset(imported_cfg.profiles, importing_cfg.profiles)
 
     def test_import_configs_override(self):
         """Test import_configs when some config keys overlap."""
@@ -563,8 +587,8 @@ profiles:
         self.assertIsNotNone(imported_cfg)
 
         # test profiles
-        self.assertIsSubset(imported_cfg.profiles,
-                            importing_cfg.profiles)
+        self.assert_is_subset(imported_cfg.profiles,
+                              importing_cfg.profiles)
 
         # test dotfiles
         self.assertEqual(importing_cfg.dotfiles['f_vimrc'],
@@ -609,6 +633,7 @@ profiles:
 
 
 def main():
+    """entry point"""
     unittest.main()
 
 

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/dotdrop-1.13.0.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/dotdrop-1.13.0.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/dotdrop-1.13.0.egg-info/entry_points.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/dotdrop-1.13.0.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/dotdrop-1.13.0.egg-info/top_level.txt
-rw-r--r--  root/root   /usr/share/doc/dotdrop/docs/howto/test-latest-dotdrop.md

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/dotdrop-1.12.9.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/dotdrop-1.12.9.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/dotdrop-1.12.9.egg-info/entry_points.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/dotdrop-1.12.9.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/dotdrop-1.12.9.egg-info/top_level.txt

No differences were encountered in the control files

More details

Full run details