mirror of
https://github.com/deadc0de6/dotdrop.git
synced 2026-02-14 17:37:26 +00:00
fix chmod on dir dotfile
This commit is contained in:
8
docs/config/config-file.md
vendored
8
docs/config/config-file.md
vendored
@@ -91,17 +91,17 @@ dotfiles:
|
||||
dst: ~/dir
|
||||
chmod: 744
|
||||
f_preserve:
|
||||
src: preserve
|
||||
dst: ~/preserve
|
||||
src: pfile
|
||||
dst: ~/pfile
|
||||
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
|
||||
`666-<umask>` for files).
|
||||
|
||||
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`.
|
||||
|
||||
On `import`, the following rules are applied:
|
||||
|
||||
@@ -180,40 +180,52 @@ class Installer:
|
||||
if self.dry:
|
||||
return self._log_install(ret, err)
|
||||
|
||||
# handle chmod
|
||||
# - 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"
|
||||
self._apply_chmod_after_install(src, dst, ret, err,
|
||||
chmod=chmod,
|
||||
force_chmod=force_chmod,
|
||||
linktype=linktype)
|
||||
|
||||
return self._log_install(ret, err)
|
||||
|
||||
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 = apply_chmod and os.path.exists(dst)
|
||||
apply_chmod = apply_chmod and (ret or (not ret and not err))
|
||||
apply_chmod = apply_chmod and chmod != CfgYaml.chmod_ignore
|
||||
if 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:
|
||||
if not apply_chmod:
|
||||
self.log.dbg('no chmod applied')
|
||||
|
||||
return self._log_install(ret, err)
|
||||
return
|
||||
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,
|
||||
is_template=True, chmod=None, ignore=None,
|
||||
@@ -594,8 +606,9 @@ class Installer:
|
||||
self.log.dbg(f'deploy sub from {dst}: {entry}')
|
||||
if not os.path.isdir(fpath):
|
||||
# is file
|
||||
fdst = os.path.join(dst, entry)
|
||||
res, err = self._copy_file(templater, fpath,
|
||||
os.path.join(dst, entry),
|
||||
fdst,
|
||||
actionexec=actionexec,
|
||||
noempty=noempty,
|
||||
ignore=ignore,
|
||||
@@ -604,6 +617,8 @@ class Installer:
|
||||
# error occured
|
||||
return res, err
|
||||
|
||||
self._apply_chmod_after_install(fpath, fdst, ret, err)
|
||||
|
||||
if res:
|
||||
# something got installed
|
||||
ret = True, None
|
||||
|
||||
103
tests-ng/chmod-install-dir.sh
vendored
Executable file
103
tests-ng/chmod-install-dir.sh
vendored
Executable 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
|
||||
Reference in New Issue
Block a user