mirror of
https://github.com/TheLocehiliosan/yadm
synced 2025-06-02 15:43:59 +00:00
Automatically exclude alt links and template files
unless yadm.auto-exclude is set to false (#234, #465). Alt files exclude pattern will be written to $GIT_DIR/info/exclude.yadm-alt and encrypt files exclude patthern to ...yadm-encrypt. Then these two files will be merged together and added to $GIT_DIR/info/exclude whenever one of them has changed.
This commit is contained in:
parent
6726730701
commit
d4796108f4
@ -217,6 +217,29 @@ def test_auto_alt(runner, yadm_cmd, paths, autoalt):
|
||||
assert str(paths.work.join(source_file)) not in linked
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("ds1_copy")
|
||||
@pytest.mark.parametrize("autoexclude", [None, "true", "false"])
|
||||
def test_alt_exclude(runner, yadm_cmd, paths, autoexclude):
|
||||
"""Test alt exclude"""
|
||||
|
||||
# set the value of auto-exclude
|
||||
if autoexclude:
|
||||
os.system(" ".join(yadm_cmd("config", "yadm.auto-exclude", autoexclude)))
|
||||
|
||||
utils.create_alt_files(paths, "##default")
|
||||
run = runner(yadm_cmd("alt", "-d"))
|
||||
assert run.success
|
||||
|
||||
run = runner(yadm_cmd("status", "-z", "-uall", "--ignored"))
|
||||
assert run.success
|
||||
assert run.err == ""
|
||||
status = run.out.split("\0")
|
||||
|
||||
for link_path in TEST_PATHS:
|
||||
flags = "??" if autoexclude == "false" else "!!"
|
||||
assert f"{flags} {link_path}" in status
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("ds1_copy")
|
||||
def test_stale_link_removal(runner, yadm_cmd, paths):
|
||||
"""Stale links to alternative files are removed
|
||||
|
@ -9,7 +9,12 @@ import pytest
|
||||
def test_exclude_encrypted(runner, tmpdir, yadm, encrypt_exists, auto_exclude, exclude):
|
||||
"""Test exclude_encrypted()"""
|
||||
|
||||
header = "# yadm-auto-excludes\n# This section is managed by yadm.\n# Any edits below will be lost.\n"
|
||||
header = """\
|
||||
# yadm-auto-excludes
|
||||
# This section is managed by yadm.
|
||||
# Any edits below will be lost.
|
||||
# yadm encrypt
|
||||
"""
|
||||
|
||||
config_function = 'function config() { echo "false";}'
|
||||
if auto_exclude:
|
||||
|
119
yadm
119
yadm
@ -691,6 +691,11 @@ function set_local_alt_values() {
|
||||
}
|
||||
|
||||
function alt_linking() {
|
||||
local -a exclude=()
|
||||
|
||||
local log="debug"
|
||||
[ -n "$loud" ] && log="echo"
|
||||
|
||||
local -i index
|
||||
for ((index = 0; index < ${#alt_targets[@]}; ++index)); do
|
||||
local target="${alt_targets[$index]}"
|
||||
@ -709,17 +714,17 @@ function alt_linking() {
|
||||
if [[ -n "$template_processor" ]]; then
|
||||
template "$template_processor" "$source" "$target"
|
||||
elif [[ "$do_copy" -eq 1 ]]; then
|
||||
debug "Copying $source to $target"
|
||||
[[ -n "$loud" ]] && echo "Copying $source to $target"
|
||||
|
||||
$log "Copying $source to $target"
|
||||
cp -f "$source" "$target"
|
||||
else
|
||||
debug "Linking $source to $target"
|
||||
[[ -n "$loud" ]] && echo "Linking $source to $target"
|
||||
|
||||
$log "Linking $source to $target"
|
||||
ln_relative "$source" "$target"
|
||||
fi
|
||||
|
||||
exclude+=("${target#"$YADM_WORK"}")
|
||||
done
|
||||
|
||||
update_exclude alt "${exclude[@]}"
|
||||
}
|
||||
|
||||
function ln_relative() {
|
||||
@ -1473,18 +1478,35 @@ function version() {
|
||||
|
||||
# ****** Utility Functions ******
|
||||
|
||||
function exclude_encrypted() {
|
||||
function update_exclude() {
|
||||
|
||||
local auto_exclude
|
||||
auto_exclude=$(config --bool yadm.auto-exclude)
|
||||
[ "$auto_exclude" == "false" ] && return 0
|
||||
|
||||
# do nothing if there is no YADM_ENCRYPT
|
||||
[ -e "$YADM_ENCRYPT" ] || return 0
|
||||
local exclude_path="${YADM_REPO}/info/exclude"
|
||||
local newline=$'\n'
|
||||
|
||||
readonly exclude_path="${YADM_REPO}/info/exclude"
|
||||
readonly newline=$'\n'
|
||||
readonly exclude_flag="# yadm-auto-excludes"
|
||||
local part_path="$exclude_path.yadm-$1"
|
||||
local part_str
|
||||
part_str=$(join_string "$newline" "${@:2}")
|
||||
|
||||
if [ -e "$part_path" ]; then
|
||||
if [ "$part_str" = "$(<"$part_path")" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
rm -f "$part_path"
|
||||
elif [ -z "$part_str" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -n "$part_str" ]; then
|
||||
assert_parent "$part_path"
|
||||
cat >"$part_path" <<<"$part_str"
|
||||
fi
|
||||
|
||||
local exclude_flag="# yadm-auto-excludes"
|
||||
|
||||
local exclude_header="${exclude_flag}${newline}"
|
||||
exclude_header="${exclude_header}# This section is managed by yadm."
|
||||
@ -1492,30 +1514,6 @@ function exclude_encrypted() {
|
||||
exclude_header="${exclude_header}# Any edits below will be lost."
|
||||
exclude_header="${exclude_header}${newline}"
|
||||
|
||||
# read encrypt
|
||||
local encrypt_data=""
|
||||
local pattern
|
||||
while IFS='' read -r pattern || [ -n "$pattern" ]; do
|
||||
case ${pattern:0:1} in
|
||||
\#)
|
||||
pattern=""
|
||||
;;
|
||||
!)
|
||||
# Prepend / to the pattern so that it matches the same files as in
|
||||
# parse_encrypt (i.e. only from the root)
|
||||
pattern="!/${pattern:1}$newline"
|
||||
;;
|
||||
*)
|
||||
if ! [[ $pattern =~ ^[[:blank:]]*(#|$) ]]; then
|
||||
pattern="/$pattern$newline"
|
||||
else
|
||||
pattern=""
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
encrypt_data="${encrypt_data}${pattern}"
|
||||
done <"$YADM_ENCRYPT"
|
||||
|
||||
# read info/exclude
|
||||
local unmanaged=""
|
||||
local managed=""
|
||||
@ -1532,14 +1530,39 @@ function exclude_encrypted() {
|
||||
done <"$exclude_path"
|
||||
fi
|
||||
|
||||
if [ "${exclude_header}${encrypt_data}" != "$managed" ]; then
|
||||
local exclude_str=""
|
||||
for suffix in alt encrypt; do
|
||||
if [ -e "${exclude_path}.yadm-$suffix" ]; then
|
||||
local header="# yadm $suffix$newline"
|
||||
exclude_str="$exclude_str$header$(<"$exclude_path".yadm-"$suffix")"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "${exclude_header}${exclude_str}${newline}" != "$managed" ]; then
|
||||
debug "Updating ${exclude_path}"
|
||||
assert_parent "$exclude_path"
|
||||
printf "%s" "${unmanaged}${exclude_header}${encrypt_data}" >"$exclude_path"
|
||||
cat >"$exclude_path" <<<"${unmanaged}${exclude_header}${exclude_str}"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function exclude_encrypted() {
|
||||
local -a exclude=()
|
||||
|
||||
if [ -r "$YADM_ENCRYPT" ]; then
|
||||
local pattern
|
||||
while IFS='' read -r pattern || [ -n "$pattern" ]; do
|
||||
# Prepend / to the pattern so that it matches the same files as in
|
||||
# parse_encrypt (i.e. only from the root)
|
||||
if [ "${pattern:0:1}" = "!" ]; then
|
||||
exclude+=("!/${pattern:1}")
|
||||
elif ! [[ $pattern =~ ^[[:blank:]]*(#|$) ]]; then
|
||||
exclude+=("/$pattern")
|
||||
fi
|
||||
done <"$YADM_ENCRYPT"
|
||||
fi
|
||||
|
||||
update_exclude encrypt "${exclude[@]}"
|
||||
}
|
||||
|
||||
function query_distro() {
|
||||
@ -1956,19 +1979,11 @@ function parse_encrypt() {
|
||||
|
||||
local pattern
|
||||
while IFS='' read -r pattern || [ -n "$pattern" ]; do
|
||||
case ${pattern:0:1} in
|
||||
\#)
|
||||
# Ignore comments
|
||||
;;
|
||||
!)
|
||||
exclude+=("--exclude=/${pattern:1}")
|
||||
;;
|
||||
*)
|
||||
if ! [[ $pattern =~ ^[[:blank:]]*(#|$) ]]; then
|
||||
include+=("$pattern")
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if [ "${pattern:0:1}" = "!" ]; then
|
||||
exclude+=("--exclude=/${pattern:1}")
|
||||
elif ! [[ $pattern =~ ^[[:blank:]]*(#|$) ]]; then
|
||||
include+=("$pattern")
|
||||
fi
|
||||
done <"$YADM_ENCRYPT"
|
||||
|
||||
if [ ${#include[@]} -gt 0 ]; then
|
||||
|
15
yadm.1
15
yadm.1
@ -363,7 +363,8 @@ you may still run "yadm alt" manually to create the alternate links. This
|
||||
feature is enabled by default.
|
||||
.TP
|
||||
.B yadm.auto-exclude
|
||||
Disable the automatic exclusion of patterns defined in
|
||||
Disable the automatic exclusion of created alternate links, template files and
|
||||
patterns defined in
|
||||
.IR $HOME/.config/yadm/encrypt .
|
||||
This feature is enabled by default.
|
||||
.TP
|
||||
@ -614,6 +615,12 @@ configuration.
|
||||
Even if disabled, links can be manually created by running
|
||||
.BR "yadm alt" .
|
||||
|
||||
Created links are automatically added to the repository's
|
||||
.I info/exclude
|
||||
file. This can be disabled using the
|
||||
.I yadm.auto-exclude
|
||||
configuration.
|
||||
|
||||
Class is a special value which is stored locally on each host (inside the local
|
||||
repository). To use alternate symlinks using class, you must set the value of
|
||||
class using the configuration
|
||||
@ -748,6 +755,12 @@ would look like:
|
||||
<%+ whatever.extra %>
|
||||
<% fi -%>
|
||||
|
||||
Created files are automatically added to the repository's
|
||||
.I info/exclude
|
||||
file. This can be disabled using the
|
||||
.I yadm.auto-exclude
|
||||
configuration.
|
||||
|
||||
.SH ENCRYPTION
|
||||
|
||||
It can be useful to manage confidential files, like SSH or GPG keys, across
|
||||
|
Loading…
Reference in New Issue
Block a user