diff --git a/dotdrop/installer.py b/dotdrop/installer.py index 613955c..9c89132 100644 --- a/dotdrop/installer.py +++ b/dotdrop/installer.py @@ -137,7 +137,8 @@ class Installer: # symlink ret, err = self._link(templater, src, dst, actionexec=actionexec, - is_template=is_template) + is_template=is_template, + ignore=ignore) elif linktype == LinkTypes.LINK_CHILDREN: # symlink direct children if not isdir: @@ -162,7 +163,7 @@ class Installer: # but not when # - error (not r, err) # - aborted (not r, err) - if (ret or (not ret and not err)): + if os.path.exists(dst) and (ret or (not ret and not err)): if not chmod: chmod = utils.get_file_perm(src) dstperms = utils.get_file_perm(dst) @@ -242,7 +243,7 @@ class Installer: ######################################################## def _link(self, templater, src, dst, actionexec=None, - is_template=True): + is_template=True, ignore=None): """ install link:link @@ -259,7 +260,8 @@ class Installer: ret, err = self.install(templater, src, tmp, LinkTypes.NOLINK, actionexec=actionexec, - is_template=is_template) + is_template=is_template, + ignore=ignore) if not ret and not os.path.exists(tmp): return ret, err src = tmp @@ -324,7 +326,8 @@ class Installer: ret2, err2 = self.install(templater, subsrc, tmp, LinkTypes.NOLINK, actionexec=actionexec, - is_template=is_template) + is_template=is_template, + ignore=ignore) if not ret2 and err2 and not os.path.exists(tmp): continue subsrc = tmp @@ -488,11 +491,6 @@ class Installer: # default to nothing installed and no error ret = False, None - # create the directory anyway - if not self._create_dirs(dst): - err = 'creating directory for {}'.format(dst) - return False, err - # handle all files in dir for entry in os.listdir(src): fpath = os.path.join(src, entry) @@ -532,6 +530,7 @@ class Installer: @classmethod def _write_content_to_file(cls, content, src, dst): """write content to file""" + if content: # write content the file try: @@ -680,8 +679,6 @@ class Installer: self.log.dry('would mkdir -p {}'.format(directory)) return True self.log.dbg('mkdir -p {}'.format(directory)) - if not self.comparing: - self.log.sub('create directory {}'.format(directory)) os.makedirs(directory, exist_ok=True) return os.path.exists(directory) diff --git a/tests-ng/actions-empty-dir.sh b/tests-ng/actions-empty-dir.sh new file mode 100755 index 0000000..6e4d8de --- /dev/null +++ b/tests-ng/actions-empty-dir.sh @@ -0,0 +1,190 @@ +#!/usr/bin/env bash +# author: deadc0de6 (https://github.com/deadc0de6) +# Copyright (c) 2017, deadc0de6 +# +# test pre/post/naked actions +# returns 1 in case of error +# + +# exit on first error +set -ev + +# 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" +hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true + +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 action temp +tmpa=`mktemp -d --suffix='-dotdrop-tests' || mktemp -d` +# 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` + +# create the config file +cfg="${tmps}/config.yaml" + +cat > ${cfg} << _EOF +actions: + clearemptydir: find -L '{0}' -empty -xtype d -delete +config: + backup: true + create: true + dotpath: dotfiles +dotfiles: + f_dir1: + dst: ${tmpd}/dir1 + src: dir1 + ignoreempty: true + actions: + - clearemptydir ${tmpd}/dir1 + instignore: + - '*ignore' + f_dir2: + dst: ${tmpd}/dir2 + src: dir2 + link: link_children + ignoreempty: true + actions: + - clearemptydir ${tmpd}/dir2 + instignore: + - '*ignore' + f_dir3: + dst: ${tmpd}/dir3 + src: dir3 + link: link + ignoreempty: true + actions: + - clearemptydir ${tmpd}/dir3 + instignore: + - '*ignore' +profiles: + p1: + dotfiles: + - f_dir1 + - f_dir2 + - f_dir3 +_EOF +#cat ${cfg} + +# create the dotfile +mkdir ${tmps}/dotfiles/dir1 +mkdir ${tmps}/dotfiles/dir1/empty +echo "to-ignore" > ${tmps}/dotfiles/dir1/empty/this.ignore +mkdir ${tmps}/dotfiles/dir1/not-empty +echo "file" > ${tmps}/dotfiles/dir1/not-empty/file +mkdir ${tmps}/dotfiles/dir1/sub +mkdir ${tmps}/dotfiles/dir1/sub/empty +echo "to-ignore-too" > ${tmps}/dotfiles/dir1/sub/empty/that.ignore + +# create the dotfile +mkdir ${tmps}/dotfiles/dir2 +mkdir ${tmps}/dotfiles/dir2/empty +echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir2/empty/this.ignore +mkdir ${tmps}/dotfiles/dir2/not-empty +echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir2/not-empty/file +mkdir ${tmps}/dotfiles/dir2/sub +mkdir ${tmps}/dotfiles/dir2/sub/empty +echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir2/sub/empty/that.ignore + +# create the dotfile +mkdir ${tmps}/dotfiles/dir3 +mkdir ${tmps}/dotfiles/dir3/empty +echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir3/empty/this.ignore +mkdir ${tmps}/dotfiles/dir3/not-empty +echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir3/not-empty/file +mkdir ${tmps}/dotfiles/dir3/sub +mkdir ${tmps}/dotfiles/dir3/sub/empty +echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir3/sub/empty/that.ignore + +# install +cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V + +# checks normal +[ ! -d ${tmpd}/dir1 ] && exit 1 +[ -d ${tmpd}/dir1/empty ] && exit 1 +[ -e ${tmpd}/dir1/empty/this.ignore ] && exit 1 +[ ! -d ${tmpd}/dir1/not-empty ] && exit 1 +[ ! -e ${tmpd}/dir1/not-empty/file ] && exit 1 +[ -d ${tmpd}/dir1/sub ] && exit 1 +[ -d ${tmpd}/dir1/sub/empty ] && exit 1 +[ -e ${tmpd}/dir1/sub/empty/that.ignore ] && exit 1 +grep "file" ${tmpd}/dir1/not-empty/file + +# checks link_children +[ ! -d ${tmpd}/dir2 ] && exit 1 +[ ! -h ${tmpd}/dir2/empty ] && exit 1 +[ -e ${tmpd}/dir2/empty/this.ignore ] && exit 1 +[ ! -d ${tmpd}/dir2/not-empty ] && exit 1 +[ ! -h ${tmpd}/dir2/not-empty ] && exit 1 +[ ! -e ${tmpd}/dir2/not-empty/file ] && exit 1 +[ -d ${tmpd}/dir2/sub ] && exit 1 +[ -d ${tmpd}/dir2/sub/empty ] && exit 1 +[ -e ${tmpd}/dir2/sub/empty/that.ignore ] && exit 1 +grep "p1" ${tmpd}/dir2/not-empty/file + +# checks link +[ ! -d ${tmpd}/dir3 ] && exit 1 +[ ! -h ${tmpd}/dir3 ] && exit 1 +[ -d ${tmpd}/dir3/empty ] && exit 1 +[ -e ${tmpd}/dir3/empty/this.ignore ] && exit 1 +[ ! -d ${tmpd}/dir3/not-empty ] && exit 1 +[ ! -e ${tmpd}/dir3/not-empty/file ] && exit 1 +[ -d ${tmpd}/dir3/sub ] && exit 1 +[ -d ${tmpd}/dir3/sub/empty ] && exit 1 +[ -e ${tmpd}/dir3/sub/empty/that.ignore ] && exit 1 +grep "p1" ${tmpd}/dir3/not-empty/file + +# second install won't trigger the action +cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V # 2>&1 | tee ${tmpa}/log + +# check normal +[ -d ${tmpd}/dir1/empty ] && echo "empty directory not cleaned" && exit 1 +[ -d ${tmpd}/dir1/sub/empty ] && echo "empty directory not cleaned" && exit 1 + +# check link_children +[ -d ${tmpd}/dir2/empty ] && echo "empty directory not cleaned" && exit 1 +[ -d ${tmpd}/dir2/sub/empty ] && echo "empty directory not cleaned" && exit 1 + +# check link +[ -d ${tmpd}/dir3/empty ] && echo "empty directory not cleaned" && exit 1 +[ -d ${tmpd}/dir3/sub/empty ] && echo "empty directory not cleaned" && exit 1 + +## CLEANING +rm -rf ${tmps} ${tmpd} ${tmpa} + +echo "OK" +exit 0 diff --git a/tests-ng/install-link-children.sh b/tests-ng/install-link-children.sh new file mode 100755 index 0000000..fa0d10a --- /dev/null +++ b/tests-ng/install-link-children.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +# author: deadc0de6 (https://github.com/deadc0de6) +# Copyright (c) 2017, deadc0de6 +# +# test link_dotfile_default +# returns 1 in case of error +# + +# exit on first error +set -ev + +# 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" +hash coverage 2>/dev/null && bin="coverage run -a --source=dotdrop -m dotdrop.dotdrop" || true + +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 config file +cfg="${tmps}/config.yaml" + +cat > ${cfg} << _EOF +config: + backup: true + create: true + dotpath: dotfiles + link_dotfile_default: nolink +dotfiles: + d_dir1: + dst: ${tmpd}/dir1 + src: dir1 + link: link_children + instignore: + - '*ignore' +profiles: + p1: + dotfiles: + - d_dir1 +_EOF +#cat ${cfg} + +# create the dotfile +mkdir ${tmps}/dotfiles/dir1 +mkdir ${tmps}/dotfiles/dir1/empty +echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir1/empty/this.ignore +mkdir ${tmps}/dotfiles/dir1/not-empty +echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir1/not-empty/file +mkdir ${tmps}/dotfiles/dir1/sub +mkdir ${tmps}/dotfiles/dir1/sub/empty +echo "{{@@ profile @@}}" > ${tmps}/dotfiles/dir1/sub/empty/that.ignore + +# install +cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -V +#cat ${cfg} + +# check normal +[ ! -d ${tmpd}/dir1 ] && exit 1 +[ -d ${tmpd}/dir1/empty ] && exit 1 +[ -d ${tmpd}/dir1/sub ] && exit 1 +[ -d ${tmpd}/dir1/sub/empty ] && exit 1 +[ ! -d ${tmpd}/dir1/not-empty ] && exit 1 + +[ ! -e ${tmpd}/dir1/not-empty/file ] && exit 1 + +# ignored files +[ -e ${tmpd}/dir1/empty/this.ignore ] && exit 1 +[ -e ${tmpd}/dir1/sub/empty/that.ignore ] && exit 1 + +grep "p1" ${tmpd}/dir1/not-empty/file + +## CLEANING +rm -rf ${tmps} ${tmpd} + +echo "OK" +exit 0 diff --git a/tests-ng/transformations.sh b/tests-ng/transformations.sh index 470e63e..93d18f6 100755 --- a/tests-ng/transformations.sh +++ b/tests-ng/transformations.sh @@ -118,6 +118,8 @@ echo ${tokend} > ${tmpx}/a/somefile echo ${tokend} > ${tmpx}/b/somefile echo ${tokend} > ${tmpx}/c/somefile echo ${tokend} > ${tmpx}/a/dir1/otherfile +# create a fake file to ensure dir is created +echo ${tokend} > ${tmpx}/a/dir2/token tar -cf ${tmps}/dotfiles/ghi -C ${tmpx} . rm -rf ${tmpx} tar -tf ${tmps}/dotfiles/ghi