diff --git a/update-dots.sh b/update-dots.sh deleted file mode 100644 index c38f7736b..000000000 --- a/update-dots.sh +++ /dev/null @@ -1,308 +0,0 @@ -#!/bin/bash -# This script updates the dotfiles by fetching the latest version from the Git repository and then replacing files -# that have not been modified by the user to preserve changes. The remaining files will be replaced with the new ones. - -source ./scriptdata/environment-variables - -set -euo pipefail -cd "$(dirname "$0")" -export base="$(pwd)" - -# Define colors -GREEN="\033[0;32m" -RED="\033[0;31m" -BLUE="\033[0;34m" -CYAN="\033[0;36m" -YELLOW="\033[1;33m" -MAGENTA="\033[0;35m" -RESET="\033[0m" - -# Define paths to update -folders=(".config" ".local/bin" ".local/share" ".local/state") -excludes=(".config/hypr/custom" ".config/ags/user_options.jsonc" ".config/hypr/hyprland.conf") - -get_checksum() { - # Get the checksum of a specific file - local file="$1" - md5sum "$file" | awk '{print $1}' -} - -file_in_excludes() { - # Check if a file is in the exclude_folders - local file="$1" - for exc in "${excludes[@]}"; do - if [[ $file == "$exc"* ]]; then - return 0 - fi - done - return 1 -} - -get_destination() { - # Get the correct destination of the file based on XDG base dirs - local file="$1" - local localdir="$(echo $file | cut -d/ -f1-2)" - local everything_else="$(echo $file | cut -d/ -f3-)" - # Check if path is config - if [ "$(echo $file | cut -d/ -f1)" = ".config" ]; then - printf "$XDG_CONFIG_HOME/$(echo $file | cut -d/ -f2-)" - - # Local directory - elif [ "$localdir" = ".local/bin" ]; then - printf "$XDG_BIN_HOME/$everything_else" - - # There are no files in either of the following right now, but putting it here just in case as .local was specified - elif [ "$localdir" = ".local/share" ]; then - printf "$XDG_DATA_HOME/$everything_else" - elif [ "$localdir" = ".local/state" ]; then - printf "$XDG_STATE_HOME/$everything_else" - fi -} - -# Greetings! -cat << 'EOF' -################################################################################################### -| | -| Hi there! | -| | -| This script will update your dotfiles (.config, .local, etc) by retrieving the latest version | -| from the Git repository and then replacing the old config files with the updated ones. | -| To preserve your customizations, it will ask you if you wanna keep some customized | -| files untouched. | -| | -################################################################################################### -EOF - -read -rp "Do you want to continue? [Y/n] " REPLY -echo -if [[ $REPLY =~ ^[Nn]$ ]]; then - echo -e "${RED}Exiting.${RESET}" - exit 0 -fi - -# End of Greetings - -current_branch=$(git rev-parse --abbrev-ref HEAD) - -# fetch the latest version of the repository -if ! git fetch; then - echo -e "${RED}Failed to fetch the latest version of the repository. Exiting...${RESET}" - exit 1 -fi - -# Check if there are any changes -if [[ $(git rev-list HEAD...origin/"$current_branch" --count) -eq 0 ]]; then - echo -e "${GREEN}Repository is already up-to-date. Do not run git pull before this script. Exiting...${RESET}" - exit 0 -fi -echo -e "${CYAN}Excluding files and folders that remain untouched:${RESET} ${excludes[@]}" - -# Then check which files have been customized by the user since the last update to preserve user configurations -modified_files=() - -# Find all files in the specified folders and their subfolders -while IFS= read -r -d '' file; do - # If the file is not in the home directory, skip it - if [[ ! -f "$(get_destination $file)" ]] || file_in_excludes "$file"; then - echo -e "${YELLOW}Skipping $file${RESET}" - continue - fi - - # Calculate checksums - base_checksum=$(get_checksum "$base/$file") - home_checksum=$(get_checksum "$(get_destination $file)") - - # Compare checksums and add to modified_files if necessary - if [[ $base_checksum != $home_checksum ]]; then - modified_files+=("$file") - fi -done < <(find "${folders[@]}" -type f -print0) - -echo - -# Output all modified files -if [[ ${#modified_files[@]} -gt 0 ]]; then - echo -e "${MAGENTA}Customized Files detected: ${RESET}The following files have been customized by you or your system:" - for file in "${modified_files[@]}"; do - echo -e "${BLUE}$file${RESET}" - done -else - read -rp "${YELLOW}No files detected that have been customized since the last update. All files will be replaced. Are you sure you want to continue? [Y/n] ${RESET}" REPLY - echo - if [[ $REPLY =~ ^[Nn]$ ]]; then - echo -e "${RED}Exiting.${RESET}" - exit 0 - fi -fi - -cat << 'EOF' -Do you want to keep these files untouched? -[Y] Yes, keep them. -[n] No, replace them. -[i] Check the files individually. -EOF -read -rp "Answer: " REPLY -echo - -case $REPLY in - [Nn]) - echo -e "${RED}Replacing all files.${RESET}" - modified_files=() - ;; - [Ii]) - new_modified_files=() - replaced_files=() - for file in "${modified_files[@]}"; do - read -rp "Do you want to keep $file untouched? [Y/n] " REPLY - echo - if [[ $REPLY =~ ^[Nn]$ ]]; then - replaced_files+=("$file") - else - new_modified_files+=("$file") - fi - done - modified_files=("${new_modified_files[@]}") - echo -e "${CYAN}_____________________________________________________${RESET}" - echo -e "${MAGENTA}These User configured/modified files will be kept:${RESET}" - for file in "${modified_files[@]}"; do - echo -e "${BLUE}$file${RESET}" - done - echo -e "${CYAN}_____________________________________________________${RESET}" - echo -e "${MAGENTA}These User configured/modified files will be replaced:${RESET}" - for file in "${replaced_files[@]}"; do - echo -e "${BLUE}$file${RESET}" - done - echo -e "${CYAN}_____________________________________________________${RESET}" - read -rp "Do you want to continue? [y/N] " REPLY - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - echo -e "${RED}Exiting...${RESET}" - exit 0 - fi - ;; - *) - echo -e "${GREEN}Keeping every customized file${RESET}" - ;; -esac - -# Update the repository -if ! git pull; then - echo -e "${RED}Git pull failed. Consider recloning the project or resolving conflicts manually.${RESET}" - read -rp "Should I clone the repository to a temporary folder in cache and copy the files from there? [y/N] " REPLY - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - echo -e "${RED}Exiting...${RESET}" - exit 1 - fi - - mkdir -p ./cache - temp_folder=$(mktemp -d -p ./cache) - git clone --branch "$current_branch" https://github.com/end-4/dots-hyprland/ --depth=1 "$temp_folder" - # Replace the existing dotfiles with the new ones - for folder in "${folders[@]}"; do - find "$temp_folder/$folder" -print0 | while IFS= read -r -d '' file; do - file=${file//$temp_folder\//} - if [[ -d "$temp_folder/$file" ]]; then - mkdir -p "$(get_destination $file)" - fi - if [[ -f "$temp_folder/$file" ]] && ! file_in_excludes "$file" && [[ ! " ${modified_files[*]} " =~ " $file " ]]; then - destination=$(get_destination $file) - echo -e "${BLUE}Replacing $destination ...${RESET}" - mkdir -p "$(dirname "$destination")" - cp -f "$temp_folder/$file" "$destination" - fi - done - done - - deleted_files=() - renamed_files=() - - # Extract deleted files and save to variable - deleted_files=$(git diff --name-status HEAD origin/$current_branch | awk '$1 == "D" {print $2}') - - # Extract renamed files and save to variable - renamed_files=$(git diff --name-status HEAD origin/$current_branch | awk '$1 ~ /^R/ {print $2}') - - - files_to_remove=() - - for file in $deleted_files; do - - if ! file_in_excludes "$file" && [[ ! " ${modified_files[*]} " =~ " $file " ]]; then - files_to_remove+=("$file") - fi - done - for file in $renamed_files; do - if ! file_in_excludes "$file" && [[ ! " ${modified_files[*]} " =~ " $file " ]]; then - files_to_remove+=("$file") - fi - done - - # Remove files - for file in "${files_to_remove[@]}"; do - echo -e "${YELLOW}Removing $file ...${RESET}" - homefile="$(get_destination $file)" - if [[ -f "$homefile" ]]; then - rm -rf "$homefile" - fi - done - - echo -e "${GREEN}New dotfiles have been copied. Cleaning up temporary folder...${RESET}" - rm -rf "$temp_folder" - echo -e "${GREEN}Done. You may exit now.${RESET}" - exit 0 -fi - - -# Check git diff to determine which files have been removed and which have been renamed -deleted_files=() -renamed_files=() - -# Extract deleted files and save to variable -deleted_files=$(git diff --name-status @{1} | awk '$1 == "D" {print $2}') - -# Extract renamed files and save to variable -renamed_files=$(git diff --name-status @{1} | awk '$1 ~ /^R/ {print $2}') - - -files_to_remove=() - -for file in $deleted_files; do - - if ! file_in_excludes "$file" && [[ ! " ${modified_files[*]} " =~ " $file " ]]; then - files_to_remove+=("$file") - fi -done -for file in $renamed_files; do - if ! file_in_excludes "$file" && [[ ! " ${modified_files[*]} " =~ " $file " ]]; then - files_to_remove+=("$file") - fi -done - -# Remove files -for file in "${files_to_remove[@]}"; do - echo -e "${YELLOW}Removing $file ...${RESET}" - homefile=$(get_destination $file) - if [[ -f "$homefile" ]]; then - rm -rf "$homefile" - fi -done - - -# Replace unmodified files -for folder in "${folders[@]}"; do - find "$folder" -print0 | while IFS= read -r -d '' file; do - if [[ -d "$file" ]]; then - mkdir -p "$(get_destination $file)" - fi - if [[ -f "$file" ]] && ! file_in_excludes "$file" && [[ ! " ${modified_files[*]} " =~ " $file " ]]; then - destination="$(get_destination $file)" - echo -e "${BLUE}Replacing \"$destination\" ...${RESET}" - mkdir -p "$(dirname "$destination")" - cp -f "$base/$file" "$destination" - fi - done -done - -echo -e "${GREEN}Done. You may exit now.${RESET}" -