mirror of
https://github.com/deadc0de6/dotdrop.git
synced 2026-02-04 22:39:43 +00:00
improve comparison
This commit is contained in:
@@ -16,16 +16,14 @@ import dotdrop.utils as utils
|
||||
|
||||
class Comparator:
|
||||
|
||||
# TODO add ignore
|
||||
def __init__(self, diffopts='', ignore=[], debug=False):
|
||||
"""diff left (deployed file) and right (dotdrop dotfile)"""
|
||||
self.diffopts = diffopts
|
||||
self.ignore = [os.path.expanduser(i) for i in ignore]
|
||||
self.debug = debug
|
||||
self.log = Logger()
|
||||
|
||||
def compare(self, left, right):
|
||||
"""compare two files/directories"""
|
||||
"""diff left (dotdrop dotfile) and right (deployed file)"""
|
||||
left = os.path.expanduser(left)
|
||||
right = os.path.expanduser(right)
|
||||
if not os.path.isdir(left):
|
||||
@@ -52,32 +50,41 @@ class Comparator:
|
||||
comp = filecmp.dircmp(left, right, ignore=self.ignore)
|
||||
# handle files only in deployed file
|
||||
for i in comp.left_only:
|
||||
ret.append('Only in {}: {}'.format(left, i))
|
||||
if os.path.join(left, i) in self.ignore:
|
||||
continue
|
||||
ret.append('only in left: \"{}\"\n'.format(i))
|
||||
for i in comp.right_only:
|
||||
ret.append('Only in {}: {}'.format(right, i))
|
||||
if os.path.join(right, i) in self.ignore:
|
||||
continue
|
||||
ret.append('only in right: \"{}\"\n'.format(i))
|
||||
|
||||
for i in comp.common_funny:
|
||||
# same left and right but different type
|
||||
funny = comp.common_funny
|
||||
for i in funny:
|
||||
lfile = os.path.join(left, i)
|
||||
rfile = os.path.join(right, i)
|
||||
diff = self._diff(lfile, rfile)
|
||||
ret.append(diff)
|
||||
short = os.path.basename(lfile)
|
||||
# file vs dir
|
||||
ret.append('different type: \"{}\"\n'.format(short))
|
||||
|
||||
for i in comp.diff_files:
|
||||
# content is different
|
||||
funny = comp.diff_files
|
||||
funny.extend(comp.funny_files)
|
||||
funny = list(set(funny))
|
||||
for i in funny:
|
||||
lfile = os.path.join(left, i)
|
||||
rfile = os.path.join(right, i)
|
||||
diff = self._diff(lfile, rfile)
|
||||
diff = self._diff(lfile, rfile, header=True)
|
||||
ret.append(diff)
|
||||
|
||||
for i in comp.funny_files:
|
||||
lfile = os.path.join(left, i)
|
||||
rfile = os.path.join(right, i)
|
||||
diff = self._diff(lfile, rfile)
|
||||
ret.append(diff)
|
||||
return ''.join(ret)
|
||||
|
||||
return '\n'.join(ret)
|
||||
|
||||
def _diff(self, left, right):
|
||||
def _diff(self, left, right, header=False):
|
||||
"""diff using the unix tool diff"""
|
||||
diff = utils.diff(left, right, raw=False,
|
||||
opts=self.diffopts, debug=self.debug)
|
||||
if header:
|
||||
lshort = os.path.basename(left)
|
||||
rshort = os.path.basename(right)
|
||||
diff = 'diff \"{}\":\n{}'.format(lshort, diff)
|
||||
return diff
|
||||
|
||||
@@ -15,6 +15,7 @@ from dotdrop.version import __version__ as VERSION
|
||||
from dotdrop.logger import Logger
|
||||
from dotdrop.templategen import Templategen
|
||||
from dotdrop.installer import Installer
|
||||
from dotdrop.comparator import Comparator
|
||||
from dotdrop.dotfile import Dotfile
|
||||
from dotdrop.config import Cfg
|
||||
from dotdrop.utils import *
|
||||
@@ -38,7 +39,8 @@ Usage:
|
||||
dotdrop install [-fndVb] [-c <path>] [-p <profile>]
|
||||
dotdrop import [-ldVb] [-c <path>] [-p <profile>] <paths>...
|
||||
dotdrop compare [-Vb] [-c <path>] [-p <profile>]
|
||||
[-o <opts>] [--files=<files>]
|
||||
[-o <opts>] [-i <name>...]
|
||||
[--files=<files>]
|
||||
dotdrop update [-fdVb] [-c <path>] <path>
|
||||
dotdrop listfiles [-Vb] [-c <path>] [-p <profile>]
|
||||
dotdrop list [-Vb] [-c <path>]
|
||||
@@ -49,6 +51,7 @@ Options:
|
||||
-p --profile=<profile> Specify the profile to use [default: {}].
|
||||
-c --cfg=<path> Path to the config [default: config.yaml].
|
||||
--files=<files> Comma separated list of files to compare.
|
||||
-i --ignore=<name> File name to ignore when diffing.
|
||||
-o --dopts=<opts> Diff options [default: ].
|
||||
-n --nodiff Do not diff when installing.
|
||||
-l --link Import and link.
|
||||
@@ -160,45 +163,60 @@ def _select(selections, dotfiles):
|
||||
return selected, ret
|
||||
|
||||
|
||||
def compare(opts, conf, tmp, focus=None):
|
||||
def compare(opts, conf, tmp, focus=None, ignore=[]):
|
||||
"""compare dotfiles and return True if all identical"""
|
||||
dotfiles = conf.get_dotfiles(opts['profile'])
|
||||
if dotfiles == []:
|
||||
msg = 'no dotfiles defined for this profile (\"{}\")'
|
||||
LOG.err(msg.format(opts['profile']))
|
||||
return True
|
||||
t = Templategen(base=opts['dotpath'], debug=opts['debug'])
|
||||
inst = Installer(create=opts['create'], backup=opts['backup'],
|
||||
dry=opts['dry'], base=opts['dotpath'],
|
||||
debug=opts['debug'])
|
||||
|
||||
# compare only specific files
|
||||
ret = True
|
||||
same = True
|
||||
selected = dotfiles
|
||||
if focus:
|
||||
selected, ret = _select(focus.replace(' ', '').split(','), dotfiles)
|
||||
|
||||
if len(selected) < 1:
|
||||
return ret
|
||||
return False
|
||||
|
||||
t = Templategen(base=opts['dotpath'], debug=opts['debug'])
|
||||
inst = Installer(create=opts['create'], backup=opts['backup'],
|
||||
dry=opts['dry'], base=opts['dotpath'],
|
||||
debug=opts['debug'])
|
||||
comp = Comparator(diffopts=opts['dopts'], debug=opts['debug'],
|
||||
ignore=ignore)
|
||||
|
||||
for dotfile in selected:
|
||||
if opts['debug']:
|
||||
LOG.dbg('comparing {}'.format(dotfile))
|
||||
src = dotfile.src
|
||||
if not os.path.lexists(dotfile.dst):
|
||||
LOG.emph('\"{}\" does not exist on local\n'.format(dotfile.dst))
|
||||
|
||||
tmpsrc = None
|
||||
if dotfile.trans:
|
||||
# apply transformation
|
||||
tmpsrc = apply_trans(opts, dotfile)
|
||||
if not tmpsrc:
|
||||
# could not apply trans
|
||||
continue
|
||||
src = tmpsrc
|
||||
# create a fake dotfile which is the result of the transformation
|
||||
same, diff = inst.compare(t, tmp, opts['profile'],
|
||||
src, dotfile.dst, opts=opts['dopts'])
|
||||
# install dotfile to temporary dir
|
||||
ret, insttmp = inst.install_to_temp(t, tmp, opts['profile'],
|
||||
src, dotfile.dst)
|
||||
if not ret:
|
||||
# failed to install to tmp
|
||||
continue
|
||||
diff = comp.compare(insttmp, dotfile.dst)
|
||||
if tmpsrc:
|
||||
# clean tmp transformed dotfile if any
|
||||
tmpsrc = os.path.join(opts['dotpath'], tmpsrc)
|
||||
if os.path.exists(tmpsrc):
|
||||
remove(tmpsrc)
|
||||
if same:
|
||||
if os.path.exists(insttmp):
|
||||
# clean temporary installed dotfile
|
||||
remove(insttmp)
|
||||
if diff == '':
|
||||
if opts['debug']:
|
||||
LOG.dbg('diffing \"{}\" VS \"{}\"'.format(dotfile.key,
|
||||
dotfile.dst))
|
||||
@@ -207,9 +225,9 @@ def compare(opts, conf, tmp, focus=None):
|
||||
LOG.log('diffing \"{}\" VS \"{}\"'.format(dotfile.key,
|
||||
dotfile.dst))
|
||||
LOG.emph(diff)
|
||||
ret = False
|
||||
same = False
|
||||
|
||||
return ret
|
||||
return same
|
||||
|
||||
|
||||
def update(opts, conf, path):
|
||||
@@ -384,7 +402,7 @@ def main():
|
||||
# compare local dotfiles with dotfiles stored in dotdrop
|
||||
tmp = get_tmpdir()
|
||||
opts['dopts'] = args['--dopts']
|
||||
ret = compare(opts, conf, tmp, args['--files'])
|
||||
ret = compare(opts, conf, tmp, args['--files'], args['--ignore'])
|
||||
if os.listdir(tmp):
|
||||
LOG.raw('\ntemporary files available under {}'.format(tmp))
|
||||
else:
|
||||
|
||||
@@ -194,11 +194,12 @@ class Installer:
|
||||
tmpdst = os.path.join(tmpdir, sub)
|
||||
return self.install(templater, profile, src, tmpdst), tmpdst
|
||||
|
||||
def compare(self, templater, tmpdir, profile, src, dst, opts=''):
|
||||
def install_to_temp(self, templater, tmpdir, profile, src, dst):
|
||||
"""compare a temporary generated dotfile with the local one"""
|
||||
ret = False
|
||||
tmpdst = ''
|
||||
# saved some flags while comparing
|
||||
self.comparing = True
|
||||
retval = False, ''
|
||||
drysaved = self.dry
|
||||
self.dry = False
|
||||
diffsaved = self.diff
|
||||
@@ -209,26 +210,15 @@ class Installer:
|
||||
src = os.path.expanduser(src)
|
||||
dst = os.path.expanduser(dst)
|
||||
if self.debug:
|
||||
self.log.dbg('comparing {} and {}'.format(src, dst))
|
||||
if not os.path.lexists(dst):
|
||||
# destination dotfile does not exist
|
||||
retval = False, '\"{}\" does not exist on local\n'.format(dst)
|
||||
else:
|
||||
# install the dotfile to a temp directory for comparing
|
||||
ret, tmpdst = self._install_to_temp(templater, profile,
|
||||
src, dst, tmpdir)
|
||||
if ret:
|
||||
if self.debug:
|
||||
self.log.dbg('diffing {} and {}'.format(tmpdst, dst))
|
||||
comparator = Comparator(opts, self.debug)
|
||||
diff = comparator.compare(tmpdst, dst)
|
||||
if diff == '':
|
||||
retval = True, ''
|
||||
else:
|
||||
retval = False, diff
|
||||
self.log.dbg('tmp install {} to {}'.format(src, dst))
|
||||
# install the dotfile to a temp directory for comparing
|
||||
ret, tmpdst = self._install_to_temp(templater, profile,
|
||||
src, dst, tmpdir)
|
||||
if self.debug:
|
||||
self.log.dbg('tmp installed in {}'.format(tmpdst))
|
||||
# reset flags
|
||||
self.dry = drysaved
|
||||
self.diff = diffsaved
|
||||
self.comparing = False
|
||||
self.create = createsaved
|
||||
return retval
|
||||
return ret, tmpdst
|
||||
|
||||
Reference in New Issue
Block a user