git-syncd (3199B)
1#!/bin/bash 2 3GIT_SYNCD_CONFIG_DIR=${GIT_SYNCD_CONFIG_DIR:-"$HOME/.config/git-sync"} 4GIT_SYNCD_CONFIG=${GIT_SYNCD_CONFIG:-"$GIT_SYNCD_CONFIG_DIR/syncd.rc"} 5 6git_syncd=$0 7 8git_syncd_repos=() 9 10# auto sync exclude regex pattern 11declare -g -A git_syncd_exclude=() 12 13# maximum time seconds between fetching changes and syncing 14git_syncd_default_sync_timeout=600 15declare -g -A git_syncd_sync_timeout=() 16 17# number of seconds to wait after deteced change to push 18git_syncd_default_sync_delay=300 19declare -g -A git_syncd_sync_delay=() 20 21sync() { 22 echo "starting sync.." 23 cd "$repo" && git-sync -n -s 24} 25 26watcher() { 27 repo=$1 28 echo $repo ${git_syncd_exclude[@]} ${git_syncd_exclude[$repo]} 29 exclude=${git_syncd_exclude[$repo]:-'\.git'} 30 sync_delay=${git_syncd_sync_delay[$repo]:-$git_syncd_default_sync_delay} 31 sync_timeout=${git_syncd_sync_timeout[$repo]:-$git_syncd_default_sync_timeout} 32 sync "$repo" 33 timeout=$sync_timeout 34 while true; do 35 if [ ! -e "$repo" ]; then 36 echo "Repo does not exist" 37 echo "sleeping (${timeout}s)" 38 sleep $timeout 39 continue 40 fi 41 echo "watching (${timeout}s)" 42 file=$(timeout "$timeout" wd "$repo" inotifywait "." -r \ 43 -e modify,move,create,delete --exclude "$exclude" 2>/dev/null) 44 rc=$? 45 if [ ! -z "$file" ]; then 46 echo "inotify wake: $file" 47 timeout=$sync_delay 48 elif [ $rc -eq 124 ]; then 49 sync "$repo" 50 timeout=$sync_timeout 51 fi 52 sleep 1 53 done 54} 55 56log_prefix() { 57 repo="$1" 58 repo_name=$(basename "$repo") 59 repo_dir_name=$(basename $(dirname "$repo")) 60 while read -r line; do 61 prefix="$(date "+%Y-%m-%d %T")" #$repo_dir_name/$repo_name" 62 prefix="$(echo "$prefix" | tr -d "\"" | tr -d "'")" 63 echo "[$prefix] $line" 64 done 65} 66 67kill_all() { 68 pkill -A -9 git-syncd 69} 70 71git_syncd_watchers=() 72kill_watchers() { 73 kill_all 74 return 75 fail=0 76 for pid in "${git_syncd_watchers[@]}"; do 77 echo "killing $pid.." >&2 78 pkill -P "$pid" &>/dev/null 79 waitpid -t 10 "$pid" &>/dev/null 80 kill -0 -P "$pid" &>/dev/null && notify-send "Failed to kill git-syncd watcher" && fail=1 81 done 82 [ $fail -ne 0 ] && exit 1 83 git_syncd_watchers=() 84} 85start_watchers() { 86 for repo in "${git_syncd_repos[@]}"; do 87 echo "watching '$repo'.." 88 $git_syncd watch "$repo" & 89 git_syncd_watchers+=($!) 90 done 91} 92 93load_config() { 94 git_syncd_repos=() 95 declare -g -A git_syncd_exclude=() 96 declare -g -A git_syncd_sync_delay=() 97 declare -g -A git_syncd_sync_timeout=() 98 if [ -e "$GIT_SYNCD_CONFIG" ]; then 99 echo "sourcing '$GIT_SYNCD_CONFIG'.." 100 source "$GIT_SYNCD_CONFIG" 101 fi 102} 103 104if [ "$1" = "watch" ]; then 105 shift 106 repo="$1"; shift 107 repo_dir_name="$(basename $(dirname "$repo"))" 108 repo_name="$(basename "$repo")" 109 log_path="$HOME/.log/git-sync/$repo_dir_name" 110 mkdir -p "$log_path" 111 load_config 112 watcher "$repo" 2>&1 | log_prefix "$repo" > "$log_path/$repo_name" 113 exit 114fi 115 116load_config 117trap kill_all EXIT 118start_watchers 119while true; do 120 file=$(inotifywait --format "%w%f" -e modify,delete "$GIT_SYNCD_CONFIG") 121 if [ ! -z "$file" ]; then 122 mod_path="$(realpath "$file" 2>/dev/null)" 123 config_path="$(realpath "$GIT_SYNCD_CONFIG" 2>/dev/null)" 124 echo "config $mod_path $config_path" 125 if [ "$mod_path" = "$config_path" ]; then 126 kill_watchers 127 load_config 128 start_watchers 129 fi 130 fi 131 sleep 2 132done