1
0
mirror of https://github.com/deadc0de6/dotdrop.git synced 2026-02-04 14:31:46 +00:00

Merge branch 'master' of github.com:deadc0de6/dotdrop

This commit is contained in:
deadc0de6
2021-01-29 21:45:45 +01:00
12 changed files with 1261 additions and 6 deletions

View File

@@ -169,6 +169,12 @@ Make sure to quote those when using wildcards in the config file.
Patterns used on a specific dotfile can be specified relative to the dotfile destination (`dst`).
Similar to a `.gitignore` file, you can prefix ignore patterns with an exclamation point (`!`).
This so-called "negative ignore pattern" will cause any files that match that pattern to __not__ be ignored,
provided they *would have* been ignored by an earlier ignore pattern (dotdrop will warn if that is not the
case). This feature allows you to, for example, ignore all files within a certain directory, except for one
particular one (see example below).
```yaml
config:
cmpignore:
@@ -216,3 +222,14 @@ config:
- "testdir"
...
```
To ignore all files within a certain directory relative to `dst`, except one called `custom_plugin.zsh`:
```yaml
dotfiles:
d_zsh:
src: zsh
dst: ~/.config/zsh
impignore:
- "plugins/*"
- "!plugins/custom_plugin.zsh"
```

View File

@@ -8,6 +8,7 @@ handle the update of dotfiles
import os
import shutil
import filecmp
import fnmatch
# local imports
from dotdrop.logger import Logger
@@ -283,8 +284,23 @@ class Updater:
continue
if self.debug:
self.log.dbg('cp -r {} {}'.format(exist, new))
# Newly created directory should be copied as is (for efficiency).
shutil.copytree(exist, new)
def ig(src, names):
whitelist, blacklist = set(), set()
for ignore in self.ignores:
for name in names:
path = os.path.join(src, name)
if ignore.startswith('!') and \
fnmatch.fnmatch(path, ignore[1:]):
# add to whitelist
whitelist.add(name)
elif fnmatch.fnmatch(path, ignore):
# add to blacklist
blacklist.add(name)
return blacklist - whitelist
shutil.copytree(exist, new, ignore=ig)
self.log.sub('\"{}\" dir added'.format(new))
# remove dirs that don't exist in deployed version

View File

@@ -13,6 +13,7 @@ import fnmatch
import inspect
import importlib
import filecmp
import itertools
from shutil import rmtree, which
# local import
@@ -203,12 +204,33 @@ def must_ignore(paths, ignores, debug=False):
return False
if debug:
LOG.dbg('must ignore? \"{}\" against {}'.format(paths, ignores))
ignored_negative, ignored = categorize(
lambda ign: ign.startswith('!'), ignores)
for p in paths:
for i in ignores:
ignore_matches = []
# First ignore dotfiles
for i in ignored:
if fnmatch.fnmatch(p, i):
if debug:
LOG.dbg('ignore \"{}\" match: {}'.format(i, p))
return True
ignore_matches.append(p)
# Then remove any matches that actually shouldn't be ignored
for ni in ignored_negative:
# Each of these will start with an '!' so we need to remove that
ni = ni[1:]
if fnmatch.fnmatch(p, ni):
if debug:
LOG.dbg('negative ignore \"{}\" match: {}'.format(ni, p))
try:
ignore_matches.remove(p)
except ValueError:
LOG.warn('no files that are currently being ignored match '
'\"{}\". In order for a negative ignore pattern '
'to work, it must match a file that is being '
'ignored by a previous ignore pattern.'.format(ni)
)
if ignore_matches:
return True
if debug:
LOG.dbg('NOT ignoring {}'.format(paths))
return False
@@ -229,18 +251,31 @@ def patch_ignores(ignores, prefix, debug=False):
if debug:
LOG.dbg('ignores before patching: {}'.format(ignores))
for ignore in ignores:
negative = ignore.startswith('!')
if negative:
ignore = ignore[1:]
if os.path.isabs(ignore):
# is absolute
new.append(ignore)
if negative:
new.append('!' + ignore)
else:
new.append(ignore)
continue
if STAR in ignore:
if ignore.startswith(STAR) or ignore.startswith(os.sep):
# is glob
new.append(ignore)
if negative:
new.append('!' + ignore)
else:
new.append(ignore)
continue
# patch ignore
path = os.path.join(prefix, ignore)
new.append(path)
if negative:
new.append('!' + path)
else:
new.append(path)
if debug:
LOG.dbg('ignores after patching: {}'.format(new))
return new
@@ -352,3 +387,12 @@ def adapt_workers(options, logger):
if options.dry and options.workers > 1:
logger.warn('workers set to 1 when --dry is used')
options.workers = 1
def categorize(function, iterable):
"""separate an iterable into elements for which
function(element) is true for each element and
for which function(element) is false for each
element"""
return (tuple(filter(function, iterable)),
tuple(itertools.filterfalse(function, iterable)))

View File

@@ -0,0 +1,152 @@
#!/usr/bin/env bash
# author: jtt9340 (https://github.com/jtt9340)
#
# test compare negative ignore relative
# returns 1 in case of error
#
# exit on first error
set -e
# all this crap to get current path
if [ $(uname) = Darwin ]; then
# Unfortunately, readlink works differently on macOS than it does on GNU/Linux
# (the -f option behaves differently) and the realpath command does not exist.
# Workarounds I find on the Internet suggest just using Homebrew to install coreutils
# so you can get the GNU coreutils on your Mac. But, I don't want this script to
# assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
# they then installed the GNU coreutils.
readlink() {
TARGET_FILE=$1
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]; do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT
}
rl="readlink"
else
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
fi
cur=$(dirname "$(${rl} "${0}")")
# dotdrop path can be pass as argument
ddpath="${cur}/../"
[ -n "${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
################################################################
# dotdrop directory
basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
echo "[+] dotdrop dir: ${basedir}"
echo "[+] dotpath dir: ${basedir}/dotfiles"
# the dotfile to be imported
tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
# some files
mkdir -p ${tmpd}/program/ignore_me
echo "some data" > ${tmpd}/program/a
echo "some data" > ${tmpd}/program/ignore_me/b
echo "some data" > ${tmpd}/program/ignore_me/c
# create the config file
cfg="${basedir}/config.yaml"
create_conf ${cfg} # sets token
# import
echo "[+] import"
cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
# make some changes to generate a diff
echo "some other data" > ${tmpd}/program/a
echo "some other data" > ${tmpd}/program/ignore_me/b
echo "some other data" > ${tmpd}/program/ignore_me/c
# expects two diffs (no need to test comparing normal - 3 diffs, as that is taken care of in compare-negative-ignore.sh)
patt0="ignore_me/*"
patt1="!ignore_me/c"
echo "[+] comparing with ignore (patterns: ${patt0} and ${patt1}) - 2 diffs"
set +e
cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --ignore=${patt0} --ignore=${patt1}
[ "$?" = "0" ] && exit 1
set -e
########################################
# Test ignores specified in config.yaml
########################################
# add some files
mkdir -p ${tmpd}/.zsh
echo "some data" > ${tmpd}/.zsh/somefile
mkdir -p ${tmpd}/.zsh/plugins
echo "some data" > ${tmpd}/.zsh/plugins/someplugin
echo "[+] import .zsh"
cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/.zsh
touch ${tmpd}/.zsh/plugins/ignore-1.zsh
touch ${tmpd}/.zsh/plugins/ignore-2.zsh
# adding ignore in config.yaml
cfg2="${basedir}/config2.yaml"
sed '/d_zsh:/a\
\ \ \ \ cmpignore:\
\ \ \ \ - "plugins/ignore-?.zsh"\
\ \ \ \ - "!plugins/ignore-2.zsh"
' ${cfg} > ${cfg2}
# expects one diff
patt0="plugins/ignore-?.zsh"
patt1="!plugins/ignore-2.zsh"
echo "[+] comparing with ignore (patterns: ${patt0} and ${patt1}) - 1 diff"
set +e
cd ${ddpath} | ${bin} compare -c ${cfg} --verbose -C ${tmpd}/.zsh --ignore=${patt0} --ignore=${patt1}
[ "$?" = "0" ] && exit 1
set -e
# expects one diff
echo "[+] comparing .zsh with ignore in dotfile - 1 diff expected"
set +e
cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose -C ${tmpd}/.zsh
ret="$?"
echo ${ret}
[ "${ret}" = "0" ] && exit 1
set -e
# clean
rm -rf ${basedir} ${tmpd}
echo "OK"

View File

@@ -0,0 +1,132 @@
#!/usr/bin/env bash
# author: jtt9340 (https://github.com/jtt9340)
#
# test install negative ignore absolute/relative
# returns 1 in case of error
#
# exit on first error
#set -e
# all this crap to get current path
if [ $(uname) = Darwin ]; then
# Unfortunately, readlink works differently on macOS than it does on GNU/Linux
# (the -f option behaves differently) and the realpath command does not exist.
# Workarounds I find on the Internet suggest just using Homebrew to install coreutils
# so you can get the GNU coreutils on your Mac. But, I don't want this script to
# assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
# they then installed the GNU coreutils.
readlink() {
TARGET_FILE=$1
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]; do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT
}
rl="readlink"
else
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
fi
cur=$(dirname "$(${rl} "${0}")")
# dotdrop path can be pass as argument
ddpath="${cur}/../"
[ -n "${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' 2>/dev/null || mktemp -d`
echo "[+] dotdrop dir: ${basedir}"
echo "[+] dotpath dir: ${basedir}/dotfiles"
# the dotfile to be imported
tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
# some files
mkdir -p ${tmpd}/program/ignore_me
echo "some data" > ${tmpd}/program/a
echo "some data" > ${tmpd}/program/ignore_me/b
echo "some data" > ${tmpd}/program/ignore_me/c
# create the config file
cfg="${basedir}/config.yaml"
create_conf ${cfg} # sets token
# import
echo "[+] import"
cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
# make some changes to generate a diff
echo "some other data" > ${tmpd}/program/a
echo "some other data" > ${tmpd}/program/ignore_me/b
echo "some other data" > ${tmpd}/program/ignore_me/c
echo "[+] comparing normal - 3 diffs"
set +e
cd ${ddpath} | ${bin} compare -c ${cfg} --verbose
[ "$?" = 0 ] && exit 1 # We don't want an exit status of 0
set -e
# expects two diffs
patt0="*/ignore_me/*"
patt1="!*/ignore_me/c"
echo "[+] comparing with ignore (patterns: ${patt0} and ${patt1}) - 2 diffs"
set +e
cd ${ddpath} | ${bin} compare -c ${cfg} --verbose --ignore=${patt0} --ignore=${patt1}
[ "$?" = "0" ] && exit 1
set -e
# Adding ignore in dotfile
cfg2="${basedir}/config2.yaml"
sed '/d_program:/a\
\ \ \ \ cmpignore:\
\ \ \ \ - "*/ignore_me/*"\
\ \ \ \ - "!*/ignore_me/c"
' ${cfg} > ${cfg2}
# still expects two diffs
echo "[+] comparing with ignore in dotfile - 2 diffs"
set +e
cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose
[ "$?" = "0" ] && exit 1
set -e
# clean
rm -rf ${basedir} ${tmpd}
echo "OK"
exit 0

View File

@@ -0,0 +1,119 @@
#!/usr/bin/env bash
# author: jtt9340 (https://github.com/jtt9340)
#
# test install cmpignore with negative ignores globally
# returns 1 in case of error
#
# exit on first error
set -e
# all this crap to get current path
if [ $(uname) = Darwin ]; then
# Unfortunately, readlink works differently on macOS than it does on GNU/Linux
# (the -f option behaves differently) and the realpath command does not exist.
# Workarounds I find on the Internet suggest just using Homebrew to install coreutils
# so you can get the GNU coreutils on your Mac. But, I don't want this script to
# assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
# they then installed the GNU coreutils.
readlink() {
TARGET_FILE=$1
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]; do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT
}
rl="readlink"
else
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
fi
cur=$(dirname "$(${rl} "${0}")")
# dotdrop path can be pass as argument
ddpath="${cur}/../"
[ -n "${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
################################################################
# dotdrop directory
basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
echo "[+] dotdrop dir: ${basedir}"
echo "[+] dotpath dir: ${basedir}/dotfiles"
# the dotfile to be imported
tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
# some files
mkdir -p ${tmpd}/{program,config}
touch ${tmpd}/program/a
touch ${tmpd}/config/a
# create the config file
cfg="${basedir}/config.yaml"
create_conf ${cfg} # sets token
# import
echo "[+] import"
cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/config
# add files
echo "[+] add files"
touch ${tmpd}/program/b
touch ${tmpd}/config/b
# adding ignore in dotfile
cfg2="${basedir}/config2.yaml"
sed '/dotpath: dotfiles/a\
\ \ cmpignore:\
\ \ \ \ - "*/config/*"\
\ \ \ \ - "!*/config/a"\
' ${cfg} > ${cfg2}
cat ${cfg2}
# expects one diff
echo "[+] comparing with ignore in dotfile - 1 diff"
set +e
cd ${ddpath} | ${bin} compare -c ${cfg2} --verbose
[ "$?" = "0" ] && exit 1
set -e
## CLEANING
rm -rf ${basedir} ${tmpd}
echo "OK"
exit 0

View File

@@ -0,0 +1,135 @@
#!/usr/bin/env bash
# author: jtt9340 (https://github.com/jtt9340)
#
# test global negative ignore update
# returns 1 in case of error
#
# exit on first error
set -e
# all this crap to get current path
if [ $(uname) = Darwin ]; then
# Unfortunately, readlink works differently on macOS than it does on GNU/Linux
# (the -f option behaves differently) and the realpath command does not exist.
# Workarounds I find on the Internet suggest just using Homebrew to install coreutils
# so you can get the GNU coreutils on your Mac. But, I don't want this script to
# assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
# they then installed the GNU coreutils.
readlink() {
TARGET_FILE=$1
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]; do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT
}
rl="readlink"
else
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
fi
cur=$(dirname "$(${rl} "${0}")")
# dotdrop path can be pass as argument
ddpath="${cur}/../"
[ -n "${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
################################################################
# dotdrop directory
basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
echo "[+] dotdrop dir: ${basedir}"
echo "[+] dotpath dir: ${basedir}/dotfiles"
mkdir -p ${basedir}/dotfiles/a/{b,c}
echo 'a' > ${basedir}/dotfiles/a/b/abfile1
echo 'a' > ${basedir}/dotfiles/a/b/abfile2
echo 'a' > ${basedir}/dotfiles/a/b/abfile3
echo 'a' > ${basedir}/dotfiles/a/c/acfile
# the dotfile to be updated
tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
cp -r ${basedir}/dotfiles/a ${tmpd}/
# create the config file
cfg="${basedir}/config.yaml"
cat > ${cfg} << _EOF
config:
backup: false
create: true
dotpath: dotfiles
upignore:
- "*/newdir/b/*"
- "!*/newdir/b/d"
- "*/abfile?"
- "!*/abfile3"
dotfiles:
f_abc:
dst: ${tmpd}/a
src: a
profiles:
p1:
dotfiles:
- f_abc
_EOF
# edit/add files
echo "[+] edit/add files"
mkdir -p ${tmpd}/a/newdir/b
echo 'b' > ${tmpd}/a/b/abfile1
echo 'b' > ${tmpd}/a/b/abfile2
echo 'b' > ${tmpd}/a/b/abfile3
echo 'b' > ${tmpd}/a/b/abfile4
touch ${tmpd}/a/newdir/b/{c,d}
# update
echo "[+] update"
cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key f_abc
# check files haven't been updated
set +e
grep 'a' ${basedir}/dotfiles/a/b/abfile1 >/dev/null 2>&1 || (echo "abfile1 should not have been updated" && exit 1)
grep 'a' ${basedir}/dotfiles/a/b/abfile2 >/dev/null 2>&1 || (echo "abfile2 should not have been updated" && exit 1)
grep 'b' ${basedir}/dotfiles/a/b/abfile3 >/dev/null 2>&1 || (echo "abfile3 was not updated" && exit 1)
set -e
[ -e ${basedir}/dotfiles/a/b/abfile4 ] && echo "abfile4 should not have been updated" && exit 1
[ -e ${basedir}/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been updated" && exit 1
[ ! -e ${basedir}/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been updated" && exit 1
## CLEANING
rm -rf ${basedir} ${tmpd}
echo "OK"
exit 0

View File

@@ -0,0 +1,116 @@
#!/usr/bin/env bash
# author: jtt9340 (https://github.com/jtt9340)
#
# test negative ignore import
# returns 1 in case of error
#
# exit on first error
set -e
# all this crap to get current path
if [ $(uname) = Darwin ]; then
# Unfortunately, readlink works differently on macOS than it does on GNU/Linux
# (the -f option behaves differently) and the realpath command does not exist.
# Workarounds I find on the Internet suggest just using Homebrew to install coreutils
# so you can get the GNU coreutils on your Mac. But, I don't want this script to
# assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
# they then installed the GNU coreutils.
readlink() {
TARGET_FILE=$1
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]; do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT
}
rl="readlink"
else
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
fi
cur=$(dirname "$(${rl} "${0}")")
# dotdrop path can be pass as argument
ddpath="${cur}/../"
[ -n "${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
basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
mkdir -p ${basedir}/dotfiles
# the dotfile destination
tmpd=`mkdir -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
# dotdrop directory
echo "[+] dotdrop dir: ${basedir}"
echo "[+] dotpath dir: ${basedir}/dotfiles"
mkdir -p ${tmpd}/a/{b,c}
echo 'a' > ${tmpd}/a/b/abfile1
echo 'a' > ${tmpd}/a/b/abfile2
echo 'a' > ${tmpd}/a/b/abfile3
echo 'a' > ${tmpd}/a/c/acfile
mkdir -p ${tmpd}/a/newdir/b
touch ${tmpd}/a/newdir/b/{c,d}
# create the config file
cfg="${basedir}/config.yaml"
cfg2="${basedir}/config2.yaml"
create_conf ${cfg} # sets token
sed '/dotpath: dotfiles/a\
\ \ impignore:\
\ \ \ \ - "*/newdir/b/*"\
\ \ \ \ - "!*/newdir/b/d"\
\ \ \ \ - "*/abfile?"\
\ \ \ \ - "!*/abfile3"
' ${cfg} > ${cfg2}
# import
echo "[+] import"
cd ${ddpath} | ${bin} import -f -c ${cfg2} --verbose --profile=p1 ${tmpd}/a --as=~/a
# check files haven't been imported
[ -e ${basedir}/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been imported" && exit 1
[ ! -e ${basedir}/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been imported" && exit 1
[ -e ${basedir}/dotfiles/a/b/abfile1 ] && echo "abfile1 should not have been imported" && exit 1
[ -e ${basedir}/dotfiles/a/b/abfile2 ] && echo "abfile2 should not have been imported" && exit 1
[ ! -e ${basedir}/dotfiles/a/b/abfile3 ] && echo "abfile3 should have been imported" && exit 1
## CLEANING
rm -rf ${tmpd} ${basedir}
echo "OK"
exit 0

View File

@@ -0,0 +1,126 @@
#!/usr/bin/env bash
# author: jtt9340 (https://github.com/jtt9340)
#
# test install negative ignore absolute/relative
# returns 1 in case of error
#
# exit on first error
set -e
# all this crap to get current path
if [ $(uname) = Darwin ]; then
# Unfortunately, readlink works differently on macOS than it does on GNU/Linux
# (the -f option behaves differently) and the realpath command does not exist.
# Workarounds I find on the Internet suggest just using Homebrew to install coreutils
# so you can get the GNU coreutils on your Mac. But, I don't want this script to
# assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
# they then installed the GNU coreutils.
readlink() {
TARGET_FILE=$1
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]; do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT
}
rl="readlink"
else
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
fi
cur=$(dirname "$(${rl} "${0}")")
# dotdrop path can be pass as argument
ddpath="${cur}/../"
[ -n "${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
################################################################
# dotdrop directory
basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
echo "[+] dotdrop dir: ${basedir}"
echo "[+] dotpath dir: ${basedir}/dotfiles"
# the dotfile to be imported
tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
# some files
mkdir -p ${tmpd}/program/ignore_me
echo "some data" > ${tmpd}/program/a
echo "some data" > ${tmpd}/program/ignore_me/b
echo "some data" > ${tmpd}/program/ignore_me/c
# create the config file
cfg="${basedir}/config.yaml"
create_conf ${cfg} # sets token
# import
echo "[+] import"
cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
# adding ignore in dotfile
cfg2="${basedir}/config2.yaml"
sed '/d_program:/a\
\ \ \ \ instignore:\
\ \ \ \ - "*/ignore_me/*"\
\ \ \ \ - "!*/ignore_me/c"
' ${cfg} > ${cfg2}
# install
rm -rf ${tmpd}
echo "[+] install with negative ignore in dotfile"
cd ${ddpath} | ${bin} install -c ${cfg2} --verbose
[ "$?" != "0" ] && exit 1
echo '(1) expect structure to be
.
└── program
├── a
└── ignore_me
└── c'
[[ -n "$(find ${tmpd}/program -name a)" ]] || exit 1
echo "(1) found program/a ... good"
[[ -n "$(find ${tmpd}/program/ignore_me -name b)" ]] && exit 1
echo "(1) didn't find program/b ... good"
[[ -n "$(find ${tmpd}/program/ignore_me -name c)" ]] || exit 1
echo "(1) found program/c ... good"
## CLEANING
rm -rf ${basedir} ${tmpd}
echo "OK"
exit 0

View File

@@ -0,0 +1,116 @@
#!/usr/bin/env bash
# author: jtt9340 (https://github.com/jtt9340)
#
# test that dotdrop warns when a negative ignore pattern
# does not match a file that would be ignored
# returns 1 in case of error
#
# exit on first error
set -e
# all this crap to get current path
if [ $(uname) = Darwin ]; then
# Unfortunately, readlink works differently on macOS than it does on GNU/Linux
# (the -f option behaves differently) and the realpath command does not exist.
# Workarounds I find on the Internet suggest just using Homebrew to install coreutils
# so you can get the GNU coreutils on your Mac. But, I don't want this script to
# assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
# they then installed the GNU coreutils.
readlink() {
TARGET_FILE=$1
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]; do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT
}
rl="readlink"
else
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
fi
cur=$(dirname "$(${rl} "${0}")")
# dotdrop path can be pass as argument
ddpath="${cur}/../"
[ -n "${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
################################################################
# dotdrop directory
basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
echo "[+] dotdrop dir: ${basedir}"
echo "[+] dotpath dir: ${basedir}/dotfiles"
# the dotfile to be imported
tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
# some files
mkdir -p ${tmpd}/program/ignore_me
echo "some data" > ${tmpd}/program/a
echo "some data" > ${tmpd}/program/ignore_me/b
echo "some data" > ${tmpd}/program/ignore_me/c
# create the config file
cfg="${basedir}/config.yaml"
create_conf ${cfg} # sets token
# import
echo "[+] import"
cd ${ddpath} | ${bin} import -f -c ${cfg} ${tmpd}/program
# adding ignore in dotfile
cfg2="${basedir}/config2.yaml"
sed '/d_program:/a\
\ \ \ \ instignore:\
\ \ \ \ - "!*/ignore_me/c"
' ${cfg} > ${cfg2}
# install
rm -rf ${tmpd}
echo "[+] install with negative ignore in dotfile"
echo '(1) expect dotdrop install to warn when negative ignore pattern does not match an already-ignored file'
patt="[WARN] no files that are currently being ignored match \"*/ignore_me/c\". In order for a negative ignore
pattern to work, it must match a file that is being ignored by a previous ignore pattern."
cd ${ddpath} | ${bin} install -c ${cfg2} --verbose 2>&1 >/dev/null | grep -F "${patt}" ||
(echo "dotdrop did not warn when negative ignore pattern did not match an already-ignored file" && exit 1)
## CLEANING
rm -rf ${basedir} ${tmpd}
echo "OK"
exit 0

View File

@@ -0,0 +1,135 @@
#!/usr/bin/env bash
# author: jtt9340 (https://github.com/jtt9340)
#
# test ignore update negative relative pattern
# returns 1 in case of error
#
# exit on first error
set -e
# all this crap to get current path
if [ $(uname) = Darwin ]; then
# Unfortunately, readlink works differently on macOS than it does on GNU/Linux
# (the -f option behaves differently) and the realpath command does not exist.
# Workarounds I find on the Internet suggest just using Homebrew to install coreutils
# so you can get the GNU coreutils on your Mac. But, I don't want this script to
# assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
# they then installed the GNU coreutils.
readlink() {
TARGET_FILE=$1
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]; do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT
}
rl="readlink"
else
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
fi
cur=$(dirname "$(${rl} "${0}")")
# dotdrop path can be pass as argument
ddpath="${cur}/../"
[ -n "${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
################################################################
# dotdrop directory
basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
echo "[+] dotdrop dir: ${basedir}"
echo "[+] dotpath dir: ${basedir}/dotfiles"
mkdir -p ${basedir}/dotfiles/a/{b,c}
echo 'a' > ${basedir}/dotfiles/a/b/abfile1
echo 'a' > ${basedir}/dotfiles/a/b/abfile2
echo 'a' > ${basedir}/dotfiles/a/b/abfile3
echo 'a' > ${basedir}/dotfiles/a/c/acfile
# the dotfile to be updated
tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
cp -r ${basedir}/dotfiles/a ${tmpd}/
# create the config file
cfg="${basedir}/config.yaml"
cat > ${cfg} << _EOF
config:
backup: false
create: true
dotpath: dotfiles
dotfiles:
f_abc:
dst: ${tmpd}/a
src: a
upignore:
- "newdir/b/*"
- "!newdir/b/d"
- "b/abfile?"
- "!b/abfile3"
profiles:
p1:
dotfiles:
- f_abc
_EOF
# edit/add files
echo "[+] edit/add files"
mkdir -p ${tmpd}/a/newdir/b
echo 'b' > ${tmpd}/a/b/abfile1
echo 'b' > ${tmpd}/a/b/abfile2
echo 'b' > ${tmpd}/a/b/abfile3
echo 'b' > ${tmpd}/a/b/abfile4
touch ${tmpd}/a/newdir/b/{c,d}
# update
echo "[+] update"
cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key f_abc
# check files haven't been updated
set +e
grep a ${basedir}/dotfiles/a/b/abfile1 >/dev/null 2>&1 || (echo "abfile1 should not have been updated" && exit 1)
grep a ${basedir}/dotfiles/a/b/abfile2 >/dev/null 2>&1 || (echo "abfile2 should not have been updated" && exit 1)
grep b ${basedir}/dotfiles/a/b/abfile3 >/dev/null 2>&1 || (echo "abfile3 should have been updated" && exit 1)
set -e
[ -e ${basedir}/dotfiles/a/b/abfile4 ] && echo "abfile4 should not have been updated" && exit 1
[ -e ${basedir}/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been updated" && exit 1
[ ! -e ${basedir}/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been updated" && exit 1
## CLEANING
rm -rf ${basedir} ${tmpd}
echo "OK"
exit 0

View File

@@ -0,0 +1,147 @@
#!/usr/bin/env bash
# author: jtt9340 (https://github.com/jtt9340)
#
# test negative ignore update
# returns 1 in case of error
#
# exit on first error
set -e
# all this crap to get current path
if [ $(uname) = Darwin ]; then
# Unfortunately, readlink works differently on macOS than it does on GNU/Linux
# (the -f option behaves differently) and the realpath command does not exist.
# Workarounds I find on the Internet suggest just using Homebrew to install coreutils
# so you can get the GNU coreutils on your Mac. But, I don't want this script to
# assume (a) users have Homebrew installed and (b) if they have Homebrew installed, that
# they then installed the GNU coreutils.
readlink() {
TARGET_FILE=$1
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]; do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT
}
rl="readlink"
else
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
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}/../"
[ -n "${1}" ] && ddpath="${1}"
[ ! -d ${ddpath} ] && exho "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
################################################################
# $1 pattern
# $2 path
grep_or_fail()
{
set +e
grep "${1}" "${2}" >/dev/null 2>&1 || (echo "pattern not found in ${2}" && exit 1)
set -e
}
# dotdrop directory
basedir=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
echo "[+] dotdrop dir: ${basedir}"
echo "[+] dotpath dir: ${basedir}/dotfiles"
mkdir -p ${basedir}/dotfiles/a/{b,c}
echo 'a' > ${basedir}/dotfiles/a/b/abfile1
echo 'a' > ${basedir}/dotfiles/a/b/abfile2
echo 'a' > ${basedir}/dotfiles/a/b/abfile3
echo 'a' > ${basedir}/dotfiles/a/c/acfile
# the dotfile to be updated
tmpd=`mktemp -d --suffix='-dotdrop-tests' 2>/dev/null || mktemp -d`
cp -r ${basedir}/dotfiles/a ${tmpd}/
# create the config file
cfg="${basedir}/config.yaml"
cat > ${cfg} << _EOF
config:
backup: false
create: true
dotpath: dotfiles
dotfiles:
f_abc:
dst: ${tmpd}/a
src: a
upignore:
- "*/newdir/b/*"
- "!*/newdir/b/d"
- "*/abfile?"
- "!*/abfile3"
profiles:
p1:
dotfiles:
- f_abc
_EOF
# edit/add files
echo "[+] edit/add files"
mkdir -p ${tmpd}/a/newdir/b
echo 'b' > ${tmpd}/a/b/abfile1
echo 'b' > ${tmpd}/a/b/abfile2
echo 'b' > ${tmpd}/a/b/abfile3
echo 'b' > ${tmpd}/a/b/abfile4
touch ${tmpd}/a/newdir/b/{c,d}
# update
echo "[+] update"
cd ${ddpath} | ${bin} update -f -c ${cfg} --verbose --profile=p1 --key f_abc
# check files haven't been updated
grep_or_fail a ${basedir}/dotfiles/a/b/abfile1
grep_or_fail a ${basedir}/dotfiles/a/b/abfile2
grep_or_fail b ${basedir}/dotfiles/a/b/abfile3
[ -e ${basedir}/dotfiles/a/b/abfile4 ] && echo "abfile4 should not have been updated" && exit 1
[ -e ${basedir}/dotfiles/a/newdir/b/c ] && echo "newdir/b/c should not have been updated" && exit 1
[ ! -e ${basedir}/dotfiles/a/newdir/b/d ] && echo "newdir/b/d should have been updated" && exit 1
## CLEANING
rm -rf ${basedir} ${tmpd}
echo "OK"
exit 0