-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsync-forks
executable file
·151 lines (121 loc) · 3.52 KB
/
sync-forks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env bash
set -o errexit
set -o errtrace
set -o functrace
set -o pipefail
declare -r SYNCMIRROR_PREFIX="$(
readlink -f "$(
readlink -f "$(
dirname "$(
readlink -f "$0"
)"
)"
)"
)"
declare -r SYNCMIRROR_WORK_DIR="$(pwd)"
source "$SYNCMIRROR_PREFIX"/concurrent/concurrent.lib.sh
export CONCURRENT_LIMIT=3
export CONCURRENT_COMPACT=0
if [ "$SYNCMIRROR_PREFIX" == "$SYNCMIRROR_WORK_DIR" ]; then
echo "cannot create tmp directories in sync mirror's prefix" >&2
#exit 1
fi
#trap 'Log::Func' DEBUG
#trap -- 'Log::Trace ; exit 1' ERR
SyncMirror::TmpCreate() {
local -r WorkingDirectory="$1"
local -i RandomNumber="$RANDOM"
while [ -d "$WorkingDirectory/.sync-mirror.$RandomNumber" ]; do
RandomNumber="$RANDOM"
done
echo "creating tmp directory: $WorkingDirectory/.sync-mirror.$RandomNumber" >&2
mkdir "$WorkingDirectory/.sync-mirror.$RandomNumber"
echo "$WorkingDirectory/.sync-mirror.$RandomNumber"
}
SyncMirror::TmpCleanup() {
local -r TmpDir="$1"
if [ -d "$TmpDir" ] && \
[[ "$TmpDir" =~ ^$SYNCMIRROR_WORK_DIR/\.sync-mirror\..*$ ]]; then
rm -frv "$TmpDir"
fi
}
SyncMirror::Log() {
echo "$@" >&2
echo "$(date '+%F %R') $@" >> "$SYNCMIRROR_WORK_DIR"/sync-mirrors.errors
}
SyncMirror::CheckRepoSize() {
local -i Size
local -r Repo="$1"
# Find size of repository in bytes
Size="$(du -s "$Repo" | grep -oP '^[0-9]+')"
if [ $Size -gt 1074000 ]; then
SyncMirror::Log "$RepoName is over GitHub's 1GiB limit: $(
du -hs "$Repo" | grep -oP '^[0-9]+[BKMG]'
)"
return 1
fi
}
SyncMirror::Mirror() {
local -r RepoName="$1"
local -r RepoUpstreamUrl="$2"
local TmpDir
TmpDir="$(SyncMirror::TmpCreate "$SYNCMIRROR_WORK_DIR")"
trap "SyncMirror::TmpCleanup $TmpDir" SIGINT SIGTERM
trap -- "SyncMirror::TmpCleanup $TmpDir" ERR
echo "cloning: $RepoUpstreamUrl" >&2
GIT_TERMINAL_PROMPT=0 git clone --bare "$RepoUpstreamUrl" "$TmpDir" || {
SyncMirror::Log "cloning failed for: $RepoUpstreamUrl"
return 1
}
SyncMirror::CheckRepoSize "$TmpDir" || return 3
pushd "$TmpDir" > /dev/null
echo "setting remote origin" >&2
git remote set-url --push origin \
"[email protected]:chlorm-forks/${RepoName}.git" || {
SyncMirror::Log "failed to add upstream remote to: $RepoName"
}
echo "fetching origin" >&2
git fetch -p origin || {
SyncMirror::Log "git failed to fetch upstream for $RepoName"
}
echo "pushing changes" >&2
# Don't push with --mirror or --prune as both options may overwrite
# data. This prevents someone from cleaning the commit history on
# a repo we are mirroring and then overwriting our mirror with an
# empty repo.
git push --all || {
SyncMirror::Log "git push failed for $RepoName"
}
popd > /dev/null
SyncMirror::TmpCleanup "$TmpDir"
}
if [ -f "$1" ]; then
MirrorListFile="$1"
else
MirrorListFile="$SYNCMIRROR_PREFIX/mirror.list"
fi
if [ -n "$1" ]; then
declare -r Mirror="$1"
fi
echo "Mirror list: $MirrorListFile" >&2
declare -A MirrorList
while read Line; do
# Don't attempt to eval comments or empty lines
if [[ "$Line" =~ ^\#.* ]] || [ -z "$Line" ]; then
continue
fi
echo "mirror file line: $Line" >&2
eval MirrorList+=($Line)
done < "$MirrorListFile"
if [ -n "$Mirror" ]; then
SyncMirror::Mirror "$Mirror" "${MirrorList["$Mirror"]}"
else
declare -a ConcurrentArgs
for i in "${!MirrorList[@]}"; do
ConcurrentArgs+=(
'-' "$i" 'SyncMirror::Mirror' "$i" "${MirrorList["$i"]}"
)
done
eval concurrent "${ConcurrentArgs[@]}"
fi
exit 0