yann@1822
|
1 |
#!/bin/bash
|
yann@1822
|
2 |
#set -x
|
yann@1822
|
3 |
|
yann@1837
|
4 |
export LC_ALL=C
|
yann@1837
|
5 |
|
yann@1822
|
6 |
my_name="$( basename "${0}" )"
|
yann@1822
|
7 |
|
yann@1822
|
8 |
usage() {
|
yann@1822
|
9 |
cat <<-_EOF_
|
yann@1822
|
10 |
Usage:
|
yann@1822
|
11 |
${my_name} <repos_dir> <M.m.p>
|
yann@1822
|
12 |
_EOF_
|
yann@1822
|
13 |
}
|
yann@1822
|
14 |
|
yann@1822
|
15 |
repos="${1}"
|
yann@1822
|
16 |
version="${2}"
|
yann@1822
|
17 |
|
yann@1822
|
18 |
[ -n "${repos}" ] || { usage; exit 1; }
|
yann@1822
|
19 |
[ -d "${repos}" ] || { printf "${my_name}: ${repos}: no such file or directory\n"; exit 1; }
|
yann@1822
|
20 |
[ -n "${version}" ] || { usage; exit 1; }
|
yann@1822
|
21 |
|
yann@1822
|
22 |
gen_bound_revs() {
|
yann@1822
|
23 |
r1=$( hg log \
|
yann@1822
|
24 |
|awk 'BEGIN {
|
yann@1822
|
25 |
found=0;
|
yann@1822
|
26 |
}
|
yann@1822
|
27 |
$1=="'"${label}"':" {
|
yann@1822
|
28 |
split($2,a,":"); rev=a[1];
|
yann@1822
|
29 |
}
|
yann@1822
|
30 |
$0~/^summary:[[:space:]]*[[:digit:]]+\.[[:digit:]]+: '"${msg}"'/ \
|
yann@1822
|
31 |
&& found==0 {
|
yann@1822
|
32 |
printf( "%d\n", rev ); found=1;
|
yann@1822
|
33 |
}'
|
yann@1822
|
34 |
)
|
yann@1822
|
35 |
|
yann@1822
|
36 |
r2=$( hg log -b "${branch}" \
|
yann@1822
|
37 |
|awk '$1=="changeset:" {
|
yann@1822
|
38 |
split($2,a,":");
|
yann@1822
|
39 |
printf( "%d\n", a[1] );
|
yann@1822
|
40 |
nextfile;
|
yann@1822
|
41 |
}'
|
yann@1822
|
42 |
)
|
yann@1822
|
43 |
|
yann@1822
|
44 |
r1_log=$((r1+log_offset))
|
yann@1822
|
45 |
if [ ${#r1_log} -gt ${#r2} ]; then
|
yann@1822
|
46 |
rev_w=${#r1_log}
|
yann@1822
|
47 |
else
|
yann@1822
|
48 |
rev_w=${#r2}
|
yann@1822
|
49 |
fi
|
yann@1822
|
50 |
}
|
yann@1822
|
51 |
|
yann@1822
|
52 |
print_intro_mail() {
|
yann@1822
|
53 |
cat <<-_EOF_
|
yann@1822
|
54 |
Hello all!
|
yann@1822
|
55 |
|
yann@1822
|
56 |
I'm pleased to announce the release of crosstool-NG ${version}!
|
yann@1822
|
57 |
|
yann@1822
|
58 |
As usual, there has been quite a number of improvements, new features,
|
yann@1822
|
59 |
and bug fixes all around. The most notable changes are listed below:
|
yann@1822
|
60 |
|
yann@1822
|
61 |
YEM:
|
yann@1822
|
62 |
YEM: PUT YOUR MESSAGE HERE
|
yann@1822
|
63 |
YEM:
|
yann@1822
|
64 |
|
yann@1822
|
65 |
This marks the beginning of the ${ver_M}.${ver_m} maintenance branch, and the end of
|
yann@1822
|
66 |
the previous maintenance branch. As always, comments and suggestions
|
yann@1822
|
67 |
are most welcome!
|
yann@1822
|
68 |
|
yann@1822
|
69 |
The release can be found at the following URLs:
|
yann@1822
|
70 |
Changelog: http://ymorin.is-a-geek.org/download/crosstool-ng/crosstool-ng-${version}.changelog
|
yann@1822
|
71 |
Tarball: http://ymorin.is-a-geek.org/download/crosstool-ng/crosstool-ng-${version}.tar.bz2
|
yann@1833
|
72 |
Patches: http://ymorin.is-a-geek.org/download/crosstool-ng/01-fixes/${version}/
|
yann@1822
|
73 |
|
yann@1822
|
74 |
As a reminder, the home for crosstool-NG is:
|
yann@1822
|
75 |
http://ymorin.is-a-geek.org/projects/crosstool
|
yann@1822
|
76 |
|
yann@1822
|
77 |
Crosstool-NG also has a Freshmeat page:
|
yann@1833
|
78 |
http://freshmeat.net/projects/crosstool-ng
|
yann@1822
|
79 |
_EOF_
|
yann@1822
|
80 |
}
|
yann@1822
|
81 |
|
yann@1822
|
82 |
print_intro_changelog_full_release() {
|
yann@1822
|
83 |
cat <<-_EOF_
|
yann@1822
|
84 |
crosstool-NG ${version} -- ${date}
|
yann@1822
|
85 |
|
yann@1822
|
86 |
This is a feature-release. Significant changes are:
|
yann@1822
|
87 |
|
yann@1822
|
88 |
YEM:
|
yann@1822
|
89 |
YEM: PUT YOUR MESSAGE HERE
|
yann@1822
|
90 |
YEM:
|
yann@1822
|
91 |
_EOF_
|
yann@1822
|
92 |
}
|
yann@1822
|
93 |
|
yann@1822
|
94 |
print_intro_changelog_bug_fix() {
|
yann@1822
|
95 |
cat <<-_EOF_
|
yann@1822
|
96 |
crosstool-NG ${version} -- ${date}
|
yann@1822
|
97 |
|
yann@1822
|
98 |
This is a bug-fix-only release.
|
yann@1822
|
99 |
_EOF_
|
yann@1822
|
100 |
}
|
yann@1822
|
101 |
|
yann@1822
|
102 |
print_author_stats() {
|
yann@1822
|
103 |
printf "\nMany thanks to the people who contributed to this release:\n\n"
|
yann@1822
|
104 |
prev_author=""
|
yann@1822
|
105 |
template='{author|person}\n'
|
yann@1822
|
106 |
hg log -b "${branch}" -r "${r1_log}:${r2}" \
|
yann@1822
|
107 |
--template "${template}" \
|
yann@1822
|
108 |
|sed -r -e 's/"//g;' \
|
yann@1822
|
109 |
|awk -F '' '{
|
yann@1822
|
110 |
nb[$0]++;
|
yann@1822
|
111 |
}
|
yann@1822
|
112 |
END {
|
yann@1822
|
113 |
for( author in nb ) {
|
yann@1822
|
114 |
printf( " %4d %s\n", nb[author], author );
|
yann@1822
|
115 |
}
|
yann@1822
|
116 |
}' \
|
yann@1943
|
117 |
|sort -s -k1nr -k2
|
yann@1822
|
118 |
}
|
yann@1822
|
119 |
|
yann@1822
|
120 |
print_author_shortlog() {
|
yann@1822
|
121 |
printf "\nHere is the per-author shortlog:\n"
|
yann@1822
|
122 |
prev_author=""
|
yann@1822
|
123 |
template='{author|person}|{rev}|{branches}|{desc|firstline}\n'
|
yann@1822
|
124 |
hg log -b "${branch}" -r "${r1_log}:${r2}" \
|
yann@1822
|
125 |
--template "${template}" \
|
yann@1822
|
126 |
|awk -F '' '{
|
yann@1822
|
127 |
n=split( $0,a,"|" );
|
yann@1822
|
128 |
printf( "%s", gensub("\"","","g",a[1]) );
|
yann@1822
|
129 |
printf( "|%0*d", '${rev_w}', a[2] );
|
yann@1822
|
130 |
for(i=3;i<=n;i++) {
|
yann@1822
|
131 |
printf( "|%s", a[i] );
|
yann@1822
|
132 |
}
|
yann@1822
|
133 |
printf( "\n" );
|
yann@1822
|
134 |
}' \
|
yann@1822
|
135 |
|sort \
|
yann@1822
|
136 |
|while read line; do
|
yann@1822
|
137 |
author="$( echo "${line}" |cut -d \| -f 1 )"
|
yann@1822
|
138 |
rev="$( echo "${line}" |cut -d \| -f 2 )"
|
yann@1822
|
139 |
br="$( echo "${line}" |cut -d \| -f 3 )"
|
yann@1822
|
140 |
desc="$( echo "${line}" |cut -d \| -f 4- )"
|
yann@1822
|
141 |
|
yann@1822
|
142 |
case "${br}" in
|
yann@1822
|
143 |
${branch}) ;;
|
yann@1822
|
144 |
[0-9]*.*) continue;;
|
yann@1822
|
145 |
*) ;;
|
yann@1822
|
146 |
esac
|
yann@1822
|
147 |
|
yann@1822
|
148 |
case "${desc}" in
|
yann@1822
|
149 |
Merge.) continue;;
|
yann@1822
|
150 |
*": close "*" branch"*) continue;;
|
yann@1822
|
151 |
# *\(merged\)) continue;;
|
yann@1822
|
152 |
esac
|
yann@1822
|
153 |
|
yann@1822
|
154 |
author="$( echo "${author}" |sed -r -e 's/"//g;' )"
|
yann@1822
|
155 |
|
yann@1822
|
156 |
if [ ! "${prev_author}" = "${author}" ]; then
|
yann@1822
|
157 |
printf "\n"
|
yann@1822
|
158 |
printf " ${author}:\n"
|
yann@1822
|
159 |
prev_author="${author}"
|
yann@1822
|
160 |
fi
|
yann@1822
|
161 |
rev="$( echo "${rev}" |sed -r -e 's/^0*//;' )"
|
yann@1822
|
162 |
|
yann@1822
|
163 |
printf "%s\n" "${desc}" \
|
yann@1822
|
164 |
|fmt -w 65 \
|
yann@1822
|
165 |
|(first=1; while read l; do
|
yann@1822
|
166 |
if [ -n "${first}" ]; then
|
yann@1822
|
167 |
printf " [%*d] %s\n" ${rev_w} ${rev} "${l}"
|
yann@1822
|
168 |
first=
|
yann@1822
|
169 |
else
|
yann@1822
|
170 |
printf " %*.*s %s\n" ${rev_w} ${rev_w} '' "${l}"
|
yann@1822
|
171 |
fi
|
yann@1822
|
172 |
done)
|
yann@1822
|
173 |
done
|
yann@1822
|
174 |
}
|
yann@1822
|
175 |
|
yann@1822
|
176 |
print_diffstat() {
|
yann@1822
|
177 |
printf "\nThe diffstat follows:\n\n"
|
yann@1822
|
178 |
hg diff -r "${r1}:${r2}" --color=never \
|
yann@1822
|
179 |
|diffstat -r 2 -p 1 -w 10 \
|
yann@1822
|
180 |
|tail -n 1 \
|
yann@1822
|
181 |
|sed -r -e 's/^ */ /;'
|
yann@1822
|
182 |
|
yann@1822
|
183 |
hg diff -r "${r1}:${r2}" --color=never \
|
yann@1822
|
184 |
|diffstat -f 1 -r 2 -p 1 -w 10 \
|
yann@1822
|
185 |
|head -n -1 \
|
yann@1822
|
186 |
|while read file line; do
|
yann@1822
|
187 |
if [ ${#file} -gt 57 ]; then
|
yann@1833
|
188 |
file="$( echo "${file}" |sed -r -e 's/^(.{,24}).*(.{28})$/\1.....\2/;' )"
|
yann@1822
|
189 |
fi
|
yann@1822
|
190 |
printf " %-57s %s\n" "${file}" "${line}"
|
yann@1822
|
191 |
done
|
yann@1822
|
192 |
}
|
yann@1822
|
193 |
|
yann@1833
|
194 |
print_short_diffstat() {
|
yann@1833
|
195 |
printf "\nThe short diffstat follows:\n\n"
|
yann@1833
|
196 |
|
yann@1833
|
197 |
eval total=$(( $(
|
yann@1833
|
198 |
hg diff -r "${r1}:${r2}" --color=never "${i}" \
|
yann@1833
|
199 |
|diffstat -r 2 -p 1 -w 10 \
|
yann@1833
|
200 |
|tail -n 1 \
|
yann@1833
|
201 |
|sed -r -e 's/^[[:space:]]*[[:digit:]]+ files? changed(,[[:space:]]+|$)//;' \
|
yann@1833
|
202 |
-e 's/([[:digit:]]+)[^-\+]+\((-|\+)\)/\1/g;' \
|
yann@1833
|
203 |
-e 's/,//g; s/ /+/; s/^$/0/;'
|
yann@1833
|
204 |
) ))
|
yann@1833
|
205 |
printf " %-24.24s %5d(+/-)\n" "Total" ${total}
|
yann@1833
|
206 |
others=${total}
|
yann@1833
|
207 |
|
yann@1833
|
208 |
{ for i in \
|
yann@1833
|
209 |
kconfig/ \
|
yann@1833
|
210 |
patches/ \
|
yann@1833
|
211 |
config/*/ \
|
yann@1833
|
212 |
scripts/build/*/ \
|
yann@1833
|
213 |
samples/ \
|
yann@1833
|
214 |
; do
|
yann@1833
|
215 |
eval val=$(( $(
|
yann@1833
|
216 |
hg diff -r "${r1}:${r2}" --color=never "${i}" \
|
yann@1833
|
217 |
|diffstat -r 2 -p 1 -w 10 \
|
yann@1833
|
218 |
|tail -n 1 \
|
yann@1833
|
219 |
|sed -r -e 's/^[[:space:]]*[[:digit:]]+ files? changed(,[[:space:]]+|$)//;' \
|
yann@1833
|
220 |
-e 's/([[:digit:]]+)[^-\+]+\((-|\+)\)/\1/g;' \
|
yann@1833
|
221 |
-e 's/,//g; s/ /+/; s/^$/0/;'
|
yann@1833
|
222 |
) ))
|
yann@1833
|
223 |
if [ ${val} -gt $((total/100)) ]; then
|
yann@1833
|
224 |
printf "%d %s\n" $(((1000*val)/total)) "${i}"
|
yann@1833
|
225 |
others=$((others-val))
|
yann@1833
|
226 |
fi
|
yann@1833
|
227 |
done; printf "%d Others\n" $(((1000*others)/total)); } \
|
yann@1833
|
228 |
|sort -nr \
|
yann@1833
|
229 |
|{ while read v i; do
|
yann@1833
|
230 |
if [ "${i}" = "Others" ]; then
|
yann@1833
|
231 |
others=${v}
|
yann@1833
|
232 |
else
|
yann@1833
|
233 |
printf " %-24.24s %3d.%d%%\n" "${i}" $((v/10)) $((v%10))
|
yann@1833
|
234 |
fi
|
yann@1833
|
235 |
done; printf " %-24.24s %3d.%d%%\n" "Others" $((others/10)) $((others%10)); }
|
yann@1833
|
236 |
}
|
yann@1833
|
237 |
|
yann@1822
|
238 |
ver_M="$( printf "${version}" |cut -d . -f 1 )"
|
yann@1822
|
239 |
ver_m="$( printf "${version}" |cut -d . -f 2 )"
|
yann@1822
|
240 |
ver_p="$( printf "${version}" |cut -d . -f 3 )"
|
yann@1822
|
241 |
|
yann@1822
|
242 |
prefix="$(pwd)/crosstool-ng-${version}"
|
yann@1822
|
243 |
pushd "${repos}" >/dev/null 2>&1
|
yann@1822
|
244 |
|
yann@1822
|
245 |
printf "Checking for existing tag: "
|
yann@1822
|
246 |
if hg tags |grep -E '^'"crosstool-ng-${version}"'\>' >/dev/null; then
|
yann@1822
|
247 |
printf "already tagged\n"
|
yann@1822
|
248 |
exit 1
|
yann@1822
|
249 |
fi
|
yann@1822
|
250 |
printf "no\n"
|
yann@1822
|
251 |
|
yann@1822
|
252 |
if [ ${ver_p} -eq 0 ]; then
|
yann@1822
|
253 |
print_mail="yes"
|
yann@1822
|
254 |
print_intro_changelog="print_intro_changelog_full_release"
|
yann@1822
|
255 |
label="parent"
|
yann@1822
|
256 |
msg="create maintenance branch, (update|bump) version to [[:digit:]]+"'\'".[[:digit:]]+"'\'".0"'$'
|
yann@1822
|
257 |
branch="default"
|
yann@1822
|
258 |
log_offset=0
|
yann@1822
|
259 |
else
|
yann@1822
|
260 |
print_mail="no"
|
yann@1822
|
261 |
print_intro_changelog="print_intro_changelog_bug_fix"
|
yann@1822
|
262 |
label="changeset"
|
yann@1822
|
263 |
msg="(update|bump) version to ${ver_M}"'\'".${ver_m}"'\'".$((ver_p-1))"'\+hg$'
|
yann@1822
|
264 |
branch="${ver_M}.${ver_m}"
|
yann@1822
|
265 |
log_offset=1
|
yann@1822
|
266 |
fi
|
yann@1822
|
267 |
|
yann@1822
|
268 |
printf "Computing boundary revisions:"
|
yann@1822
|
269 |
gen_bound_revs
|
yann@1822
|
270 |
printf " %d:%d\n" ${r1} ${r2}
|
yann@1822
|
271 |
|
yann@1822
|
272 |
printf "Tagging release:"
|
yann@1822
|
273 |
hg up "${branch}" >/dev/null
|
yann@1822
|
274 |
if [ ${ver_p} -eq 0 ]; then
|
yann@1822
|
275 |
printf " update version"
|
yann@1822
|
276 |
hg branch "${ver_M}.${ver_m}" >/dev/null
|
yann@1822
|
277 |
echo "${version}" >".version"
|
yann@1822
|
278 |
hg ci -m "${ver_M}.${ver_m}: create maintenance branch, update version to ${version}"
|
yann@1822
|
279 |
else
|
yann@1822
|
280 |
printf " update version"
|
yann@1822
|
281 |
echo "${version}" >".version"
|
yann@1822
|
282 |
hg ci -m "${ver_M}.${ver_m}: update version to ${version}"
|
yann@1822
|
283 |
fi
|
yann@1822
|
284 |
|
yann@1822
|
285 |
printf ", tag"
|
yann@1822
|
286 |
hg tag -m "Tagging release ${version}" crosstool-ng-${version}
|
yann@1822
|
287 |
|
yann@1822
|
288 |
printf ", update version"
|
yann@1822
|
289 |
echo "${version}+hg" >".version"
|
yann@1822
|
290 |
hg ci -m "${ver_M}.${ver_m}: update version to ${version}+hg"
|
yann@1822
|
291 |
|
yann@1822
|
292 |
printf ", date"
|
yann@1822
|
293 |
date="$( hg log -r crosstool-ng-${version} --template '{date|isodate}\n' \
|
yann@1822
|
294 |
|sed -r -e 's/-|://g; s/ /./; s/ //;' \
|
yann@1822
|
295 |
)"
|
yann@1822
|
296 |
printf ", done.\n"
|
yann@1822
|
297 |
|
yann@1822
|
298 |
if [ ${ver_p} -eq 0 ]; then
|
yann@1822
|
299 |
printf "Generating release mail:"
|
yann@1822
|
300 |
printf " intro"
|
yann@1822
|
301 |
print_intro_mail > "${prefix}.mail"
|
yann@1822
|
302 |
printf ", stats"
|
yann@1822
|
303 |
print_author_stats >>"${prefix}.mail"
|
yann@1822
|
304 |
printf ", shortlog"
|
yann@1822
|
305 |
print_author_shortlog >>"${prefix}.mail"
|
yann@1833
|
306 |
printf ", diffstat"
|
yann@1833
|
307 |
print_short_diffstat >>"${prefix}.mail"
|
yann@1822
|
308 |
printf ", done.\n"
|
yann@1822
|
309 |
fi
|
yann@1822
|
310 |
|
yann@1822
|
311 |
printf "Generating release changelog:"
|
yann@1822
|
312 |
printf " intro"
|
yann@1822
|
313 |
${print_intro_changelog} > "${prefix}.changelog"
|
yann@1822
|
314 |
printf ", stats"
|
yann@1822
|
315 |
print_author_stats >>"${prefix}.changelog"
|
yann@1822
|
316 |
printf ", shortlog"
|
yann@1822
|
317 |
print_author_shortlog >>"${prefix}.changelog"
|
yann@1822
|
318 |
printf ", diffstat"
|
yann@1822
|
319 |
print_diffstat >>"${prefix}.changelog"
|
yann@1822
|
320 |
printf ", done.\n"
|
yann@1822
|
321 |
|
yann@1822
|
322 |
popd >/dev/null 2>&1
|
yann@1822
|
323 |
|
yann@1822
|
324 |
printf "Creating tarball:"
|
yann@1822
|
325 |
prefix="crosstool-ng-${version}"
|
yann@2028
|
326 |
printf " archive"
|
yann@2028
|
327 |
hg archive --cwd "${repos}" -r "${prefix}" -X '.hg*' "$(pwd)/${prefix}.tar.bz2"
|
yann@2028
|
328 |
date="$( hg log -R "${repos}" -r "${prefix}" --template '{date|rfc822date}\n' )"
|
yann@1822
|
329 |
printf ", sum"
|
yann@1822
|
330 |
for s in md5 sha1 sha512; do
|
yann@1822
|
331 |
${s}sum "${prefix}.tar.bz2" >"${prefix}.tar.bz2.${s}"
|
yann@1822
|
332 |
done
|
yann@1822
|
333 |
printf ", touch"
|
yann@1822
|
334 |
touch -d "${date}" "${prefix}"*
|
yann@1822
|
335 |
printf ", done.\n"
|
yann@1822
|
336 |
|
yann@1822
|
337 |
if [ ${ver_p} -eq 0 ]; then
|
yann@1822
|
338 |
printf "\nAn editor will be launched for you to edit the mail.\n"
|
yann@1822
|
339 |
read -p "Press enter when ready..." foo
|
yann@1833
|
340 |
cp "${prefix}.mail"{,.orig}
|
yann@1822
|
341 |
vi "${prefix}.mail"
|
yann@1833
|
342 |
diff -du -U 1 "${prefix}.mail"{.orig,} |patch -p0 "${prefix}.changelog" >/dev/null
|
yann@1833
|
343 |
rm -f "${prefix}".{mail,changelog}.orig
|
yann@1822
|
344 |
fi
|
yann@1822
|
345 |
|
yann@1822
|
346 |
printf "\nAn editor will be launched for you to review the changelog.\n"
|
yann@1822
|
347 |
read -p "Press enter when ready..." foo
|
yann@1822
|
348 |
vi "${prefix}.changelog"
|
yann@1822
|
349 |
|
yann@1822
|
350 |
printf "\nNow, you can push the changes with: hg push -R '${repos}'\n"
|