2026-05-03 03:15:01 +02:00

139 lines
4.4 KiB
Bash
Executable File

#!/usr/bin/env bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
environments_DIR=${environments_DIR:-"$SCRIPT_DIR/environments"}
LOGLEVEL=${LOGLVL:-2}
create_trash(){
mkdir -p "$HOME/.local/share/Trash/files"
}
move_to_trash(){
mv "$1" "$HOME/.local/share/Trash/files/"
}
remark() {
level="${1:-2}"
message="${2:-""}"
level_as_text=(
"ERROR"
"WARNING"
"INFO"
)
if [ "$level" -le "$LOGLEVEL" ]; then
printf "${level_as_text[$level]}: $message"
fi
}
create_structure(){
path_env_home="$1"
FORCED=${2:-"false"}
LOGLEVEL=${3:-2}
entrys=$(
{
find "$path_env_home" -type d
find "$path_env_home" -type f
} | awk -F/ '{ printf("%04d %s\n", NF, $0) }' \
| sort -n -k1,1 -k2 \
| cut -d' ' -f2-
) # Enusre: Folders before files and sort by depth
declare -a structure
echo "$entrys" | while IFS= read -r entry; do
relative_entry=$(echo "$entry" | sed "s#$path_env_home##g")
if [ -z "$relative_entry" ]; then
continue
fi
relative_entry=${HOME}${relative_entry}
if [[ ("$FORCED" == "true") || (-z "$(ls $relative_entry 2> /dev/null)") ]]; then
# The entry dose not exist
structure+=( "$entry" )
if [ -d "$entry" ]; then
mkdir -p "$relative_entry"
remark 2 "Created directory: $relative_entry"
else
cp -r "$entry" "$relative_entry"
remark 2 "Created file: $relative_entry"
fi
continue
else
remark 1 "'$relative_entry' exists in home directory. Not overwriting."
fi
done
}
cleanup_structure(){
enviorment_name="$1"
FORCED=${2:-"false"}
LOGLEVEL=${3:-2}
# Remmove unchanged template files
# Remove dirs when empty, starting from the deepest level
path_env_home="$environments_DIR/$enviorment_name/home"
create_trash
entrys=$(
{
find "$path_env_home" -type f
find "$path_env_home" -type d
} | awk -F/ '{ printf("%04d %s\n", NF, $0) }' \
| sort -nr -k1,1 -k2 \
| cut -d' ' -f2-
)
echo "$entrys" | while IFS= read -r entry; do
relative_entry=$(echo "$entry" | sed "s#$path_env_home##g")
if [ -z "$relative_entry" ]; then
continue
fi
relative_entry=${HOME}${relative_entry}
if [[ (! -f "$relative_entry") && (! -d "$relative_entry") ]]; then
continue
fi
if [[ (-d "$entry" && -f "$relative_entry") || (-f "$entry" && -d "$relative_entry") ]]; then
remark 1 "'$relative_entry' is a directory and a file. Skipping cleanup."
continue
fi
if [ -d "$relative_entry" ]; then
if [ -z "$(ls -A "$relative_entry")" ]; then
move_to_trash "$relative_entry"
remark 2 "Removed empty directory: $relative_entry"
elif [[ ("$FORCED" == "true") && "$(find "$relative_entry/" -type d | wc -l)" -eq "1" ]] && diff -q <(find "$relative_entry" -type f -printf "%P\n" 2>&1 | sort) <(find "$entry" -type f -printf "%P\n" 2>&1 | sort); then
# If no directories are above and the files are the same as in the template
move_to_trash "$relative_entry"
remark 2 "Force removed unchanged directory: $relative_entry"
else
remark 1 "Directory '$relative_entry' is not empty. Skipping removal."
fi
else
result=$(diff "$entry" "$relative_entry")
if [[ $result == "" || "$FORCED" == "true" ]]; then
move_to_trash "$relative_entry"
remark 2 "Removed unchanged file: $relative_entry"
else
remark 1 "File '$relative_entry' has changes. Skipping removal"
remark 1 "\n$result\n"
fi
fi
done;
}
open_environment(){
name=$1
FORCED=${2:-"false"}
LOGLEVEL=${3:-2}
if [ -z "$name" ]; then
remark 0 "Usage: open_environment <env_name>"
return 1
fi
if [ ! -d "$environments_DIR/$name" ]; then
remark 0 "Environment '$name' does not exist."
return 1
fi
create_structure "$environments_DIR/$name/home" "$FORCED" "$loglevel"
echo "$environments_DIR/$name/shell.nix"
echo "$environments_DIR/$name/shell.nix" >&3
}
"$@"