mirror of
https://github.com/deadc0de6/dotdrop.git
synced 2026-02-05 13:48:48 +00:00
wrap conf and args into a new Options class
This commit is contained in:
@@ -138,6 +138,7 @@ class Cfg:
|
||||
if self.key_actions_post in d.actions:
|
||||
for action in d.actions[self.key_actions_post]:
|
||||
action.action = t.generate_string(action.action)
|
||||
return self.get_dotfiles(profile)
|
||||
|
||||
def _load_file(self):
|
||||
"""load the yaml file"""
|
||||
@@ -335,14 +336,24 @@ class Cfg:
|
||||
|
||||
# make sure we have an absolute dotpath
|
||||
self.curdotpath = self.lnk_settings[self.key_dotpath]
|
||||
self.lnk_settings[self.key_dotpath] = self.abs_or_rel(self.curdotpath)
|
||||
self.lnk_settings[self.key_dotpath] = \
|
||||
self._abs_path(self.curdotpath)
|
||||
|
||||
# make sure we have an absolute workdir
|
||||
self.curworkdir = self.lnk_settings[self.key_workdir]
|
||||
self.lnk_settings[self.key_workdir] = self.abs_or_rel(self.curworkdir)
|
||||
self.lnk_settings[self.key_workdir] = \
|
||||
self._abs_path(self.curworkdir)
|
||||
|
||||
return True
|
||||
|
||||
def _abs_path(self, path):
|
||||
"""return absolute path of path relative to the confpath"""
|
||||
path = os.path.expanduser(path)
|
||||
if not os.path.isabs(path):
|
||||
d = os.path.dirname(self.cfgpath)
|
||||
return os.path.join(d, path)
|
||||
return path
|
||||
|
||||
def _get_included_dotfiles(self, profile):
|
||||
"""find all dotfiles for a specific profile
|
||||
when using the include keyword"""
|
||||
@@ -427,15 +438,6 @@ class Cfg:
|
||||
if self.key_ignoreempty not in self.lnk_settings:
|
||||
self.lnk_settings[self.key_ignoreempty] = self.default_ignoreempty
|
||||
|
||||
def abs_or_rel(self, path):
|
||||
"""path is either absolute or relative to the config path"""
|
||||
path = os.path.expanduser(path)
|
||||
if not os.path.isabs(path):
|
||||
absconf = os.path.join(os.path.dirname(
|
||||
self.cfgpath), path)
|
||||
return absconf
|
||||
return path
|
||||
|
||||
def _save(self, content, path):
|
||||
"""writes the config to file"""
|
||||
ret = False
|
||||
|
||||
@@ -7,11 +7,9 @@ entry point
|
||||
|
||||
import os
|
||||
import sys
|
||||
import socket
|
||||
from docopt import docopt
|
||||
|
||||
# local imports
|
||||
from dotdrop.version import __version__ as VERSION
|
||||
from dotdrop.options import Options
|
||||
from dotdrop.logger import Logger
|
||||
from dotdrop.templategen import Templategen
|
||||
from dotdrop.installer import Installer
|
||||
@@ -23,91 +21,42 @@ from dotdrop.utils import get_tmpdir, remove, strip_home, run
|
||||
from dotdrop.linktypes import LinkTypes
|
||||
|
||||
LOG = Logger()
|
||||
ENV_PROFILE = 'DOTDROP_PROFILE'
|
||||
ENV_NOBANNER = 'DOTDROP_NOBANNER'
|
||||
PROFILE = socket.gethostname()
|
||||
if ENV_PROFILE in os.environ:
|
||||
PROFILE = os.environ[ENV_PROFILE]
|
||||
TRANS_SUFFIX = 'trans'
|
||||
|
||||
BANNER = """ _ _ _
|
||||
__| | ___ | |_ __| |_ __ ___ _ __
|
||||
/ _` |/ _ \| __/ _` | '__/ _ \| '_ |
|
||||
\__,_|\___/ \__\__,_|_| \___/| .__/ v{}
|
||||
|_|""".format(VERSION)
|
||||
|
||||
USAGE = """
|
||||
{}
|
||||
|
||||
Usage:
|
||||
dotdrop install [-tfndVbD] [-c <path>] [-p <profile>] [<key>...]
|
||||
dotdrop import [-ldVb] [-c <path>] [-p <profile>] <path>...
|
||||
dotdrop compare [-Vb] [-c <path>] [-p <profile>]
|
||||
[-o <opts>] [-C <file>...] [-i <pattern>...]
|
||||
dotdrop update [-fdVbkP] [-c <path>] [-p <profile>]
|
||||
[-i <pattern>...] [<path>...]
|
||||
dotdrop listfiles [-VTb] [-c <path>] [-p <profile>]
|
||||
dotdrop detail [-Vb] [-c <path>] [-p <profile>] [<key>...]
|
||||
dotdrop list [-Vb] [-c <path>]
|
||||
dotdrop --help
|
||||
dotdrop --version
|
||||
|
||||
Options:
|
||||
-p --profile=<profile> Specify the profile to use [default: {}].
|
||||
-c --cfg=<path> Path to the config [default: config.yaml].
|
||||
-C --file=<path> Path of dotfile to compare.
|
||||
-i --ignore=<pattern> Pattern to ignore.
|
||||
-o --dopts=<opts> Diff options [default: ].
|
||||
-n --nodiff Do not diff when installing.
|
||||
-t --temp Install to a temporary directory for review.
|
||||
-T --template Only template dotfiles.
|
||||
-D --showdiff Show a diff before overwriting.
|
||||
-l --inv-link Invert the value of "link_by_default" when importing.
|
||||
-P --show-patch Provide a one-liner to manually patch template.
|
||||
-f --force Do not warn if exists.
|
||||
-k --key Treat <path> as a dotfile key.
|
||||
-V --verbose Be verbose.
|
||||
-d --dry Dry run.
|
||||
-b --no-banner Do not display the banner.
|
||||
-v --version Show version.
|
||||
-h --help Show this screen.
|
||||
|
||||
""".format(BANNER, PROFILE)
|
||||
|
||||
###########################################################
|
||||
# entry point
|
||||
###########################################################
|
||||
|
||||
|
||||
def cmd_install(opts, conf, temporary=False, keys=[]):
|
||||
def cmd_install(o):
|
||||
"""install dotfiles for this profile"""
|
||||
dotfiles = conf.get_dotfiles(opts['profile'])
|
||||
if keys:
|
||||
dotfiles = o.dotfiles
|
||||
if o.install_keys:
|
||||
# filtered dotfiles to install
|
||||
dotfiles = [d for d in dotfiles if d.key in set(keys)]
|
||||
dotfiles = [d for d in dotfiles if d.key in set(o.install_keys)]
|
||||
if not dotfiles:
|
||||
msg = 'no dotfile to install for this profile (\"{}\")'
|
||||
LOG.warn(msg.format(opts['profile']))
|
||||
LOG.warn(msg.format(o.profile))
|
||||
return False
|
||||
|
||||
t = Templategen(base=opts['dotpath'], variables=opts['variables'],
|
||||
debug=opts['debug'])
|
||||
t = Templategen(base=o.dotpath, variables=o.variables,
|
||||
debug=o.debug)
|
||||
tmpdir = None
|
||||
if temporary:
|
||||
if o.install_temporary:
|
||||
tmpdir = get_tmpdir()
|
||||
inst = Installer(create=opts['create'], backup=opts['backup'],
|
||||
dry=opts['dry'], safe=opts['safe'],
|
||||
base=opts['dotpath'], workdir=opts['workdir'],
|
||||
diff=opts['installdiff'], debug=opts['debug'],
|
||||
totemp=tmpdir, showdiff=opts['showdiff'])
|
||||
inst = Installer(create=o.create, backup=o.backup,
|
||||
dry=o.dry, safe=o.safe,
|
||||
base=o.dotpath, workdir=o.workdir,
|
||||
diff=o.installdiff, debug=o.debug,
|
||||
totemp=tmpdir, showdiff=o.showdiff)
|
||||
installed = []
|
||||
for dotfile in dotfiles:
|
||||
preactions = []
|
||||
if not temporary and dotfile.actions \
|
||||
if not o.install_temporary and dotfile.actions \
|
||||
and Cfg.key_actions_pre in dotfile.actions:
|
||||
for action in dotfile.actions[Cfg.key_actions_pre]:
|
||||
preactions.append(action)
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('installing {}'.format(dotfile))
|
||||
if hasattr(dotfile, 'link') and dotfile.link == LinkTypes.PARENTS:
|
||||
r = inst.link(t, dotfile.src, dotfile.dst, actions=preactions)
|
||||
@@ -117,59 +66,60 @@ def cmd_install(opts, conf, temporary=False, keys=[]):
|
||||
src = dotfile.src
|
||||
tmp = None
|
||||
if dotfile.trans_r:
|
||||
tmp = apply_trans(opts, dotfile)
|
||||
tmp = apply_trans(o.dotpath, dotfile, debug=o.debug)
|
||||
if not tmp:
|
||||
continue
|
||||
src = tmp
|
||||
r = inst.install(t, src, dotfile.dst, actions=preactions,
|
||||
noempty=dotfile.noempty)
|
||||
if tmp:
|
||||
tmp = os.path.join(opts['dotpath'], tmp)
|
||||
tmp = os.path.join(o.dotpath, tmp)
|
||||
if os.path.exists(tmp):
|
||||
remove(tmp)
|
||||
if len(r) > 0:
|
||||
if not temporary and Cfg.key_actions_post in dotfile.actions:
|
||||
if not o.install_temporary and \
|
||||
Cfg.key_actions_post in dotfile.actions:
|
||||
actions = dotfile.actions[Cfg.key_actions_post]
|
||||
# execute action
|
||||
for action in actions:
|
||||
if opts['dry']:
|
||||
if o.dry:
|
||||
LOG.dry('would execute action: {}'.format(action))
|
||||
else:
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('executing post action {}'.format(action))
|
||||
action.execute()
|
||||
installed.extend(r)
|
||||
if temporary:
|
||||
if o.install_temporary:
|
||||
LOG.log('\nInstalled to tmp \"{}\".'.format(tmpdir))
|
||||
LOG.log('\n{} dotfile(s) installed.'.format(len(installed)))
|
||||
return True
|
||||
|
||||
|
||||
def cmd_compare(opts, conf, tmp, focus=[], ignore=[]):
|
||||
def cmd_compare(o, tmp):
|
||||
"""compare dotfiles and return True if all identical"""
|
||||
dotfiles = conf.get_dotfiles(opts['profile'])
|
||||
dotfiles = o.dotfiles
|
||||
if dotfiles == []:
|
||||
msg = 'no dotfile defined for this profile (\"{}\")'
|
||||
LOG.warn(msg.format(opts['profile']))
|
||||
LOG.warn(msg.format(o.profile))
|
||||
return True
|
||||
# compare only specific files
|
||||
same = True
|
||||
selected = dotfiles
|
||||
if focus:
|
||||
selected = _select(focus, dotfiles)
|
||||
if o.compare_focus:
|
||||
selected = _select(o.compare_focus, dotfiles)
|
||||
|
||||
if len(selected) < 1:
|
||||
return False
|
||||
|
||||
t = Templategen(base=opts['dotpath'], variables=opts['variables'],
|
||||
debug=opts['debug'])
|
||||
inst = Installer(create=opts['create'], backup=opts['backup'],
|
||||
dry=opts['dry'], base=opts['dotpath'],
|
||||
workdir=opts['workdir'], debug=opts['debug'])
|
||||
comp = Comparator(diffopts=opts['dopts'], debug=opts['debug'])
|
||||
t = Templategen(base=o.dotpath, variables=o.variables,
|
||||
debug=o.debug)
|
||||
inst = Installer(create=o.create, backup=o.backup,
|
||||
dry=o.dry, base=o.dotpath,
|
||||
workdir=o.workdir, debug=o.debug)
|
||||
comp = Comparator(diffopts=o.compare_dopts, debug=o.debug)
|
||||
|
||||
for dotfile in selected:
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('comparing {}'.format(dotfile))
|
||||
src = dotfile.src
|
||||
if not os.path.lexists(os.path.expanduser(dotfile.dst)):
|
||||
@@ -181,7 +131,7 @@ def cmd_compare(opts, conf, tmp, focus=[], ignore=[]):
|
||||
tmpsrc = None
|
||||
if dotfile.trans_r:
|
||||
# apply transformation
|
||||
tmpsrc = apply_trans(opts, dotfile)
|
||||
tmpsrc = apply_trans(o.dotpath, dotfile, debug=o.debug)
|
||||
if not tmpsrc:
|
||||
# could not apply trans
|
||||
same = False
|
||||
@@ -193,15 +143,15 @@ def cmd_compare(opts, conf, tmp, focus=[], ignore=[]):
|
||||
# failed to install to tmp
|
||||
same = False
|
||||
continue
|
||||
ignores = list(set(ignore + dotfile.cmpignore))
|
||||
ignores = list(set(o.compare_ignore + dotfile.cmpignore))
|
||||
diff = comp.compare(insttmp, dotfile.dst, ignore=ignores)
|
||||
if tmpsrc:
|
||||
# clean tmp transformed dotfile if any
|
||||
tmpsrc = os.path.join(opts['dotpath'], tmpsrc)
|
||||
tmpsrc = os.path.join(o.dotpath, tmpsrc)
|
||||
if os.path.exists(tmpsrc):
|
||||
remove(tmpsrc)
|
||||
if diff == '':
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
line = '=> compare {}: diffing with \"{}\"'
|
||||
LOG.dbg(line.format(dotfile.key, dotfile.dst))
|
||||
LOG.dbg('same file')
|
||||
@@ -214,16 +164,20 @@ def cmd_compare(opts, conf, tmp, focus=[], ignore=[]):
|
||||
return same
|
||||
|
||||
|
||||
def cmd_update(opts, conf, paths, iskey=False, ignore=[], showpatch=False):
|
||||
def cmd_update(o):
|
||||
"""update the dotfile(s) from path(s) or key(s)"""
|
||||
ret = True
|
||||
updater = Updater(conf, opts['dotpath'], opts['profile'],
|
||||
opts['variables'], opts['dry'], opts['safe'],
|
||||
iskey=iskey, debug=opts['debug'], ignore=[],
|
||||
showpatch=showpatch)
|
||||
paths = o.update_path
|
||||
iskey = o.update_iskey
|
||||
ignore = o.update_ignore
|
||||
showpatch = o.update_showpatch
|
||||
|
||||
updater = Updater(o.dotpath, o.dotfiles, o.variables,
|
||||
o.dry, o.safe, iskey=iskey, debug=o.debug,
|
||||
ignore=ignore, showpatch=showpatch)
|
||||
if not iskey:
|
||||
# update paths
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('update by paths: {}'.format(paths))
|
||||
for path in paths:
|
||||
if not updater.update_path(path):
|
||||
@@ -233,8 +187,8 @@ def cmd_update(opts, conf, paths, iskey=False, ignore=[], showpatch=False):
|
||||
keys = paths
|
||||
if not keys:
|
||||
# if not provided, take all keys
|
||||
keys = [d.key for d in conf.get_dotfiles(opts['profile'])]
|
||||
if opts['debug']:
|
||||
keys = [d.key for d in o.dotfiles]
|
||||
if o.debug:
|
||||
LOG.dbg('update by keys: {}'.format(keys))
|
||||
for key in keys:
|
||||
if not updater.update_key(key):
|
||||
@@ -242,12 +196,13 @@ def cmd_update(opts, conf, paths, iskey=False, ignore=[], showpatch=False):
|
||||
return ret
|
||||
|
||||
|
||||
def cmd_importer(opts, conf, paths):
|
||||
def cmd_importer(o):
|
||||
"""import dotfile(s) from paths"""
|
||||
ret = True
|
||||
cnt = 0
|
||||
paths = o.import_path
|
||||
for path in paths:
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('trying to import {}'.format(path))
|
||||
if not os.path.lexists(path):
|
||||
LOG.err('\"{}\" does not exist, ignored!'.format(path))
|
||||
@@ -257,37 +212,37 @@ def cmd_importer(opts, conf, paths):
|
||||
dst = os.path.abspath(dst)
|
||||
src = strip_home(dst)
|
||||
strip = '.' + os.sep
|
||||
if opts['keepdot']:
|
||||
if o.keepdot:
|
||||
strip = os.sep
|
||||
src = src.lstrip(strip)
|
||||
|
||||
# create a new dotfile
|
||||
dotfile = Dotfile('', dst, src)
|
||||
|
||||
linktype = LinkTypes(opts['link'])
|
||||
linktype = LinkTypes(o.link)
|
||||
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('new dotfile: {}'.format(dotfile))
|
||||
|
||||
# prepare hierarchy for dotfile
|
||||
srcf = os.path.join(opts['dotpath'], src)
|
||||
srcf = os.path.join(o.dotpath, src)
|
||||
if not os.path.exists(srcf):
|
||||
cmd = ['mkdir', '-p', '{}'.format(os.path.dirname(srcf))]
|
||||
if opts['dry']:
|
||||
if o.dry:
|
||||
LOG.dry('would run: {}'.format(' '.join(cmd)))
|
||||
else:
|
||||
r, _ = run(cmd, raw=False, debug=opts['debug'], checkerr=True)
|
||||
r, _ = run(cmd, raw=False, debug=o.debug, checkerr=True)
|
||||
if not r:
|
||||
LOG.err('importing \"{}\" failed!'.format(path))
|
||||
ret = False
|
||||
continue
|
||||
cmd = ['cp', '-R', '-L', dst, srcf]
|
||||
if opts['dry']:
|
||||
if o.dry:
|
||||
LOG.dry('would run: {}'.format(' '.join(cmd)))
|
||||
if linktype == LinkTypes.PARENTS:
|
||||
LOG.dry('would symlink {} to {}'.format(srcf, dst))
|
||||
else:
|
||||
r, _ = run(cmd, raw=False, debug=opts['debug'], checkerr=True)
|
||||
r, _ = run(cmd, raw=False, debug=o.debug, checkerr=True)
|
||||
if not r:
|
||||
LOG.err('importing \"{}\" failed!'.format(path))
|
||||
ret = False
|
||||
@@ -295,42 +250,42 @@ def cmd_importer(opts, conf, paths):
|
||||
if linktype == LinkTypes.PARENTS:
|
||||
remove(dst)
|
||||
os.symlink(srcf, dst)
|
||||
retconf, dotfile = conf.new(dotfile, opts['profile'],
|
||||
link=linktype, debug=opts['debug'])
|
||||
retconf, dotfile = o.conf.new(dotfile, o.profile,
|
||||
link=linktype, debug=o.debug)
|
||||
if retconf:
|
||||
LOG.sub('\"{}\" imported'.format(path))
|
||||
cnt += 1
|
||||
else:
|
||||
LOG.warn('\"{}\" ignored'.format(path))
|
||||
if opts['dry']:
|
||||
if o.dry:
|
||||
LOG.dry('new config file would be:')
|
||||
LOG.raw(conf.dump())
|
||||
LOG.raw(o.conf.dump())
|
||||
else:
|
||||
conf.save()
|
||||
o.conf.save()
|
||||
LOG.log('\n{} file(s) imported.'.format(cnt))
|
||||
return ret
|
||||
|
||||
|
||||
def cmd_list_profiles(conf):
|
||||
def cmd_list_profiles(o):
|
||||
"""list all profiles"""
|
||||
LOG.log('Available profile(s):')
|
||||
for p in conf.get_profiles():
|
||||
for p in o.profiles:
|
||||
LOG.sub(p)
|
||||
LOG.log('')
|
||||
|
||||
|
||||
def cmd_list_files(opts, conf, templateonly=False):
|
||||
def cmd_list_files(o):
|
||||
"""list all dotfiles for a specific profile"""
|
||||
if not opts['profile'] in conf.get_profiles():
|
||||
LOG.warn('unknown profile \"{}\"'.format(opts['profile']))
|
||||
if o.profile not in o.profiles:
|
||||
LOG.warn('unknown profile \"{}\"'.format(o.profile))
|
||||
return
|
||||
what = 'Dotfile(s)'
|
||||
if templateonly:
|
||||
if o.listfiles_templateonly:
|
||||
what = 'Template(s)'
|
||||
LOG.emph('{} for profile \"{}\"\n'.format(what, opts['profile']))
|
||||
for dotfile in conf.get_dotfiles(opts['profile']):
|
||||
if templateonly:
|
||||
src = os.path.join(opts['dotpath'], dotfile.src)
|
||||
LOG.emph('{} for profile \"{}\"\n'.format(what, o.profile))
|
||||
for dotfile in o.dotfiles:
|
||||
if o.listfiles_templateonly:
|
||||
src = os.path.join(o.dotpath, dotfile.src)
|
||||
if not Templategen.is_template(src):
|
||||
continue
|
||||
LOG.log('{} (src: \"{}\", link: {})'.format(dotfile.key, dotfile.src,
|
||||
@@ -339,18 +294,18 @@ def cmd_list_files(opts, conf, templateonly=False):
|
||||
LOG.log('')
|
||||
|
||||
|
||||
def cmd_detail(opts, conf, keys=None):
|
||||
def cmd_detail(o):
|
||||
"""list details on all files for all dotfile entries"""
|
||||
if not opts['profile'] in conf.get_profiles():
|
||||
LOG.warn('unknown profile \"{}\"'.format(opts['profile']))
|
||||
if o.profile not in o.profiles:
|
||||
LOG.warn('unknown profile \"{}\"'.format(o.profile))
|
||||
return
|
||||
dotfiles = conf.get_dotfiles(opts['profile'])
|
||||
if keys:
|
||||
dotfiles = o.dotfiles
|
||||
if o.detail_keys:
|
||||
# filtered dotfiles to install
|
||||
dotfiles = [d for d in dotfiles if d.key in set(keys)]
|
||||
LOG.emph('dotfiles details for profile \"{}\":\n'.format(opts['profile']))
|
||||
dotfiles = [d for d in dotfiles if d.key in set(o.details_keys)]
|
||||
LOG.emph('dotfiles details for profile \"{}\":\n'.format(o.profile))
|
||||
for d in dotfiles:
|
||||
_detail(opts['dotpath'], d)
|
||||
_detail(o.dotpath, d)
|
||||
LOG.log('')
|
||||
|
||||
|
||||
@@ -379,12 +334,6 @@ def _detail(dotpath, dotfile):
|
||||
LOG.sub('{} (template:{})'.format(p, template))
|
||||
|
||||
|
||||
def _header():
|
||||
"""print the header"""
|
||||
LOG.log(BANNER)
|
||||
LOG.log('')
|
||||
|
||||
|
||||
def _select(selections, dotfiles):
|
||||
selected = []
|
||||
for selection in selections:
|
||||
@@ -400,16 +349,16 @@ def _select(selections, dotfiles):
|
||||
return selected
|
||||
|
||||
|
||||
def apply_trans(opts, dotfile):
|
||||
def apply_trans(dotpath, dotfile, debug=False):
|
||||
"""apply the read transformation to the dotfile
|
||||
return None if fails and new source if succeed"""
|
||||
src = dotfile.src
|
||||
new_src = '{}.{}'.format(src, TRANS_SUFFIX)
|
||||
trans = dotfile.trans_r
|
||||
if opts['debug']:
|
||||
if debug:
|
||||
LOG.dbg('executing transformation {}'.format(trans))
|
||||
s = os.path.join(opts['dotpath'], src)
|
||||
temp = os.path.join(opts['dotpath'], new_src)
|
||||
s = os.path.join(dotpath, src)
|
||||
temp = os.path.join(dotpath, new_src)
|
||||
if not trans.transform(s, temp):
|
||||
msg = 'transformation \"{}\" failed for {}'
|
||||
LOG.err(msg.format(trans.key, dotfile.key))
|
||||
@@ -426,110 +375,64 @@ def apply_trans(opts, dotfile):
|
||||
|
||||
def main():
|
||||
"""entry point"""
|
||||
ret = True
|
||||
args = docopt(USAGE, version=VERSION)
|
||||
|
||||
try:
|
||||
conf = Cfg(os.path.expanduser(args['--cfg']),
|
||||
debug=args['--verbose'])
|
||||
o = Options()
|
||||
except ValueError as e:
|
||||
LOG.err('Config format error: {}'.format(str(e)))
|
||||
return False
|
||||
|
||||
opts = conf.get_settings()
|
||||
opts['dry'] = args['--dry']
|
||||
opts['profile'] = args['--profile']
|
||||
opts['safe'] = not args['--force']
|
||||
opts['debug'] = args['--verbose']
|
||||
opts['installdiff'] = not args['--nodiff']
|
||||
opts['link'] = LinkTypes.NOLINK
|
||||
if opts['link_by_default']:
|
||||
opts['link'] = LinkTypes.PARENTS
|
||||
|
||||
# Only invert link type from NOLINK to PARENTS and vice-versa
|
||||
if args['--inv-link'] and opts['link'] == LinkTypes.NOLINK:
|
||||
opts['link'] = LinkTypes.PARENTS
|
||||
if args['--inv-link'] and opts['link'] == LinkTypes.PARENTS:
|
||||
opts['link'] = LinkTypes.NOLINK
|
||||
|
||||
opts['variables'] = conf.get_variables(opts['profile'],
|
||||
debug=opts['debug'])
|
||||
opts['showdiff'] = opts['showdiff'] or args['--showdiff']
|
||||
|
||||
if opts['debug']:
|
||||
LOG.dbg('config file: {}'.format(args['--cfg']))
|
||||
LOG.dbg('options:\n{}'.format(opts))
|
||||
LOG.dbg('configs:\n{}'.format(conf.dump()))
|
||||
|
||||
# resolve dynamic paths
|
||||
conf.eval_dotfiles(opts['profile'], opts['variables'],
|
||||
debug=opts['debug'])
|
||||
|
||||
if ENV_NOBANNER not in os.environ \
|
||||
and opts['banner'] \
|
||||
and not args['--no-banner']:
|
||||
_header()
|
||||
|
||||
ret = True
|
||||
try:
|
||||
|
||||
if args['list']:
|
||||
if o.cmd_list:
|
||||
# list existing profiles
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('running cmd: list')
|
||||
cmd_list_profiles(conf)
|
||||
cmd_list_profiles(o)
|
||||
|
||||
elif args['listfiles']:
|
||||
elif o.cmd_listfiles:
|
||||
# list files for selected profile
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('running cmd: listfiles')
|
||||
cmd_list_files(opts, conf, templateonly=args['--template'])
|
||||
cmd_list_files(o)
|
||||
|
||||
elif args['install']:
|
||||
elif o.cmd_install:
|
||||
# install the dotfiles stored in dotdrop
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('running cmd: install')
|
||||
ret = cmd_install(opts, conf, temporary=args['--temp'],
|
||||
keys=args['<key>'])
|
||||
ret = cmd_install(o)
|
||||
|
||||
elif args['compare']:
|
||||
elif o.cmd_compare:
|
||||
# compare local dotfiles with dotfiles stored in dotdrop
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('running cmd: compare')
|
||||
tmp = get_tmpdir()
|
||||
opts['dopts'] = args['--dopts']
|
||||
ret = cmd_compare(opts, conf, tmp, focus=args['--file'],
|
||||
ignore=args['--ignore'])
|
||||
ret = cmd_compare(o, tmp)
|
||||
# clean tmp directory
|
||||
remove(tmp)
|
||||
|
||||
elif args['import']:
|
||||
elif o.cmd_import:
|
||||
# import dotfile(s)
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('running cmd: import')
|
||||
ret = cmd_importer(opts, conf, args['<path>'])
|
||||
ret = cmd_importer(o)
|
||||
|
||||
elif args['update']:
|
||||
elif o.cmd_update:
|
||||
# update a dotfile
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('running cmd: update')
|
||||
iskey = args['--key']
|
||||
ret = cmd_update(opts, conf, args['<path>'],
|
||||
iskey=iskey, ignore=args['--ignore'],
|
||||
showpatch=args['--show-patch'])
|
||||
ret = cmd_update(o)
|
||||
|
||||
elif args['detail']:
|
||||
elif o.cmd_detail:
|
||||
# detail files
|
||||
if opts['debug']:
|
||||
if o.debug:
|
||||
LOG.dbg('running cmd: update')
|
||||
cmd_detail(opts, conf, keys=args['<key>'])
|
||||
cmd_detail(o)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
LOG.err('interrupted')
|
||||
ret = False
|
||||
|
||||
if opts['debug']:
|
||||
LOG.dbg('configs:\n{}'.format(conf.dump()))
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
169
dotdrop/options.py
Normal file
169
dotdrop/options.py
Normal file
@@ -0,0 +1,169 @@
|
||||
"""
|
||||
author: deadc0de6 (https://github.com/deadc0de6)
|
||||
Copyright (c) 2017, deadc0de6
|
||||
|
||||
stores all options to use across dotdrop
|
||||
"""
|
||||
|
||||
import os
|
||||
import socket
|
||||
from docopt import docopt
|
||||
|
||||
# local imports
|
||||
from dotdrop.version import __version__ as VERSION
|
||||
from dotdrop.linktypes import LinkTypes
|
||||
from dotdrop.logger import Logger
|
||||
from dotdrop.config import Cfg
|
||||
|
||||
|
||||
PROFILE = socket.gethostname()
|
||||
ENV_PROFILE = 'DOTDROP_PROFILE'
|
||||
ENV_NOBANNER = 'DOTDROP_NOBANNER'
|
||||
if ENV_PROFILE in os.environ:
|
||||
PROFILE = os.environ[ENV_PROFILE]
|
||||
|
||||
BANNER = """ _ _ _
|
||||
__| | ___ | |_ __| |_ __ ___ _ __
|
||||
/ _` |/ _ \| __/ _` | '__/ _ \| '_ |
|
||||
\__,_|\___/ \__\__,_|_| \___/| .__/ v{}
|
||||
|_|""".format(VERSION)
|
||||
|
||||
USAGE = """
|
||||
{}
|
||||
|
||||
Usage:
|
||||
dotdrop install [-tfndVbD] [-c <path>] [-p <profile>] [<key>...]
|
||||
dotdrop import [-ldVb] [-c <path>] [-p <profile>] <path>...
|
||||
dotdrop compare [-Vb] [-c <path>] [-p <profile>]
|
||||
[-o <opts>] [-C <file>...] [-i <pattern>...]
|
||||
dotdrop update [-fdVbkP] [-c <path>] [-p <profile>]
|
||||
[-i <pattern>...] [<path>...]
|
||||
dotdrop listfiles [-VTb] [-c <path>] [-p <profile>]
|
||||
dotdrop detail [-Vb] [-c <path>] [-p <profile>] [<key>...]
|
||||
dotdrop list [-Vb] [-c <path>]
|
||||
dotdrop --help
|
||||
dotdrop --version
|
||||
|
||||
Options:
|
||||
-p --profile=<profile> Specify the profile to use [default: {}].
|
||||
-c --cfg=<path> Path to the config [default: config.yaml].
|
||||
-C --file=<path> Path of dotfile to compare.
|
||||
-i --ignore=<pattern> Pattern to ignore.
|
||||
-o --dopts=<opts> Diff options [default: ].
|
||||
-n --nodiff Do not diff when installing.
|
||||
-t --temp Install to a temporary directory for review.
|
||||
-T --template Only template dotfiles.
|
||||
-D --showdiff Show a diff before overwriting.
|
||||
-l --inv-link Invert the value of "link_by_default" when importing.
|
||||
-P --show-patch Provide a one-liner to manually patch template.
|
||||
-f --force Do not warn if exists.
|
||||
-k --key Treat <path> as a dotfile key.
|
||||
-V --verbose Be verbose.
|
||||
-d --dry Dry run.
|
||||
-b --no-banner Do not display the banner.
|
||||
-v --version Show version.
|
||||
-h --help Show this screen.
|
||||
|
||||
""".format(BANNER, PROFILE)
|
||||
|
||||
|
||||
class Options:
|
||||
|
||||
def __init__(self, args=None):
|
||||
"""constructor
|
||||
@key: action key
|
||||
@action: action string
|
||||
"""
|
||||
self.args = args
|
||||
if not args:
|
||||
self.args = docopt(USAGE, version=VERSION)
|
||||
self.log = Logger()
|
||||
self.debug = self.args['--verbose']
|
||||
self.confpath = os.path.expanduser(self.args['--cfg'])
|
||||
self.log.dbg('config file: {}'.format(self.confpath))
|
||||
|
||||
self._read_config()
|
||||
self._apply_args()
|
||||
self._fill_attr()
|
||||
if ENV_NOBANNER not in os.environ \
|
||||
and self.banner \
|
||||
and not self.args['--no-banner']:
|
||||
self._header()
|
||||
if self.debug:
|
||||
self._print_attr()
|
||||
|
||||
def _header():
|
||||
"""print the header"""
|
||||
self.log.log(BANNER)
|
||||
self.log.log('')
|
||||
|
||||
def _read_config(self):
|
||||
self.conf = Cfg(self.confpath, debug=self.debug)
|
||||
# transform the configs in attribute
|
||||
for k, v in self.conf.get_settings().items():
|
||||
setattr(self, k, v)
|
||||
|
||||
def _apply_args(self):
|
||||
# the commands
|
||||
self.cmd_list = self.args['list']
|
||||
self.cmd_listfiles = self.args['listfiles']
|
||||
self.cmd_install = self.args['install']
|
||||
self.cmd_compare = self.args['compare']
|
||||
self.cmd_import = self.args['import']
|
||||
self.cmd_update = self.args['update']
|
||||
self.cmd_detail = self.args['detail']
|
||||
|
||||
# adapt attributes based on arguments
|
||||
self.dry = self.args['--dry']
|
||||
self.profile = self.args['--profile']
|
||||
self.safe = not self.args['--force']
|
||||
self.installdiff = not self.args['--nodiff']
|
||||
self.showdiff = self.showdiff or self.args['--showdiff']
|
||||
self.link = LinkTypes.NOLINK
|
||||
if self.link_by_default:
|
||||
self.link = LinkTypes.PARENTS
|
||||
|
||||
if self.args['--inv-link']:
|
||||
# Only invert link type from NOLINK to PARENTS and vice-versa
|
||||
if self.link == LinkTypes.NOLINK:
|
||||
self.link = LinkTypes.PARENTS
|
||||
elif self.link == LinkTypes.PARENTS:
|
||||
self.link = LinkTypes.NOLINK
|
||||
|
||||
# "listfiles" specifics
|
||||
self.listfiles_templateonly = self.args['--template']
|
||||
# "install" specifics
|
||||
self.install_temporary = self.args['--temp']
|
||||
self.install_keys = self.args['<key>']
|
||||
# "compare" specifics
|
||||
self.compare_dopts = self.args['--dopts']
|
||||
self.compare_focus = self.args['--file']
|
||||
self.compare_ignore = self.args['--ignore']
|
||||
# "import" specifics
|
||||
self.import_path = self.args['<path>']
|
||||
# "update" specifics
|
||||
self.update_path = self.args['<path>']
|
||||
self.update_iskey = self.args['--key']
|
||||
self.update_ignore = self.args['--ignore']
|
||||
self.update_showpatch = self.args['--show-patch']
|
||||
# "detail" specifics
|
||||
self.detail_keys = self.args['<key>']
|
||||
|
||||
def _fill_attr(self):
|
||||
# variables
|
||||
self.variables = self.conf.get_variables(self.profile,
|
||||
debug=self.debug).copy()
|
||||
# the dotfiles
|
||||
self.dotfiles = self.conf.eval_dotfiles(self.profile, self.variables,
|
||||
debug=self.debug).copy()
|
||||
self.profiles = self.conf.get_profiles()
|
||||
|
||||
def _print_attr(self):
|
||||
self.log.dbg('options:')
|
||||
for att in dir(self):
|
||||
if att.startswith('_'):
|
||||
continue
|
||||
val = getattr(self, att)
|
||||
if callable(val):
|
||||
continue
|
||||
self.log.dbg('- {}: \"{}\"'.format(att, val))
|
||||
@@ -20,12 +20,11 @@ TILD = '~'
|
||||
|
||||
class Updater:
|
||||
|
||||
def __init__(self, conf, dotpath, profile, variables, dry, safe,
|
||||
def __init__(self, dotpath, dotfiles, variables, dry, safe,
|
||||
iskey=False, debug=False, ignore=[], showpatch=False):
|
||||
"""constructor
|
||||
@conf: configuration
|
||||
@dotpath: path where dotfiles are stored
|
||||
@profile: profile selected
|
||||
@dotfiles: dotfiles for this profile
|
||||
@variables: dictionary of variables for the templates
|
||||
@dry: simulate
|
||||
@safe: ask for overwrite if True
|
||||
@@ -34,9 +33,8 @@ class Updater:
|
||||
@ignore: pattern to ignore when updating
|
||||
@showpatch: show patch if dotfile to update is a template
|
||||
"""
|
||||
self.conf = conf
|
||||
self.dotpath = dotpath
|
||||
self.profile = profile
|
||||
self.dotfiles = dotfiles
|
||||
self.variables = variables
|
||||
self.dry = dry
|
||||
self.safe = safe
|
||||
@@ -79,7 +77,7 @@ class Updater:
|
||||
self.log.dbg('ignore pattern(s): {}'.format(self.ignores))
|
||||
|
||||
left = os.path.expanduser(path)
|
||||
right = os.path.join(self.conf.abs_or_rel(self.dotpath), dotfile.src)
|
||||
right = os.path.join(self.dotpath, dotfile.src)
|
||||
right = os.path.expanduser(right)
|
||||
|
||||
if self._ignore([left, right]):
|
||||
@@ -128,7 +126,7 @@ class Updater:
|
||||
|
||||
def _get_dotfile_by_key(self, key):
|
||||
"""get the dotfile matching this key"""
|
||||
dotfiles = self.conf.get_dotfiles(self.profile)
|
||||
dotfiles = self.dotfiles
|
||||
subs = [d for d in dotfiles if d.key == key]
|
||||
if not subs:
|
||||
self.log.err('key \"{}\" not found!'.format(key))
|
||||
@@ -141,7 +139,7 @@ class Updater:
|
||||
|
||||
def _get_dotfile_by_path(self, path):
|
||||
"""get the dotfile matching this path"""
|
||||
dotfiles = self.conf.get_dotfiles(self.profile)
|
||||
dotfiles = self.dotfiles
|
||||
subs = [d for d in dotfiles if d.dst == path]
|
||||
if not subs:
|
||||
self.log.err('\"{}\" is not managed!'.format(path))
|
||||
|
||||
@@ -10,9 +10,9 @@ import string
|
||||
import random
|
||||
import tempfile
|
||||
|
||||
from dotdrop.config import Cfg
|
||||
from dotdrop.utils import *
|
||||
from dotdrop.options import Options
|
||||
from dotdrop.linktypes import LinkTypes
|
||||
from dotdrop.utils import *
|
||||
|
||||
TMPSUFFIX = '.dotdrop'
|
||||
|
||||
@@ -81,20 +81,56 @@ def create_dir(path):
|
||||
return path
|
||||
|
||||
|
||||
def load_config(confpath, profile):
|
||||
def _fake_args():
|
||||
args = {}
|
||||
args['--verbose'] = False
|
||||
args['--no-banner'] = False
|
||||
args['--dry'] = False
|
||||
args['--force'] = False
|
||||
args['--nodiff'] = False
|
||||
args['--showdiff'] = True
|
||||
args['--inv-link'] = False
|
||||
args['--template'] = False
|
||||
args['--temp'] = False
|
||||
args['<key>'] = []
|
||||
args['--dopts'] = ''
|
||||
args['--file'] = []
|
||||
args['--ignore'] = []
|
||||
args['<path>'] = []
|
||||
args['--key'] = False
|
||||
args['--ignore'] = []
|
||||
args['--show-patch'] = False
|
||||
# cmds
|
||||
args['list'] = False
|
||||
args['listfiles'] = False
|
||||
args['install'] = False
|
||||
args['compare'] = False
|
||||
args['import'] = False
|
||||
args['update'] = False
|
||||
args['detail'] = False
|
||||
return args
|
||||
|
||||
|
||||
def load_options(confpath, profile):
|
||||
"""Load the config file from path"""
|
||||
conf = Cfg(confpath)
|
||||
opts = conf.get_settings()
|
||||
opts['dry'] = False
|
||||
opts['profile'] = profile
|
||||
opts['safe'] = True
|
||||
opts['installdiff'] = True
|
||||
opts['link'] = LinkTypes.NOLINK.value
|
||||
opts['showdiff'] = True
|
||||
opts['debug'] = True
|
||||
opts['dopts'] = ''
|
||||
opts['variables'] = {}
|
||||
return conf, opts
|
||||
# create the fake args (bypass docopt)
|
||||
args = _fake_args()
|
||||
args['--cfg'] = confpath
|
||||
args['--profile'] = profile
|
||||
# and get the options
|
||||
# TODO need to patch options
|
||||
o = Options(args=args)
|
||||
o.profile = profile
|
||||
o.dry = False
|
||||
o.profile = profile
|
||||
o.safe = True
|
||||
o.installdiff = True
|
||||
o.link = LinkTypes.NOLINK.value
|
||||
o.showdiff = True
|
||||
o.debug = True
|
||||
o.dopts = ''
|
||||
o.variables = {}
|
||||
return o
|
||||
|
||||
|
||||
def get_path_strip_version(path):
|
||||
|
||||
@@ -16,7 +16,7 @@ from dotdrop.templategen import Templategen
|
||||
|
||||
# from tests.helpers import *
|
||||
from tests.helpers import create_dir, get_string, get_tempdir, clean, \
|
||||
create_random_file, create_fake_config, load_config, edit_content
|
||||
create_random_file, create_fake_config, load_options, edit_content
|
||||
|
||||
|
||||
class TestCompare(unittest.TestCase):
|
||||
@@ -26,12 +26,12 @@ class TestCompare(unittest.TestCase):
|
||||
CONFIG_DOTPATH = 'dotfiles'
|
||||
CONFIG_NAME = 'config.yaml'
|
||||
|
||||
def compare(self, opts, conf, tmp, nbdotfiles):
|
||||
dotfiles = conf.get_dotfiles(opts['profile'])
|
||||
def compare(self, o, tmp, nbdotfiles):
|
||||
dotfiles = o.dotfiles
|
||||
self.assertTrue(len(dotfiles) == nbdotfiles)
|
||||
t = Templategen(base=opts['dotpath'], debug=True)
|
||||
inst = Installer(create=opts['create'], backup=opts['backup'],
|
||||
dry=opts['dry'], base=opts['dotpath'], debug=True)
|
||||
t = Templategen(base=o.dotpath, debug=True)
|
||||
inst = Installer(create=o.create, backup=o.backup,
|
||||
dry=o.dry, base=o.dotpath, debug=True)
|
||||
comp = Comparator()
|
||||
results = {}
|
||||
for dotfile in dotfiles:
|
||||
@@ -98,50 +98,53 @@ class TestCompare(unittest.TestCase):
|
||||
backup=self.CONFIG_BACKUP,
|
||||
create=self.CONFIG_CREATE)
|
||||
self.assertTrue(os.path.exists(confpath))
|
||||
conf, opts = load_config(confpath, profile)
|
||||
opts['longkey'] = True
|
||||
o = load_options(confpath, profile)
|
||||
o.longkey = True
|
||||
dfiles = [d1, d2, d3, d4, d5]
|
||||
|
||||
# import the files
|
||||
cmd_importer(opts, conf, dfiles)
|
||||
conf, opts = load_config(confpath, profile)
|
||||
o.import_path = dfiles
|
||||
cmd_importer(o)
|
||||
o = load_options(confpath, profile)
|
||||
|
||||
# compare the files
|
||||
expected = {d1: True, d2: True, d3: True, d4: True, d5: True}
|
||||
results = self.compare(opts, conf, tmp, len(dfiles))
|
||||
results = self.compare(o, tmp, len(dfiles))
|
||||
self.assertTrue(results == expected)
|
||||
|
||||
# modify file
|
||||
edit_content(d1, get_string(20))
|
||||
expected = {d1: False, d2: True, d3: True, d4: True, d5: True}
|
||||
results = self.compare(opts, conf, tmp, len(dfiles))
|
||||
results = self.compare(o, tmp, len(dfiles))
|
||||
self.assertTrue(results == expected)
|
||||
|
||||
# modify binary file
|
||||
edit_content(d4, bytes(get_string(20), 'ascii'), binary=True)
|
||||
expected = {d1: False, d2: True, d3: True, d4: False, d5: True}
|
||||
results = self.compare(opts, conf, tmp, len(dfiles))
|
||||
results = self.compare(o, tmp, len(dfiles))
|
||||
self.assertTrue(results == expected)
|
||||
|
||||
# add file in directory
|
||||
d7, _ = create_random_file(d5)
|
||||
self.assertTrue(os.path.exists(d7))
|
||||
expected = {d1: False, d2: True, d3: True, d4: False, d5: False}
|
||||
results = self.compare(opts, conf, tmp, len(dfiles))
|
||||
results = self.compare(o, tmp, len(dfiles))
|
||||
self.assertTrue(results == expected)
|
||||
|
||||
# modify all files
|
||||
edit_content(d2, get_string(20))
|
||||
edit_content(d3, get_string(21))
|
||||
expected = {d1: False, d2: False, d3: False, d4: False, d5: False}
|
||||
results = self.compare(opts, conf, tmp, len(dfiles))
|
||||
results = self.compare(o, tmp, len(dfiles))
|
||||
self.assertTrue(results == expected)
|
||||
|
||||
# test compare from dotdrop
|
||||
self.assertFalse(cmd_compare(opts, conf, tmp))
|
||||
self.assertFalse(cmd_compare(o, tmp))
|
||||
# test focus
|
||||
self.assertFalse(cmd_compare(opts, conf, tmp, focus=d4))
|
||||
self.assertFalse(cmd_compare(opts, conf, tmp, focus='/tmp/fake'))
|
||||
o.focus = d4
|
||||
self.assertFalse(cmd_compare(o, tmp))
|
||||
o.focus = '/tmp/fake'
|
||||
self.assertFalse(cmd_compare(o, tmp))
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -12,7 +12,6 @@ import yaml
|
||||
from dotdrop.dotdrop import cmd_importer
|
||||
from dotdrop.dotdrop import cmd_list_profiles
|
||||
from dotdrop.dotdrop import cmd_list_files
|
||||
from dotdrop.dotdrop import _header
|
||||
from dotdrop.dotdrop import cmd_update
|
||||
from dotdrop.config import Cfg
|
||||
|
||||
@@ -34,11 +33,11 @@ class TestImport(unittest.TestCase):
|
||||
content = yaml.load(f)
|
||||
return content
|
||||
|
||||
def assert_file(self, path, conf, profile):
|
||||
def assert_file(self, path, o, profile):
|
||||
"""Make sure path has been inserted in conf for profile"""
|
||||
strip = get_path_strip_version(path)
|
||||
self.assertTrue(strip in [x.src for x in conf.get_dotfiles(profile)])
|
||||
dsts = [os.path.expanduser(x.dst) for x in conf.get_dotfiles(profile)]
|
||||
self.assertTrue(strip in [x.src for x in o.dotfiles])
|
||||
dsts = [os.path.expanduser(x.dst) for x in o.dotfiles]
|
||||
self.assertTrue(path in dsts)
|
||||
|
||||
def assert_in_yaml(self, path, dic, link=False):
|
||||
@@ -69,7 +68,7 @@ class TestImport(unittest.TestCase):
|
||||
backup=self.CONFIG_BACKUP,
|
||||
create=self.CONFIG_CREATE)
|
||||
self.assertTrue(os.path.exists(confpath))
|
||||
conf, opts = load_config(confpath, profile)
|
||||
o = load_options(confpath, profile)
|
||||
|
||||
# create some random dotfiles
|
||||
dotfile1, content1 = create_random_file(src)
|
||||
@@ -107,25 +106,27 @@ class TestImport(unittest.TestCase):
|
||||
|
||||
# import the dotfiles
|
||||
dfiles = [dotfile1, dotfile2, dotfile3, dotfile4, dotfile5]
|
||||
cmd_importer(opts, conf, dfiles)
|
||||
o.import_path = dfiles
|
||||
cmd_importer(o)
|
||||
# import symlink
|
||||
opts[Cfg.key_dotfiles_link] = True
|
||||
o.link = LinkTypes.PARENTS
|
||||
sfiles = [dotfile6, dotfile7]
|
||||
cmd_importer(opts, conf, sfiles)
|
||||
opts[Cfg.key_dotfiles_link] = False
|
||||
o.import_path = sfiles
|
||||
cmd_importer(o)
|
||||
o.link = LinkTypes.NOLINK
|
||||
|
||||
# reload the config
|
||||
conf, opts = load_config(confpath, profile)
|
||||
o = load_options(confpath, profile)
|
||||
|
||||
# test dotfiles in config class
|
||||
self.assertTrue(profile in conf.get_profiles())
|
||||
self.assert_file(dotfile1, conf, profile)
|
||||
self.assert_file(dotfile2, conf, profile)
|
||||
self.assert_file(dotfile3, conf, profile)
|
||||
self.assert_file(dotfile4, conf, profile)
|
||||
self.assert_file(dotfile5, conf, profile)
|
||||
self.assert_file(dotfile6, conf, profile)
|
||||
self.assert_file(dotfile7, conf, profile)
|
||||
self.assertTrue(profile in o.profiles)
|
||||
self.assert_file(dotfile1, o, profile)
|
||||
self.assert_file(dotfile2, o, profile)
|
||||
self.assert_file(dotfile3, o, profile)
|
||||
self.assert_file(dotfile4, o, profile)
|
||||
self.assert_file(dotfile5, o, profile)
|
||||
self.assert_file(dotfile6, o, profile)
|
||||
self.assert_file(dotfile7, o, profile)
|
||||
|
||||
# test dotfiles in yaml file
|
||||
y = self.load_yaml(confpath)
|
||||
@@ -193,15 +194,15 @@ class TestImport(unittest.TestCase):
|
||||
self.assertTrue(os.path.islink(dotfile7))
|
||||
self.assertTrue(os.path.realpath(dotfile7) == indt7)
|
||||
|
||||
cmd_list_profiles(conf)
|
||||
cmd_list_files(opts, conf)
|
||||
_header()
|
||||
cmd_list_profiles(o)
|
||||
cmd_list_files(o)
|
||||
|
||||
# fake test update
|
||||
editcontent = 'edited'
|
||||
edit_content(dotfile1, editcontent)
|
||||
opts['safe'] = False
|
||||
cmd_update(opts, conf, [dotfile1])
|
||||
o.safe = False
|
||||
o.update_path = [dotfile1]
|
||||
cmd_update(o)
|
||||
c2 = open(indt1, 'r').read()
|
||||
self.assertTrue(editcontent == c2)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import filecmp
|
||||
|
||||
from dotdrop.config import Cfg
|
||||
from tests.helpers import create_dir, get_string, get_tempdir, clean, \
|
||||
create_random_file, load_config
|
||||
create_random_file, load_options
|
||||
from dotdrop.dotfile import Dotfile
|
||||
from dotdrop.installer import Installer
|
||||
from dotdrop.action import Action
|
||||
@@ -181,12 +181,12 @@ exec bspwm
|
||||
self.assertTrue(conf is not None)
|
||||
|
||||
# install them
|
||||
conf, opts = load_config(confpath, profile)
|
||||
opts['safe'] = False
|
||||
opts['debug'] = True
|
||||
opts['showdiff'] = True
|
||||
opts['variables'] = {}
|
||||
cmd_install(opts, conf)
|
||||
o = load_options(confpath, profile)
|
||||
o.safe = False
|
||||
o.debug = True
|
||||
o.showdiff = True
|
||||
o.variables = {}
|
||||
cmd_install(o)
|
||||
|
||||
# now compare the generated files
|
||||
self.assertTrue(os.path.exists(dst1))
|
||||
@@ -233,7 +233,7 @@ exec bspwm
|
||||
self.assertTrue(tempcontent == header())
|
||||
|
||||
def test_link_children(self):
|
||||
|
||||
"""test the link children"""
|
||||
# create source dir
|
||||
src_dir = get_tempdir()
|
||||
self.assertTrue(os.path.exists(src_dir))
|
||||
@@ -257,6 +257,7 @@ exec bspwm
|
||||
self.assertEqual(os.path.realpath(dst), src)
|
||||
|
||||
def test_fails_without_src(self):
|
||||
"""test fails without src"""
|
||||
src = '/some/non/existant/file'
|
||||
|
||||
installer = Installer()
|
||||
@@ -272,7 +273,7 @@ exec bspwm
|
||||
.format(src))
|
||||
|
||||
def test_fails_when_src_file(self):
|
||||
|
||||
"""test fails when src file"""
|
||||
# create source dir
|
||||
src_dir = get_tempdir()
|
||||
self.assertTrue(os.path.exists(src_dir))
|
||||
@@ -296,6 +297,7 @@ exec bspwm
|
||||
.format(src))
|
||||
|
||||
def test_creates_dst(self):
|
||||
"""test creates dst"""
|
||||
src_dir = get_tempdir()
|
||||
self.assertTrue(os.path.exists(src_dir))
|
||||
self.addCleanup(clean, src_dir)
|
||||
@@ -316,7 +318,7 @@ exec bspwm
|
||||
self.assertTrue(os.path.exists(dst_dir))
|
||||
|
||||
def test_prompts_to_replace_dst(self):
|
||||
|
||||
"""test prompts to replace dst"""
|
||||
# create source dir
|
||||
src_dir = get_tempdir()
|
||||
self.assertTrue(os.path.exists(src_dir))
|
||||
@@ -354,7 +356,7 @@ exec bspwm
|
||||
|
||||
@patch('dotdrop.installer.Templategen')
|
||||
def test_runs_templater(self, mocked_templategen):
|
||||
|
||||
"""test runs templater"""
|
||||
# create source dir
|
||||
src_dir = get_tempdir()
|
||||
self.assertTrue(os.path.exists(src_dir))
|
||||
|
||||
@@ -74,22 +74,26 @@ class TestListings(unittest.TestCase):
|
||||
backup=self.CONFIG_BACKUP,
|
||||
create=self.CONFIG_CREATE)
|
||||
self.assertTrue(os.path.exists(confpath))
|
||||
conf, opts = load_config(confpath, profile)
|
||||
o = load_options(confpath, profile)
|
||||
dfiles = [d1, d2, d3, d4, d5]
|
||||
|
||||
# import the files
|
||||
cmd_importer(opts, conf, dfiles)
|
||||
conf, opts = load_config(confpath, profile)
|
||||
o.import_path = dfiles
|
||||
cmd_importer(o)
|
||||
o = load_options(confpath, profile)
|
||||
|
||||
# listfiles
|
||||
cmd_list_profiles(conf)
|
||||
cmd_list_profiles(o)
|
||||
|
||||
# list files
|
||||
cmd_list_files(opts, conf, templateonly=False)
|
||||
cmd_list_files(opts, conf, templateonly=True)
|
||||
o.listfiles_templateonly = False
|
||||
cmd_list_files(o)
|
||||
o.listfiles_templateonly = True
|
||||
cmd_list_files(o)
|
||||
|
||||
# details
|
||||
cmd_detail(opts, conf, keys=None)
|
||||
o.detail_keys = None
|
||||
cmd_detail(o)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -12,7 +12,7 @@ from dotdrop.dotdrop import cmd_update
|
||||
from dotdrop.dotdrop import cmd_importer
|
||||
|
||||
from tests.helpers import create_dir, get_string, get_tempdir, clean, \
|
||||
create_random_file, create_fake_config, load_config, edit_content
|
||||
create_random_file, create_fake_config, load_options, edit_content
|
||||
|
||||
|
||||
class TestUpdate(unittest.TestCase):
|
||||
@@ -67,12 +67,13 @@ class TestUpdate(unittest.TestCase):
|
||||
backup=self.CONFIG_BACKUP,
|
||||
create=self.CONFIG_CREATE)
|
||||
self.assertTrue(os.path.exists(confpath))
|
||||
conf, opts = load_config(confpath, profile)
|
||||
o = load_options(confpath, profile)
|
||||
dfiles = [d1, dir1, d2]
|
||||
|
||||
# import the files
|
||||
cmd_importer(opts, conf, dfiles)
|
||||
conf, opts = load_config(confpath, profile)
|
||||
o.import_path = dfiles
|
||||
cmd_importer(o)
|
||||
o = load_options(confpath, profile)
|
||||
|
||||
# edit the files
|
||||
edit_content(d1, 'newcontent')
|
||||
@@ -87,9 +88,10 @@ class TestUpdate(unittest.TestCase):
|
||||
create_random_file(dpath)
|
||||
|
||||
# update it
|
||||
opts['safe'] = False
|
||||
opts['debug'] = True
|
||||
cmd_update(opts, conf, [d1, dir1])
|
||||
o.safe = False
|
||||
o.debug = True
|
||||
o.update_path = [d1, dir1]
|
||||
cmd_update(o)
|
||||
|
||||
# test content
|
||||
newcontent = open(d1, 'r').read()
|
||||
@@ -100,7 +102,7 @@ class TestUpdate(unittest.TestCase):
|
||||
edit_content(d2, 'newcontentbykey')
|
||||
|
||||
# update it by key
|
||||
dfiles = conf.get_dotfiles(profile)
|
||||
dfiles = o.dotfiles
|
||||
d2key = ''
|
||||
for ds in dfiles:
|
||||
t = os.path.expanduser(ds.dst)
|
||||
@@ -108,9 +110,11 @@ class TestUpdate(unittest.TestCase):
|
||||
d2key = ds.key
|
||||
break
|
||||
self.assertTrue(d2key != '')
|
||||
opts['safe'] = False
|
||||
opts['debug'] = True
|
||||
cmd_update(opts, conf, [d2key], iskey=True)
|
||||
o.safe = False
|
||||
o.debug = True
|
||||
o.update_path = [d2key]
|
||||
o.iskey = True
|
||||
cmd_update(o)
|
||||
|
||||
# test content
|
||||
newcontent = open(d2, 'r').read()
|
||||
|
||||
Reference in New Issue
Block a user