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:
@@ -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,
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
112
tests-ng/filter_file.sh
Executable 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
127
tests-ng/func_file.sh
Executable 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user