feat(installer): added feature to delete files in config

When adding files or directory in a .delete directory that file or
folder will be removed
This commit is contained in:
2026-03-14 10:35:14 -04:00
parent cfe0b7dd80
commit 0b0d064c0c
+110
View File
@@ -68,6 +68,26 @@ copy_file() {
fi fi
} }
delete_file() {
local dst="$1"
if $dry_run; then
echo "delete: $dst"
else
rm -f "$dst"
echo "deleted: $dst"
fi
}
delete_dir() {
local dst="$1"
if $dry_run; then
echo "delete dir: $dst"
else
rm -rf "$dst"
echo "deleted dir: $dst"
fi
}
if [[ ! -d "$src_dir" ]]; then if [[ ! -d "$src_dir" ]]; then
echo "Error: source config directory not found: $src_dir" >&2 echo "Error: source config directory not found: $src_dir" >&2
exit 1 exit 1
@@ -104,11 +124,55 @@ if [[ ! -e "$base_path" ]]; then
exit 1 exit 1
fi fi
check_delete_marker() {
local rel_path="$1"
# Check centralized .delete folder: config/.delete/path/to/dir_or_file
if [[ -f "$src_dir/.delete/$rel_path" ]] || [[ -d "$src_dir/.delete/$rel_path" ]]; then
return 0
fi
# Check inline .delete marker: config/path/to/.delete/dir_or_file
local parent_path="$src_dir/$rel_path"
local parent_dir=$(dirname "$parent_path")
local base_name=$(basename "$parent_path")
if [[ -f "$parent_dir/.delete/$base_name" ]] || [[ -d "$parent_dir/.delete/$base_name" ]]; then
return 0
fi
return 1
}
# Check if a path is a .delete directory or inside one (should be skipped during traversal)
is_in_delete_dir() {
local rel_path="$1"
# Check if the path itself is a .delete directory or any parent is .delete
local current="$rel_path"
while [[ "$current" != "." && "$current" != "/" && -n "$current" ]]; do
local base
base=$(basename "$current")
if [[ "$base" == ".delete" ]]; then
return 0
fi
current=$(dirname "$current")
done
return 1
}
sync_file() { sync_file() {
local src_path="$1" local src_path="$1"
local rel_path=${src_path#"$src_dir"/} local rel_path=${src_path#"$src_dir"/}
local dst_path="$dest_dir/$rel_path" local dst_path="$dest_dir/$rel_path"
# Check if there's a corresponding .delete marker for this file
if check_delete_marker "$rel_path"; then
if [[ -f "$dst_path" ]]; then
delete_file "$dst_path"
deleted_files+=("$dst_path")
fi
return
fi
if [[ ! -f "$dst_path" ]]; then if [[ ! -f "$dst_path" ]]; then
copy_file "$src_path" "$dst_path" copy_file "$src_path" "$dst_path"
return return
@@ -135,9 +199,55 @@ elif [[ -d "$base_path" ]]; then
continue continue
fi fi
# Check if this is a .delete directory - process its contents to delete in destination
if [[ -d "$src_path" && "$(basename "$rel_path")" == ".delete" ]]; then
# Get the parent directory of the .delete folder
parent_rel_path=$(dirname "$rel_path")
# Process all files in this .delete directory to delete corresponding files in destination
for delete_marker in "$src_path"/**; do
if [[ -e "$delete_marker" ]]; then
# Get the basename of the marker (file/dir to delete)
marker_basename=$(basename "$delete_marker")
# Construct the target path in the parent directory
target_rel_path="$parent_rel_path/$marker_basename"
target_dst_path="$dest_dir/$target_rel_path"
if [[ -d "$delete_marker" ]]; then
if [[ -d "$target_dst_path" ]]; then
delete_dir "$target_dst_path"
fi
elif [[ -f "$delete_marker" ]]; then
if [[ -f "$target_dst_path" ]]; then
delete_file "$target_dst_path"
fi
fi
fi
done
# Delete the .delete folder in destination if it exists
delete_dst_path="$dest_dir/$rel_path"
if [[ -d "$delete_dst_path" ]]; then
delete_dir "$delete_dst_path"
fi
continue
fi
# Skip anything inside a .delete directory - don't process or copy
if is_in_delete_dir "$rel_path"; then
continue
fi
dst_path="$dest_dir/$rel_path" dst_path="$dest_dir/$rel_path"
if [[ -d "$src_path" ]]; then if [[ -d "$src_path" ]]; then
# Check if there's a .delete marker for this directory
if check_delete_marker "$rel_path"; then
if [[ -d "$dst_path" ]]; then
delete_dir "$dst_path"
deleted_dirs+=("$dst_path")
fi
continue
fi
if ! $dry_run; then if ! $dry_run; then
mkdir -p "$dst_path" mkdir -p "$dst_path"
else else