1
0
mirror of https://github.com/deadc0de6/dotdrop.git synced 2026-02-05 09:08:50 +00:00

add instignore for #195

This commit is contained in:
deadc0de6
2019-11-16 19:28:33 +01:00
parent 2d64e2ee59
commit 1910514981
6 changed files with 166 additions and 17 deletions

View File

@@ -137,9 +137,12 @@ def cmd_install(o):
if not tmp: if not tmp:
continue continue
src = tmp src = tmp
ignores = list(set(o.install_ignore + dotfile.instignore))
ignores = patch_ignores(ignores, dotfile.dst, debug=o.debug)
r, err = inst.install(t, src, dotfile.dst, r, err = inst.install(t, src, dotfile.dst,
actionexec=pre_actions_exec, actionexec=pre_actions_exec,
noempty=dotfile.noempty) noempty=dotfile.noempty,
ignore=ignores)
if tmp: if tmp:
tmp = os.path.join(o.dotpath, tmp) tmp = os.path.join(o.dotpath, tmp)
if os.path.exists(tmp): if os.path.exists(tmp):

View File

@@ -19,8 +19,9 @@ class Dotfile(DictParser):
def __init__(self, key, dst, src, def __init__(self, key, dst, src,
actions=[], trans_r=None, trans_w=None, actions=[], trans_r=None, trans_w=None,
link=LinkTypes.NOLINK, cmpignore=[], link=LinkTypes.NOLINK, noempty=False,
noempty=False, upignore=[]): cmpignore=[], upignore=[],
instignore=[]):
""" """
constructor constructor
@key: dotfile key @key: dotfile key
@@ -30,12 +31,12 @@ class Dotfile(DictParser):
@trans_r: transformation to change dotfile before it is installed @trans_r: transformation to change dotfile before it is installed
@trans_w: transformation to change dotfile before updating it @trans_w: transformation to change dotfile before updating it
@link: link behavior @link: link behavior
@cmpignore: patterns to ignore when comparing
@noempty: ignore empty template if True @noempty: ignore empty template if True
@upignore: patterns to ignore when updating @upignore: patterns to ignore when updating
@cmpignore: patterns to ignore when comparing
@instignore: patterns to ignore when installing
""" """
self.actions = actions self.actions = actions
self.cmpignore = cmpignore
self.dst = dst self.dst = dst
self.key = key self.key = key
self.link = LinkTypes.get(link) self.link = LinkTypes.get(link)
@@ -44,6 +45,8 @@ class Dotfile(DictParser):
self.trans_r = trans_r self.trans_r = trans_r
self.trans_w = trans_w self.trans_w = trans_w
self.upignore = upignore self.upignore = upignore
self.cmpignore = cmpignore
self.instignore = instignore
if self.link != LinkTypes.NOLINK and \ if self.link != LinkTypes.NOLINK and \
( (

View File

@@ -48,7 +48,9 @@ class Installer:
self.action_executed = False self.action_executed = False
self.log = Logger() self.log = Logger()
def install(self, templater, src, dst, actionexec=None, noempty=False): def install(self, templater, src, dst,
actionexec=None, noempty=False,
ignore=[]):
""" """
install src to dst using a template install src to dst using a template
@templater: the templater object @templater: the templater object
@@ -56,6 +58,7 @@ class Installer:
@dst: dotfile destination path in the FS @dst: dotfile destination path in the FS
@actionexec: action executor callback @actionexec: action executor callback
@noempty: render empty template flag @noempty: render empty template flag
@ignore: pattern to ignore when installing
return return
- True, None : success - True, None : success
@@ -83,9 +86,10 @@ class Installer:
if isdir: if isdir:
return self._handle_dir(templater, src, dst, return self._handle_dir(templater, src, dst,
actionexec=actionexec, actionexec=actionexec,
noempty=noempty) noempty=noempty, ignore=ignore)
return self._handle_file(templater, src, dst, return self._handle_file(templater, src, dst,
actionexec=actionexec, noempty=noempty) actionexec=actionexec,
noempty=noempty, ignore=ignore)
def link(self, templater, src, dst, actionexec=None): def link(self, templater, src, dst, actionexec=None):
""" """
@@ -272,11 +276,19 @@ class Installer:
return tmp return tmp
def _handle_file(self, templater, src, dst, def _handle_file(self, templater, src, dst,
actionexec=None, noempty=False): actionexec=None, noempty=False,
ignore=[]):
"""install src to dst when is a file""" """install src to dst when is a file"""
if self.debug: if self.debug:
self.log.dbg('generate template for {}'.format(src)) self.log.dbg('generate template for {}'.format(src))
self.log.dbg('ignore empty: {}'.format(noempty)) self.log.dbg('ignore empty: {}'.format(noempty))
self.log.dbg('ignore pattern: {}'.format(ignore))
if utils.must_ignore([src, dst], ignore, debug=self.debug):
if self.debug:
self.log.dbg('ignoring install of {} to {}'.format(src, dst))
return False, None
if utils.samefile(src, dst): if utils.samefile(src, dst):
# symlink loop # symlink loop
err = 'dotfile points to itself: {}'.format(dst) err = 'dotfile points to itself: {}'.format(dst)
@@ -310,7 +322,9 @@ class Installer:
err = 'installing {} to {}'.format(src, dst) err = 'installing {} to {}'.format(src, dst)
return False, err return False, err
def _handle_dir(self, templater, src, dst, actionexec=None, noempty=False): def _handle_dir(self, templater, src, dst,
actionexec=None, noempty=False,
ignore=[]):
"""install src to dst when is a directory""" """install src to dst when is a directory"""
if self.debug: if self.debug:
self.log.dbg('install dir {}'.format(src)) self.log.dbg('install dir {}'.format(src))
@@ -328,7 +342,8 @@ class Installer:
res, err = self._handle_file(templater, f, res, err = self._handle_file(templater, f,
os.path.join(dst, entry), os.path.join(dst, entry),
actionexec=actionexec, actionexec=actionexec,
noempty=noempty) noempty=noempty,
ignore=ignore)
if not res and err: if not res and err:
# error occured # error occured
ret = res, err ret = res, err
@@ -341,7 +356,8 @@ class Installer:
res, err = self._handle_dir(templater, f, res, err = self._handle_dir(templater, f,
os.path.join(dst, entry), os.path.join(dst, entry),
actionexec=actionexec, actionexec=actionexec,
noempty=noempty) noempty=noempty,
ignore=ignore)
if not res and err: if not res and err:
# error occured # error occured
ret = res, err ret = res, err

View File

@@ -225,6 +225,7 @@ class Options(AttrMonitor):
if a.kind == Action.pre] if a.kind == Action.pre]
self.install_default_actions_post = [a for a in self.default_actions self.install_default_actions_post = [a for a in self.default_actions
if a.kind == Action.post] if a.kind == Action.post]
self.install_ignore = self.instignore
# "compare" specifics # "compare" specifics
self.compare_dopts = self.args['--dopts'] self.compare_dopts = self.args['--dopts']
self.compare_focus = self.args['--file'] self.compare_focus = self.args['--file']

View File

@@ -17,7 +17,6 @@ class Settings(DictParser):
# settings item keys # settings item keys
key_backup = 'backup' key_backup = 'backup'
key_banner = 'banner' key_banner = 'banner'
key_cmpignore = 'cmpignore'
key_create = 'create' key_create = 'create'
key_default_actions = 'default_actions' key_default_actions = 'default_actions'
key_dotpath = 'dotpath' key_dotpath = 'dotpath'
@@ -28,6 +27,8 @@ class Settings(DictParser):
key_link_on_import = 'link_on_import' key_link_on_import = 'link_on_import'
key_showdiff = 'showdiff' key_showdiff = 'showdiff'
key_upignore = 'upignore' key_upignore = 'upignore'
key_cmpignore = 'cmpignore'
key_instignore = 'instignore'
key_workdir = 'workdir' key_workdir = 'workdir'
key_minversion = 'minversion' key_minversion = 'minversion'
@@ -36,18 +37,18 @@ class Settings(DictParser):
key_import_configs = 'import_configs' key_import_configs = 'import_configs'
key_import_variables = 'import_variables' key_import_variables = 'import_variables'
def __init__(self, backup=True, banner=True, cmpignore=[], def __init__(self, backup=True, banner=True,
create=True, default_actions=[], dotpath='dotfiles', create=True, default_actions=[], dotpath='dotfiles',
ignoreempty=True, import_actions=[], import_configs=[], ignoreempty=True, import_actions=[], import_configs=[],
import_variables=[], keepdot=False, import_variables=[], keepdot=False,
link_dotfile_default=LinkTypes.NOLINK, link_dotfile_default=LinkTypes.NOLINK,
link_on_import=LinkTypes.NOLINK, longkey=False, link_on_import=LinkTypes.NOLINK, longkey=False,
showdiff=False, upignore=[], workdir='~/.config/dotdrop', upignore=[], cmpignore=[], instignore=[],
workdir='~/.config/dotdrop', showdiff=False,
minversion=None): minversion=None):
self.backup = backup self.backup = backup
self.banner = banner self.banner = banner
self.create = create self.create = create
self.cmpignore = cmpignore
self.default_actions = default_actions self.default_actions = default_actions
self.dotpath = dotpath self.dotpath = dotpath
self.ignoreempty = ignoreempty self.ignoreempty = ignoreempty
@@ -58,6 +59,8 @@ class Settings(DictParser):
self.longkey = longkey self.longkey = longkey
self.showdiff = showdiff self.showdiff = showdiff
self.upignore = upignore self.upignore = upignore
self.cmpignore = cmpignore
self.instignore = instignore
self.workdir = workdir self.workdir = workdir
self.link_dotfile_default = LinkTypes.get(link_dotfile_default) self.link_dotfile_default = LinkTypes.get(link_dotfile_default)
self.link_on_import = LinkTypes.get(link_on_import) self.link_on_import = LinkTypes.get(link_on_import)
@@ -85,11 +88,12 @@ class Settings(DictParser):
self.key_workdir: self.workdir, self.key_workdir: self.workdir,
self.key_minversion: self.minversion, self.key_minversion: self.minversion,
} }
self._serialize_seq(self.key_cmpignore, dic)
self._serialize_seq(self.key_default_actions, dic) self._serialize_seq(self.key_default_actions, dic)
self._serialize_seq(self.key_import_actions, dic) self._serialize_seq(self.key_import_actions, dic)
self._serialize_seq(self.key_import_configs, dic) self._serialize_seq(self.key_import_configs, dic)
self._serialize_seq(self.key_import_variables, dic) self._serialize_seq(self.key_import_variables, dic)
self._serialize_seq(self.key_cmpignore, dic)
self._serialize_seq(self.key_upignore, dic) self._serialize_seq(self.key_upignore, dic)
self._serialize_seq(self.key_instignore, dic)
return {self.key_yaml: dic} return {self.key_yaml: dic}

122
tests-ng/install-ignore.sh Executable file
View File

@@ -0,0 +1,122 @@
#!/usr/bin/env bash
# author: deadc0de6 (https://github.com/deadc0de6)
# Copyright (c) 2019, deadc0de6
#
# test install ignore absolute/relative
# 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
################################################################
# dotdrop directory
basedir=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
echo "[+] dotdrop dir: ${basedir}"
echo "[+] dotpath dir: ${basedir}/dotfiles"
# the dotfile to be imported
tmpd=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d`
# some files
mkdir -p ${tmpd}/{program,config,vscode}
echo "some data" > ${tmpd}/program/a
echo "some data" > ${tmpd}/config/a
echo "some data" > ${tmpd}/vscode/extensions.txt
echo "some data" > ${tmpd}/vscode/keybindings.json
# create the config file
cfg="${basedir}/config.yaml"
create_conf ${cfg} # sets token
# import
echo "[+] import"
cd ${ddpath} | ${bin} import -c ${cfg} ${tmpd}/program
cd ${ddpath} | ${bin} import -c ${cfg} ${tmpd}/config
cd ${ddpath} | ${bin} import -c ${cfg} ${tmpd}/vscode
# add files on filesystem
echo "[+] add files"
echo "new data" > ${basedir}/dotfiles/${tmpd}/README.md
echo "new data" > ${basedir}/dotfiles/${tmpd}/vscode/README.md
echo "new data" > ${basedir}/dotfiles/${tmpd}/program/README.md
mkdir -p ${basedir}/dotfiles/${tmpd}/readmes
echo "new data" > ${basedir}/dotfiles/${tmpd}/readmes/README.md
# install
rm -rf ${tmpd}
echo "[+] install normal"
cd ${ddpath} | ${bin} install -c ${cfg} --verbose
[ "$?" != "0" ] && exit 1
nb=`find ${tmpd} -iname 'README.md' | wc -l`
echo "(1) found ${nb} README.md file(s)"
[ "${nb}" != "2" ] && exit 1
# adding ignore in dotfile
cfg2="${basedir}/config2.yaml"
sed '/d_program:/a \ \ \ \ instignore:\n\ \ \ \ - "README.md"' ${cfg} > ${cfg2}
cat ${cfg2}
# install
rm -rf ${tmpd}
echo "[+] install with ignore in dotfile"
cd ${ddpath} | ${bin} install -c ${cfg2} --verbose
[ "$?" != "0" ] && exit 1
nb=`find ${tmpd} -iname 'README.md' | wc -l`
echo "(2) found ${nb} README.md file(s)"
[ "${nb}" != "1" ] && exit 1
# adding ignore in config
cfg2="${basedir}/config2.yaml"
sed '/^config:/a \ \ instignore:\n\ \ - "README.md"' ${cfg} > ${cfg2}
cat ${cfg2}
# install
rm -rf ${tmpd}
echo "[+] install with ignore in config"
cd ${ddpath} | ${bin} install -c ${cfg2} --verbose
[ "$?" != "0" ] && exit 1
nb=`find ${tmpd} -iname 'README.md' | wc -l`
echo "(3) found ${nb} README.md file(s)"
[ "${nb}" != "0" ] && exit 1
## CLEANING
rm -rf ${basedir} ${tmpd}
echo "OK"
exit 0