diff --git a/.env.example b/.env.example index 4133de0..f59bc47 100644 --- a/.env.example +++ b/.env.example @@ -6,15 +6,15 @@ commit_username="" commit_email="" # Indivdual file syntax: -# Note: script.sh starts its search in $HOME which is /home/{username}/ +# Note: script.sh starts its search in $HOME which is /home/{username}/ # Using below example the script will search for: /home/{username}/printer_data/config/printer.cfg #path_printercfg=printer_data/config/printer.cfg # Backup folder syntax: -# Note: script.sh starts its search in $HOME which is /home/{username}/ +# Note: script.sh starts its search in $HOME which is /home/{username}/ # Using below example the script will search for: /home/{username}/printer_data/config/* -# The star denotes a wildcard meaning that any and all files in the folder will be selected -path_klipperdata=printer_data/config/* +# /* must always be at the end of the path when backing up a folder so that the files inside of the folder are properly filtered and searched +# removing /* from the end of the path may have undesired effects on your backup -backup_folder=config_backup/klipper +path_klipperdata=printer_data/config/* \ No newline at end of file diff --git a/script.sh b/script.sh index a76a2f1..fe5af43 100755 --- a/script.sh +++ b/script.sh @@ -10,17 +10,28 @@ parent_path=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd -P) # Initialize variables from .env file source "$parent_path"/.env -# Change directory to parent path -cd "$parent_path" || exit +backup_folder="config_backup" +backup_path="$HOME/$backup_folder" # Check if backup folder exists, create one if it does not -if [ ! -d "$HOME/$backup_folder" ]; then - mkdir -p "$HOME/$backup_folder" +if [ ! -d "$backup_path" ]; then + mkdir -p "$backup_path" fi +# cd to $HOME location, this keeps the script from adding /home/{username} to the folder structure when using --parents +cd "$HOME" while IFS= read -r path; do + # Check if path is a directory or not a file (needed for /* checking as /* treats the path as not a directory) + if [[ -d "$HOME/$path" || ! -f "$HOME/$path" ]]; then + # Check if path does not end in /* or / + if [[ ! "$path" =~ /\*$ && ! "$path" =~ /$ ]]; then + path="$path/*" + elif [[ ! "$path" =~ \$ && ! "$path" =~ /\*$ ]]; then + path="$path*" + fi + fi # Iterate over every file in the path - for file in $HOME/$path; do + for file in $path; do # Check if it's a symbolic link if [ -h "$file" ]; then echo "Skipping symbolic link: $file" @@ -28,15 +39,15 @@ while IFS= read -r path; do elif [[ $(basename "$file") =~ ^printer-[0-9]+_[0-9]+\.cfg$ ]]; then echo "Skipping file: $file" else - cp -r $file $HOME/$backup_folder/ + cp -r --parents "$file" "$backup_path/" fi done done < <(grep -v '^#' "$parent_path/.env" | grep 'path_' | sed 's/^.*=//') -# Add basic readme to backup repo -backup_parent_directory=$(dirname "$backup_folder") -cp "$parent_path"/.gitignore "$HOME/$backup_parent_directory/.gitignore" -echo -e "# klipper-backup 💾 \nKlipper backup script for manual or automated GitHub backups \n\nThis backup is provided by [klipper-backup](https://github.com/Staubgeborener/klipper-backup)." > "$HOME/$backup_parent_directory/README.md" +cp "$parent_path"/.gitignore "$backup_path/.gitignore" + +# Create and add Readme to backup folder +echo -e "# klipper-backup 💾 \nKlipper backup script for manual or automated GitHub backups \n\nThis backup is provided by [klipper-backup](https://github.com/Staubgeborener/klipper-backup)." > "$backup_path/README.md" # Individual commit message, if no parameter is set, use the current timestamp as commit message timezone=$(timedatectl | grep "Time zone" | awk '{print $3}') @@ -49,22 +60,38 @@ else fi # Git commands -cd "$HOME/$backup_parent_directory" +cd "$backup_path" # Check if .git exists else init git repo if [ ! -d ".git" ]; then - mkdir .git + mkdir .git echo "[init] - defaultBranch = $branch_name" >> .git/config #Add desired branch name to config before init + defaultBranch = "$branch_name"" >> .git/config #Add desired branch name to config before init git init - branch=$(git symbolic-ref --short -q HEAD) -else - branch=$(git symbolic-ref --short -q HEAD) + +# Check if the current checked out branch matches the branch name given in .env if not then redefine branch_name to use the checked out branch and warn the user of the mismatch +elif [[ $(git symbolic-ref --short -q HEAD) != "$branch_name" ]]; then + branch_name=$(git symbolic-ref --short -q HEAD) + echo "$(tput setaf 1)The branch name defined in .env does not match the branch that is currently checked out, to remove this warning update branch_name in .env to $branch_name$(tput sgr0)" fi [[ "$commit_username" != "" ]] && git config user.name "$commit_username" || git config user.name "$(whoami)" [[ "$commit_email" != "" ]] && git config user.email "$commit_email" || git config user.email "$(whoami)@$(hostname --long)" + +# Check if remote origin already exists and create if one does not +if [ -z "$(git remote get-url origin 2>/dev/null)" ]; then + git remote add origin https://"$github_token"@github.com/"$github_username"/"$github_repository".git +fi + +git config advice.skippedCherryPicks false git add . git commit -m "$commit_message" -git push -u https://"$github_token"@github.com/"$github_username"/"$github_repository".git $branch -# Remove klipper folder after backup so that any file deletions can be logged on next backup -rm -rf $HOME/$backup_folder/ \ No newline at end of file + +# Only attempt to pull or push when actual changes were commited. cleaner output then pulling and pushing when already up to date. +if [[ $(git rev-parse HEAD) != $(git ls-remote $(git rev-parse --abbrev-ref @{u} 2>/dev/null | sed 's/\// /g') | cut -f1) ]]; then + git pull origin "$branch_name" --rebase + git push -u origin "$branch_name" +fi + +# Remove files except .git folder after backup so that any file deletions can be logged on next backup +find "$backup_path" -maxdepth 1 -mindepth 1 ! -name '.git' -exec rm -rf {} \; +