mirror of
https://github.com/deadc0de6/dotdrop.git
synced 2026-02-09 12:54:18 +00:00
implement feature for #198
This commit is contained in:
@@ -57,6 +57,8 @@ class CfgYaml:
|
|||||||
key_import_configs = 'import_configs'
|
key_import_configs = 'import_configs'
|
||||||
key_import_variables = 'import_variables'
|
key_import_variables = 'import_variables'
|
||||||
key_import_profile_dfs = 'import'
|
key_import_profile_dfs = 'import'
|
||||||
|
key_import_sep = ':'
|
||||||
|
key_import_ignore_key = 'ignore'
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
key_settings_dotpath = 'dotpath'
|
key_settings_dotpath = 'dotpath'
|
||||||
@@ -539,15 +541,17 @@ class CfgYaml:
|
|||||||
return
|
return
|
||||||
paths = self._glob_paths(paths)
|
paths = self._glob_paths(paths)
|
||||||
for p in paths:
|
for p in paths:
|
||||||
path = self._norm_path(p)
|
path, fatal_not_found = self._norm_extended_import_path(p)
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.dbg('import variables from {}'.format(path))
|
self.log.dbg('import variables from {}'.format(path))
|
||||||
var = self._import_sub(path, self.key_variables,
|
var = self._import_sub(path, self.key_variables,
|
||||||
mandatory=False)
|
mandatory=False,
|
||||||
|
fatal_not_found=fatal_not_found)
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.dbg('import dynvariables from {}'.format(path))
|
self.log.dbg('import dynvariables from {}'.format(path))
|
||||||
dvar = self._import_sub(path, self.key_dvariables,
|
dvar = self._import_sub(path, self.key_dvariables,
|
||||||
mandatory=False)
|
mandatory=False,
|
||||||
|
fatal_not_found=fatal_not_found)
|
||||||
merged = self._merge_dict(dvar, var)
|
merged = self._merge_dict(dvar, var)
|
||||||
merged = self._rec_resolve_vars(merged)
|
merged = self._rec_resolve_vars(merged)
|
||||||
# execute dvar
|
# execute dvar
|
||||||
@@ -559,6 +563,15 @@ class CfgYaml:
|
|||||||
"""remove profile variables from dic if found"""
|
"""remove profile variables from dic if found"""
|
||||||
[dic.pop(k, None) for k in self.prokeys]
|
[dic.pop(k, None) for k in self.prokeys]
|
||||||
|
|
||||||
|
def _norm_extended_import_path(self, path):
|
||||||
|
"""normalize imported path and its attribute if any"""
|
||||||
|
fields = path.split(self.key_import_sep)
|
||||||
|
fatal_not_found = True
|
||||||
|
if len(fields) > 1:
|
||||||
|
if fields[1] == self.key_import_ignore_key:
|
||||||
|
fatal_not_found = False
|
||||||
|
return self._norm_path(fields[0]), fatal_not_found
|
||||||
|
|
||||||
def _import_actions(self):
|
def _import_actions(self):
|
||||||
"""import external actions from paths"""
|
"""import external actions from paths"""
|
||||||
paths = self.settings.get(self.key_import_actions, None)
|
paths = self.settings.get(self.key_import_actions, None)
|
||||||
@@ -566,12 +579,13 @@ class CfgYaml:
|
|||||||
return
|
return
|
||||||
paths = self._glob_paths(paths)
|
paths = self._glob_paths(paths)
|
||||||
for p in paths:
|
for p in paths:
|
||||||
path = self._norm_path(p)
|
path, fatal_not_found = self._norm_extended_import_path(p)
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.dbg('import actions from {}'.format(path))
|
self.log.dbg('import actions from {}'.format(path))
|
||||||
new = self._import_sub(path, self.key_actions,
|
new = self._import_sub(path, self.key_actions,
|
||||||
mandatory=False,
|
mandatory=False,
|
||||||
patch_func=self._norm_actions)
|
patch_func=self._norm_actions,
|
||||||
|
fatal_not_found=fatal_not_found)
|
||||||
self.actions = self._merge_dict(new, self.actions)
|
self.actions = self._merge_dict(new, self.actions)
|
||||||
|
|
||||||
def _import_profiles_dotfiles(self):
|
def _import_profiles_dotfiles(self):
|
||||||
@@ -592,9 +606,16 @@ class CfgYaml:
|
|||||||
|
|
||||||
def _import_config(self, path):
|
def _import_config(self, path):
|
||||||
"""import config from path"""
|
"""import config from path"""
|
||||||
path = self._norm_path(path)
|
path, fatal_not_found = self._norm_extended_import_path(path)
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.dbg('import config from {}'.format(path))
|
self.log.dbg('import config from {}'.format(path))
|
||||||
|
if not os.path.exists(path):
|
||||||
|
err = 'config path not found: {}'.format(path)
|
||||||
|
if fatal_not_found:
|
||||||
|
raise YamlException(err)
|
||||||
|
else:
|
||||||
|
self.log.warn(err)
|
||||||
|
return
|
||||||
sub = CfgYaml(path, profile=self.profile, debug=self.debug)
|
sub = CfgYaml(path, profile=self.profile, debug=self.debug)
|
||||||
# settings is ignored
|
# settings is ignored
|
||||||
self.dotfiles = self._merge_dict(self.dotfiles, sub.dotfiles)
|
self.dotfiles = self._merge_dict(self.dotfiles, sub.dotfiles)
|
||||||
@@ -617,15 +638,18 @@ class CfgYaml:
|
|||||||
for path in paths:
|
for path in paths:
|
||||||
self._import_config(path)
|
self._import_config(path)
|
||||||
|
|
||||||
def _import_sub(self, path, key,
|
def _import_sub(self, path, key, mandatory=False,
|
||||||
mandatory=False, patch_func=None):
|
patch_func=None, fatal_not_found=True):
|
||||||
"""
|
"""
|
||||||
import the block "key" from "path"
|
import the block "key" from "path"
|
||||||
patch_func is applied to each element if defined
|
patch_func is applied to each element if defined
|
||||||
"""
|
"""
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.dbg('import \"{}\" from \"{}\"'.format(key, path))
|
self.log.dbg('import \"{}\" from \"{}\"'.format(key, path))
|
||||||
extdict = self._load_yaml(path)
|
self.log.dbg('ignore non existing: \"{}\"'.format(fatal_not_found))
|
||||||
|
extdict = self._load_yaml(path, fatal_not_found=fatal_not_found)
|
||||||
|
if extdict is None and not fatal_not_found:
|
||||||
|
return {}
|
||||||
new = self._get_entry(extdict, key, mandatory=mandatory)
|
new = self._get_entry(extdict, key, mandatory=mandatory)
|
||||||
if patch_func:
|
if patch_func:
|
||||||
if self.debug:
|
if self.debug:
|
||||||
@@ -834,11 +858,16 @@ class CfgYaml:
|
|||||||
"""dump the config dictionary"""
|
"""dump the config dictionary"""
|
||||||
return self.yaml_dict
|
return self.yaml_dict
|
||||||
|
|
||||||
def _load_yaml(self, path):
|
def _load_yaml(self, path, fatal_not_found=True):
|
||||||
"""load a yaml file to a dict"""
|
"""load a yaml file to a dict"""
|
||||||
content = {}
|
content = {}
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
raise YamlException('config path not found: {}'.format(path))
|
err = 'config path not found: {}'.format(path)
|
||||||
|
if fatal_not_found:
|
||||||
|
raise YamlException(err)
|
||||||
|
else:
|
||||||
|
self.log.warn(err)
|
||||||
|
return None
|
||||||
try:
|
try:
|
||||||
content = self._yaml_load(path)
|
content = self._yaml_load(path)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
158
tests-ng/import-non-existing.sh
Executable file
158
tests-ng/import-non-existing.sh
Executable file
@@ -0,0 +1,158 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# author: deadc0de6 (https://github.com/deadc0de6)
|
||||||
|
# Copyright (c) 2019, deadc0de6
|
||||||
|
#
|
||||||
|
# test import not existing
|
||||||
|
#
|
||||||
|
|
||||||
|
# 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`
|
||||||
|
#echo "dotfile destination: ${tmpd}"
|
||||||
|
|
||||||
|
# create the dotfile
|
||||||
|
echo "test" > ${tmps}/dotfiles/abc
|
||||||
|
|
||||||
|
# create the config file
|
||||||
|
cfg="${tmps}/config.yaml"
|
||||||
|
|
||||||
|
cat > ${cfg} << _EOF
|
||||||
|
config:
|
||||||
|
backup: true
|
||||||
|
create: true
|
||||||
|
dotpath: dotfiles
|
||||||
|
import_variables:
|
||||||
|
- /variables/does/not/exist:ignore
|
||||||
|
import_actions:
|
||||||
|
- /actions/does/not/exist:ignore
|
||||||
|
import_configs:
|
||||||
|
- /configs/does/not/exist:ignore
|
||||||
|
dotfiles:
|
||||||
|
f_abc:
|
||||||
|
dst: ${tmpd}/abc
|
||||||
|
src: abc
|
||||||
|
profiles:
|
||||||
|
p1:
|
||||||
|
dotfiles:
|
||||||
|
- f_abc
|
||||||
|
_EOF
|
||||||
|
#cat ${cfg}
|
||||||
|
|
||||||
|
# dummy call
|
||||||
|
cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
|
||||||
|
|
||||||
|
cat > ${cfg} << _EOF
|
||||||
|
config:
|
||||||
|
backup: true
|
||||||
|
create: true
|
||||||
|
dotpath: dotfiles
|
||||||
|
import_variables:
|
||||||
|
- /variables/does/not/exist
|
||||||
|
dotfiles:
|
||||||
|
f_abc:
|
||||||
|
dst: ${tmpd}/abc
|
||||||
|
src: abc
|
||||||
|
profiles:
|
||||||
|
p1:
|
||||||
|
dotfiles:
|
||||||
|
- f_abc
|
||||||
|
_EOF
|
||||||
|
|
||||||
|
# dummy call
|
||||||
|
set +e
|
||||||
|
cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
|
||||||
|
[ "$?" = "0" ] && echo "variables" && exit 1
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cat > ${cfg} << _EOF
|
||||||
|
config:
|
||||||
|
backup: true
|
||||||
|
create: true
|
||||||
|
dotpath: dotfiles
|
||||||
|
import_actions:
|
||||||
|
- /actions/does/not/exist
|
||||||
|
dotfiles:
|
||||||
|
f_abc:
|
||||||
|
dst: ${tmpd}/abc
|
||||||
|
src: abc
|
||||||
|
profiles:
|
||||||
|
p1:
|
||||||
|
dotfiles:
|
||||||
|
- f_abc
|
||||||
|
_EOF
|
||||||
|
|
||||||
|
# dummy call
|
||||||
|
set +e
|
||||||
|
cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
|
||||||
|
[ "$?" = "0" ] && echo "actions" && exit 1
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cat > ${cfg} << _EOF
|
||||||
|
config:
|
||||||
|
backup: true
|
||||||
|
create: true
|
||||||
|
dotpath: dotfiles
|
||||||
|
import_configs:
|
||||||
|
- /configs/does/not/exist
|
||||||
|
dotfiles:
|
||||||
|
f_abc:
|
||||||
|
dst: ${tmpd}/abc
|
||||||
|
src: abc
|
||||||
|
profiles:
|
||||||
|
p1:
|
||||||
|
dotfiles:
|
||||||
|
- f_abc
|
||||||
|
_EOF
|
||||||
|
|
||||||
|
# dummy call
|
||||||
|
set +e
|
||||||
|
cd ${ddpath} | ${bin} files -c ${cfg} -p p1 -V
|
||||||
|
[ "$?" = "0" ] && echo "configs" && exit 1
|
||||||
|
set -e
|
||||||
|
|
||||||
|
## CLEANING
|
||||||
|
rm -rf ${tmps} ${tmpd}
|
||||||
|
|
||||||
|
echo "OK"
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user