From 6f165d0d3e2500d8860f3bcc111de056b3f28b02 Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Sun, 7 Jul 2019 18:44:23 +0200 Subject: [PATCH] adding minimum version for config file (#174) --- dotdrop/cfg_yaml.py | 26 ++++++++ dotdrop/settings.py | 6 +- tests-ng/minversion.sh | 133 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100755 tests-ng/minversion.sh diff --git a/dotdrop/cfg_yaml.py b/dotdrop/cfg_yaml.py index 17e6d76..cd81bda 100644 --- a/dotdrop/cfg_yaml.py +++ b/dotdrop/cfg_yaml.py @@ -11,6 +11,7 @@ import glob from copy import deepcopy # local imports +from dotdrop.version import __version__ as VERSION from dotdrop.settings import Settings from dotdrop.logger import Logger from dotdrop.templategen import Templategen @@ -62,6 +63,7 @@ class CfgYaml: key_settings_workdir = 'workdir' key_settings_link_dotfile_default = 'link_dotfile_default' key_settings_noempty = 'ignoreempty' + key_settings_minversion = 'minversion' key_imp_link = 'link_on_import' # link values @@ -138,6 +140,11 @@ class CfgYaml: self.settings = Settings(None).serialize().get(self.key_settings) self.settings.update(self.ori_settings) + # resolve minimum version + if self.key_settings_minversion in self.settings: + minversion = self.settings[self.key_settings_minversion] + self._check_minversion(minversion) + # resolve settings paths p = self._norm_path(self.settings[self.key_settings_dotpath]) self.settings[self.key_settings_dotpath] = p @@ -790,6 +797,11 @@ class CfgYaml: if self.key_profiles not in content: content[self.key_profiles] = None + if self.dirty_deprecated: + # add minversion + settings = content[self.key_settings] + settings[self.key_settings_minversion] = VERSION + # save to file if self.debug: self.log.dbg('saving to {}'.format(self.path)) @@ -943,3 +955,17 @@ class CfgYaml: self.log.dbg('resolved: {} -> {}'.format(e, et)) new.append(et) return new + + def _check_minversion(self, minversion): + if not minversion: + return + try: + cur = tuple([int(x) for x in VERSION.split('.')]) + cfg = tuple([int(x) for x in minversion.split('.')]) + except Exception: + err = 'bad version: \"{}\" VS \"{}\"'.format(VERSION, minversion) + raise YamlException(err) + if cur < cfg: + err = 'current dotdrop version is too old for that config file.' + err += ' Please update.' + raise YamlException(err) diff --git a/dotdrop/settings.py b/dotdrop/settings.py index 51ef59f..b42ed0b 100644 --- a/dotdrop/settings.py +++ b/dotdrop/settings.py @@ -29,6 +29,7 @@ class Settings(DictParser): key_showdiff = 'showdiff' key_upignore = 'upignore' key_workdir = 'workdir' + key_minversion = 'minversion' # import keys key_import_actions = 'import_actions' @@ -41,7 +42,8 @@ class Settings(DictParser): import_variables=[], keepdot=False, link_dotfile_default=LinkTypes.NOLINK, link_on_import=LinkTypes.NOLINK, longkey=False, - showdiff=False, upignore=[], workdir='~/.config/dotdrop'): + showdiff=False, upignore=[], workdir='~/.config/dotdrop', + minversion=None): self.backup = backup self.banner = banner self.create = create @@ -59,6 +61,7 @@ class Settings(DictParser): self.workdir = workdir self.link_dotfile_default = LinkTypes.get(link_dotfile_default) self.link_on_import = LinkTypes.get(link_on_import) + self.minversion = minversion def _serialize_seq(self, name, dic): """serialize attribute 'name' into 'dic'""" @@ -80,6 +83,7 @@ class Settings(DictParser): self.key_longkey: self.longkey, self.key_showdiff: self.showdiff, self.key_workdir: self.workdir, + self.key_minversion: self.minversion, } self._serialize_seq(self.key_cmpignore, dic) self._serialize_seq(self.key_default_actions, dic) diff --git a/tests-ng/minversion.sh b/tests-ng/minversion.sh new file mode 100755 index 0000000..e827287 --- /dev/null +++ b/tests-ng/minversion.sh @@ -0,0 +1,133 @@ +#!/usr/bin/env bash +# author: deadc0de6 (https://github.com/deadc0de6) +# Copyright (c) 2019, deadc0de6 +# +# test minversion + +# 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" + +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 +# the dotfile destination +tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d` + +cfg="${tmps}/config.yaml" +cat > ${cfg} << _EOF +config: + backup: true + create: true + dotpath: dotfiles +dotfiles: + f_abc: + dst: ${tmpd}/abc + src: abc + link: true +profiles: + p1: + dotfiles: + - f_abc +_EOF + +# create the source +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 + +# ensure minversion is present +cat ${cfg} +grep 'link: link' ${cfg} +grep 'minversion' ${cfg} + +# fake a higher version +cat > ${cfg} << _EOF +config: + backup: true + create: true + dotpath: dotfiles + minversion: 100.1.2 +dotfiles: + f_abc: + dst: ${tmpd}/abc + src: abc + link: true +profiles: + p1: + dotfiles: + - f_abc +_EOF + +# compare +set +e +cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -V +[ "$?" != "1" ] && echo "minversion not working" && exit 1 +set -e + +# all clean +cat > ${cfg} << _EOF +config: + backup: true + create: true + dotpath: dotfiles +dotfiles: + f_abc: + dst: ${tmpd}/abc + src: abc +profiles: + p1: + dotfiles: + - f_abc +_EOF + +# compare +cd ${ddpath} | ${bin} compare -c ${cfg} -p p1 -V + +# test +cat ${cfg} +grep 'minversion' ${cfg} && echo "minversion added, not needed" && exit 1 + +## CLEANING +rm -rf ${tmps} ${tmpd} + +echo "OK" +exit 0