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:
8
docs/config/config-file.md
vendored
8
docs/config/config-file.md
vendored
@@ -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:
|
||||||
|
|||||||
@@ -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
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