Mercurial > gnulib
changeset 40184:7f0ac0398fae
gnulib-tool: Improve handling of multiple --local-dir options.
* doc/gnulib.texi (Extending Gnulib): Explain how multiple --local-dir
options work.
* gnulib-tool (func_path_prepend): Remove function.
(func_path_foreach): Make IFS handling more robust.
(local_gnulib_path): Collect --local-dir values using func_path_append,
not func_path_prepend.
(func_determine_path_separator): Make IFS handling more robust.
(func_lookup_file_cb): New function.
(func_lookup_file): Rewritten to use func_lookup_file_cb instead of
func_lookup_local_file. Apply the patches in the reverse order of their
origin in $local_gnulib_path.
(func_count_relative_local_gnulib_path): Make IFS handling more robust.
* NEWS: Mention that the first --local-dir option is the one with
highest priority.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Thu, 14 Feb 2019 20:50:57 +0100 |
parents | 9301e0f7fe60 |
children | a7fe9f54c3df |
files | ChangeLog NEWS doc/gnulib.texi gnulib-tool |
diffstat | 4 files changed, 100 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Sun Feb 10 12:49:39 2019 +0100 +++ b/ChangeLog Thu Feb 14 20:50:57 2019 +0100 @@ -1,3 +1,21 @@ +2019-02-14 Bruno Haible <bruno@clisp.org> + + gnulib-tool: Improve handling of multiple --local-dir options. + * doc/gnulib.texi (Extending Gnulib): Explain how multiple --local-dir + options work. + * gnulib-tool (func_path_prepend): Remove function. + (func_path_foreach): Make IFS handling more robust. + (local_gnulib_path): Collect --local-dir values using func_path_append, + not func_path_prepend. + (func_determine_path_separator): Make IFS handling more robust. + (func_lookup_file_cb): New function. + (func_lookup_file): Rewritten to use func_lookup_file_cb instead of + func_lookup_local_file. Apply the patches in the reverse order of their + origin in $local_gnulib_path. + (func_count_relative_local_gnulib_path): Make IFS handling more robust. + * NEWS: Mention that the first --local-dir option is the one with + highest priority. + 2019-02-10 Bruno Haible <bruno@clisp.org> libtextstyle: New module.
--- a/NEWS Sun Feb 10 12:49:39 2019 +0100 +++ b/NEWS Thu Feb 14 20:50:57 2019 +0100 @@ -3,6 +3,10 @@ Date Modules Changes +2019-02-14 gnulib-tool If you use multiple --local-dir options at once: + The first one now has the highest priority, not the + last one. + 2019-01-04 (all) The meaning of the 'Link' section in the module descriptions has been clarified: It overrides the combined 'Link' sections from the dependencies.
--- a/doc/gnulib.texi Sun Feb 10 12:49:39 2019 +0100 +++ b/doc/gnulib.texi Thu Feb 14 20:50:57 2019 +0100 @@ -714,6 +714,15 @@ Otherwise, @command{gnulib-tool} uses the file included in Gnulib. @end itemize +You can specify the @option{--local-dir} multiple times. In this case, +the first specified directory has the highest precedence. That is, a +@file{@var{file}} found in one directory will shadow any @file{@var{file}} +and @file{@var{file}.diff} in the later directories and in the Gnulib +directory. And a file @file{@var{file}.diff} found in one directory will +be applied on top of the combination of @file{@var{file}} and +@file{@var{file}.diff} files found in the later directories and in the +Gnulib directory. + Please make wise use of this option. It also allows you to easily hold back modifications you make to Gnulib macros in cases it may be better to share them.
--- a/gnulib-tool Sun Feb 10 12:49:39 2019 +0100 +++ b/gnulib-tool Thu Feb 14 20:50:57 2019 +0100 @@ -556,21 +556,8 @@ fi } -# func_path_prepend pathvar directory -# puts directory before pathvar, delimiting directories by PATH_SEPARATOR. -# Newly added directory into pathvar has the highest priority. -func_path_prepend () -{ - if eval "test -n \"\$$1\""; then - eval "$1=\$2\$PATH_SEPARATOR\$$1" - else - eval "$1=\$2" - fi -} - # func_path_append pathvar directory -# Similar to func_path_prepend except that the newest directory has the lowest -# priority. +# appends directory to pathvar, delimiting directories by PATH_SEPARATOR. func_path_append () { if eval "test -n \"\$$1\""; then @@ -590,7 +577,7 @@ set %start% "$@" for _fpf_arg do - case $_fpf_arg in + case "$_fpf_arg" in %start%) set dummy ;; @@ -613,17 +600,18 @@ # with processed directory from path. func_path_foreach () { - fpf_save_IFS=$IFS - fpf_dirs=$1 ; shift - fpf_cb=$1 ; shift + fpf_dirs="$1"; shift + fpf_cb="$1"; shift fpf_rc=false - IFS=$PATH_SEPARATOR + fpf_save_IFS="$IFS" + IFS="$PATH_SEPARATOR" for fpf_dir in $fpf_dirs do + IFS="$fpf_save_IFS" func_path_foreach_inner "$@" && fpf_rc=: done - IFS=$fpf_save_IFS + IFS="$fpf_save_IFS" $fpf_rc } @@ -1049,7 +1037,7 @@ # update, create-testdir, create-megatestdir, test, megatest, # copy-file # - destdir from --dir -# - local_gnulib_path from --local-dir +# - local_gnulib_path from --local-dir, highest priority dir comes first # - modcache true or false, from --cache-modules/--no-cache-modules # - verbose integer, default 0, inc/decremented by --verbose/--quiet # - libname, supplied_libname from --lib @@ -1197,11 +1185,11 @@ if test $# = 0; then func_fatal_error "missing argument for --local-dir" fi - func_path_prepend local_gnulib_path "$1" + func_path_append local_gnulib_path "$1" shift ;; --local-dir=* ) local_dir=`echo "X$1" | sed -e 's/^X--local-dir=//'` - func_path_prepend local_gnulib_path "$local_dir" + func_path_append local_gnulib_path "$local_dir" shift ;; --cache-modules | --cache-module | --cache-modul | --cache-modu | --cache-mod | --cache-mo | --cache-m | --cache- | --cache | --cach | --cac | --ca ) modcache=true @@ -1575,18 +1563,19 @@ # Remove trailing slashes from the directory names. This is necessary for # m4base (to avoid an error in func_import) and optional for the others. sed_trimtrailingslashes='s,\([^/]\)//*$,\1,' - old_local_gnulib_path=$local_gnulib_path - save_IFS=$IFS + old_local_gnulib_path="$local_gnulib_path" + local_gnulib_path= + save_IFS="$IFS" IFS=: - local_gnulib_path= for dir in $old_local_gnulib_path do + IFS="$save_IFS" case "$dir" in */ ) dir=`echo "$dir" | sed -e "$sed_trimtrailingslashes"` ;; esac func_path_append local_gnulib_path "$dir" done - IFS=$save_IFS + IFS="$save_IFS" case "$sourcebase" in */ ) sourcebase=`echo "$sourcebase" | sed -e "$sed_trimtrailingslashes"` ;; esac @@ -1630,8 +1619,8 @@ fi # func_lookup_local_file_cb dir file -# return true and set func_lookup_local_file_result if the file 'dir/file' -# exists +# returns true and sets func_lookup_local_file_result if the file $dir/$file +# exists. func_lookup_local_file_cb () { test -n "$func_lookup_local_file_result" && return 1 # already found? @@ -1653,6 +1642,25 @@ func_path_foreach "$local_gnulib_path" func_lookup_local_file_cb %dir% "$1" } +# func_lookup_file_cb dir +# does one step in processing the $local_gnulib_path, looking for $dir/$lkfile +# and $dir/$lkfile.diff. +func_lookup_file_cb () +{ + # If we found the file already in a --local-dir of higher priority, nothing + # more to do. + if test -z "$lookedup_file"; then + # Otherwise, look for $dir/$lkfile and $dir/$lkfile.diff. + if test -f "$1/$lkfile"; then + lookedup_file="$1/$lkfile" + else + if test -f "$1/$lkfile.diff"; then + lkpatches="$1/$lkfile.diff${lkpatches:+$PATH_SEPARATOR$lkpatches}" + fi + fi + fi +} + # func_lookup_file file # looks up a file in $local_gnulib_path or $gnulib_dir, or combines it through # 'patch'. @@ -1664,27 +1672,39 @@ func_lookup_file () { lkfile="$1" - if func_lookup_local_file "$lkfile"; then - lookedup_file=$func_lookup_local_file_result - lookedup_tmp= - else + # Each element in $local_gnulib_path is a directory whose contents overrides + # or amends the result of the lookup in the rest of $local_gnulib_path and + # $gnulib_dir. So, the first element of $local_gnulib_path is the highest + # priority one. + lookedup_file= + lkpatches= + func_path_foreach "$local_gnulib_path" func_lookup_file_cb %dir% + # Treat $gnulib_dir like a lowest-priority --local-dir, except that here we + # don't look for .diff files. + if test -z "$lookedup_file"; then if test -f "$gnulib_dir/$lkfile"; then - if func_lookup_local_file "$lkfile.diff"; then - lkbase=`echo "$lkfile" | sed -e 's,^.*/,,'` - rm -f "$tmp/$lkbase" - cp "$gnulib_dir/$lkfile" "$tmp/$lkbase" - patch -s "$tmp/$lkbase" < "$func_lookup_local_file_result" >&2 \ - || func_fatal_error "patch file $func_lookup_local_file_result didn't apply cleanly" - lookedup_file="$tmp/$lkbase" - lookedup_tmp=true - else - lookedup_file="$gnulib_dir/$lkfile" - lookedup_tmp= - fi + lookedup_file="$gnulib_dir/$lkfile" else func_fatal_error "file $gnulib_dir/$lkfile not found" fi fi + # Now apply the patches, from lowest-priority to highest-priority. + lookedup_tmp= + if test -n "$lkpatches"; then + lkbase=`echo "$lkfile" | sed -e 's,^.*/,,'` + rm -f "$tmp/$lkbase" + cp "$lookedup_file" "$tmp/$lkbase" + save_IFS="$IFS" + IFS="$PATH_SEPARATOR" + for patchfile in $lkpatches; do + IFS="$save_IFS" + patch -s "$tmp/$lkbase" < "$patchfile" >&2 \ + || func_fatal_error "patch file $patchfile didn't apply cleanly" + done + IFS="$save_IFS" + lookedup_file="$tmp/$lkbase" + lookedup_tmp=true + fi } # func_sanitize_modulelist @@ -5562,11 +5582,12 @@ # - relative_local_dir path to be stored into gl_LOCAL_DIR func_count_relative_local_gnulib_path () { - save_IFS=$IFS - IFS=$PATH_SEPARATOR relative_local_gnulib_path= + save_IFS="$IFS" + IFS="$PATH_SEPARATOR" for local_dir in $local_gnulib_path do + IFS="$save_IFS" # Store the local_dir relative to destdir. case "$local_dir" in "" | /*) @@ -5582,7 +5603,7 @@ esac func_path_append relative_local_gnulib_path "$relative_local_dir" done - IFS=$save_IFS + IFS="$save_IFS" } # Create m4/gnulib-cache.m4.