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