mirror of
https://github.com/deadc0de6/dotdrop.git
synced 2026-02-15 18:30:05 +00:00
improve comparison
This commit is contained in:
@@ -40,9 +40,27 @@ class Comparator:
|
|||||||
ignore = []
|
ignore = []
|
||||||
local_path = os.path.expanduser(local_path)
|
local_path = os.path.expanduser(local_path)
|
||||||
deployed_path = os.path.expanduser(deployed_path)
|
deployed_path = os.path.expanduser(deployed_path)
|
||||||
|
|
||||||
self.log.dbg(f'comparing \"{local_path}\" and \"{deployed_path}\"')
|
self.log.dbg(f'comparing \"{local_path}\" and \"{deployed_path}\"')
|
||||||
self.log.dbg(f'ignore pattern(s): {ignore}')
|
self.log.dbg(f'ignore pattern(s): {ignore}')
|
||||||
|
|
||||||
|
return self._compare(local_path, deployed_path,
|
||||||
|
ignore=ignore, mode=mode,
|
||||||
|
recurse=True)
|
||||||
|
|
||||||
|
def _compare(self, local_path, deployed_path,
|
||||||
|
ignore=None, mode=None,
|
||||||
|
recurse=False):
|
||||||
|
if not ignore:
|
||||||
|
ignore = []
|
||||||
|
|
||||||
|
# test existence
|
||||||
|
if not os.path.exists(local_path):
|
||||||
|
return f'=> \"{local_path}\" does not exist on destination\n'
|
||||||
|
if not self.ignore_missing_in_dotdrop:
|
||||||
|
if not os.path.exists(deployed_path):
|
||||||
|
return f'=> \"{deployed_path}\" does not exist in dotdrop\n'
|
||||||
|
|
||||||
# test type of file
|
# test type of file
|
||||||
if os.path.isdir(local_path) and not os.path.isdir(deployed_path):
|
if os.path.isdir(local_path) and not os.path.isdir(deployed_path):
|
||||||
ret = f'\"{local_path}\" is a dir'
|
ret = f'\"{local_path}\" is a dir'
|
||||||
@@ -53,7 +71,7 @@ class Comparator:
|
|||||||
ret += f' while \"{deployed_path}\" is a dir\n'
|
ret += f' while \"{deployed_path}\" is a dir\n'
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# test content
|
# is a file
|
||||||
if not os.path.isdir(local_path):
|
if not os.path.isdir(local_path):
|
||||||
self.log.dbg(f'{local_path} is a file')
|
self.log.dbg(f'{local_path} is a file')
|
||||||
ret = self._comp_file(local_path, deployed_path, ignore)
|
ret = self._comp_file(local_path, deployed_path, ignore)
|
||||||
@@ -61,9 +79,11 @@ class Comparator:
|
|||||||
ret = self._comp_mode(local_path, deployed_path, mode=mode)
|
ret = self._comp_mode(local_path, deployed_path, mode=mode)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
# is a directory
|
||||||
self.log.dbg(f'\"{local_path}\" is a directory')
|
self.log.dbg(f'\"{local_path}\" is a directory')
|
||||||
|
ret = ''
|
||||||
ret = self._comp_dir(local_path, deployed_path, ignore)
|
if recurse:
|
||||||
|
ret = self._comp_dir(local_path, deployed_path, ignore)
|
||||||
if not ret:
|
if not ret:
|
||||||
ret = self._comp_mode(local_path, deployed_path, mode=mode)
|
ret = self._comp_mode(local_path, deployed_path, mode=mode)
|
||||||
return ret
|
return ret
|
||||||
@@ -95,7 +115,7 @@ class Comparator:
|
|||||||
debug=self.debug):
|
debug=self.debug):
|
||||||
self.log.dbg(f'ignoring diff {local_path} and {deployed_path}')
|
self.log.dbg(f'ignoring diff {local_path} and {deployed_path}')
|
||||||
return ''
|
return ''
|
||||||
return self._diff(local_path, deployed_path)
|
return self._diff(local_path, deployed_path, header=True)
|
||||||
|
|
||||||
def _comp_dir(self, local_path, deployed_path, ignore):
|
def _comp_dir(self, local_path, deployed_path, ignore):
|
||||||
"""compare a directory"""
|
"""compare a directory"""
|
||||||
@@ -114,7 +134,7 @@ class Comparator:
|
|||||||
if not os.path.isdir(deployed_path):
|
if not os.path.isdir(deployed_path):
|
||||||
return f'\"{deployed_path}\" is a file\n'
|
return f'\"{deployed_path}\" is a file\n'
|
||||||
|
|
||||||
# return self._compare_dirs(local_path, deployed_path, ignore)
|
#return self._compare_dirs(local_path, deployed_path, ignore)
|
||||||
return self._compare_dirs2(local_path, deployed_path, ignore)
|
return self._compare_dirs2(local_path, deployed_path, ignore)
|
||||||
|
|
||||||
def _compare_dirs2(self, local_path, deployed_path, ignore):
|
def _compare_dirs2(self, local_path, deployed_path, ignore):
|
||||||
@@ -126,11 +146,13 @@ class Comparator:
|
|||||||
deploy_tree = FTreeDir(deployed_path, ignores=ignore, debug=self.debug)
|
deploy_tree = FTreeDir(deployed_path, ignores=ignore, debug=self.debug)
|
||||||
lonly, ronly, common = local_tree.compare(deploy_tree)
|
lonly, ronly, common = local_tree.compare(deploy_tree)
|
||||||
|
|
||||||
|
for i in lonly:
|
||||||
|
path = os.path.join(local_path, i)
|
||||||
|
ret.append(f'=> \"{path}\" does not exist on destination\n')
|
||||||
if not self.ignore_missing_in_dotdrop:
|
if not self.ignore_missing_in_dotdrop:
|
||||||
for i in lonly:
|
for i in ronly:
|
||||||
ret.append(f'=> \"{i}\" does not exist on destination\n')
|
path = os.path.join(deployed_path, i)
|
||||||
for i in ronly:
|
ret.append(f'=> \"{path}\" does not exist in dotdrop\n')
|
||||||
ret.append(f'=> \"{i}\" does not exist in dotdrop\n')
|
|
||||||
|
|
||||||
# test for content difference
|
# test for content difference
|
||||||
# and mode difference
|
# and mode difference
|
||||||
@@ -138,14 +160,10 @@ class Comparator:
|
|||||||
for i in common:
|
for i in common:
|
||||||
source_file = os.path.join(local_path, i)
|
source_file = os.path.join(local_path, i)
|
||||||
deployed_file = os.path.join(deployed_path, i)
|
deployed_file = os.path.join(deployed_path, i)
|
||||||
diff = self._diff(source_file, deployed_file, header=True)
|
subret = self._compare(source_file, deployed_file,
|
||||||
if diff:
|
ignore=None, mode=None,
|
||||||
ret.append(diff)
|
recurse=False)
|
||||||
continue
|
ret.extend(subret)
|
||||||
ret = self._comp_mode(local_path, deployed_path)
|
|
||||||
if ret:
|
|
||||||
short = os.path.basename(source_file)
|
|
||||||
ret.append(f'=> different type: \"{short}\"\n')
|
|
||||||
|
|
||||||
return ''.join(ret)
|
return ''.join(ret)
|
||||||
|
|
||||||
@@ -230,7 +248,7 @@ class Comparator:
|
|||||||
"""diff two files"""
|
"""diff two files"""
|
||||||
out = diff(modified=local_path, original=deployed_path,
|
out = diff(modified=local_path, original=deployed_path,
|
||||||
diff_cmd=self.diff_cmd, debug=self.debug)
|
diff_cmd=self.diff_cmd, debug=self.debug)
|
||||||
if header:
|
if header and out:
|
||||||
lshort = os.path.basename(local_path)
|
lshort = os.path.basename(local_path)
|
||||||
out = f'=> diff \"{lshort}\":\n{out}'
|
out = f'=> diff \"{lshort}\":\n{out}'
|
||||||
return out
|
return out
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ from dotdrop.utils import must_ignore
|
|||||||
|
|
||||||
|
|
||||||
class FTreeDir:
|
class FTreeDir:
|
||||||
"""directory tree for comparison"""
|
"""
|
||||||
|
directory tree for comparison
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, path, ignores=None, debug=False):
|
def __init__(self, path, ignores=None, debug=False):
|
||||||
self.path = path
|
self.path = path
|
||||||
@@ -24,14 +26,27 @@ class FTreeDir:
|
|||||||
self._walk()
|
self._walk()
|
||||||
|
|
||||||
def _walk(self):
|
def _walk(self):
|
||||||
for root, _, files in os.walk(self.path):
|
"""
|
||||||
|
index directory
|
||||||
|
ignore empty directory
|
||||||
|
test for ignore pattern
|
||||||
|
"""
|
||||||
|
for root, dirs, files in os.walk(self.path):
|
||||||
for file in files:
|
for file in files:
|
||||||
fpath = os.path.join(root, file)
|
fpath = os.path.join(root, file)
|
||||||
if must_ignore([fpath], ignores=self.ignores,
|
if must_ignore([fpath], ignores=self.ignores,
|
||||||
debug=self.debug):
|
debug=self.debug):
|
||||||
continue
|
continue
|
||||||
self.entries.append(fpath)
|
self.entries.append(fpath)
|
||||||
self.entries.sort()
|
for dname in dirs:
|
||||||
|
dpath = os.path.join(root, dname)
|
||||||
|
if len(os.listdir(dpath)) < 1:
|
||||||
|
# ignore empty directory
|
||||||
|
continue
|
||||||
|
if must_ignore([dpath], ignores=self.ignores,
|
||||||
|
debug=self.debug):
|
||||||
|
continue
|
||||||
|
self.entries.append(dpath)
|
||||||
|
|
||||||
def compare(self, other):
|
def compare(self, other):
|
||||||
"""
|
"""
|
||||||
@@ -39,8 +54,11 @@ class FTreeDir:
|
|||||||
- left_only (only in self)
|
- left_only (only in self)
|
||||||
- right_only (only in other)
|
- right_only (only in other)
|
||||||
- in_both (in both)
|
- in_both (in both)
|
||||||
|
the relative path are returned
|
||||||
"""
|
"""
|
||||||
left_only = set(self.entries) - set(other.entries)
|
left = [os.path.relpath(entry, self.path) for entry in self.entries]
|
||||||
right_only = set(other.entries) - set(self.entries)
|
right = [os.path.relpath(entry, other.path) for entry in other.entries]
|
||||||
in_both = set(self.entries) & set(other.entries)
|
left_only = set(left) - set(right)
|
||||||
|
right_only = set(right) - set(left)
|
||||||
|
in_both = set(left) & set(right)
|
||||||
return list(left_only), list(right_only), list(in_both)
|
return list(left_only), list(right_only), list(in_both)
|
||||||
|
|||||||
2
tests-ng/chmod-compare.sh
vendored
2
tests-ng/chmod-compare.sh
vendored
@@ -92,6 +92,7 @@ _EOF
|
|||||||
cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1
|
cd "${ddpath}" | ${bin} install -f -c "${cfg}" -p p1
|
||||||
|
|
||||||
# compare
|
# compare
|
||||||
|
echo "compare after install..."
|
||||||
cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1
|
cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1
|
||||||
|
|
||||||
# import
|
# import
|
||||||
@@ -109,6 +110,7 @@ chmod 700 "${fnormal}"
|
|||||||
chmod 700 "${flink}"
|
chmod 700 "${flink}"
|
||||||
|
|
||||||
set +e
|
set +e
|
||||||
|
cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 -V
|
||||||
out=$(cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 2>&1)
|
out=$(cd "${ddpath}" | ${bin} compare -c "${cfg}" -p p1 2>&1)
|
||||||
cnt=$(echo "${out}" | grep 'modes differ' | wc -l)
|
cnt=$(echo "${out}" | grep 'modes differ' | wc -l)
|
||||||
set -e
|
set -e
|
||||||
|
|||||||
7
tests-ng/compare-negative-ignore-relative.sh
vendored
7
tests-ng/compare-negative-ignore-relative.sh
vendored
@@ -66,8 +66,7 @@ cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose --ignore="${patt0}" --igno
|
|||||||
[ "$?" = "0" ] && exit 1
|
[ "$?" = "0" ] && exit 1
|
||||||
cnt=$(cd "${ddpath}" | ${bin} compare -c "${cfg}" --ignore="${patt0}" --ignore=${patt1} | grep '^=> diff' | wc -l)
|
cnt=$(cd "${ddpath}" | ${bin} compare -c "${cfg}" --ignore="${patt0}" --ignore=${patt1} | grep '^=> diff' | wc -l)
|
||||||
set -e
|
set -e
|
||||||
|
[ "${cnt}" != "2" ] && echo "bad number of diffs (1): ${cnt}/2" && exit 1
|
||||||
[ "${cnt}" != "2" ] && echo "bad number of diffs: ${cnt}/2" && exit 1
|
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Test ignores specified in config.yaml
|
# Test ignores specified in config.yaml
|
||||||
@@ -101,7 +100,7 @@ cd "${ddpath}" | ${bin} compare -c "${cfg}" --verbose -C "${tmpd}"/.zsh --ignore
|
|||||||
cnt=$(cd "${ddpath}" | ${bin} compare -c "${cfg}" -C "${tmpd}"/.zsh --ignore="${patt0}" --ignore=${patt1} | grep 'does not exist in dotdrop$' | wc -l)
|
cnt=$(cd "${ddpath}" | ${bin} compare -c "${cfg}" -C "${tmpd}"/.zsh --ignore="${patt0}" --ignore=${patt1} | grep 'does not exist in dotdrop$' | wc -l)
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
[ "${cnt}" != "1" ] && echo "bad number of diffs: ${cnt}/1" && exit 1
|
[ "${cnt}" != "1" ] && echo "bad number of diffs (2): ${cnt}/1" && exit 1
|
||||||
|
|
||||||
# expects one diff
|
# expects one diff
|
||||||
echo "[+] comparing .zsh with ignore in dotfile - expect 1 diff"
|
echo "[+] comparing .zsh with ignore in dotfile - expect 1 diff"
|
||||||
@@ -111,6 +110,6 @@ cd "${ddpath}" | ${bin} compare -c "${cfg2}" --verbose -C "${tmpd}"/.zsh
|
|||||||
cnt=$(cd "${ddpath}" | ${bin} compare -c "${cfg2}" -C "${tmpd}"/.zsh | grep 'does not exist in dotdrop$' | wc -l)
|
cnt=$(cd "${ddpath}" | ${bin} compare -c "${cfg2}" -C "${tmpd}"/.zsh | grep 'does not exist in dotdrop$' | wc -l)
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
[ "${cnt}" != "1" ] && echo "bad number of diffs: ${cnt}/1" && exit 1
|
[ "${cnt}" != "1" ] && echo "bad number of diffs (3): ${cnt}/1" && exit 1
|
||||||
|
|
||||||
echo "OK"
|
echo "OK"
|
||||||
|
|||||||
Reference in New Issue
Block a user