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:
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
160
tests-ng/workdir.sh
Executable 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
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user