From 5c3944c8281f51a9a7ca5fa537dc38dba22b711f Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Sun, 11 Oct 2020 21:10:06 +0200 Subject: [PATCH] add ability to template link value for #268 --- docs/config-details.md | 27 +++++- docs/config.md | 1 + dotdrop/cfg_yaml.py | 33 +++---- tests-ng/template-link-value.sh | 148 ++++++++++++++++++++++++++++++++ tests.sh | 2 +- 5 files changed, 194 insertions(+), 17 deletions(-) create mode 100755 tests-ng/template-link-value.sh diff --git a/docs/config-details.md b/docs/config-details.md index f98d95f..bdb51c7 100644 --- a/docs/config-details.md +++ b/docs/config-details.md @@ -556,7 +556,32 @@ profiles: - f_somefile ``` -Make sure to quote the path in the config file. +## Dynamic dotfile link value + +Dotfile `link` value can be dynamically constructed using +define variables (([variables and dynvariables](config.md#variables)). + +For example +```yaml +variables: + link_value: "nolink" +dotfiles: + f_test: + src: test + dst: ~/.test + link: "{{@@ link_value @@}}" +profiles: + linux: + dotfiles: + - f_test + variables: + link_value: "link" + windows: + dotfiles: + - f_test +``` + +Make sure to quote the link value in the config file. ## Dynamic actions diff --git a/docs/config.md b/docs/config.md index 6efc194..287e855 100644 --- a/docs/config.md +++ b/docs/config.md @@ -73,6 +73,7 @@ Entry | Related doc -------- | ------------- dotfile src | [dynamic dotfile paths](config-details.md#dynamic-dotfile-paths) dotfile dst | [dynamic dotfile paths](config-details.md#dynamic-dotfile-paths) +dotfile link | [Dynamic dotfile link value](config-details.md#Dynamic-dotfile-link-value) variables | [variables](config-details.md#entry-variables) dynvariables | [dynvariables](config-details.md#entry-dynvariables) actions | [dynamic actions](config-details.md#dynamic-actions) diff --git a/dotdrop/cfg_yaml.py b/dotdrop/cfg_yaml.py index 83255ea..94fe490 100644 --- a/dotdrop/cfg_yaml.py +++ b/dotdrop/cfg_yaml.py @@ -242,15 +242,15 @@ class CfgYaml: # process profile ALL self._resolve_profile_all() - # patch dotfiles paths - self._template_dotfiles_paths() + # template dotfiles entries + self._template_dotfiles_entries() if self._debug: self._dbg('########### {} ###########'.format('final config')) self._debug_entries() ######################################################## - # outside available methods + # public methods ######################################################## def resolve_dotfile_src(self, src, templater=None): @@ -596,15 +596,7 @@ class CfgYaml: v[self.key_trans_r] = v[self.old_key_trans_r] del v[self.old_key_trans_r] new[k] = v - # normalize the link value - if self.key_dotfile_link in v: - # check link value - val = v[self.key_dotfile_link] - if val not in self.allowed_link_val: - err = 'bad value: {}'.format(val) - self._log.err(err) - raise YamlException('config content error: {}'.format(err)) - else: + if self.key_dotfile_link not in v: # apply link value if undefined val = self.settings[self.key_settings_link_dotfile_default] v[self.key_dotfile_link] = val @@ -1119,10 +1111,10 @@ class CfgYaml: new[k] = vt return new - def _template_dotfiles_paths(self): - """template dotfiles paths""" + def _template_dotfiles_entries(self): + """template dotfiles entries""" if self._debug: - self._dbg('templating dotfiles paths') + self._dbg('templating dotfiles entries') dotfiles = self.dotfiles.copy() # make sure no dotfiles path is None @@ -1164,6 +1156,17 @@ class CfgYaml: dst = dotfile[self.key_dotfile_dst] newdst = self.resolve_dotfile_dst(dst, templater=self._tmpl) dotfile[self.key_dotfile_dst] = newdst + # normalize the link value + if self.key_dotfile_link in dotfile: + # link + link = dotfile[self.key_dotfile_link] + newlink = self._template_item(link) + dotfile[self.key_dotfile_link] = newlink + # check link value + if newlink not in self.allowed_link_val: + err = 'bad value: {}'.format(newlink) + self._log.err(err) + raise YamlException('config content error: {}'.format(err)) def _rec_resolve_variables(self, variables): """recursive resolve variables""" diff --git a/tests-ng/template-link-value.sh b/tests-ng/template-link-value.sh new file mode 100755 index 0000000..dfcc203 --- /dev/null +++ b/tests-ng/template-link-value.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash +# author: deadc0de6 (https://github.com/deadc0de6) +# Copyright (c) 2020, deadc0de6 +# +# test tmeplate link value +# returns 1 in case of error +# + +# exit on first error +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 +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)" + +################################################################ +# this is the test +################################################################ + +# the dotfile source +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` +echo "dotfiles destination: ${tmpd}" + +# create the config file +cfg="${tmps}/config.yaml" + +cat > ${cfg} << _EOF +config: + backup: true + create: true + dotpath: dotfiles +variables: + link_true: "link" + link_false: "nolink" + link_children_val: "link_children" +dynvariables: + dyn_link_true: "echo link" + dyn_link_false: "echo nolink" + dyn_link_children_val: "echo link_children" +dotfiles: + f_a: + dst: ${tmpd}/a + src: a + link: "{{@@ link_false @@}}" + f_b: + dst: ${tmpd}/b + src: b + link: "{{@@ link_true @@}}" + f_c: + dst: ${tmpd}/c + src: c + link: "{{@@ dyn_link_false @@}}" + f_d: + dst: ${tmpd}/d + src: d + link: "{{@@ dyn_link_true @@}}" + f_e: + dst: ${tmpd}/e + src: e + link: "{{@@ link_children_val @@}}" + f_f: + dst: ${tmpd}/f + src: f + link: "{{@@ dyn_link_children_val @@}}" +profiles: + p1: + dotfiles: + - f_a + - f_b + - f_c + - f_d + - f_e + - f_f +_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 + +# install +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 + +# 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 + +## CLEANING +rm -rf ${tmps} ${tmpd} + +echo "OK" +exit 0 diff --git a/tests.sh b/tests.sh index 06266c7..d8c470c 100755 --- a/tests.sh +++ b/tests.sh @@ -96,4 +96,4 @@ else fi ## done -echo "All test finished successfully" +echo "All test finished successfully in ${SECONDS}s"