Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 418 #419

Merged
merged 10 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions dotdrop/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,15 +249,19 @@
if not os.path.isdir(in_fs):
# is a file
self.log.dbg(f'{in_fs} is file')
copyfile(in_fs, srcf, debug=self.debug)
if not copyfile(in_fs, srcf, debug=self.debug):
self.log.err(f'importing \"{in_fs}\" failed')
return False

Check warning on line 254 in dotdrop/importer.py

View check run for this annotation

Codecov / codecov/patch

dotdrop/importer.py#L253-L254

Added lines #L253 - L254 were not covered by tests
else:
# is a dir
if os.path.exists(srcf):
shutil.rmtree(srcf)
self.log.dbg(f'{in_fs} is dir')
copytree_with_ign(in_fs, srcf,
ignore_func=self._ignore,
debug=self.debug)
if not copytree_with_ign(in_fs, srcf,
ignore_func=self._ignore,
debug=self.debug):
self.log.err(f'importing \"{in_fs}\" failed')
return False
except shutil.Error as exc:
in_dotpath = exc.args[0][0][0]
why = exc.args[0][0][2]
Expand Down
14 changes: 10 additions & 4 deletions dotdrop/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,8 @@

# remove symlink
if self.backup and not os.path.isdir(dst):
self._backup(dst)
if not self._backup(dst):
return False, f'could not backup {dst}'

Check warning on line 488 in dotdrop/installer.py

View check run for this annotation

Codecov / codecov/patch

dotdrop/installer.py#L488

Added line #L488 was not covered by tests
overwrite = True
try:
removepath(dst)
Expand Down Expand Up @@ -770,7 +771,8 @@
overwrite = True

if self.backup:
self._backup(dst)
if not self._backup(dst):
return False, f'could not backup {dst}'

Check warning on line 775 in dotdrop/installer.py

View check run for this annotation

Codecov / codecov/patch

dotdrop/installer.py#L775

Added line #L775 was not covered by tests
else:
self.log.dbg(f'file does not exist on filesystem: {dst}')

Expand Down Expand Up @@ -869,16 +871,20 @@
def _backup(self, path):
"""backup file pointed by path"""
if self.dry:
return
return True

Check warning on line 874 in dotdrop/installer.py

View check run for this annotation

Codecov / codecov/patch

dotdrop/installer.py#L874

Added line #L874 was not covered by tests
dst = path.rstrip(os.sep) + self.backup_suffix
self.log.log(f'backup {path} to {dst}')
# os.rename(path, dst)
# copy to preserve mode on chmod=preserve
# since we expect dotfiles this shouldn't have
# such a big impact but who knows.
copyfile(path, dst, debug=self.debug)
if not copyfile(path, dst, debug=self.debug):
return False

Check warning on line 882 in dotdrop/installer.py

View check run for this annotation

Codecov / codecov/patch

dotdrop/installer.py#L882

Added line #L882 was not covered by tests
if not os.path.exists(dst):
return False

Check warning on line 884 in dotdrop/installer.py

View check run for this annotation

Codecov / codecov/patch

dotdrop/installer.py#L884

Added line #L884 was not covered by tests
stat = os.stat(path)
os.chown(dst, stat.st_uid, stat.st_gid)
return True

def _exec_pre_actions(self, actionexec):
"""execute action executor"""
Expand Down
10 changes: 6 additions & 4 deletions dotdrop/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,16 +287,18 @@ def _merge_dirs_create_left_only(self, diff, left, right,
self.log.dry(f'would cp -r {exist} {new}')
continue
self.log.dbg(f'cp -r {exist} {new}')
cpied_cnt = 0
try:
ign_func = self._ignore(ignores)
copytree_with_ign(exist, new,
ignore_func=ign_func,
debug=self.debug)
cpied_cnt = copytree_with_ign(exist, new,
ignore_func=ign_func,
debug=self.debug)
except OSError as exc:
msg = f'error copying dir {exist}'
self.log.err(f'{msg}: {exc}')
continue
self.log.sub(f'\"{new}\" dir added')
if cpied_cnt:
self.log.sub(f'\"{new}\" dir added')

def _ignore(self, ignores):
def ignore_func(path):
Expand Down
33 changes: 25 additions & 8 deletions dotdrop/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,15 +303,18 @@


def _cp(src, dst, ignore_func=None, debug=False):
"""the copy function for copytree"""
"""
the copy function for copytree
returns the numb of files copied
"""
if ignore_func and ignore_func(src):
return
return 0

Check warning on line 311 in dotdrop/utils.py

View check run for this annotation

Codecov / codecov/patch

dotdrop/utils.py#L311

Added line #L311 was not covered by tests
if not os.path.isfile(src):
# ignore special files
if debug:
LOG.dbg(f'ignore special file \"{src}\"',
force=True)
return
return 0
dstdir = os.path.dirname(dst)
if debug:
LOG.dbg(f'mkdir \"{dstdir}\"',
Expand All @@ -320,21 +323,29 @@
if debug:
LOG.dbg(f'cp {src} {dst}',
force=True)
shutil.copy2(src, dst)
path = shutil.copy2(src, dst)
if os.path.exists(path):
return 1
return 0

Check warning on line 329 in dotdrop/utils.py

View check run for this annotation

Codecov / codecov/patch

dotdrop/utils.py#L329

Added line #L329 was not covered by tests


def copyfile(src, dst, debug=False):
"""
copy file from src to dst
no dir expected!
returns True if file was copied
"""
_cp(src, dst, debug=debug)
return _cp(src, dst, debug=debug) == 1


def copytree_with_ign(src, dst, ignore_func=None, debug=False):
"""copytree with support for ignore"""
"""
copytree with support for ignore
returns the numb of files installed
"""
if debug:
LOG.dbg(f'copytree \"{src}\" to \"{dst}\"', force=True)
copied_count = 0
for entry in os.listdir(src):
srcf = os.path.join(src, entry)
dstf = os.path.join(dst, entry)
Expand All @@ -346,12 +357,18 @@
LOG.dbg(f'mkdir \"{dstf}\"',
force=True)
os.makedirs(dstf, exist_ok=True)
copytree_with_ign(srcf, dstf, ignore_func=ignore_func)
copied_count += copytree_with_ign(srcf,
dstf,
ignore_func=ignore_func)
else:
if debug:
LOG.dbg(f'copytree, copy file \"{src}\" to \"{dst}\"',
force=True)
_cp(srcf, dstf, ignore_func=ignore_func, debug=debug)
copied_count += _cp(srcf,
dstf,
ignore_func=ignore_func,
debug=debug)
return copied_count


def uniq_list(a_list):
Expand Down
15 changes: 10 additions & 5 deletions scripts/check-doc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ if ! which remark >/dev/null 2>&1; then
exit 1
fi

echo "------------------------"
echo "checking internal links"
find . -type f -iname '*.md' | while read -r line; do
remark -f -u validate-links "${line}"
done
in_cicd="${GH_WORKFLOW:-}"
if [ -n "${in_cicd}" ]; then
echo "------------------------"
echo "checking internal links"
find . -type f -iname '*.md' | while read -r line; do
remark -f -u validate-links "${line}"
done
else
echo "not checking internal links..."
fi

echo "documentation OK"
1 change: 1 addition & 0 deletions scripts/check_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
]
IGNORES = [
'badgen.net',
'coveralls.io',
]
OK_WHEN_FORBIDDEN = [
'linux.die.net'
Expand Down
51 changes: 42 additions & 9 deletions tests-ng/update-ignore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,45 @@ tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
dt="${tmps}/dotfiles"
mkdir -p "${dt}"
clear_on_exit "${tmps}"
clear_on_exit "${tmpd}"

# dotfiles in dotdrop
# "a" dotfiles in dotdrop
mkdir -p "${dt}"/a/{b,c,x}
echo 'a' > "${dt}"/a/b/abfile
echo 'a' > "${dt}"/a/c/acfile
echo 'a' > "${dt}"/a/x/xfile

# "dir" dotfiles in dotdrop
mkdir -p "${dt}"/dir/{a,b,c}
echo 'a' > "${dt}"/dir/a/a
echo 'b' > "${dt}"/dir/b/b
echo 'c' > "${dt}"/dir/c/c

# create destinations
cp -r "${dt}"/a "${tmpd}"/
cp -r "${dt}"/dir "${tmpd}"/

# update "a" dotdrop files
mkdir -p "${dt}"/a/be-gone
echo 'a' > "${dt}"/a/be-gone/file

# filesystem files
# update "a" filesystem files
touch "${tmpd}"/a/newfile
echo 'b' > "${tmpd}"/a/c/acfile
mkdir -p "${tmpd}"/a/newdir/b
touch "${tmpd}"/a/newdir/b/c
mkdir -p "${tmpd}"/a/x
echo "b" > "${tmpd}"/a/x/xfile
echo "c" > "${tmpd}"/a/x/yfile

clear_on_exit "${tmps}"
clear_on_exit "${tmpd}"
# update "dir" filesystem
echo "new" > "${tmpd}"/dir/a/a
mkdir -p "${dt}"/dir/a/be-gone
touch "${tmpd}"/dir/newfile
mkdir -p "${tmpd}"/dir/ignore
echo "ignore-me" > "${tmpd}"/dir/ignore/ignore-me
echo 'ignore-me' > "${tmpd}"/dir/ignore-file

# create the config file
cfg="${tmps}/config.yaml"
Expand All @@ -78,22 +95,38 @@ dotfiles:
- "*/cfile"
- "*/newfile"
- "*/newdir"
- "*/x/**"
- "*/x/*"
d_dir:
dst: ${tmpd}/dir
src: dir
upignore:
- "*/ignore/*"
- "*/ignore-file"
profiles:
p1:
dotfiles:
- f_abc
- d_dir
_EOF

# update
echo "[+] update"
cd "${ddpath}" | ${bin} update -f -c "${cfg}" --verbose --profile=p1 --key f_abc
cd "${ddpath}" | ${bin} update -f --verbose -c "${cfg}" --profile=p1

# check files haven't been updated
# check "a" files are correct
grep_or_fail 'b' "${dt}/a/c/acfile"
grep_or_fail 'a' "${dt}/a/x/xfile"
[ -e "${dt}"/a/newfile ] && echo "should not have been updated" && exit 1
[ -d "${dt}"/a/be-gone ] && echo "should have been removed" && exit 1
[ -e "${dt}"/a/newfile ] && echo "'a' newfile should have been removed" && exit 1
[ -d "${dt}"/a/be-gone ] && echo "'a' be-gone should have been removed" && exit 1
[ -e "${dt}"/x/yfile ] && echo "'a' yfile should not have been added" && exit 1

# check "dir" files are correct
grep_or_fail 'new' "${dt}"/dir/a/a
[ -d "${dt}"/dir/a/be-gone ] && echo "'dir' be-gone should have been removed" && exit 1
[ ! -e "${tmpd}"/dir/newfile ] && echo "'dir' newfile should have been removed" && exit 1
[ -d "${dt}"/dir/ignore ] && echo "'dir' ignore dir not ignored" && exit 1
[ -f "${dt}"/dir/ignore/ignore-me ] && echo "'dir' ignore-me not ignored" && exit 1
[ -f "${dt}"/dir/ignore-file ] && echo "'dir' ignore-file not ignored" && exit 1

echo "OK"
exit 0