1
0
mirror of https://github.com/deadc0de6/dotdrop.git synced 2026-02-05 10:18:49 +00:00

Merge pull request #201 from deadc0de6/ignore_not_existing

custom functions and custom filters
This commit is contained in:
deadc0de
2020-01-12 12:02:52 +01:00
committed by GitHub
10 changed files with 309 additions and 10 deletions

View File

@@ -85,6 +85,7 @@ def cmd_install(o):
return False
t = Templategen(base=o.dotpath, variables=o.variables,
func_file=o.func_file, filter_file=o.filter_file,
debug=o.debug)
tmpdir = None
if o.install_temporary:
@@ -205,6 +206,7 @@ def cmd_compare(o, tmp):
return False
t = Templategen(base=o.dotpath, variables=o.variables,
func_file=o.func_file, filter_file=o.filter_file,
debug=o.debug)
inst = Installer(create=o.create, backup=o.backup,
dry=o.dry, base=o.dotpath,

View File

@@ -31,6 +31,8 @@ class Settings(DictParser):
key_instignore = 'instignore'
key_workdir = 'workdir'
key_minversion = 'minversion'
key_func_file = 'func_file'
key_filter_file = 'filter_file'
# import keys
key_import_actions = 'import_actions'
@@ -45,7 +47,7 @@ class Settings(DictParser):
link_on_import=LinkTypes.NOLINK, longkey=False,
upignore=[], cmpignore=[], instignore=[],
workdir='~/.config/dotdrop', showdiff=False,
minversion=None):
minversion=None, func_file=[], filter_file=[]):
self.backup = backup
self.banner = banner
self.create = create
@@ -65,6 +67,8 @@ class Settings(DictParser):
self.link_dotfile_default = LinkTypes.get(link_dotfile_default)
self.link_on_import = LinkTypes.get(link_on_import)
self.minversion = minversion
self.func_file = func_file
self.filter_file = filter_file
def _serialize_seq(self, name, dic):
"""serialize attribute 'name' into 'dic'"""
@@ -95,5 +99,7 @@ class Settings(DictParser):
self._serialize_seq(self.key_cmpignore, dic)
self._serialize_seq(self.key_upignore, dic)
self._serialize_seq(self.key_instignore, dic)
self._serialize_seq(self.key_func_file, dic)
self._serialize_seq(self.key_filter_file, dic)
return {self.key_yaml: dic}

View File

@@ -23,10 +23,13 @@ COMMENT_END = '@@#}'
class Templategen:
def __init__(self, base='.', variables={}, debug=False):
def __init__(self, base='.', variables={},
func_file=[], filter_file=[], debug=False):
"""constructor
@base: directory path where to search for templates
@variables: dictionary of variables for templates
@func_file: file path to load functions from
@filter_file: file path to load filters from
@debug: enable debug
"""
self.base = base.rstrip(os.sep)
@@ -49,10 +52,19 @@ class Templategen:
# adding header method
self.env.globals['header'] = self._header
# adding helper methods
self.env.globals['exists'] = jhelpers.exists
self.env.globals['exists_in_path'] = jhelpers.exists_in_path
self.env.globals['basename'] = jhelpers.basename
self.env.globals['dirname'] = jhelpers.dirname
if self.debug:
self.log.dbg('load global functions:')
self._load_funcs_to_dic(jhelpers, self.env.globals)
if func_file:
for f in func_file:
if self.debug:
self.log.dbg('load custom functions from {}'.format(f))
self._load_path_to_dic(f, self.env.globals)
if filter_file:
for f in filter_file:
if self.debug:
self.log.dbg('load custom filters from {}'.format(f))
self._load_path_to_dic(f, self.env.filters)
if self.debug:
self.log.dbg('template additional variables: {}'.format(variables))
@@ -84,6 +96,23 @@ class Templategen:
"""update variables"""
self.env.globals.update(variables)
def _load_path_to_dic(self, path, dic):
mod = utils.get_module_from_path(path)
if not mod:
self.log.warn('cannot load module \"{}\"'.format(path))
return
self._load_funcs_to_dic(mod, dic)
def _load_funcs_to_dic(self, mod, dic):
"""dynamically load functions from module to dic"""
if not mod or not dic:
return
funcs = utils.get_module_functions(mod)
for name, func in funcs:
if self.debug:
self.log.dbg('load function \"{}\"'.format(name))
dic[name] = func
def _header(self, prepend=''):
"""add a comment usually in the header of a dotfile"""
return '{}{}'.format(prepend, utils.header())

View File

@@ -11,6 +11,8 @@ import os
import uuid
import shlex
import fnmatch
import inspect
import importlib
from shutil import rmtree
# local import
@@ -192,3 +194,24 @@ def patch_ignores(ignores, prefix, debug=False):
if debug:
LOG.dbg('ignores after patching: {}'.format(new))
return new
def get_module_functions(mod):
"""return a list of fonction from a module"""
funcs = []
for m in inspect.getmembers(mod):
name, func = m
if not inspect.isfunction(func):
continue
funcs.append((name, func))
return funcs
def get_module_from_path(path):
"""get module from path"""
if not path or not os.path.exists(path):
return None
module_name = os.path.basename(path).rstrip('.py')
loader = importlib.machinery.SourceFileLoader(module_name, path)
mod = loader.load_module()
return mod

112
tests-ng/filter_file.sh Executable file
View File

@@ -0,0 +1,112 @@
#!/usr/bin/env bash
# author: deadc0de6 (https://github.com/deadc0de6)
# Copyright (c) 2017, deadc0de6
#
# test jinja2 filters from filter_file
# 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"
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}"
filter_file=`mktemp`
filter_file2=`mktemp`
# create the config file
cfg="${tmps}/config.yaml"
cat > ${cfg} << _EOF
config:
backup: true
create: true
dotpath: dotfiles
filter_file:
- ${filter_file}
- ${filter_file2}
dotfiles:
f_abc:
dst: ${tmpd}/abc
src: abc
profiles:
p1:
dotfiles:
- f_abc
_EOF
#cat ${cfg}
cat << _EOF > ${filter_file}
def filter1(arg1):
return "filtered"
def filter2(arg1, arg2=''):
return arg2
_EOF
cat << _EOF > ${filter_file2}
def filter3(integer):
return str(int(integer) - 10)
_EOF
# create the dotfile
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
# install
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
## CLEANING
rm -rf ${tmps} ${tmpd} ${filter_file} ${filter_file2}
echo "OK"
exit 0

127
tests-ng/func_file.sh Executable file
View File

@@ -0,0 +1,127 @@
#!/usr/bin/env bash
# author: deadc0de6 (https://github.com/deadc0de6)
# Copyright (c) 2017, deadc0de6
#
# test jinja2 functions from func_file
# 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"
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}"
func_file=`mktemp`
func_file2=`mktemp`
# create the config file
cfg="${tmps}/config.yaml"
cat > ${cfg} << _EOF
config:
backup: true
create: true
dotpath: dotfiles
func_file:
- ${func_file}
- ${func_file2}
dotfiles:
f_abc:
dst: ${tmpd}/abc
src: abc
profiles:
p1:
dotfiles:
- f_abc
_EOF
#cat ${cfg}
cat << _EOF > ${func_file}
def func1(something):
if something:
return True
return False
_EOF
cat << _EOF > ${func_file2}
def func2(inp):
return not inp
_EOF
# create the dotfile
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 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(False) @@%}" >> ${tmps}/dotfiles/abc
echo "yes" >> ${tmps}/dotfiles/abc
echo "{%@@ endif @@%}" >> ${tmps}/dotfiles/abc
# install
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
set +e
grep '^nope$' ${tmpd}/abc >/dev/null && exit 1
set -e
## CLEANING
rm -rf ${tmps} ${tmpd} ${func_file} ${func_file2}
echo "OK"
exit 0

View File

@@ -159,7 +159,7 @@ cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
rm -rf ${tmpd}/abc
## CLEANING
rm -rf ${tmps} ${tmpd} ${scr}
rm -rf ${tmps} ${tmpd}
echo "OK"
exit 0

View File

@@ -137,7 +137,7 @@ grep "dotfile dst filename: `basename ${tmpd}/def`" ${tmpd}/def
grep "dotfile dst dirname: `dirname ${tmpd}/def`" ${tmpd}/def
## CLEANING
rm -rf ${tmps} ${tmpd} ${scr}
rm -rf ${tmps} ${tmpd}
echo "OK"
exit 0

View File

@@ -102,7 +102,7 @@ grep '^dvar4: var1 var2 var3' ${tmpd}/abc >/dev/null
#cat ${tmpd}/abc
## CLEANING
rm -rf ${tmps} ${tmpd} ${scr}
rm -rf ${tmps} ${tmpd}
echo "OK"
exit 0

View File

@@ -215,7 +215,7 @@ cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V
grep '^p1$' ${tmpd}/abc/file1
## CLEANING
rm -rf ${tmps} ${tmpd} ${scr}
rm -rf ${tmps} ${tmpd}
echo "OK"
exit 0