1
0
mirror of https://github.com/deadc0de6/dotdrop.git synced 2026-02-10 03:59:17 +00:00

fix chmod on dir dotfile

This commit is contained in:
deadc0de6
2023-09-22 10:54:45 +02:00
committed by deadc0de
parent 235614da9a
commit 92e23923fe
3 changed files with 152 additions and 34 deletions

View File

@@ -91,17 +91,17 @@ dotfiles:
dst: ~/dir dst: ~/dir
chmod: 744 chmod: 744
f_preserve: f_preserve:
src: preserve src: pfile
dst: ~/preserve dst: ~/pfile
chmod: preserve chmod: preserve
``` ```
The `chmod` value defines the file permissions in octal notation to apply on dotfiles. If undefined The `chmod` value defines the file permissions in octal notation to apply to the dotfile. If undefined
new files will get the system default permissions (see `umask`, `777-<umask>` for directories and new files will get the system default permissions (see `umask`, `777-<umask>` for directories and
`666-<umask>` for files). `666-<umask>` for files).
The special keyword `preserve` allows to ensure that if the dotfiles already exists The special keyword `preserve` allows to ensure that if the dotfiles already exists
on the filesystem, it is not altered during `install` and the `chmod` value won't on the filesystem, its permission is not altered during `install` and the `chmod` config value won't
be changed during `update`. be changed during `update`.
On `import`, the following rules are applied: On `import`, the following rules are applied:

View File

@@ -180,40 +180,52 @@ class Installer:
if self.dry: if self.dry:
return self._log_install(ret, err) return self._log_install(ret, err)
# handle chmod self._apply_chmod_after_install(src, dst, ret, err,
# - on success (r, not err) chmod=chmod,
# - no change (not r, not err) force_chmod=force_chmod,
# but not when linktype=linktype)
# - error (not r, err)
# - aborted (not r, err) return self._log_install(ret, err)
# - special keyword "preserve"
def _apply_chmod_after_install(self, src, dst, ret, err,
chmod=None,
force_chmod=False,
linktype=LinkTypes.NOLINK):
"""
handle chmod after install
- on success (r, not err)
- no change (not r, not err)
but not when
- error (not r, err)
- aborted (not r, err)
- special keyword "preserve"
"""
apply_chmod = linktype in [LinkTypes.NOLINK, LinkTypes.LINK_CHILDREN] apply_chmod = linktype in [LinkTypes.NOLINK, LinkTypes.LINK_CHILDREN]
apply_chmod = apply_chmod and os.path.exists(dst) apply_chmod = apply_chmod and os.path.exists(dst)
apply_chmod = apply_chmod and (ret or (not ret and not err)) apply_chmod = apply_chmod and (ret or (not ret and not err))
apply_chmod = apply_chmod and chmod != CfgYaml.chmod_ignore apply_chmod = apply_chmod and chmod != CfgYaml.chmod_ignore
if apply_chmod: if not apply_chmod:
if not chmod:
chmod = get_file_perm(src)
self.log.dbg(f'applying chmod {chmod:o} to {dst}')
dstperms = get_file_perm(dst)
if dstperms != chmod:
# apply mode
msg = f'chmod {dst} to {chmod:o}'
if not force_chmod and self.safe and not self.log.ask(msg):
ret = False
err = 'aborted'
else:
if not self.comparing:
self.log.sub(f'chmod {dst} to {chmod:o}')
if chmodit(dst, chmod, debug=self.debug):
ret = True
else:
ret = False
err = 'chmod failed'
else:
self.log.dbg('no chmod applied') self.log.dbg('no chmod applied')
return
return self._log_install(ret, err) if not chmod:
chmod = get_file_perm(src)
self.log.dbg(f'dotfile in dotpath perm: {chmod:o}')
self.log.dbg(f'applying chmod {chmod:o} to {dst}')
dstperms = get_file_perm(dst)
if dstperms != chmod:
# apply mode
msg = f'chmod {dst} to {chmod:o}'
if not force_chmod and self.safe and not self.log.ask(msg):
ret = False
err = 'aborted'
else:
if not self.comparing:
self.log.sub(f'chmod {dst} to {chmod:o}')
if chmodit(dst, chmod, debug=self.debug):
ret = True
else:
ret = False
err = 'chmod failed'
def install_to_temp(self, templater, tmpdir, src, dst, def install_to_temp(self, templater, tmpdir, src, dst,
is_template=True, chmod=None, ignore=None, is_template=True, chmod=None, ignore=None,
@@ -594,8 +606,9 @@ class Installer:
self.log.dbg(f'deploy sub from {dst}: {entry}') self.log.dbg(f'deploy sub from {dst}: {entry}')
if not os.path.isdir(fpath): if not os.path.isdir(fpath):
# is file # is file
fdst = os.path.join(dst, entry)
res, err = self._copy_file(templater, fpath, res, err = self._copy_file(templater, fpath,
os.path.join(dst, entry), fdst,
actionexec=actionexec, actionexec=actionexec,
noempty=noempty, noempty=noempty,
ignore=ignore, ignore=ignore,
@@ -604,6 +617,8 @@ class Installer:
# error occured # error occured
return res, err return res, err
self._apply_chmod_after_install(fpath, fdst, ret, err)
if res: if res:
# something got installed # something got installed
ret = True, None ret = True, None

103
tests-ng/chmod-install-dir.sh vendored Executable file
View File

@@ -0,0 +1,103 @@
#!/usr/bin/env bash
# author: deadc0de6 (https://github.com/deadc0de6)
# Copyright (c) 2023, deadc0de6
#
# test chmod dir sub file on install
#
## start-cookie
set -euo errtrace pipefail
cur=$(cd "$(dirname "${0}")" && pwd)
ddpath="${cur}/../"
PPATH="{PYTHONPATH:-}"
export PYTHONPATH="${ddpath}:${PPATH}"
altbin="python3 -m dotdrop.dotdrop"
if hash coverage 2>/dev/null; then
mkdir -p coverages/
altbin="coverage run -p --data-file coverages/coverage --source=dotdrop -m dotdrop.dotdrop"
fi
bin="${DT_BIN:-${altbin}}"
# shellcheck source=tests-ng/helpers
source "${cur}"/helpers
echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)"
## end-cookie
################################################################
# this is the test
################################################################
# $1 path
# $2 rights
has_rights()
{
echo "testing ${1} is ${2}"
[ ! -e "$1" ] && echo "$(basename "$1") does not exist" && exit 1
local mode
mode=$(stat -L -c '%a' "$1")
[ "${mode}" != "$2" ] && echo "bad mode for $(basename "$1") (${mode} VS expected ${2})" && exit 1
true
}
# the dotfile source
tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
mkdir -p "${tmps}"/dotfiles
# the dotfile destination
tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d)
#echo "dotfile destination: ${tmpd}"
clear_on_exit "${tmps}"
clear_on_exit "${tmpd}"
# create the config file
cfg="${tmps}/config.yaml"
cat > "${cfg}" << _EOF
config:
backup: true
create: true
dotpath: dotfiles
force_chmod: true
dotfiles:
d_dir:
src: dir
dst: ${tmpd}/dir
profiles:
p1:
dotfiles:
- d_dir
_EOF
#cat ${cfg}
mkdir -p "${tmps}"/dotfiles/dir
echo 'file1' > "${tmps}"/dotfiles/dir/file1
chmod 700 "${tmps}"/dotfiles/dir/file1
echo 'file2' > "${tmps}"/dotfiles/dir/file2
chmod 777 "${tmps}"/dotfiles/dir/file2
echo 'file3' > "${tmps}"/dotfiles/dir/file3
chmod 644 "${tmps}"/dotfiles/dir/file3
ls -l "${tmps}"/dotfiles/dir/
# install
echo "install (1)"
cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 -V
has_rights "${tmpd}/dir/file1" "700"
has_rights "${tmpd}/dir/file2" "777"
has_rights "${tmpd}/dir/file3" "644"
# modify
chmod 666 "${tmpd}/dir/file1"
chmod 666 "${tmpd}/dir/file2"
chmod 666 "${tmpd}/dir/file3"
# install
echo "install (2)"
cd "${ddpath}" | ${bin} install -c "${cfg}" -f -p p1 -V
has_rights "${tmpd}/dir/file1" "700"
has_rights "${tmpd}/dir/file2" "777"
has_rights "${tmpd}/dir/file3" "644"
echo "OK"
exit 0