-
Notifications
You must be signed in to change notification settings - Fork 1
/
template-sync.sh
executable file
·203 lines (162 loc) · 4.78 KB
/
template-sync.sh
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/bin/sh
url=""
threshold=20
debug=false
commit=""
directory=""
while [ "$#" -gt 0 ]; do
case "$1" in
--threshold=*)
threshold="${1#*=}"
;;
--debug)
debug=true
;;
--commit=*)
commit="${1#*=}"
;;
--directory=*)
directory="${1#*=}"
;;
*)
if [ -z "$url" ]; then
url="$1"
else
echo "Unknown argument : $1"
exit 1
fi
;;
esac
shift
done
if "$debug"; then
exec 3>&1
else
exec 3>/dev/null
fi
project_dir=$(pwd)
temp_dir=$(mktemp -d)
cd "$temp_dir" || return
mkdir temp
mkdir template
mkdir project
mkdir template_modified
mkdir project_modified
git_template_sync() {
if [ "$debug" = true ]; then
git "$@"
else
git "$@" 1>&3 2>&3
fi
}
removing_useless_files() {
path="$1"
if [ -d "$path" ]; then
find "$path" -type f -name "*.lock" -exec rm -f {} +
find "$path" -type f -name "*-lock*" -exec rm -f {} +
find "$path" -type d -name ".git" -exec rm -rf {} +
# find "$path" -type f -name "*.json" -exec rm -f {} +
find "$path" -type f -name "*.md" -exec rm -f {} +
find "$path" -type f -name "*README*" -exec rm -f {} +
else
echo "Error while sorting useless files"
exit 1
fi
}
estimate_similarity_index() {
git_template_sync checkout "$sha"
cp -r . ../template_modified
removing_useless_files "../template_modified"
total_template_modified_files=$(find "../template_modified" -type f | wc -l)
cd ..
tmpfile1=$(mktemp)
tmpfile2=$(mktemp)
(find template_modified/ -type f | sort | sed -e 's|template_modified/||' -e 's/\.yml/\.yaml/') > "$tmpfile1"
(find project_modified/ -type f | sort | sed -e 's|project_modified/||' -e 's/\.yml/\.yaml/') > "$tmpfile2"
common_files=$(comm -12 "$tmpfile1" "$tmpfile2" | wc -l)
ratio=$(echo "scale=4; $common_files / $total_template_modified_files" | bc)
ratio_percent=$(printf "%.0f" "$(echo "$ratio * 100" | bc)")
rm "$tmpfile1" "$tmpfile2"
}
git_template_sync clone "$project_dir" project/
cp -r project/* project_modified/
removing_useless_files "project_modified"
if [ -n "$directory" ]; then
git_template_sync clone "$url" temp/
cd temp/ || return
git_template_sync subtree split -P "$directory" -b branch/template
cd ../template/ || return
git_template_sync init
git_template_sync pull ../temp/ branch/template
else
git_template_sync clone "$url" template/
cd template/ || return
fi
if [ -n "$commit" ]; then
git_template_sync reset --hard "$commit"
fi
api_shas=$(git log --pretty=format:"%H")
index=0
for sha in $api_shas;
do
estimate_similarity_index
if [ "$index" -eq 0 ]; then
ratioMax=$ratio_percent
ratioMin=$ratio_percent
fi
if [ "$ratio_percent" -gt "$ratioMax" ]; then
ratioMax=$ratio_percent
elif [ "$ratio_percent" -lt "$ratioMin" ]; then
ratioMin=$ratio_percent
fi
rm -rf template_modified/*
cd template/ || return
index=$((index + 1))
done
ratioThreshold=$(echo "$ratioMax - ($ratioMax - $ratioMin) / 3" | bc)
index=0
for sha in $api_shas;
do
estimate_similarity_index
if [ "$ratio_percent" -gt "$ratioThreshold" ] || [ "$ratio_percent" -eq "$ratioThreshold" ]; then
diff=$(git diff --shortstat --no-index --diff-filter=d -- project template_modified)
insertions=$(echo "$diff" | awk '{print $4}')
deletions=$(echo "$diff" | awk '{print $6}')
sum=$((insertions + deletions))
if [ $index -eq 0 ]; then
minSum=$sum
wantedSha=$sha
fi
if [ -z "$minSum" ]; then
echo "Error during the commits sorting process"
exit 1
fi
if [ $sum -lt "$minSum" ] || [ $sum -eq "$minSum" ]; then
minSum=$sum
wantedSha=$sha
fi
index=$((index + 1))
fi
rm -rf template_modified/*
cd template/ || return
done
echo "The targeted commit in the template is :"
git --no-pager show --no-patch "$wantedSha"
if [ -n "$directory" ]; then
printf "\n\n"
echo "As your template comes from the subdirectory of a monorepo,
its SHA is different from the monorepo history. If you want to check it, use his name, tag or date to retrieve it."
fi
printf "\n\n"
git_template_sync checkout main
git_template_sync switch -c template-squash
# echo "Enter the message for the commit which is gonna be cherry picked on your project"
# read -r message
git reset --soft "$wantedSha" && git_template_sync commit -m "squashed commit updating template"
squash_commit=$(git rev-parse HEAD)
cd "$project_dir" || return
git_template_sync remote add template "$temp_dir"/template
git_template_sync fetch template template-squash
git cherry-pick -Xrename-threshold="$threshold"% "$squash_commit"
git_template_sync remote rm template
rm -rf "$temp_dir"