#!/bin/bash ### update_autogen - update some auto-generated files in the Emacs tree ## Copyright (C) 2011-2014 Free Software Foundation, Inc. ## Author: Glenn Morris ## This file is part of GNU Emacs. ## GNU Emacs is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## GNU Emacs is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## You should have received a copy of the GNU General Public License ## along with GNU Emacs. If not, see . ### Commentary: ## This is a helper script to update some generated files in the Emacs ## repository. This is suitable for running from cron. ## Only Emacs maintainers need use this, so it uses bash features. ## ## By default, it updates the versioned loaddefs-like files in lisp, ## except ldefs-boot.el. ### Code: die () # write error to stderr and exit { [ $# -gt 0 ] && echo "$PN: $@" >&2 exit 1 } PN=${0##*/} # basename of script PD=${0%/*} [ "$PD" = "$0" ] && PD=. # if PATH includes PWD ## This should be the admin directory. cd $PD cd ../ [ -d admin ] || die "Could not locate admin directory" usage () { cat 1>&2 < /dev/null" EXIT while getopts ":hcfqA:CIL" option ; do case $option in (h) usage ;; (c) commit=1 ;; (f) force=1 ;; (q) quiet=1 ;; (A) autogendir=$OPTARG [ -d "$autogendir" ] || die "No autogen directory: $autogendir" ;; (C) clean=1 ;; (I) info_flag=1 ;; (L) lboot_flag=1 ;; (\?) die "Bad option -$OPTARG" ;; (:) die "Option -$OPTARG requires an argument" ;; (*) die "getopts error" ;; esac done shift $(( --OPTIND )) OPTIND=1 ## Does not work 100% because a lot of Emacs batch output comes on stderr (?). [ "$quiet" ] && exec 1> /dev/null echo "Running bzr status..." bzr status -S ${autogendir:+$sources} ${ldefs_flag:+lisp} \ ${info_flag:+doc} >| $tempfile || \ die "bzr status error for input files" ## The lisp portion could be more permissive, eg only care about .el files. while read stat file; do case $stat in M) echo "Locally modified: $file" [ "$force" ] || die "There are local modifications" ;; *) die "Unexpected status ($stat) for $file" ;; esac done < $tempfile ## Probably this is overkill, and there's no need to "bootstrap" just ## for making autoloads. [ "$clean" ] && { echo "Running 'make maintainer-clean'..." make maintainer-clean #|| die "Cleaning error" rm -f $ldefs_in } echo "Running autoreconf..." autoreconf ${clean:+-f} -i -I m4 2>| $tempfile retval=$? ## Annoyingly, autoreconf puts the "installing `./foo' messages on stderr. if [ "$quiet" ]; then grep -v 'installing `\.' $tempfile 1>&2 else cat "$tempfile" 1>&2 fi [ $retval -ne 0 ] && die "autoreconf error" ## Uses global $commit. commit () { local type=$1 shift [ $# -gt 0 ] || { echo "No files were modified" return 0 } echo "Modified file(s): $@" [ "$commit" ] || return 0 echo "Committing..." ## bzr status output is always relative to top-level, not PWD. bzr commit -m "Auto-commit of $type files." "$@" || return $? echo "Committed files: $@" } # function commit ## No longer used since info/dir is now generated at install time if needed, ## and is not in the repository any more. info_dir () { local basefile=build-aux/dir_top outfile=info/dir echo "Regenerating info/dir..." ## Header contains non-printing characters, so this is more ## reliable than using echo. rm -f $outfile cp $basefile $outfile local topic file dircat dirent ## FIXME inefficient looping. for topic in "Texinfo documentation system" "Emacs" "GNU Emacs Lisp" \ "Emacs editing modes" "Emacs network features" "Emacs misc features" \ "Emacs lisp libraries"; do cat - <> $outfile $topic EOF ## Bit faster than doc/*/*.texi. for file in doc/emacs/emacs.texi doc/lispintro/*.texi \ doc/lispref/elisp.texi doc/misc/*.texi; do ## FIXME do not ignore w32 if OS is w32. case $file in *-xtra.texi|*efaq-w32.texi) continue ;; esac dircat=`sed -n -e 's/@value{emacsname}/Emacs/' -e 's/^@dircategory //p' $file` ## TODO warn about unknown topics (check-info in top-level ## Makefile does this). [ "$dircat" = "$topic" ] || continue sed -n -e 's/@value{emacsname}/Emacs/' \ -e 's/@acronym{\([A-Z]*\)}/\1/' \ -e '/^@direntry/,/^@end direntry/ s/^\([^@]\)/\1/p' \ $file >> $outfile done done bzr status -S $outfile >| $tempfile || \ die "bzr status error for generated $outfile" local modified while read stat file; do [ "$stat" != "M" ] && \ die "Unexpected status ($stat) for generated $file" modified="$modified $file" done < $tempfile commit "info/dir" $modified || die "bzr commit error" } # function info_dir [ "$autogendir" ] && { oldpwd=$PWD cp $genfiles $autogendir/ cd $autogendir || die "cd error for $autogendir" echo "Checking status of generated files..." bzr status -S $basegen >| $tempfile || \ die "bzr status error for generated files" modified= while read stat file; do [ "$stat" != "M" ] && \ die "Unexpected status ($stat) for generated $file" modified="$modified $file" done < $tempfile cd $oldpwd commit "generated" $modified || die "bzr commit error" exit 0 } # $autogendir [ "$info_flag" ] && info_dir [ "$ldefs_flag" ] || exit 0 echo "Finding loaddef targets..." sed -n -e '/^AUTOGEN_VCS/,/^$/ s/\\//p' lisp/Makefile.in | \ sed '/AUTOGEN_VCS/d' >| $tempfile || die "sed error" genfiles= while read genfile; do [ -r lisp/$genfile ] || die "Unable to read $genfile" genfiles="$genfiles $genfile" done < $tempfile [ "$genfiles" ] || die "Error setting genfiles" [ -e Makefile ] || { echo "Running ./configure..." ## Minimize required packages. ./configure --without-x || die "configure error" } ## Build the minimum needed to get the autoloads. echo "Running lib/ make..." make -C lib "$@" all || die "make lib error" echo "Running src/ make..." make -C src "$@" bootstrap-emacs || die "make src error" echo "Running lisp/ make..." make -C lisp "$@" autoloads EMACS=../src/bootstrap-emacs || die "make src error" ## Ignore comment differences. [ ! "$lboot_flag" ] || \ diff -q -I '^;' $ldefs_in $ldefs_out || \ cp $ldefs_in $ldefs_out || die "cp ldefs_boot error" cd lisp echo "Checking status of loaddef files..." ## It probably would be fine to just check+commit lisp/, since ## making autoloads should not effect any other files. But better ## safe than sorry. bzr status -S $genfiles ${ldefs_out#lisp/} >| $tempfile || \ die "bzr status error for generated files" modified= while read stat file; do [ "$stat" != "M" ] && die "Unexpected status ($stat) for generated $file" modified="$modified $file" done < $tempfile cd ../ commit "loaddefs" $modified || die "bzr commit error" exit 0 ### update_autogen ends here