#!/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 " 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 } "$@"