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

more uninstall

This commit is contained in:
deadc0de6
2023-09-16 15:57:21 +02:00
committed by deadc0de
parent b157a5c4ca
commit 8c807dc1fa
4 changed files with 91 additions and 26 deletions

View File

@@ -16,6 +16,7 @@ from dotdrop.options import Options
from dotdrop.logger import Logger
from dotdrop.templategen import Templategen
from dotdrop.installer import Installer
from dotdrop.uninstaller import Uninstaller
from dotdrop.updater import Updater
from dotdrop.comparator import Comparator
from dotdrop.importer import Importer
@@ -621,14 +622,41 @@ def cmd_detail(opts):
def cmd_uninstall(opts):
paths = opts.uninstall_path
iskey = opts.uninstall_iskey
prof = opts.conf.get_profile()
dotfiles = opts.dotfiles
keys = opts.uninstall_key
if not paths:
# is entire profile
# TODO
# TODO
if keys:
# update only specific keys for this profile
dotfiles = []
for key in uniq_list(keys):
dotfile = opts.conf.get_dotfile(key)
if dotfile:
dotfiles.append(dotfile)
if not dotfiles:
msg = f'no dotfile to uninstall for this profile (\"{opts.profile}\")'
LOG.warn(msg)
return False
if opts.debug:
lfs = [k.key for k in dotfiles]
LOG.dbg(f'dotfiles registered for uninstall: {lfs}')
uninst = Uninstaller(base=opts.dotpath,
workdir=opts.workdir,
dry=opts.dry,
debug=opts.debug,
backup_suffix=opts.install_backup_suffix)
uninstalled = 0
for df in dotfiles:
res, msg = uninst.uninstall(df.src,
df.dst,
df.link)
if not res:
LOG.err(msg)
continue
uninstalled += 1
LOG.log(f'\n{uninstalled} dotfile(s) uninstalled.')
def cmd_remove(opts):

View File

@@ -68,7 +68,7 @@ Usage:
dotdrop update [-VbfdkPz] [-c <path>] [-p <profile>]
[-w <nb>] [-i <pattern>...] [<path>...]
dotdrop remove [-Vbfdk] [-c <path>] [-p <profile>] [<path>...]
dotdrop uninstall [-Vbfdk] [-c <path>] [-p <profile>] [<path>...]
dotdrop uninstall [-Vbfd] [-c <path>] [-p <profile>] [<key>...]
dotdrop files [-VbTG] [-c <path>] [-p <profile>]
dotdrop detail [-Vb] [-c <path>] [-p <profile>] [<key>...]
dotdrop profiles [-VbG] [-c <path>]
@@ -343,8 +343,7 @@ class Options(AttrMonitor):
def _apply_args_uninstall(self):
"""uninstall specifics"""
self.uninstall_path = self.args['<path>']
self.uninstall_iskey = self.args['--key']
self.uninstall_key = self.args['<key>']
def _apply_args_detail(self):
"""detail specifics"""
@@ -361,6 +360,7 @@ class Options(AttrMonitor):
self.cmd_update = self.args['update']
self.cmd_detail = self.args['detail']
self.cmd_remove = self.args['remove']
self.cmd_uninstall = self.args['uninstall']
# adapt attributes based on arguments
self.safe = not self.args['--force']

View File

@@ -22,6 +22,8 @@ class Uninstaller:
@debug: enable debug
@backup_suffix: suffix for dotfile backup file
"""
# TODO dry
# TODO force
base = os.path.expanduser(base)
base = os.path.normpath(base)
self.base = base
@@ -60,27 +62,32 @@ class Uninstaller:
msg = f'uninstalling \"{path}\" (link: {linktype})'
self.log.dbg(msg)
self._remove(path)
ret, msg = self._remove(path)
if ret:
if not self.dry:
self.log.sub(f'uninstall {dst}')
return ret, msg
def _remove(self, path):
"""remove path"""
# TODO handle symlink
backup = f'{path}{self.backup_suffix}'
if os.path.exists(backup):
self.log.dbg(f'backup exists for {path}: {backup}')
return self._replace(path, backup)
try:
removepath(path, self.log)
except OSError as exc:
err = f'removing \"{path}\" failed: {exc}'
return False, err
return True, ''
def _replace(self, path, backup):
"""replace path by backup"""
if os.path.isdir(path):
# TODO
return False, 'TODO'
try:
self.log.dbg(f'mv {backup} {path}')
os.replace(path, backup)
except OSError as exc:
err = f'replacing \"{path}\" by \"{backup}\" failed: {exc}'
return False, err
return True, ''

54
tests-ng/uninstall.sh vendored
View File

@@ -25,6 +25,14 @@ echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sg
################################################################
# this is the test
################################################################
# $1 pattern
# $2 path
grep_or_fail()
{
grep "${1}" "${2}" >/dev/null 2>&1 || (echo "pattern \"${1}\" not found in ${2}" && exit 1)
}
# dotdrop directory
basedir=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
mkdir -p "${basedir}"/dotfiles
@@ -36,6 +44,8 @@ clear_on_exit "${basedir}"
clear_on_exit "${tmpd}"
echo "modified" > "${basedir}"/dotfiles/x
mkdir -p "${basedir}"/dotfiles/y
echo "modified" > "${basedir}"/dotfiles/y/file
# create the config file
cfg="${basedir}/config.yaml"
@@ -48,10 +58,14 @@ dotfiles:
f_x:
src: x
dst: ${tmpd}/x
d_y:
src: y
dst: ${tmpd}/y
profiles:
p1:
dotfiles:
- f_x
- d_y
_EOF
#########################
@@ -60,37 +74,53 @@ _EOF
# install
echo "[+] install (1)"
cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 --verbose | grep '^1 dotfile(s) installed.$'
[ "$?" != "0" ] && exit 1
cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 --verbose | grep '^2 dotfile(s) installed.$'
# tests
[ ! -e "${tmpd}"/x ] && echo "f_x not installed" && exit 1
grep 'modified' "${tmpd}"/x
[ ! -e "${tmpd}"/y/file ] && echo "d_y not installed" && exit 1
grep_or_fail 'modified' "${tmpd}"/x
grep_or_fail 'modified' "${tmpd}"/y/file
# uninstall
echo "[+] uninstall"
echo "[+] uninstall (1)"
cd "${ddpath}" | ${bin} uninstall -c "${cfg}" -f -p p1 --verbose
[ "$?" != "0" ] && exit 1
[ -e "${tmpd}"/x ] && echo "f_x not installed" && exit 1
# tests
[ -e "${tmpd}"/x ] && echo "f_x not uninstalled" && exit 1
[ -d "${tmpd}"/y ] && echo "d_y not uninstalled" && exit 1
[ -e "${tmpd}"/y/file ] && echo "d_y file not uninstalled" && exit 1
#########################
## with original
#########################
echo 'original' > "${tmpd}"/x
mkdir -p "${tmpd}"/y
echo "original" > "${tmpd}"/y/file
# install
echo "[+] install (2)"
cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 --verbose | grep '^1 dotfile(s) installed.$'
[ "$?" != "0" ] && exit 1
cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 --verbose | grep '^2 dotfile(s) installed.$'
# tests
[ ! -e "${tmpd}"/x ] && echo "f_x not installed" && exit 1
grep 'modified' "${tmpd}"/x
[ ! -d "${tmpd}"/y ] && echo "d_y not installed" && exit 1
[ ! -e "${tmpd}"/y/file ] && echo "d_y file not installed" && exit 1
grep_or_fail 'modified' "${tmpd}"/x
grep_or_fail 'modified' "${tmpd}"/y/file
# uninstall
echo "[+] uninstall"
echo "[+] uninstall (2)"
cd "${ddpath}" | ${bin} uninstall -c "${cfg}" -f -p p1 --verbose
[ "$?" != "0" ] && exit 1
[ -e "${tmpd}"/x ] && echo "f_x not installed" && exit 1
grep 'original' "${tmpd}"/x
# TODO handle directory
# tests
[ ! -e "${tmpd}"/x ] && echo "f_x backup not restored" && exit 1
[ ! -d "${tmpd}"/y ] && echo "d_y backup not restored" && exit 1
[ ! -e "${tmpd}"/y/file ] && echo "d_y backup not restored" && exit 1
grep_or_fail 'original' "${tmpd}"/x
grep_or_fail 'original' "${tmpd}"/y/file
echo "OK"
exit 0