minor fix to release script
[cvc5.git] / contrib / cut-release
1 #!/bin/bash
2 #
3 # usage: cut-release [-n] version-designation [make-args...]
4 #
5
6 function isthatright {
7 if [ -z "$1" ]; then
8 echo -n "Does that look right? [y/n] "
9 else
10 echo -n "$1? [y/n] "
11 fi
12 while read yn; do
13 if [ "$yn" = y -o "$yn" = Y -o "$yn" = yes -o "$yn" = YES -o "$yn" = Yes ]; then
14 break
15 elif [ "$yn" = n -o "$yn" = N -o "$yn" = no -o "$yn" = NO -o "$yn" = No ]; then
16 echo "Aborting as per user request." >&2
17 exit 1
18 else
19 echo -n "[y/n] "
20 fi
21 done
22 }
23
24 if [ "$1" = -n ]; then
25 dryrun=true
26 shift
27 else
28 dryrun=false
29 fi
30
31 if [ $# -lt 1 ]; then
32 echo "Usage: $(basename "$0") [-n] version-designation [make-args...]" >&2
33 echo "-n does a dry run (i.e., do sanity checks and build but don't touch the repository)"
34 exit 1
35 fi
36
37 if ! [ -e src/expr/node.h -a -e .svn ]; then
38 echo "$(basename "$0"): ERROR: You should run this from the top-level of a CVC4 subversion working directory" >&2
39 exit 1
40 fi
41
42 version="$1"
43 shift
44
45 if echo "$version" | grep '[^a-zA-Z0-9_.+(){}^%#-]' &>/dev/null; then
46 echo "$(basename "$0"): ERROR: Version designation \`$version' contains illegal characters" >&2
47 exit 1
48 fi
49
50 eval "declare -a vs=($(echo "$version" | sed 's,^\([0-9]*\)\.\([0-9]*\)\(\.\([0-9]*\)\)\?\(.*\),[0]=\1 [1]=\2 [2]=\4 [3]=\5,'))"
51 major=${vs[0]}
52 minor=${vs[1]}; if [ -z "$minor" ]; then minor=0; fi
53 release=${vs[2]}; if [ -z "$release" ]; then release=0; fi
54 extra=${vs[3]}
55 echo
56 echo "Major : $major"
57 echo "Minor : $minor"
58 echo "Release: $release"
59 echo "Extra : $extra"
60 echo
61 version="$major.$minor"
62 if [ "$release" != 0 ]; then
63 version="$version.$release"
64 fi
65 version="$version$extra"
66 echo "Version: $version"
67 echo
68 isthatright
69
70 echo "Checking whether release \`$version' already exists..."
71 if ! svn ls "https://subversive.cims.nyu.edu/cvc4/cvc4/tags/releases/$version" 2>&1 >/dev/null | grep non-existent >/dev/null; then
72 echo "$(basename "$0"): ERROR: Subversion repo already contains a release \`$version'" >&2
73 $dryrun || exit 1
74 fi
75
76 echo "Checking working directory for local modifications..."
77 if $dryrun; then
78 if [ -n "$(svn status -q configure.ac)" ]; then
79 echo "$(basename "$0"): ERROR: In dry-run mode, cannot operate properly with local modifications to \"configure.ac\", sorry" >&2
80 exit 1
81 fi
82 elif [ -n "$(svn status -q)" ]; then
83 echo "$(basename "$0"): ERROR: \"svn status\" indicates there are local modifications; please commit first" >&2
84 exit 1
85 fi
86
87 root="$(svn info | grep "^Repository Root: https://subversive.cims.nyu.edu/.*" | cut -f3 -d' ')"
88 if [ -z "$root" ]; then
89 echo "$(basename "$0"): ERROR: Can't get repository root URL" 2>&1
90 $dryrun || exit 1
91 fi
92
93 echo "Checking repo for unmerged updates..."
94 if [ `svn -uq status | grep -v '^M *[0-9]* *NEWS$' | wc -l` -ne 1 ]; then
95 echo "$(basename "$0"): ERROR: This working directory isn't up to date" 2>&1
96 $dryrun || exit 1
97 fi
98
99 echo "Checking sources for broken public headers..."
100 suspect_files="\
101 $(grep -r --exclude-dir=.svn '^[ \t]*#[ \t]*include[ \t]*"[^/]*"' src |
102 grep -v '"cvc4parser_public\.h"' |
103 grep -v '"cvc4_public\.h"' |
104 grep -v '"cvc4_private\.h"' |
105 grep -v '"cvc4autoconfig\.h"' |
106 grep -v '"cvc4parser_private\.h"' |
107 cut -f1 -d: |
108 sort -u |
109 xargs grep -l '^[ \t]*#[ \t]*include[ \t]*"cvc4.*public\.h"' |
110 xargs echo)"
111 if [ -n "$suspect_files" ]; then
112 echo "$(basename "$0"): ERROR: The following publicly-installed headers appear" 2>&1
113 echo "$(basename "$0"): ERROR: to have relative #includes and may be broken up" 2>&1
114 echo "$(basename "$0"): ERROR: on install: $suspect_files" 2>&1
115 $dryrun || exit 1
116 fi
117
118 echo "Checking NEWS file for recent updates..."
119 if [ -n "$(svn status -q NEWS)" ]; then
120 echo "+ It's locally modified."
121 else
122 echo -n "+ "
123 svn info NEWS | grep '^Last Changed Date: '
124 echo
125 echo "You should probably make sure to put some notes in the NEWS file"
126 echo "for this release, indicating the most important changes from the"
127 echo "last release."
128 echo
129 isthatright "Continue without updating NEWS"
130 fi
131
132 echo "Adjusting version info lines in configure.ac..."
133 if ! grep '^m4_define(_CVC4_MAJOR, *[0-9][0-9]* *)' configure.ac &>/dev/null ||
134 ! grep '^m4_define(_CVC4_MINOR, *[0-9][0-9]* *)' configure.ac &>/dev/null ||
135 ! grep '^m4_define(_CVC4_RELEASE, *[0-9][0-9]* *)' configure.ac &>/dev/null ||
136 ! grep '^m4_define(_CVC4_EXTRAVERSION, *\[.*\] *)' configure.ac &>/dev/null; then
137 echo "$(basename "$0"): ERROR: Cannot locate the version info lines of configure.ac" >&2
138 $dryrun || exit 1
139 fi
140 perl -pi -e 's/^m4_define\(_CVC4_MAJOR, ( *)[0-9]+( *)\)/m4_define(_CVC4_MAJOR, ${1}'"$major"'$2)/;
141 s/^m4_define\(_CVC4_MINOR, ( *)[0-9]+( *)\)/m4_define(_CVC4_MINOR, ${1}'"$minor"'$2)/;
142 s/^m4_define\(_CVC4_RELEASE, ( *)[0-9]+( *)\)/m4_define(_CVC4_RELEASE, ${1}'"$release"'$2)/;
143 s/^m4_define\(_CVC4_EXTRAVERSION, ( *)\[.*\]( *)\)/m4_define(_CVC4_EXTRAVERSION, $1\['"$extra"'\]$2)/' configure.ac
144
145 trap 'echo; echo; echo "Aborting in error."; svn revert configure.ac; echo' EXIT
146
147 echo
148 echo 'Made the following change to configure.ac:'
149 echo
150 svn diff configure.ac
151 echo
152 isthatright
153
154 if ! grep '^m4_define(_CVC4_MAJOR, *'"$major"' *)' configure.ac &>/dev/null ||
155 ! grep '^m4_define(_CVC4_MINOR, *'"$minor"' *)' configure.ac &>/dev/null ||
156 ! grep '^m4_define(_CVC4_RELEASE, *'"$release"' *)' configure.ac &>/dev/null ||
157 ! grep '^m4_define(_CVC4_EXTRAVERSION, *\['"$extra"'\] *)' configure.ac &>/dev/null; then
158 echo "$(basename "$0"): INTERNAL ERROR: Cannot find the modified version info lines in configure.ac, bailing..." >&2
159 exit 1
160 fi
161 if [ -z "$(svn status -q configure.ac)" ]; then
162 echo "$(basename "$0"): INTERNAL ERROR: \"svn status\" indicates there are no local modifications to configure.ac; I expected the ones I just made!" >&2
163 exit 1
164 fi
165
166 echo "Building and checking distribution \`cvc4-$version'..."
167 if ! $SHELL -c '\
168 version="'$version'"; \
169 set -ex; \
170 ./autogen.sh || echo "autoconf failed; does library_versions have something to match $version?"; \
171 mkdir "release-$version"; \
172 cd "release-$version"; \
173 ../configure production-cln-staticbinary --disable-shared --enable-unit-testing --without-cudd --with-readline --with-portfolio; \
174 make dist "$@"; \
175 tar xf "cvc4-$version.tar.gz"; \
176 cd "cvc4-$version"; \
177 ./configure production-cln-staticbinary --disable-shared --enable-unit-testing --without-cudd --with-readline --with-portfolio; \
178 make check "$@"; \
179 make distcheck "$@"; \
180 '; then
181 exit 1
182 fi
183
184 if ! [ -e release-$version/cvc4-$version.tar.gz ]; then
185 echo "$(basename "$0"): INTERNAL ERROR: Cannot find the distribution tarball I just built" >&2
186 exit 1
187 fi
188 if ! [ -e release-$version/src/main/cvc4 ]; then
189 echo "$(basename "$0"): INTERNAL ERROR: Cannot find the binary I just built" >&2
190 exit 1
191 fi
192
193 echo
194 echo 'This release of CVC4 will identify itself as:'
195 echo
196 release-$version/src/main/cvc4 --version
197 echo
198 isthatright
199
200 echo
201 echo 'This binary release of CVC4 will identify itself as being configured like this:'
202 echo
203 release-$version/src/main/cvc4 --show-config
204 echo
205 isthatright
206
207 echo
208 echo "Signing tarball..."
209 cp -p "release-$version/cvc4-$version.tar.gz" .
210 gpg -b --armor "cvc4-$version.tar.gz"
211
212 echo
213 echo "Signing cvc4 binary..."
214 cp -p "release-$version/src/main/cvc4" "cvc4-$version"
215 gpg -b --armor "cvc4-$version"
216
217 echo
218 echo "Signing pcvc4 binary..."
219 cp -p "release-$version/src/main/pcvc4" "pcvc4-$version"
220 gpg -b --armor "pcvc4-$version"
221
222 echo
223 echo "About to run: svn commit -m \"Cutting release $version.\""
224 isthatright
225 $dryrun || svn commit -m "Cutting release $version."
226
227 echo
228 echo "About to run: svn copy -m \"Cutting release $version.\" \"$root\" \"https://subversive.cims.nyu.edu/cvc4/cvc4/tags/releases/$version\""
229 isthatright
230 $dryrun || svn copy -m "Cutting release $version." "$root" "https://subversive.cims.nyu.edu/cvc4/cvc4/tags/releases/$version"
231
232 echo
233 if [ "$(svn info | grep '^URL: https://subversive.cims.nyu.edu/cvc4/cvc4/trunk$')" ]; then
234 if [ "$release" = 0 ]; then
235 echo "About to run: svn copy -m \"Branching release $version for bugfixes.\" \"https://subversive.cims.nyu.edu/cvc4/cvc4/tags/releases/$version\" \"https://subversive.cims.nyu.edu/cvc4/cvc4/branches/releases/$version.x\""
236 isthatright
237 $dryrun || svn copy -m "Branching release $version for bugfixes." "https://subversive.cims.nyu.edu/cvc4/cvc4/tags/releases/$version" "https://subversive.cims.nyu.edu/cvc4/cvc4/branches/releases/$version.x"
238 else
239 echo "Not branching, because this is a minor release (i.e., not a \"dot-oh\""
240 echo "release), so I'm guessing you have a devel repository outside of trunk"
241 echo "somewhere? You can still make a branch manually, of course."
242 fi
243 else
244 echo "Not branching, because it appears there already is a branch"
245 echo "to work with for version $version ..? (You're not on trunk.)"
246 echo "You can still make a branch manually, of course."
247 fi
248
249 echo
250 echo "Done. Next steps are to upload and advertise these packages and to add"
251 echo "a $version release to Bugzilla."
252
253 trap '' EXIT
254