mirror of
https://github.com/deadc0de6/dotdrop.git
synced 2026-03-23 03:45:08 +00:00
adding ability to add custom functions and filters for #200
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}
|
||||
|
||||
@@ -6,7 +6,6 @@ jinja2 template generator
|
||||
"""
|
||||
|
||||
import os
|
||||
import inspect
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
# local imports
|
||||
@@ -24,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)
|
||||
@@ -50,20 +52,22 @@ class Templategen:
|
||||
# adding header method
|
||||
self.env.globals['header'] = self._header
|
||||
# adding helper methods
|
||||
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))
|
||||
|
||||
def _load_funcs_to_dic(self, mod, dic):
|
||||
"""dynamically load functions from module to dic"""
|
||||
for m in inspect.getmembers(mod):
|
||||
name, func = m
|
||||
if not inspect.isfunction(func):
|
||||
continue
|
||||
if self.debug:
|
||||
self.log.dbg('load function \"{}\"'.format(name))
|
||||
dic[name] = func
|
||||
|
||||
def generate(self, src):
|
||||
"""render template from path"""
|
||||
if not os.path.exists(src):
|
||||
@@ -92,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
|
||||
|
||||
Reference in New Issue
Block a user