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

allow relative workdir and fix lstrip for home

This commit is contained in:
deadc0de6
2018-12-27 09:32:08 +01:00
parent 0cb032f349
commit 8feb417ff6
8 changed files with 201 additions and 39 deletions

View File

@@ -17,9 +17,6 @@ from dotdrop.action import Action, Transform
from dotdrop.utils import *
TILD = '~'
class Cfg:
key_all = 'ALL'
@@ -314,7 +311,12 @@ 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_dotpath(self.curdotpath)
self.lnk_settings[self.key_dotpath] = self.abs_or_rel(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)
return True
def _get_included_dotfiles(self, profile):
@@ -401,8 +403,9 @@ class Cfg:
if self.key_ignoreempty not in self.lnk_settings:
self.lnk_settings[self.key_ignoreempty] = self.default_ignoreempty
def abs_dotpath(self, path):
"""transform path to an absolute path based on config path"""
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)
@@ -424,7 +427,7 @@ class Cfg:
return elem.lower()
def _get_paths(self, path):
p = self._strip_home(path)
p = strip_home(path)
dirs = []
while True:
p, f = os.path.split(p)
@@ -466,14 +469,6 @@ class Cfg:
break
return key
def _strip_home(self, path):
"""strip home part if any"""
path = os.path.expanduser(path)
home = os.path.expanduser(TILD)
if path.startswith(home):
path = path.lstrip(home)
return path
def short_to_long(self):
"""transform all short keys to long keys"""
if not self.content[self.key_dotfiles]:
@@ -600,22 +595,28 @@ class Cfg:
def dump(self):
"""return a dump of the config"""
# temporary reset dotpath
# temporary reset paths
dotpath = self.lnk_settings[self.key_dotpath]
workdir = self.lnk_settings[self.key_workdir]
self.lnk_settings[self.key_dotpath] = self.curdotpath
self.lnk_settings[self.key_workdir] = self.curworkdir
# dump
ret = yaml.dump(self.content, default_flow_style=False, indent=2)
# restore dotpath
# restore paths
self.lnk_settings[self.key_dotpath] = dotpath
self.lnk_settings[self.key_workdir] = workdir
return ret
def save(self):
"""save the config to file"""
# temporary reset dotpath
# temporary reset paths
dotpath = self.lnk_settings[self.key_dotpath]
workdir = self.lnk_settings[self.key_workdir]
self.lnk_settings[self.key_dotpath] = self.curdotpath
self.lnk_settings[self.key_workdir] = self.curworkdir
# save
ret = self._save(self.content, self.cfgpath)
# restore dotpath
# restore path
self.lnk_settings[self.key_dotpath] = dotpath
self.lnk_settings[self.key_workdir] = workdir
return ret

View File

@@ -22,14 +22,12 @@ from dotdrop.dotfile import Dotfile
from dotdrop.config import Cfg
from dotdrop.utils import *
CUR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
LOG = Logger()
ENV_PROFILE = 'DOTDROP_PROFILE'
ENV_NOBANNER = 'DOTDROP_NOBANNER'
PROFILE = socket.gethostname()
if ENV_PROFILE in os.environ:
PROFILE = os.environ[ENV_PROFILE]
TILD = '~'
TRANS_SUFFIX = 'trans'
BANNER = """ _ _ _
@@ -235,7 +233,6 @@ def cmd_update(opts, conf, paths, iskey=False):
def cmd_importer(opts, conf, paths):
"""import dotfile(s) from paths"""
ret = True
home = os.path.expanduser(TILD)
cnt = 0
for path in paths:
if not os.path.lexists(path):
@@ -244,9 +241,7 @@ def cmd_importer(opts, conf, paths):
continue
dst = path.rstrip(os.sep)
dst = os.path.abspath(dst)
src = dst
if dst.startswith(home):
src = dst[len(home):]
src = strip_home(dst)
strip = '.' + os.sep
if opts['keepdot']:
strip = os.sep
@@ -257,7 +252,7 @@ def cmd_importer(opts, conf, paths):
linkit = opts['link'] or opts['link_by_default']
# prepare hierarchy for dotfile
srcf = os.path.join(CUR, opts['dotpath'], src)
srcf = os.path.join(opts['dotpath'], src)
if not os.path.exists(srcf):
cmd = ['mkdir', '-p', '{}'.format(os.path.dirname(srcf))]
if opts['dry']:
@@ -294,7 +289,7 @@ def cmd_importer(opts, conf, paths):
else:
conf.save()
LOG.log('\n{} file(s) imported.'.format(cnt))
return True
return ret
def cmd_list_profiles(conf):

View File

@@ -253,8 +253,7 @@ class Installer:
def _pivot_path(self, path, newdir, striphome=False):
"""change path to be under newdir"""
if striphome:
home = os.path.expanduser('~')
path = path.lstrip(home)
utils.strip_home(path)
sub = path.lstrip(os.sep)
return os.path.join(newdir, sub)

View File

@@ -14,6 +14,7 @@ from dotdrop.logger import Logger
from dotdrop.templategen import Templategen
import dotdrop.utils as utils
TILD = '~'
@@ -21,7 +22,6 @@ class Updater:
def __init__(self, conf, dotpath, dry, safe,
iskey=False, debug=False):
self.home = os.path.expanduser(TILD)
self.conf = conf
self.dotpath = dotpath
self.dry = dry
@@ -59,7 +59,7 @@ class Updater:
ret = False
new_path = None
left = os.path.expanduser(path)
right = os.path.join(self.conf.abs_dotpath(self.dotpath), dotfile.src)
right = os.path.join(self.conf.abs_or_rel(self.dotpath), dotfile.src)
right = os.path.expanduser(right)
if dotfile.trans_w:
# apply write transformation if any
@@ -95,10 +95,11 @@ class Updater:
path = os.path.expanduser(path)
path = os.path.expandvars(path)
path = os.path.abspath(path)
home = os.path.expanduser(TILD) + os.sep
# normalize the path
if path.startswith(self.home):
path = path.lstrip(self.home)
if path.startswith(home):
path = path[len(home):]
path = os.path.join(TILD, path)
return path

View File

@@ -101,3 +101,11 @@ def content_empty(string):
if string == b'\n':
return True
return False
def strip_home(path):
"""properly strip $HOME from path"""
home = os.path.expanduser('~') + os.sep
if path.startswith(home):
path = path[len(home):]
return path

160
tests-ng/workdir.sh Executable file
View File

@@ -0,0 +1,160 @@
#!/usr/bin/env bash
# author: deadc0de6 (https://github.com/deadc0de6)
# Copyright (c) 2017, deadc0de6
#
# test workdir relative or absolute
# returns 1 in case of error
#
# exit on first error
set -e
# all this crap to get current path
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
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}/../"
[ "${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 "\e[96m\e[1m==> RUNNING $(basename $BASH_SOURCE) <==\e[0m"
################################################################
# this is the test
################################################################
string="blabla"
# the dotfile source
tmp=`mktemp -d`
tmpf="${tmp}/dotfiles"
tmpw="${tmp}/workdir"
mkdir -p ${tmpf}
echo "dotfiles source (dotpath): ${tmpf}"
mkdir -p ${tmpw}
echo "workdir: ${tmpw}"
# create the config file
cfg="${tmp}/config.yaml"
echo "config file: ${cfg}"
# the dotfile destination
tmpd=`mktemp -d`
echo "dotfiles destination: ${tmpd}"
## RELATIVE
echo "RUNNING RELATIVE"
cat > ${cfg} << _EOF
config:
backup: true
create: true
dotpath: dotfiles
workdir: `echo ${tmpw} | sed 's/^.*\///g'`
dotfiles:
f_abc:
dst: ${tmpd}/abc
src: abc
link: true
profiles:
p1:
dotfiles:
- f_abc
_EOF
cat ${cfg}
# create the dotfile
echo "{{@@ profile @@}}" > ${tmpf}/abc
echo "${string}" >> ${tmpf}/abc
# install
cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
# checks
grep -r p1 ${tmpw} >/dev/null
grep -r ${string} ${tmpw} >/dev/null
[ ! -e ${tmpd}/abc ] && echo "[ERROR] dotfile not installed" && exit 1
[ ! -h ${tmpd}/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
## CLEANING
rm -rf ${tmp} ${tmpd}
## ABSOLUTE
echo "RUNNING ABSOLUTE"
# the dotfile source
tmp=`mktemp -d`
tmpf="${tmp}/dotfiles"
tmpw="${tmp}/workdir"
mkdir -p ${tmpf}
echo "dotfiles source (dotpath): ${tmpf}"
mkdir -p ${tmpw}
echo "workdir: ${tmpw}"
# create the config file
cfg="${tmp}/config.yaml"
echo "config file: ${cfg}"
# the dotfile destination
tmpd=`mktemp -d`
echo "dotfiles destination: ${tmpd}"
cat > ${cfg} << _EOF
config:
backup: true
create: true
dotpath: dotfiles
workdir: ${tmpw}
dotfiles:
f_abc:
dst: ${tmpd}/abc
src: abc
link: true
profiles:
p1:
dotfiles:
- f_abc
_EOF
cat ${cfg}
# create the dotfile
echo "{{@@ profile @@}}" > ${tmpf}/abc
echo "${string}" >> ${tmpf}/abc
# install
cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 -b -V
# checks
grep -r p1 ${tmpw} >/dev/null
grep -r ${string} ${tmpw} >/dev/null
[ ! -e ${tmpd}/abc ] && echo "[ERROR] dotfile not installed" && exit 1
[ ! -h ${tmpd}/abc ] && echo "[ERROR] dotfile is not a symlink" && exit 1
## CLEANING
rm -rf ${tmp} ${tmpd}
echo "OK"
exit 0

View File

@@ -11,6 +11,7 @@ import random
import tempfile
from dotdrop.config import Cfg
from dotdrop.utils import *
TMPSUFFIX = '.dotdrop'
@@ -96,11 +97,9 @@ def load_config(confpath, profile):
def get_path_strip_version(path):
'''Return the path of a file as stored in yaml config'''
strip = path
home = os.path.expanduser('~')
if strip.startswith(home):
strip = strip[len(home):]
return strip.lstrip('.' + os.sep)
path = strip_home(path)
path = path.lstrip('.' + os.sep)
return path
def get_dotfile_from_yaml(dic, path):

View File

@@ -89,7 +89,6 @@ class TestConfig(unittest.TestCase):
# test profile
opts = conf.get_settings()
print(conf.get_profiles())
profiles = conf.get_profiles()
self.assertTrue(pf1key in profiles)
self.assertTrue(pf2key in profiles)