Commit | Line | Data |
---|---|---|
66b87493 | 1 | #!/bin/bash |
4dde498b | 2 | ### update_autogen - update some auto-generated files in the Emacs tree |
66b87493 | 3 | |
ab422c4d | 4 | ## Copyright (C) 2011-2013 Free Software Foundation, Inc. |
66b87493 GM |
5 | |
6 | ## Author: Glenn Morris <rgm@gnu.org> | |
7 | ||
8 | ## This file is part of GNU Emacs. | |
9 | ||
10 | ## GNU Emacs is free software: you can redistribute it and/or modify | |
11 | ## it under the terms of the GNU General Public License as published by | |
12 | ## the Free Software Foundation, either version 3 of the License, or | |
13 | ## (at your option) any later version. | |
14 | ||
15 | ## GNU Emacs is distributed in the hope that it will be useful, | |
16 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | ## GNU General Public License for more details. | |
19 | ||
20 | ## You should have received a copy of the GNU General Public License | |
21 | ## along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
22 | ||
23 | ### Commentary: | |
24 | ||
4dde498b GM |
25 | ## This is a helper script to update some generated files in the Emacs |
26 | ## repository. This is suitable for running from cron. | |
66b87493 | 27 | ## Only Emacs maintainers need use this, so it uses bash features. |
c0274801 | 28 | ## |
4dde498b GM |
29 | ## By default, it updates the versioned loaddefs-like files in lisp, |
30 | ## except ldefs-boot.el. | |
66b87493 GM |
31 | |
32 | ### Code: | |
33 | ||
9ee0d174 | 34 | die () # write error to stderr and exit |
66b87493 GM |
35 | { |
36 | [ $# -gt 0 ] && echo "$PN: $@" >&2 | |
37 | exit 1 | |
38 | } | |
39 | ||
40 | PN=${0##*/} # basename of script | |
41 | PD=${0%/*} | |
42 | ||
43 | [ "$PD" = "$0" ] && PD=. # if PATH includes PWD | |
44 | ||
4dde498b | 45 | ## This should be the admin directory. |
66b87493 GM |
46 | cd $PD |
47 | cd ../ | |
4dde498b | 48 | [ -d admin ] || die "Could not locate admin directory" |
66b87493 GM |
49 | |
50 | ||
9ee0d174 | 51 | usage () |
66b87493 GM |
52 | { |
53 | cat 1>&2 <<EOF | |
f9405d87 | 54 | Usage: ${PN} [-f] [-c] [-q] [-A dir] [-I] [-L] [-C] [-- make-flags] |
4dde498b GM |
55 | Update some auto-generated files in the Emacs tree. |
56 | By default, only does the versioned loaddefs-like files in lisp/. | |
57 | This requires a build. Passes any non-option args to make (eg -- -j2). | |
66b87493 GM |
58 | Options: |
59 | -f: force an update even if the source files are locally modified. | |
60 | -c: if the update succeeds and the generated files are modified, | |
61 | commit them (caution). | |
62 | -q: be quiet; only give error messages, not status messages. | |
4dde498b | 63 | -A: only update autotools files, copying into specified dir. |
f9405d87 | 64 | -I: also update info/dir. |
11043dbd | 65 | -L: also update ldefs-boot.el. |
c0274801 | 66 | -C: start from a clean state. Slower, but more correct. |
66b87493 GM |
67 | EOF |
68 | exit 1 | |
69 | } | |
70 | ||
71 | ||
72 | ## Defaults. | |
73 | ||
74 | force= | |
75 | commit= | |
76 | quiet= | |
c0274801 | 77 | clean= |
4dde498b GM |
78 | autogendir= # was "autogen" |
79 | ldefs_flag=1 | |
11043dbd | 80 | lboot_flag= |
f9405d87 | 81 | info_flag= |
66b87493 GM |
82 | |
83 | ## Parameters. | |
c0274801 GM |
84 | ldefs_in=lisp/loaddefs.el |
85 | ldefs_out=lisp/ldefs-boot.el | |
c4444d16 | 86 | sources="configure.ac lib/Makefile.am" |
4dde498b GM |
87 | ## Files to copy into autogendir. |
88 | ## Everything: | |
74b880cb PE |
89 | genfiles=" |
90 | configure aclocal.m4 src/config.in lib/Makefile.in | |
91 | build-aux/compile build-aux/config.guess build-aux/config.sub | |
92 | build-aux/depcomp build-aux/install-sh build-aux/missing | |
93 | " | |
4dde498b GM |
94 | ## msdos-only: |
95 | genfiles="src/config.in lib/Makefile.in" | |
66b87493 GM |
96 | |
97 | for g in $genfiles; do | |
98 | basegen="$basegen ${g##*/}" | |
99 | done | |
100 | ||
101 | [ "$basegen" ] || die "internal error" | |
102 | ||
103 | tempfile=/tmp/$PN.$$ | |
104 | ||
105 | trap "rm -f $tempfile 2> /dev/null" EXIT | |
106 | ||
107 | ||
f9405d87 | 108 | while getopts ":hcfqA:CIL" option ; do |
66b87493 GM |
109 | case $option in |
110 | (h) usage ;; | |
111 | ||
112 | (c) commit=1 ;; | |
113 | ||
114 | (f) force=1 ;; | |
115 | ||
116 | (q) quiet=1 ;; | |
117 | ||
4dde498b GM |
118 | (A) autogendir=$OPTARG |
119 | [ -d "$autogendir" ] || die "No autogen directory: $autogendir" | |
120 | ;; | |
121 | ||
c0274801 GM |
122 | (C) clean=1 ;; |
123 | ||
f9405d87 GM |
124 | (I) info_flag=1 ;; |
125 | ||
11043dbd GM |
126 | (L) lboot_flag=1 ;; |
127 | ||
66b87493 GM |
128 | (\?) die "Bad option -$OPTARG" ;; |
129 | ||
130 | (:) die "Option -$OPTARG requires an argument" ;; | |
131 | ||
132 | (*) die "getopts error" ;; | |
133 | esac | |
134 | done | |
135 | shift $(( --OPTIND )) | |
136 | OPTIND=1 | |
137 | ||
66b87493 | 138 | |
c0274801 | 139 | ## Does not work 100% because a lot of Emacs batch output comes on stderr (?). |
904a432c | 140 | [ "$quiet" ] && exec 1> /dev/null |
66b87493 GM |
141 | |
142 | ||
904a432c | 143 | echo "Running bzr status..." |
66b87493 | 144 | |
f9405d87 GM |
145 | bzr status -S ${autogendir:+$sources} ${ldefs_flag:+lisp} \ |
146 | ${info_flag:+doc} >| $tempfile || \ | |
4dde498b | 147 | die "bzr status error for input files" |
66b87493 | 148 | |
c0274801 | 149 | ## The lisp portion could be more permissive, eg only care about .el files. |
66b87493 GM |
150 | while read stat file; do |
151 | ||
152 | case $stat in | |
153 | M) | |
904a432c | 154 | echo "Locally modified: $file" |
66b87493 GM |
155 | [ "$force" ] || die "There are local modifications" |
156 | ;; | |
157 | ||
158 | *) die "Unexpected status ($stat) for $file" ;; | |
159 | esac | |
160 | done < $tempfile | |
161 | ||
162 | ||
c0274801 GM |
163 | ## Probably this is overkill, and there's no need to "bootstrap" just |
164 | ## for making autoloads. | |
165 | [ "$clean" ] && { | |
166 | ||
167 | echo "Running 'make maintainer-clean'..." | |
168 | ||
169 | make maintainer-clean #|| die "Cleaning error" | |
170 | ||
171 | rm -f $ldefs_in | |
172 | } | |
173 | ||
174 | ||
904a432c | 175 | echo "Running autoreconf..." |
66b87493 | 176 | |
c0274801 | 177 | autoreconf ${clean:+-f} -i -I m4 2>| $tempfile |
f6ca84c0 GM |
178 | |
179 | retval=$? | |
180 | ||
181 | ## Annoyingly, autoreconf puts the "installing `./foo' messages on stderr. | |
182 | if [ "$quiet" ]; then | |
183 | grep -v 'installing `\.' $tempfile 1>&2 | |
184 | else | |
185 | cat "$tempfile" 1>&2 | |
186 | fi | |
187 | ||
188 | [ $retval -ne 0 ] && die "autoreconf error" | |
66b87493 GM |
189 | |
190 | ||
c0274801 GM |
191 | ## Uses global $commit. |
192 | commit () | |
193 | { | |
194 | local type=$1 | |
195 | shift | |
196 | ||
197 | [ $# -gt 0 ] || { | |
198 | echo "No files were modified" | |
199 | return 0 | |
200 | } | |
201 | ||
202 | echo "Modified file(s): $@" | |
203 | ||
204 | [ "$commit" ] || return 0 | |
205 | ||
206 | echo "Committing..." | |
207 | ||
208 | ## bzr status output is always relative to top-level, not PWD. | |
209 | bzr commit -m "Auto-commit of $type files." "$@" || return $? | |
210 | ||
211 | echo "Committed files: $@" | |
212 | } # function commit | |
213 | ||
214 | ||
62bd73fa GM |
215 | ## No longer used since info/dir is now generated at install time if needed, |
216 | ## and is not in the repository any more. | |
f9405d87 GM |
217 | info_dir () |
218 | { | |
62bd73fa | 219 | local basefile=build-aux/dir_top outfile=info/dir |
f9405d87 GM |
220 | |
221 | echo "Regenerating info/dir..." | |
222 | ||
223 | ## Header contains non-printing characters, so this is more | |
224 | ## reliable than using echo. | |
225 | rm -f $outfile | |
226 | cp $basefile $outfile | |
227 | ||
228 | local topic file dircat dirent | |
229 | ||
230 | ## FIXME inefficient looping. | |
231 | for topic in "Texinfo documentation system" "Emacs" "GNU Emacs Lisp" \ | |
232 | "Emacs editing modes" "Emacs network features" "Emacs misc features" \ | |
233 | "Emacs lisp libraries"; do | |
234 | ||
235 | cat - <<EOF >> $outfile | |
236 | ||
237 | $topic | |
238 | EOF | |
239 | ## Bit faster than doc/*/*.texi. | |
240 | for file in doc/emacs/emacs.texi doc/lispintro/*.texi \ | |
241 | doc/lispref/elisp.texi doc/misc/*.texi; do | |
242 | ||
243 | ## FIXME do not ignore w32 if OS is w32. | |
244 | case $file in | |
245 | *-xtra.texi|*efaq-w32.texi) continue ;; | |
246 | esac | |
247 | ||
248 | dircat=`sed -n -e 's/@value{emacsname}/Emacs/' -e 's/^@dircategory //p' $file` | |
249 | ||
62bd73fa GM |
250 | ## TODO warn about unknown topics (check-info in top-level |
251 | ## Makefile does this). | |
f9405d87 GM |
252 | [ "$dircat" = "$topic" ] || continue |
253 | ||
254 | sed -n -e 's/@value{emacsname}/Emacs/' \ | |
255 | -e 's/@acronym{\([A-Z]*\)}/\1/' \ | |
256 | -e '/^@direntry/,/^@end direntry/ s/^\([^@]\)/\1/p' \ | |
257 | $file >> $outfile | |
258 | ||
259 | done | |
260 | done | |
261 | ||
262 | bzr status -S $outfile >| $tempfile || \ | |
263 | die "bzr status error for generated $outfile" | |
264 | ||
265 | local modified | |
266 | ||
267 | while read stat file; do | |
268 | ||
269 | [ "$stat" != "M" ] && \ | |
270 | die "Unexpected status ($stat) for generated $file" | |
271 | ||
272 | modified="$modified $file" | |
273 | ||
274 | done < $tempfile | |
275 | ||
675f2d6d | 276 | commit "info/dir" $modified || die "bzr commit error" |
f9405d87 GM |
277 | } # function info_dir |
278 | ||
279 | ||
4dde498b GM |
280 | [ "$autogendir" ] && { |
281 | ||
282 | oldpwd=$PWD | |
283 | ||
284 | cp $genfiles $autogendir/ | |
285 | ||
286 | cd $autogendir || die "cd error for $autogendir" | |
287 | ||
288 | echo "Checking status of generated files..." | |
289 | ||
290 | bzr status -S $basegen >| $tempfile || \ | |
291 | die "bzr status error for generated files" | |
292 | ||
293 | modified= | |
294 | ||
295 | while read stat file; do | |
296 | ||
297 | [ "$stat" != "M" ] && \ | |
298 | die "Unexpected status ($stat) for generated $file" | |
299 | ||
300 | modified="$modified $file" | |
301 | ||
302 | done < $tempfile | |
303 | ||
304 | cd $oldpwd | |
305 | ||
306 | commit "generated" $modified || die "bzr commit error" | |
307 | ||
308 | exit 0 | |
309 | } # $autogendir | |
c0274801 GM |
310 | |
311 | ||
f9405d87 GM |
312 | [ "$info_flag" ] && info_dir |
313 | ||
314 | ||
c0274801 GM |
315 | [ "$ldefs_flag" ] || exit 0 |
316 | ||
317 | ||
318 | echo "Finding loaddef targets..." | |
319 | ||
320 | sed -n -e '/^AUTOGEN_VCS/,/^$/ s/\\//p' lisp/Makefile.in | \ | |
321 | sed '/AUTOGEN_VCS/d' >| $tempfile || die "sed error" | |
322 | ||
323 | genfiles= | |
324 | ||
325 | while read genfile; do | |
326 | ||
327 | [ -r lisp/$genfile ] || die "Unable to read $genfile" | |
328 | ||
329 | genfiles="$genfiles $genfile" | |
330 | done < $tempfile | |
331 | ||
332 | ||
333 | [ "$genfiles" ] || die "Error setting genfiles" | |
334 | ||
335 | ||
336 | [ -e Makefile ] || { | |
337 | echo "Running ./configure..." | |
338 | ||
4cfacdd0 GM |
339 | ## Minimize required packages. |
340 | ./configure --without-x || die "configure error" | |
66b87493 GM |
341 | } |
342 | ||
66b87493 | 343 | |
c0274801 GM |
344 | ## Build the minimum needed to get the autoloads. |
345 | echo "Running lib/ make..." | |
346 | ||
347 | make -C lib "$@" all || die "make lib error" | |
348 | ||
349 | ||
350 | echo "Running src/ make..." | |
351 | ||
352 | make -C src "$@" bootstrap-emacs || die "make src error" | |
353 | ||
354 | ||
355 | echo "Running lisp/ make..." | |
356 | ||
357 | make -C lisp "$@" autoloads EMACS=../src/bootstrap-emacs || die "make src error" | |
358 | ||
359 | ||
5fac7083 GM |
360 | ## Ignore comment differences. |
361 | [ ! "$lboot_flag" ] || \ | |
362 | diff -q -I '^;' $ldefs_in $ldefs_out || \ | |
363 | cp $ldefs_in $ldefs_out || die "cp ldefs_boot error" | |
66b87493 GM |
364 | |
365 | ||
c0274801 GM |
366 | cd lisp |
367 | ||
368 | echo "Checking status of loaddef files..." | |
369 | ||
370 | ## It probably would be fine to just check+commit lisp/, since | |
371 | ## making autoloads should not effect any other files. But better | |
372 | ## safe than sorry. | |
373 | bzr status -S $genfiles ${ldefs_out#lisp/} >| $tempfile || \ | |
374 | die "bzr status error for generated files" | |
375 | ||
376 | ||
377 | modified= | |
378 | ||
379 | while read stat file; do | |
380 | ||
381 | [ "$stat" != "M" ] && die "Unexpected status ($stat) for generated $file" | |
382 | modified="$modified $file" | |
383 | ||
384 | done < $tempfile | |
385 | ||
66b87493 | 386 | |
66b87493 GM |
387 | cd ../ |
388 | ||
66b87493 | 389 | |
c0274801 | 390 | commit "loaddefs" $modified || die "bzr commit error" |
66b87493 | 391 | |
66b87493 | 392 | |
c0274801 | 393 | exit 0 |
66b87493 GM |
394 | |
395 | ### update_autogen ends here |