Fix Savannah bug #29511: fails to build on kfreebsd-*
[findutils/ericb.git] / import-gnulib.sh
blobca47086dba1dfa2594bea836ad8fd1d184bd534c
1 #! /bin/sh
3 # import-gnulib.sh -- imports a copy of gnulib into findutils
4 # Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software
5 # Foundation, Inc.
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##########################################################################
22 # This script is intended to populate the "gnulib" directory
23 # with a subset of the gnulib code, as provided by "gnulib-tool".
25 # To use it, just run this script with the top-level sourec directory
26 # as your working directory.
28 # If CDPATH is set, it will sometimes print the name of the directory
29 # to which you have moved. Unsetting CDPATH prevents this, as does
30 # prefixing it with ".".
31 unset CDPATH
33 ## Defaults
34 # cvsdir=/doesnotexist
35 git_repo="git://git.savannah.gnu.org/gnulib.git"
36 configfile="./import-gnulib.config"
37 need_checkout=yes
38 gnulib_changed=false
40 # If $GIT_CLONE_DEPTH is not set, apply a default.
41 : ${GIT_CLONE_DEPTH:=4}
44 # Remember arguments for comments we inject into output files
45 original_cmd_line_args="$@"
47 usage() {
48 cat >&2 <<EOF
49 usage: $0 [-d gnulib-directory]
51 The default behaviour is to check out the Gnulib code via anonymous
52 CVS (or update it if there is a version already checked out). The
53 checkout or update is performed to the gnulib version indicated in
54 the configuration file $configfile.
56 If you wish to work with a different version of gnulib, use the -d option
57 to specify the directory containing the gnulib code.
58 EOF
62 do_checkout () {
63 local gitdir="$1"
64 echo checking out gnulib from GIT in $gitdir
66 if [ -z "$gnulib_version" ] ; then
67 echo "Error: There should be a gnulib_version setting in $configfile, but there is not." >&2
68 exit 1
72 if ! [ -d "$gitdir" ] ; then
73 if mkdir "$gitdir" ; then
74 echo "Created $gitdir"
75 else
76 echo "Failed to create $gitdir" >&2
77 exit 1
81 # Change directory unconditionally before issuing git commands, because
82 # we're dealing with two git repositories; the gnulib one and the
83 # findutils one.
85 if ( cd $gitdir && test -d gnulib/.git ; ) ; then
86 echo "Git repository was already initialised."
87 else
88 echo "Cloning the git repository..."
89 ( cd $gitdir && git clone --depth="${GIT_CLONE_DEPTH}" "$git_repo" ; )
92 if ( cd $gitdir/gnulib &&
93 git diff --name-only --exit-code "$gnulib_version" ; ) ; then
94 # We are already at the correct version.
95 # Nothing to do
96 gnulib_changed=false
97 echo "Already at gnulib version $gnulib_version; no change"
98 else
99 gnulib_changed=true
100 set -x
101 ( cd $gitdir/gnulib &&
102 git fetch origin &&
103 git checkout "$gnulib_version" ; )
104 set +x
108 run_gnulib_tool() {
109 local tool="$1"
110 if test -f "$tool"
111 then
112 true
113 else
114 echo "$tool does not exist, did you specify the right directory?" >&2
115 exit 1
118 if test -x "$tool"
119 then
120 true
121 else
122 echo "$tool is not executable" >&2
123 exit 1
127 if [ -d gnulib ]
128 then
129 echo "Warning: directory gnulib already exists." >&2
130 else
131 mkdir gnulib
134 set -x
135 if "$tool" --import --symlink --with-tests --dir=. --lib=libgnulib --source-base=gnulib/lib --m4-base=gnulib/m4 --local-dir=gnulib-local $modules
136 then
137 set +x
138 else
139 set +x
140 echo "$tool failed, exiting." >&2
141 exit 1
144 # gnulib-tool does not remove broken symlinks leftover from previous runs;
145 # this assumes GNU find, but should be a safe no-op if it is not
146 find -L gnulib -lname '*' -delete 2>/dev/null || :
149 rehack() {
150 printf "Updating the license of $1... "
151 # Use cp to get the permissions right first
152 cp -fp "$1" "$1".new
153 sed -e \
154 's/Free Software Foundation\([;,]\) either ''version [2]/Free Software Foundation\1 either version 3/' < "$1" > "$1".new
155 if cmp "$1" "$1".new >/dev/null
156 then
157 echo "no change needed."
158 rm -f "$1".new
159 else
160 rm -f "$1" && mv "$1".new "$1"
161 echo "done."
167 copyhack() {
168 src="$1"
169 dst="$2"
170 shift 2
171 if test -d "$dst"
172 then
173 dst="$dst"/"$(basename $src)"
175 cp -fp "$src" "$dst" && rehack "$dst"
179 update_licenses() {
180 for f in $gpl3_update_files
182 rehack "$f" || exit
183 done
188 hack_gnulib_tool_output() {
189 local gnulibdir="${1}"
190 for file in $extra_files; do
191 case $file in
192 */mdate-sh | */texinfo.tex) dest=doc;;
193 *) dest=build-aux;;
194 esac
195 copyhack "${gnulibdir}"/"$file" "$dest" || exit
196 done
198 cat > gnulib/Makefile.am <<EOF
199 # Copyright (C) 2004, 2009 Free Software Foundation, Inc.
201 # This file is free software, distributed under the terms of the GNU
202 # General Public License. As a special exception to the GNU General
203 # Public License, this file may be distributed as part of a program
204 # that contains a configuration script generated by Automake, under
205 # the same distribution terms as the rest of that program.
207 # This file was generated by $0 $original_cmd_line_args.
209 SUBDIRS = lib
210 EXTRA_DIST = m4/gnulib-cache.m4
215 refresh_output_files() {
216 autopoint -f &&
217 aclocal -I m4 -I gnulib/m4 &&
218 autoheader &&
219 autoconf &&
220 automake --add-missing --copy
224 update_version_file() {
225 local ver
226 outfile="lib/gnulib-version.c"
227 if [ -z "$gnulib_version" ] ; then
228 ver="unknown (locally modified code; no version number available)"
229 else
230 ver="$gnulib_version"
234 cat > "${outfile}".new <<EOF
235 /* This file is automatically generated by $0 and simply records which version of gnulib we used. */
236 const char * const gnulib_version = "$ver";
238 if test -f "$outfile" ; then
239 if diff "${outfile}".new "${outfile}" > /dev/null ; then
240 rm "${outfile}".new
241 return 0
244 mv "${outfile}".new "${outfile}"
248 check_merge_driver() {
249 local config_file=".git/config"
250 fixmsg="
252 We recommend that you use a git merge driver for the ChangeLog file.
253 This simplifies the task of merging branches.
254 Please see the README section in gnulib-git/gnulib/lib/git-merge-changelog.c
256 If you've read that and don't want to use it, just set the environment variable
257 DO_NOT_WANT_CHANGELOG_DRIVER.
259 Example:
260 git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
261 git config merge.merge-changelog.driver /usr/local/bin/git-merge-changelog %O %A %B
262 echo 'ChangeLog merge=merge-changelog' >> .gitattributes
264 if [[ -z "$DO_NOT_WANT_CHANGELOG_DRIVER" ]] ; then
265 if git branch | egrep -q '\* *(master|rel-)'; then
266 # We are on the master branch or a release branch.
267 # Perhaps the user is simply building from git sources.
268 # Issue our message as a warning rather than an error.
269 fatal=false
270 label="Warning"
271 else
272 fatal=true
273 label="ERROR"
275 else
276 fatal=false
277 label="Warning"
279 if git config --get merge.merge-changelog.name >/dev/null ; then
280 driver="$(git config --get merge.merge-changelog.driver |
281 sed -e 's/[ ].*//')"
282 if [[ $? -eq 0 ]]; then
283 if ! [[ -x "$driver" ]]; then
284 echo "ERROR: Merge driver $driver is not executable." >&2
285 echo "ERROR: Please fix $config_file or install $driver" >&2
286 # Always fatal - if configured, the merge driver should work.
287 exit 1
288 else
289 if [[ -f .gitattributes ]] ; then
290 echo "The ChangeLog merge driver configuration seems OK."
291 else
292 echo "$label"': you have no .gitattributes file' >&2
293 echo "$fixmsg" >&2
294 if $fatal; then
295 exit 1
299 else
300 echo "$label"': There is no driver specified in [merge "merge-changelog"] in' "$config_file" >&2
301 echo "$fixmsg" >&2
302 if $fatal; then
303 exit 1
306 else
307 echo "$label"': There is no name specified in [merge "merge-changelog"] in' "$config_file" >&2
308 echo "$fixmsg" >&2
309 if $fatal; then
310 exit 1
316 move_cvsdir() {
317 local cvs_git_root=":pserver:anonymous@pserver.git.sv.gnu.org:/gnulib.git"
319 if test -d gnulib-cvs/gnulib/CVS
320 then
321 if test x"$(cat gnulib-cvs/gnulib/CVS/Root)" == x"$cvs_git_root"; then
322 # We cannot use the git-cvspserver interface because
323 # "update -D" doesn't work.
324 echo "WARNING: Migrating from git-cvs-pserver to native git..." >&2
325 savedir=gnulib-cvs.before-nativegit-migration
326 else
327 # The old CVS repository is not updated any more.
328 echo "WARNING: Migrating from old CVS repository to native git" >&2
329 savedir=gnulib-cvs.before-git-migration
331 mv gnulib-cvs $savedir || exit 1
332 echo "Please delete $savedir eventually"
337 record_config_change() {
338 # $1: name of the import-gnulib.config file
339 # $2: name of the last.config file
340 echo "Recording current config from $1 in $2"
341 if ! cp "$1" "$2"; then
342 rm -f "$2"
343 false
348 main() {
349 ## Option parsing
350 local gnulibdir=/doesnotexist
351 while getopts "d:a" opt
353 case "$opt" in
354 d) gnulibdir="$OPTARG" ; need_checkout=no ;;
355 a) refresh_output_files && update_licenses ; exit $? ;;
356 **) usage; exit 1;;
357 esac
358 done
360 # We need the config file to tell us which modules
361 # to use, even if we don't want to know the CVS version.
362 . $configfile || exit 1
364 ## If -d was not given, do update
365 if [ $need_checkout = yes ] ; then
366 if ! git version > /dev/null; then
367 cat >&2 <<EOF
368 You now need the tool 'git' in order to check out the correct version
369 of the gnulib code. See http://git.or.cz/ for more information about git.
371 exit 1
373 move_cvsdir
374 do_checkout gnulib-git
375 check_merge_driver
376 gnulibdir=gnulib-git/gnulib
377 else
378 echo "Warning: using gnulib code which already exists in $gnulibdir" >&2
381 ## If the config file changed since we last imported, or the gnulib
382 ## code itself changed, we will need to re-run gnulib-tool.
383 lastconfig="./gnulib/last.config"
384 config_changed=false
385 if "$gnulib_changed" ; then
386 echo "The gnulib code changed, we need to re-import it."
387 else
388 if test -e "$lastconfig" ; then
389 if cmp "$lastconfig" "$configfile" ; then
390 echo "Both gnulib and the import config are unchanged."
391 else
392 echo "The gnulib import config was changed."
393 echo "We need to re-run gnulib-tool."
394 config_changed=true
396 else
397 echo "$lastconfig does not exist, we need to run gnulib-tool."
398 config_changed=true
402 ## Invoke gnulib-tool to import the code.
403 local tool="${gnulibdir}"/gnulib-tool
404 if $gnulib_changed || $config_changed ; then
405 if run_gnulib_tool "${tool}" &&
406 hack_gnulib_tool_output "${gnulibdir}" &&
407 refresh_output_files &&
408 update_licenses &&
409 update_version_file &&
410 record_config_change "$configfile" "$lastconfig"
411 then
412 echo Done.
413 else
414 echo FAILED >&2
415 exit 1
417 else
418 echo "No change to the gnulib code or configuration."
419 echo "Therefore, no need to run gnulib-tool."
423 main "$@"