Today's changes:
2022-07-31 Bruno Haible <br...@clisp.org> gnulib-tool.py: Fix typo. * pygnulib/GLTestDir.py (GLMegaTestDir.execute): Invoke os.mkdir as intended. gnulib-tool.py: Improve some error messages. * gnulib-tool.py (main): Write "*** Stop." instead of "*** Exit.". (__main__): Print an error message for GLError 5, 13, 14, 15, 16, 17, 18. * pygnulib/GLError.py (GLError.__repr__): Compute one error message, not 19. gnulib-tool.py: Write errors to stderr, not stdout. * pygnulib/constants.py: Write error messages to stderr, not stdout. gnulib-tool.py: Use mainstream coding style. * pygnulib/GLConfig.py: Use 'raise' to re-throw an exception. gnulib-tool.py: Implement options --symlink and --local-symlink. * gnulib-tool.py (main): Handle options --symlink and --local-symlink. * pygnulib/constants.py (link_if_changed): Ignore FileNotFoundError from os.remove call. gnulib-tool.py: Make --copy-file work. * gnulib-tool.py (main) [copy-file]: Fix reference to uninitialized variable. Fix error handling of os.makedirs. Pass the destdir to the GLFileAssistant. gnulib-tool.py: Allow module arguments to occur at any position. * gnulib-tool.py (main): Collect the non-option arguments in a single list, regardless of their position. Use parse_known_args instead of parse_args, and give an error message about unknown options ourselves. * gnulib-tool: Fix typo in error message. gnulib-tool.py: Make --test behaviour more similar to gnulib-tool. * gnulib-tool.py (main) [test]: Remove space from the testdir name. gnulib-tool: Clarify that --test allows zero module arguments. * gnulib-tool (func_usage): Mark the modules for --test as optional. * pygnulib/GLInfo.py (GLInfo.usage): Likewise. gnulib-tool.py: Make option processing more similar to gnulib-tool. * gnulib-tool.py (main): Allow --add-import and --remove-import with 0 modules. gnulib-tool.py: Improve compliance with GNU standards. * gnulib-tool.py (main): Handle --help and --version before testing for conflicting modes. gnulib-tool.py: Emit error message when conflicting modes are specified. * gnulib-tool.py (main): Fix test of conflicting modes. (Some options produce a value of [], and as a condition, [] evaluates to False.) gnulib-tool.py: Remove most short options. * gnulib-tool.py (main): Reorder the list of options. Remove most short options, for consistency with gnulib-tool. gnulib-tool.py: Follow gnulib-tool changes, part 19. Follow gnulib-tool changes 2015-12-09 Pavel Raiskup <prais...@redhat.com> gnulib-tool: allow multiple --local-dir usage 2019-02-14 Bruno Haible <br...@clisp.org> gnulib-tool: Improve handling of multiple --local-dir options. * gnulib-tool (func_reconstruct_cached_dir): When the argument is absolute, return it unmodified. (func_compute_relative_local_gnulib_path): Renamed from func_count_relative_local_gnulib_path. Add comment. * gnulib-tool.py: Accept multiple --local-dir options and collect the values into localpath. * pygnulib/GLConfig.py: Take a localpath argument instead of a localdir argument. (getLocalDir, setLocalDir, resetLocalDir): Remove methods. (getLocalPath, setLocalPath, resetLocalPath): New methods. * pygnulib/GLFileSystem.py (CopyAction): New class. (GLFileSystem.lookup): Consider all dirs in localpath. (GLFileSystem.shouldLink): New method. (GLFileAssistant): Use shouldLink. * pygnulib/GLModuleSystem.py (GLModuleSystem.exists): Iterate over all dirs in localpath. (GLModuleSystem.list): Likewise. * pygnulib/GLEmiter.py: Update. * pygnulib/GLImport.py (GLImport.__init__): Put the argument of gl_LOCAL_DIR into localpath, not localdir. (GLImport.actioncmd): Consider all dirs in localpath. (GLImport.relative_to_destdir, GLImport.relative_to_currdir): New methods. (GLImport.gnulib_cache): Combine all dirs in localpath. Use self.relative_to_destdir. * pygnulib/GLTestDir.py (GLTestDir.execute): Use shouldLink. gnulib-tool.py: Improve the primitives for relative file names. * pygnulib/constants.py (relativize): Don't attempt to handle absolute file names. Fix bug with relativize('../foo/bar', '../foo/bla/zut'). (relconcat): New function. gnulib-tool.py: Follow gnulib-tool changes, part 18. Follow gnulib-tool change 2005-09-20 Bruno Haible <br...@clisp.org> gnulib-tool: Remove trailing slashes * pygnulib/constants.py (remove_trailing_slashes): New function. * pygnulib/GLConfig.py (GLConfig): Use it in the setters.
>From 412c51e6c9faa6445cea9609e7c091777f513aa7 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 18:30:50 +0200 Subject: [PATCH 01/16] gnulib-tool.py: Follow gnulib-tool changes, part 18. Follow gnulib-tool change 2005-09-20 Bruno Haible <br...@clisp.org> gnulib-tool: Remove trailing slashes * pygnulib/constants.py (remove_trailing_slashes): New function. * pygnulib/GLConfig.py (GLConfig): Use it in the setters. --- ChangeLog | 11 ++++++++++- pygnulib/GLConfig.py | 19 ++++++++++++------- pygnulib/constants.py | 12 ++++++++++++ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index cb311920f7..9fec245cf5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,13 @@ -2022-07-06 Akim Demaille <a...@lrde.epita.fr> +2022-07-31 Bruno Haible <br...@clisp.org> + + gnulib-tool.py: Follow gnulib-tool changes, part 18. + Follow gnulib-tool change + 2005-09-20 Bruno Haible <br...@clisp.org> + gnulib-tool: Remove trailing slashes + * pygnulib/constants.py (remove_trailing_slashes): New function. + * pygnulib/GLConfig.py (GLConfig): Use it in the setters. + +2022-07-31 Akim Demaille <a...@lrde.epita.fr> gnulib-tool: add support for --automake-subdir-tests <https://lists.gnu.org/r/bug-gnulib/2022-01/msg00111.html> diff --git a/pygnulib/GLConfig.py b/pygnulib/GLConfig.py index 457dc2c1e3..d203820427 100644 --- a/pygnulib/GLConfig.py +++ b/pygnulib/GLConfig.py @@ -42,6 +42,7 @@ MODES = constants.MODES TESTS = constants.TESTS joinpath = constants.joinpath relpath = constants.relativize +remove_trailing_slashes = constants.remove_trailing_slashes isfile = os.path.isfile normpath = os.path.normpath @@ -68,6 +69,10 @@ class GLConfig(object): Create new GLConfig instance.''' self.table = dict() self.table['tempdir'] = tempfile.mkdtemp() + # Check and store the attributes. + # Remove trailing slashes from the directory names. This is necessary + # for m4base (to avoid an error in func_import) and optional for the + # others. # destdir self.resetDestDir() if destdir != None: @@ -408,7 +413,7 @@ class GLConfig(object): in gnulib's directory.''' if type(localdir) is str: if localdir: - self.table['localdir'] = localdir + self.table['localdir'] = remove_trailing_slashes(localdir) else: # if localdir has not str type raise TypeError('localdir must be a string, not %s' % type(localdir).__name__) @@ -431,7 +436,7 @@ class GLConfig(object): placed. Default comes from configure.ac or configure.in.''' if type(auxdir) is str: if auxdir: - self.table['auxdir'] = auxdir + self.table['auxdir'] = remove_trailing_slashes(auxdir) else: # if type of auxdir is not str raise TypeError('auxdir must be a string, not %s' % type(auxdir).__name__) @@ -450,7 +455,7 @@ class GLConfig(object): '''Specify directory relative to destdir where source code is placed.''' if type(sourcebase) is str: if sourcebase: - self.table['sourcebase'] = sourcebase + self.table['sourcebase'] = remove_trailing_slashes(sourcebase) else: # if type of sourcebase is not str raise TypeError('sourcebase must be a string, not %s' % type(sourcebase).__name__) @@ -468,7 +473,7 @@ class GLConfig(object): '''Specify directory relative to destdir where *.m4 macros are placed.''' if type(m4base) is str: if m4base: - self.table['m4base'] = m4base + self.table['m4base'] = remove_trailing_slashes(m4base) else: # if type of m4base is not str raise TypeError('m4base must be a string, not %s' % type(m4base).__name__) @@ -486,7 +491,7 @@ class GLConfig(object): '''Specify directory relative to destdir where *.po files are placed.''' if type(pobase) is str: if pobase: - self.table['pobase'] = pobase + self.table['pobase'] = remove_trailing_slashes(pobase) else: # if type of pobase is not str raise TypeError('pobase must be a string, not %s' % type(pobase).__name__) @@ -506,7 +511,7 @@ class GLConfig(object): Default value for this variable is 'doc').''' if type(docbase) is str: if docbase: - self.table['docbase'] = docbase + self.table['docbase'] = remove_trailing_slashes(docbase) else: # if type of docbase is not str raise TypeError('docbase must be a string, not %s' % type(docbase).__name__) @@ -527,7 +532,7 @@ class GLConfig(object): Default value for this variable is 'tests').''' if type(testsbase) is str: if testsbase: - self.table['testsbase'] = testsbase + self.table['testsbase'] = remove_trailing_slashes(testsbase) else: # if type of testsbase is not str raise TypeError('testsbase must be a string, not %s' % type(testsbase).__name__) diff --git a/pygnulib/constants.py b/pygnulib/constants.py index 8fd982f7a7..e951c906d0 100644 --- a/pygnulib/constants.py +++ b/pygnulib/constants.py @@ -394,6 +394,18 @@ def nlremove(text): return text +def remove_trailing_slashes(text): + '''Remove trailing slashes from a file name, except when the file name + consists only of slashes.''' + result = text + while result.endswith('/'): + result = result[:-1] + if result == '': + result = text + break + return result + + def remove_backslash_newline(text): '''Given a multiline string text, join lines: When a line ends in a backslash, remove the backslash and join the next -- 2.34.1
>From 72d3a4615864e9f77109e86ee4c1a6fe5fcb0946 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 18:35:58 +0200 Subject: [PATCH 02/16] gnulib-tool.py: Improve the primitives for relative file names. * pygnulib/constants.py (relativize): Don't attempt to handle absolute file names. Fix bug with relativize('../foo/bar', '../foo/bla/zut'). (relconcat): New function. --- ChangeLog | 5 +++++ pygnulib/constants.py | 22 ++++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9fec245cf5..00ffeffa52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Improve the primitives for relative file names. + * pygnulib/constants.py (relativize): Don't attempt to handle absolute + file names. Fix bug with relativize('../foo/bar', '../foo/bla/zut'). + (relconcat): New function. + gnulib-tool.py: Follow gnulib-tool changes, part 18. Follow gnulib-tool change 2005-09-20 Bruno Haible <br...@clisp.org> diff --git a/pygnulib/constants.py b/pygnulib/constants.py index e951c906d0..9ef2e01089 100644 --- a/pygnulib/constants.py +++ b/pygnulib/constants.py @@ -272,25 +272,20 @@ def joinpath(head, *tail): def relativize(dir1, dir2): - '''Compute a relative pathname reldir such that dir1/reldir = dir2.''' + '''Compute a relative pathname reldir such that dir1/reldir = dir2. + dir1 and dir2 must be relative pathnames.''' dir0 = os.getcwd() while dir1: dir1 = '%s%s' % (os.path.normpath(dir1), os.path.sep) dir2 = '%s%s' % (os.path.normpath(dir2), os.path.sep) - if dir1.startswith(os.path.sep): - first = dir1[:dir1.find(os.path.sep, 1)] - else: # if not dir1.startswith('/') - first = dir1[:dir1.find(os.path.sep)] + first = dir1[:dir1.find(os.path.sep)] if first != '.': if first == '..': - dir2 = os.path.basename(joinpath(dir0, dir2)) + dir2 = joinpath(os.path.basename(dir0), dir2) dir0 = os.path.dirname(dir0) else: # if first != '..' # Get first component of dir2 - if dir2.startswith(os.path.sep): - first2 = dir2[:dir2.find(os.path.sep, 1)] - else: # if not dir1.startswith('/') - first2 = dir2[:dir2.find(os.path.sep)] + first2 = dir2[:dir2.find(os.path.sep)] if first == first2: dir2 = dir2[dir2.find(os.path.sep) + 1:] else: # if first != first2 @@ -301,6 +296,13 @@ def relativize(dir1, dir2): return result +def relconcat(dir1, dir2): + '''Compute a relative pathname dir1/dir2, with obvious simplifications. + dir1 and dir2 must be relative pathnames. + dir2 is considered to be relative to dir1.''' + return os.path.normpath(os.path.join(dir1, dir2)) + + def link_relative(src, dest): '''Like ln -s, except that src is given relative to the current directory (or absolute), not given relative to the directory of dest.''' -- 2.34.1
>From b228f782b10a44736af152f0bdb7c94c7429ceab Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 18:39:19 +0200 Subject: [PATCH 03/16] gnulib-tool.py: Follow gnulib-tool changes, part 19. Follow gnulib-tool changes 2015-12-09 Pavel Raiskup <prais...@redhat.com> gnulib-tool: allow multiple --local-dir usage 2019-02-14 Bruno Haible <br...@clisp.org> gnulib-tool: Improve handling of multiple --local-dir options. * gnulib-tool (func_reconstruct_cached_dir): When the argument is absolute, return it unmodified. (func_compute_relative_local_gnulib_path): Renamed from func_count_relative_local_gnulib_path. Add comment. * gnulib-tool.py: Accept multiple --local-dir options and collect the values into localpath. * pygnulib/GLConfig.py: Take a localpath argument instead of a localdir argument. (getLocalDir, setLocalDir, resetLocalDir): Remove methods. (getLocalPath, setLocalPath, resetLocalPath): New methods. * pygnulib/GLFileSystem.py (CopyAction): New class. (GLFileSystem.lookup): Consider all dirs in localpath. (GLFileSystem.shouldLink): New method. (GLFileAssistant): Use shouldLink. * pygnulib/GLModuleSystem.py (GLModuleSystem.exists): Iterate over all dirs in localpath. (GLModuleSystem.list): Likewise. * pygnulib/GLEmiter.py: Update. * pygnulib/GLImport.py (GLImport.__init__): Put the argument of gl_LOCAL_DIR into localpath, not localdir. (GLImport.actioncmd): Consider all dirs in localpath. (GLImport.relative_to_destdir, GLImport.relative_to_currdir): New methods. (GLImport.gnulib_cache): Combine all dirs in localpath. Use self.relative_to_destdir. * pygnulib/GLTestDir.py (GLTestDir.execute): Use shouldLink. --- ChangeLog | 33 +++++++++++ gnulib-tool | 17 +++--- gnulib-tool.py | 17 +++--- gnulib-tool.py.TODO | 90 ++++++++++------------------ pygnulib/GLConfig.py | 61 ++++++++++--------- pygnulib/GLEmiter.py | 6 +- pygnulib/GLFileSystem.py | 117 ++++++++++++++++++++++++------------- pygnulib/GLImport.py | 87 ++++++++++++++++----------- pygnulib/GLModuleSystem.py | 45 +++++++------- pygnulib/GLTestDir.py | 6 +- 10 files changed, 269 insertions(+), 210 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00ffeffa52..98438a58a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,38 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Follow gnulib-tool changes, part 19. + Follow gnulib-tool changes + 2015-12-09 Pavel Raiskup <prais...@redhat.com> + gnulib-tool: allow multiple --local-dir usage + 2019-02-14 Bruno Haible <br...@clisp.org> + gnulib-tool: Improve handling of multiple --local-dir options. + * gnulib-tool (func_reconstruct_cached_dir): When the argument is + absolute, return it unmodified. + (func_compute_relative_local_gnulib_path): Renamed from + func_count_relative_local_gnulib_path. Add comment. + * gnulib-tool.py: Accept multiple --local-dir options and collect the + values into localpath. + * pygnulib/GLConfig.py: Take a localpath argument instead of a localdir + argument. + (getLocalDir, setLocalDir, resetLocalDir): Remove methods. + (getLocalPath, setLocalPath, resetLocalPath): New methods. + * pygnulib/GLFileSystem.py (CopyAction): New class. + (GLFileSystem.lookup): Consider all dirs in localpath. + (GLFileSystem.shouldLink): New method. + (GLFileAssistant): Use shouldLink. + * pygnulib/GLModuleSystem.py (GLModuleSystem.exists): Iterate over all + dirs in localpath. + (GLModuleSystem.list): Likewise. + * pygnulib/GLEmiter.py: Update. + * pygnulib/GLImport.py (GLImport.__init__): Put the argument of + gl_LOCAL_DIR into localpath, not localdir. + (GLImport.actioncmd): Consider all dirs in localpath. + (GLImport.relative_to_destdir, GLImport.relative_to_currdir): New + methods. + (GLImport.gnulib_cache): Combine all dirs in localpath. Use + self.relative_to_destdir. + * pygnulib/GLTestDir.py (GLTestDir.execute): Use shouldLink. + gnulib-tool.py: Improve the primitives for relative file names. * pygnulib/constants.py (relativize): Don't attempt to handle absolute file names. Fix bug with relativize('../foo/bar', '../foo/bla/zut'). diff --git a/gnulib-tool b/gnulib-tool index bee85856f4..f1665f4002 100755 --- a/gnulib-tool +++ b/gnulib-tool @@ -4846,12 +4846,13 @@ func_reconstruct_cached_dir () { cached_dir=$1 if test -n "$cached_dir"; then - case "$destdir" in + case "$cached_dir" in /*) - func_path_append local_gnulib_path "$destdir/$cached_dir" ;; + func_path_append local_gnulib_path "$cached_dir" ;; *) - case "$cached_dir" in + case "$destdir" in /*) + # XXX This doesn't look right. func_path_append local_gnulib_path "$destdir/$cached_dir" ;; *) func_relconcat "$destdir" "$cached_dir" @@ -5835,14 +5836,14 @@ s,//*$,/,' fi fi - # func_count_relative_local_gnulib_path + # func_compute_relative_local_gnulib_path # gl_LOCAL_DIR requires local_gnulib_path to be set relatively to destdir # Input: # - local_gnulib_path from --local-dir # - destdir from --dir # Output: # - relative_local_dir path to be stored into gl_LOCAL_DIR - func_count_relative_local_gnulib_path () + func_compute_relative_local_gnulib_path () { relative_local_gnulib_path= save_IFS="$IFS" @@ -5856,7 +5857,9 @@ s,//*$,/,' relative_local_dir="$local_dir" ;; * ) case "$destdir" in - /*) relative_local_dir="$local_dir" ;; + /*) + # XXX This doesn't look right. + relative_local_dir="$local_dir" ;; *) # destdir, local_dir are both relative. func_relativize "$destdir" "$local_dir" @@ -5883,7 +5886,7 @@ s,//*$,/,' printf '%s\n' "$actioncmd" echo echo "# Specification in the form of a few gnulib-tool.m4 macro invocations:" - func_count_relative_local_gnulib_path + func_compute_relative_local_gnulib_path echo "gl_LOCAL_DIR([$relative_local_gnulib_path])" echo "gl_MODULES([" echo "$specified_modules" | sed -e 's/^/ /g' diff --git a/gnulib-tool.py b/gnulib-tool.py index 523de7769e..0b2f866920 100755 --- a/gnulib-tool.py +++ b/gnulib-tool.py @@ -24,7 +24,7 @@ # - Line length is not limited to 79 characters. # - Line breaking before or after binary operators? Better before, like in GNU. # You can use this command to check the style: -# $ pycodestyle --max-line-length=128 --ignore=E265,W503,E241,E711,E712 gnulib-tool.py pygnulib/*.py +# $ pycodestyle --max-line-length=128 --ignore=E265,W503,E241,E711,E712,E201,E202 gnulib-tool.py pygnulib/*.py #=============================================================================== @@ -66,7 +66,7 @@ def main(): # Reset arguments mode = None destdir = None - localdir = None + localpath = None modcache = None verbose = None auxdir = None @@ -224,11 +224,12 @@ def main(): dest='destdir', default=None, nargs=1) - # localdir + # localpath parser.add_argument('-ld', '--local-dir', - dest='localdir', + action='append', + dest='localpath', default=None, - nargs=1) + nargs='?') # verbose parser.add_argument('-v', '--verbose', default=0, @@ -458,9 +459,7 @@ def main(): destdir = cmdargs.destdir if destdir != None: destdir = cmdargs.destdir[0] - localdir = cmdargs.localdir - if localdir != None: - localdir = cmdargs.localdir[0] + localpath = cmdargs.localpath libname = cmdargs.libname if libname != None: libname = cmdargs.libname[0] @@ -514,7 +513,7 @@ def main(): # Create pygnulib configuration. config = classes.GLConfig( destdir=destdir, - localdir=localdir, + localpath=localpath, m4base=m4base, auxdir=auxdir, modules=modules, diff --git a/gnulib-tool.py.TODO b/gnulib-tool.py.TODO index c0a2c975f3..26c59c5353 100644 --- a/gnulib-tool.py.TODO +++ b/gnulib-tool.py.TODO @@ -15,6 +15,37 @@ The following commits to gnulib-tool have not yet been reflected in -------------------------------------------------------------------------------- +Implement the options: + --find + --without-tests + --without-c++-tests + --without-longrunning-tests + --without-privileged-tests + --without-unportable-tests + --single-configure + --conditional-dependencies + --no-conditional-dependencies + --gnu-make + --tests-makefile-name + --automake-subdir + --no-libtool + --macro-prefix + --po-domain + --witness-c-macro + --vc-files + --no-vc-files + --no-changelog + -s | --symbolic + --local-symlink + -h | --hardlink + --local-hardlink + -S | --more-symlinks + -H | --more-hardlinks + --help (same output) + --version + +-------------------------------------------------------------------------------- + commit 76c7703cb2e9e0e803d1296618d8ab9e86e13d6c Author: Akim Demaille <akim.demai...@gmail.com> Date: Mon Jul 4 07:18:07 2022 +0200 @@ -1079,65 +1110,6 @@ Date: Wed May 1 13:39:22 2013 +0900 -------------------------------------------------------------------------------- -commit 49137e3bc6a2b3fd83c502a514e4a3b89fc1571c -Author: Bruno Haible <br...@clisp.org> -Date: Thu Feb 14 20:50:57 2019 +0100 - - 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. - -commit 55c6f22b8043843aa7cf6843326eb4abed4de75c -Author: Pavel Raiskup <prais...@redhat.com> -Date: Sat Nov 21 14:09:15 2015 +0100 - - gnulib-tool: allow multiple --local-dir usage - - * gnulib-tool: Use --local-dir to construct compound - $local_gnulib_path path instead of $local_gnulib_dir. Determine - PATH_SEPARATOR early. - (local_gnulib_dir): Rename into $local_gnulib_path everywhere. - (func_gnulib_dir): Cut out PATH_SEPARATOR detection code into - func_determine_path_separator because that needs to be detected - earlier now. - (func_determine_path_separator): New function. - (func_path_foreach, func_path_foreach_inner): New functions. - (func_path_prepend, func_path_append): Likewise. - (func_lookup_local_file, func_lookup_local_file_cb): Likewise. - (func_lookup_file, func_all_modules): Use new functions to work - with local_gnulib_path. - (func_modules_in_dir, func_exists_module): New callbacks for - func_path_foreach. - (func_exists_module, func_get_tests_module): Likewise. - (func_is_local_file, func_should_symlink): New helper methods. - (func_add_file, func_update_file): Use new func_should_symlink - instead, DRY. - (func_reconstruct_cached_local_gnulib_path): New helper. - (func_reconstruct_cached_dir): New callback. - (func_import): The cached_local_gnulib_dir renamed to - cached_local_gnulib_path similarly to local_gnulib_dir. - Use new func_reconstruct_cached_local_gnulib_path. - (func_count_relative_local_gnulib_path): New sub-method. - (func_create_testdir): Use func_should_symlink, DRY. - (func_create_megatestdir): Use new functions to work with - local_gnulib_path correctly. - (func_append_local_dir): New helper. - --------------------------------------------------------------------------------- - commit 9bdf6c8a0cdeb13c12e4b65dee9538c5468dbe1d Author: Bruno Haible <br...@clisp.org> Date: Sun Aug 19 14:06:50 2012 +0200 diff --git a/pygnulib/GLConfig.py b/pygnulib/GLConfig.py index d203820427..55b6cd2986 100644 --- a/pygnulib/GLConfig.py +++ b/pygnulib/GLConfig.py @@ -56,7 +56,7 @@ class GLConfig(object): By default all attributes are set to empty string, empty list or zero. The most common value, however, is a None value.''' - def __init__(self, destdir=None, localdir=None, auxdir=None, + def __init__(self, destdir=None, localpath=None, auxdir=None, sourcebase=None, m4base=None, pobase=None, docbase=None, testsbase=None, modules=None, avoids=None, files=None, testflags=None, libname=None, lgpl=None, makefile=None, libtool=None, conddeps=None, macro_prefix=None, @@ -77,10 +77,10 @@ class GLConfig(object): self.resetDestDir() if destdir != None: self.setDestDir(destdir) - # localdir - self.resetLocalDir() - if localdir != None: - self.setLocalDir(localdir) + # localpath + self.resetLocalPath() + if localpath != None: + self.setLocalPath(localpath) # auxdir self.resetAuxDir() if auxdir != None: @@ -402,26 +402,29 @@ class GLConfig(object): configure.ac can be found. Defaults to current directory.''' self.table['destdir'] = '' - # Define localdir methods. - def getLocalDir(self): - '''Return a local override directory where to look up files before looking - in gnulib's directory.''' - return self.table['localdir'] - - def setLocalDir(self, localdir): - '''Specify a local override directory where to look up files before looking - in gnulib's directory.''' - if type(localdir) is str: - if localdir: - self.table['localdir'] = remove_trailing_slashes(localdir) - else: # if localdir has not str type - raise TypeError('localdir must be a string, not %s' % - type(localdir).__name__) - - def resetLocalDir(self): - '''Reset a local override directory where to look up files before looking - in gnulib's directory.''' - self.table['localdir'] = '' + # Define localpath methods. + def getLocalPath(self): + '''Return a list of local override directories where to look up files + before looking in gnulib's directory. The first one has the highest + priority.''' + return self.table['localpath'] + + def setLocalPath(self, localpath): + '''Specify a list of local override directories where to look up files + before looking in gnulib's directory. The first one has the highest + priority.''' + if type(localpath) is list: + for dir in localpath: + if type(dir) is not str: + raise TypeError('localpath element must be a string, not %s' % type(dir).__name__) + else: + raise TypeError('localpath must be a list, not %s' % type(localpath).__name__) + self.table['localpath'] = [ remove_trailing_slashes(dir) for dir in localpath ] + + def resetLocalPath(self): + '''Reset a list of local override directories where to look up files + before looking in gnulib's directory.''' + self.table['localpath'] = [] # Define auxdir methods. def getAuxDir(self): @@ -998,22 +1001,22 @@ class GLConfig(object): # Define lsymbolic methods. def checkLSymbolic(self): '''Check if pygnulib will make symbolic links instead of copying files, only - for files from the local override directory.''' + for files from the local override directories.''' return self.table['lsymbolic'] def enableLSymbolic(self): '''Enable creation of symbolic links instead of copying files, only for - files from the local override directory.''' + files from the local override directories.''' self.table['lsymbolic'] = True def disableLSymbolic(self): '''Disable creation of symbolic links instead of copying files, only for - files from the local override directory.''' + files from the local override directories.''' self.table['lsymbolic'] = False def resetLSymbolic(self): '''Reset creation of symbolic links instead of copying files, only for - files from the local override directory.''' + files from the local override directories.''' self.table['lsymbolic'] = False # Define verbosity methods. diff --git a/pygnulib/GLEmiter.py b/pygnulib/GLEmiter.py index c41d4c5518..a5a13e63fb 100644 --- a/pygnulib/GLEmiter.py +++ b/pygnulib/GLEmiter.py @@ -605,7 +605,7 @@ AC_DEFUN([%V1%_LIBSOURCES], [ Emit the contents of the library Makefile. Returns str and a bool variable which shows if subdirectories are used. - GLConfig: localdir, sourcebase, libname, pobase, auxdir, makefile, libtool, + GLConfig: localpath, sourcebase, libname, pobase, auxdir, makefile, libtool, macro_prefix, podomain, conddeps, witness_c_macro. destfile is a filename relative to destdir of Makefile being generated. @@ -635,7 +635,6 @@ AC_DEFUN([%V1%_LIBSOURCES], [ raise TypeError('for_test must be a bool, not %s' % type(for_test).__name__) emit = '' - localdir = self.config['localdir'] sourcebase = self.config['sourcebase'] modcache = self.config['modcache'] libname = self.config['libname'] @@ -885,7 +884,7 @@ AC_DEFUN([%V1%_LIBSOURCES], [ Emit the contents of the tests Makefile. Returns str and a bool variable which shows if subdirectories are used. - GLConfig: localdir, modules, libname, auxdir, makefile, libtool, + GLConfig: localpath, modules, libname, auxdir, makefile, libtool, sourcebase, m4base, testsbase, macro_prefix, witness_c_macro, single_configure, libtests. @@ -914,7 +913,6 @@ AC_DEFUN([%V1%_LIBSOURCES], [ raise TypeError('for_test must be a bool, not %s' % type(for_test).__name__) emit = '' - localdir = self.config['localdir'] auxdir = self.config['auxdir'] sourcebase = self.config['sourcebase'] modcache = self.config['modcache'] diff --git a/pygnulib/GLFileSystem.py b/pygnulib/GLFileSystem.py index f17466187d..dfb1bb903f 100644 --- a/pygnulib/GLFileSystem.py +++ b/pygnulib/GLFileSystem.py @@ -23,6 +23,7 @@ import codecs import shutil import filecmp import subprocess as sp +from enum import Enum from . import constants from .GLError import GLError from .GLConfig import GLConfig @@ -45,18 +46,26 @@ isdir = os.path.isdir isfile = os.path.isfile +#=============================================================================== +# Define CopyAction class +#=============================================================================== +class CopyAction(Enum): + Copy = 0 + Symlink = 1 + + #=============================================================================== # Define GLFileSystem class #=============================================================================== class GLFileSystem(object): - '''GLFileSystem class is used to create virtual filesystem, which is based on - the gnulib directory and directory specified by localdir argument. Its main - method lookup(file) is used to find file in these directories or combine it - using Linux 'patch' utility.''' + '''GLFileSystem class is used to create virtual filesystem, which is based + on the gnulib directory and directories specified by localpath argument. + Its main method lookup(file) is used to find file in these directories or + combine it using Linux 'patch' utility.''' def __init__(self, config): - '''Create new GLFileSystem instance. The only argument is localdir, - which can be an empty string too.''' + '''Create new GLFileSystem instance. The only argument is localpath, + which can be an empty list.''' if type(config) is not GLConfig: raise TypeError('config must be a GLConfig, not %s' % type(config).__name__) @@ -70,43 +79,75 @@ class GLFileSystem(object): def lookup(self, name): '''GLFileSystem.lookup(name) -> tuple - Lookup a file in gnulib and localdir directories or combine it using Linux + Lookup a file in gnulib and localpath directories or combine it using 'patch' utility. If file was found, method returns string, else it raises GLError telling that file was not found. Function also returns flag which indicates whether file is a temporary file. - GLConfig: localdir.''' + GLConfig: localpath.''' if type(name) is not str: raise TypeError( 'name must be a string, not %s' % type(module).__name__) - # If name exists in localdir, then we use it - path_gnulib = joinpath(DIRS['root'], name) - path_local = joinpath(self.config['localdir'], name) - path_diff = joinpath(self.config['localdir'], '%s.diff' % name) - path_temp = joinpath(self.config['tempdir'], name) - try: # Try to create directories - os.makedirs(os.path.dirname(path_temp)) - except OSError as error: - pass # Skip errors if directory exists - if isfile(path_temp): - os.remove(path_temp) - if self.config['localdir'] and isfile(path_local): - result = (path_local, False) - else: # if path_local does not exist - if isfile(path_gnulib): - if self.config['localdir'] and isfile(path_diff): - shutil.copy(path_gnulib, path_temp) - command = 'patch -s "%s" < "%s" >&2' % (path_temp, path_diff) + localpath = self.config['localpath'] + # Each element in localpath is a directory whose contents overrides + # or amends the result of the lookup in the rest of localpath and + # the gnulib dir. So, the first element of localpath is the highest + # priority one. + lookedupFile = None + lookedupPatches = [] + for localdir in localpath: + file_in_localdir = joinpath(localdir, name) + if isfile(file_in_localdir): + lookedupFile = file_in_localdir + break + diff_in_localdir = joinpath(localdir, '%s.diff' % name) + if isfile(diff_in_localdir): + lookedupPatches.append(diff_in_localdir) + # Treat the gnulib dir like a lowest-priority --local-dir, except that + # here we don't look for .diff files. + if lookedupFile == None: + file_in_localdir = joinpath(DIRS['root'], name) + if isfile(file_in_localdir): + lookedupFile = file_in_localdir + if lookedupFile != None: + if len(lookedupPatches) > 0: + # Apply the patches, from lowest-priority to highest-priority. + tempFile = joinpath(self.config['tempdir'], name) + try: # Try to create directories + os.makedirs(os.path.dirname(tempFile)) + except OSError as error: + pass # Skip errors if directory exists + if isfile(tempFile): + os.remove(tempFile) + shutil.copy(lookedupFile, tempFile) + for diff_in_localdir in reversed(lookedupPatches): + command = 'patch -s "%s" < "%s" >&2' % (tempFile, diff_in_localdir) try: # Try to apply patch sp.check_call(command, shell=True) except sp.CalledProcessError as error: raise GLError(2, name) - result = (path_temp, True) - else: # if path_diff does not exist - result = (path_gnulib, False) - else: # if path_gnulib does not exist - raise GLError(1, name) + result = (tempFile, True) + else: + result = (lookedupFile, False) + else: + raise GLError(1, name) return result + def shouldLink(self, original, lookedup): + '''GLFileSystem.shouldLink(original, lookedup) + + Determines whether the original file should be copied or symlinked. + Returns a CopyAction.''' + symbolic = self.config['symbolic'] + lsymbolic = self.config['lsymbolic'] + localpath = self.config['localpath'] + if symbolic: + return CopyAction.Symlink + if lsymbolic: + for localdir in localpath: + if lookedup == joinpath(localdir, original): + return CopyAction.Symlink + return CopyAction.Copy + #=============================================================================== # Define GLFileAssistant class @@ -212,16 +253,13 @@ class GLFileAssistant(object): original = self.original rewritten = self.rewritten destdir = self.config['destdir'] - symbolic = self.config['symbolic'] - lsymbolic = self.config['lsymbolic'] if original == None: raise TypeError('original must be set before applying the method') - elif rewritten == None: + if rewritten == None: raise TypeError('rewritten must be set before applying the method') if not self.config['dryrun']: print('Copying file %s' % rewritten) - loriginal = joinpath(self.config['localdir'], original) - if (symbolic or (lsymbolic and lookedup == loriginal)) \ + if self.filesystem.shouldLink(original, lookedup) == CopyAction.Symlink \ and not tmpflag and filecmp.cmp(lookedup, tmpfile): constants.link_if_changed( lookedup, joinpath(destdir, rewritten)) @@ -242,11 +280,9 @@ class GLFileAssistant(object): original = self.original rewritten = self.rewritten destdir = self.config['destdir'] - symbolic = self.config['symbolic'] - lsymbolic = self.config['lsymbolic'] if original == None: raise TypeError('original must be set before applying the method') - elif rewritten == None: + if rewritten == None: raise TypeError('rewritten must be set before applying the method') if type(lookedup) is not str: raise TypeError('lookedup must be a string, not %s' % @@ -274,8 +310,7 @@ class GLFileAssistant(object): shutil.move(basepath, backuppath) except Exception as error: raise GLError(17, original) - loriginal = joinpath(self.config['localdir'], original) - if (symbolic or (lsymbolic and lookedup == loriginal)) \ + if self.filesystem.shouldLink(original, lookedup) == CopyAction.Symlink \ and not tmpflag and filecmp.cmp(lookedup, tmpfile): constants.link_if_changed(lookedup, basepath) else: # if any of these conditions is not met diff --git a/pygnulib/GLImport.py b/pygnulib/GLImport.py index b2691a976d..2b16ce0ea4 100644 --- a/pygnulib/GLImport.py +++ b/pygnulib/GLImport.py @@ -52,7 +52,6 @@ TESTS = constants.TESTS compiler = constants.compiler joinpath = constants.joinpath cleaner = constants.cleaner -relpath = constants.relativize isabs = os.path.isabs isdir = os.path.isdir isfile = os.path.isfile @@ -181,7 +180,7 @@ class GLImport(object): if tempdict['gl_LIB']: self.cache.setLibName(cleaner(tempdict['gl_LIB'])) if tempdict['gl_LOCAL_DIR']: - self.cache.setLocalDir(cleaner(tempdict['gl_LOCAL_DIR'])) + self.cache.setLocalPath(cleaner(tempdict['gl_LOCAL_DIR']).split(':')) if tempdict['gl_MODULES']: self.cache.setModules(cleaner(tempdict['gl_MODULES'].split())) if tempdict['gl_AVOID']: @@ -217,23 +216,14 @@ class GLImport(object): pattern = compiler(regex, re.S | re.M) self.cache.setFiles(pattern.findall(data)[-1].strip().split()) - # The self.config['localdir'] defaults to the cached one. Recall that the - # cached one is relative to $destdir, whereas the one we use is relative - # to . or absolute. - if not self.config['localdir']: - if self.cache['localdir']: - if isabs(self.config['destdir']): - localdir = joinpath( - self.config['destdir'], self.cache['localdir']) - else: # if not isabs(self.config['destdir']) - if isabs(self.cache['localdir']): - localdir = joinpath( - self.config['destdir'], self.cache['localdir']) - else: # if not isabs(self.cache['localdir']) - # NOTE: I NEED TO IMPLEMENT RELATIVE_CONCAT - localdir = os.path.relpath(joinpath(self.config['destdir'], - self.cache['localdir'])) - self.config.setLocalDir(localdir) + # The self.config['localpath'] defaults to the cached one. Recall that + # the cached one is relative to self.config['destdir'], whereas the one + # we use is relative to . or absolute. + if len(self.config['localpath']) == 0: + if len(self.cache['localpath']) > 0: + localpath = [ self.relative_to_currdir(localdir) + for localdir in self.cache['localpath'] ] + self.config.setLocalPath(localpath) if self.mode != MODES['import']: if self.cache['m4base'] and \ @@ -367,7 +357,7 @@ class GLImport(object): modules = self.config.getModules() avoids = self.config.getAvoids() destdir = self.config.getDestDir() - localdir = self.config.getLocalDir() + localpath = self.config.getLocalPath() auxdir = self.config.getAuxDir() sourcebase = self.config.getSourceBase() m4base = self.config.getM4Base() @@ -389,7 +379,7 @@ class GLImport(object): # Create command-line invocation comment. actioncmd = 'gnulib-tool --import' actioncmd += ' --dir=%s' % destdir - if localdir: + for localdir in localpath: actioncmd += ' --local-dir=%s' % localdir actioncmd += ' --lib=%s' % libname actioncmd += ' --source-base=%s' % sourcebase @@ -443,17 +433,49 @@ class GLImport(object): actioncmd += ' '.join(modules) return actioncmd + def relative_to_destdir(self, dir): + '''GLImport.relative_to_destdir(dir) -> str + + Convert a filename that represents dir, relative to the current directory, + to a filename relative to destdir. + GLConfig: destdir.''' + destdir = self.config['destdir'] + if dir.startswith('/'): + return dir + else: + if destdir.startswith('/'): + # XXX This doesn't look right. + return dir + else: + return constants.relativize(destdir, dir) + + def relative_to_currdir(self, dir): + '''GLImport.relative_to_currdir(dir) -> str + + The opposite of GLImport.relative_to_destdir: + Convert a filename that represents dir, relative to destdir, + to a filename relative to the current directory. + GLConfig: destdir.''' + destdir = self.config['destdir'] + if dir.startswith('/'): + return dir + else: + if destdir.startswith('/'): + # XXX This doesn't look right. + return joinpath(destdir, dir) + else: + return constants.relconcat(destdir, dir) + def gnulib_cache(self): '''GLImport.gnulib_cache() -> str Emit the contents of generated $m4base/gnulib-cache.m4 file. - GLConfig: destdir, localdir, tests, sourcebase, m4base, pobase, docbase, + GLConfig: destdir, localpath, tests, sourcebase, m4base, pobase, docbase, testsbase, conddeps, libtool, macro_prefix, podomain, vc_files.''' emit = '' moduletable = self.moduletable actioncmd = self.actioncmd() - destdir = self.config['destdir'] - localdir = self.config['localdir'] + localpath = self.config['localpath'] testflags = list(self.config['testflags']) sourcebase = self.config['sourcebase'] m4base = self.config['m4base'] @@ -482,13 +504,11 @@ class GLImport(object): # Specification in the form of a command-line invocation: # %s -# Specification in the form of a few \ -gnulib-tool.m4 macro invocations:\n''' % actioncmd - if not localdir or localdir.startswith('/'): - relative_localdir = localdir - else: # if localdir or not localdir.startswith('/') - relative_localdir = constants.relativize(destdir, localdir) - emit += 'gl_LOCAL_DIR([%s])\n' % relative_localdir +# Specification in the form of a few gnulib-tool.m4 macro invocations:\n''' % actioncmd + # Store the localpath relative to destdir. + relative_localpath = [ self.relative_to_destdir(localdir) + for localdir in localpath ] + emit += 'gl_LOCAL_DIR([%s])\n' % ':'.join(relative_localpath) emit += 'gl_MODULES([\n' emit += ' %s\n' % '\n '.join(modules) emit += '])\n' @@ -532,13 +552,12 @@ gnulib-tool.m4 macro invocations:\n''' % actioncmd '''GLImport.gnulib_comp(files) -> str Emit the contents of generated $m4base/gnulib-comp.m4 file. - GLConfig: destdir, localdir, tests, sourcebase, m4base, pobase, docbase, + GLConfig: destdir, localpath, tests, sourcebase, m4base, pobase, docbase, testsbase, conddeps, libtool, macro_prefix, podomain, vc_files.''' emit = '' assistant = self.assistant moduletable = self.moduletable destdir = self.config['destdir'] - localdir = self.config['localdir'] auxdir = self.config['auxdir'] testflags = list(self.config['testflags']) sourcebase = self.config['sourcebase'] @@ -740,7 +759,6 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix '''Make all preparations before the execution of the code. Returns filetable and sed transformers, which change the license.''' destdir = self.config['destdir'] - localdir = self.config['localdir'] auxdir = self.config['auxdir'] modules = list(self.config['modules']) avoids = list(self.config['avoids']) @@ -963,7 +981,6 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix if key not in filetable: raise KeyError('filetable must contain key %s' % repr(key)) destdir = self.config['destdir'] - localdir = self.config['localdir'] auxdir = self.config['auxdir'] modules = list(self.config['modules']) avoids = list(self.config['avoids']) diff --git a/pygnulib/GLModuleSystem.py b/pygnulib/GLModuleSystem.py index 48515ce36d..00b2c5f035 100644 --- a/pygnulib/GLModuleSystem.py +++ b/pygnulib/GLModuleSystem.py @@ -60,7 +60,7 @@ class GLModuleSystem(object): '''GLModuleSystem.__init__(config) -> GLModuleSystem Create new GLModuleSystem instance. Some functions use GLFileSystem class - to look up a file in localdir or gnulib directories, or combine it through + to look up a file in localpath or gnulib directories, or combine it through 'patch' utility.''' self.args = dict() if type(config) is not GLConfig: @@ -78,22 +78,22 @@ class GLModuleSystem(object): '''GLModuleSystem.exists(module) -> bool Check whether the given module exists. - GLConfig: localdir.''' + GLConfig: localpath.''' if type(module) is not str: raise TypeError( 'module must be a string, not %s' % type(module).__name__) - result = bool() + localpath = self.config['localpath'] + result = False badnames = ['ChangeLog', 'COPYING', 'README', 'TEMPLATE', 'TEMPLATE-EXTENDED', 'TEMPLATE-TESTS'] - if isfile(joinpath(DIRS['modules'], module)) or \ - all([ # Begin all(iterable) function - self.config['localdir'], - isdir(joinpath(self.config['localdir'], 'modules')), - isfile( - joinpath(self.config['localdir'], 'modules', module)) - ]): # Close all(iterable) function - if module not in badnames: - result = True + if module not in badnames: + result = isfile(joinpath(DIRS['modules'], module)) + if not result: + for localdir in localpath: + if isdir(joinpath(localdir, 'modules')) \ + and isfile(joinpath(localdir, 'modules', module)): + result = True + break return result def find(self, module): @@ -122,7 +122,7 @@ class GLModuleSystem(object): complete, so this version uses subprocess to run shell commands.''' result = '' listing = list() - localdir = self.config['localdir'] + localpath = self.config['localpath'] find_args = ['find', 'modules', '-type', 'f', '-print'] sed_args = \ [ @@ -146,16 +146,18 @@ class GLModuleSystem(object): os.chdir(constants.DIRS['root']) find = sp.Popen(find_args, stdout=sp.PIPE) result += find.stdout.read().decode("UTF-8") + os.chdir(DIRS['cwd']) - # Read modules from local directory. - if localdir and isdir(joinpath(localdir, 'modules')): - os.chdir(localdir) - find = sp.Popen(find_args, stdout=sp.PIPE) - result += find.stdout.read().decode("UTF-8") + # Read modules from local directories. + if len(localpath) > 0: + for localdir in localpath: + os.chdir(localdir) + find = sp.Popen(find_args, stdout=sp.PIPE) + result += find.stdout.read().decode("UTF-8") + os.chdir(DIRS['cwd']) sed_args += ['-e', r's,\.diff$,,'] # Save the list of the modules to file. - os.chdir(DIRS['cwd']) path = joinpath(self.config['tempdir'], 'list') with codecs.open(path, 'wb', 'UTF-8') as file: file.write(result) @@ -538,8 +540,7 @@ Include:|Link:|License:|Maintainer:)' '''GLModule.getDependencies() -> list Return list of dependencies. - GLConfig: localdir.''' - localdir = self.config['localdir'] + GLConfig: localpath.''' result = list() section = 'Depends-on:' if 'dependencies' not in self.cache: @@ -871,7 +872,7 @@ class GLModuleTable(object): included in the final modules list. If testflags iterable is enabled, then don't add module which status is in the testflags. If conddeps are enabled, then store condition for each dependency if it has a condition. - The only necessary argument is localdir, which is needed just to create + The only necessary argument is localpath, which is needed just to create modulesystem instance to look for dependencies.''' self.avoids = list() # Avoids self.dependers = dict() # Dependencies diff --git a/pygnulib/GLTestDir.py b/pygnulib/GLTestDir.py index 79f67a8fdc..7a7f5c52fb 100644 --- a/pygnulib/GLTestDir.py +++ b/pygnulib/GLTestDir.py @@ -30,6 +30,7 @@ from .GLConfig import GLConfig from .GLModuleSystem import GLModule from .GLModuleSystem import GLModuleTable from .GLModuleSystem import GLModuleSystem +from .GLFileSystem import CopyAction from .GLFileSystem import GLFileSystem from .GLFileSystem import GLFileAssistant from .GLMakefileTable import GLMakefileTable @@ -143,7 +144,6 @@ class GLTestDir(object): '''GLTestDir.execute() Create a scratch package with the given modules.''' - localdir = self.config['localdir'] auxdir = self.config['auxdir'] testflags = list(self.config['testflags']) sourcebase = self.config['sourcebase'] @@ -154,8 +154,6 @@ class GLTestDir(object): libname = self.config['libname'] libtool = self.config['libtool'] witness_c_macro = self.config['witness_c_macro'] - symbolic = self.config['symbolic'] - lsymbolic = self.config['lsymbolic'] single_configure = self.config['single_configure'] include_guard_prefix = self.config['include_guard_prefix'] macro_prefix = self.config['macro_prefix'] @@ -337,7 +335,7 @@ class GLTestDir(object): if flag: shutil.copy(lookedup, destpath) else: # if not flag - if symbolic or (lsymbolic and lookedup == joinpath(localdir, src)): + if self.filesystem.shouldLink(src, lookedup) == CopyAction.Symlink: constants.link_relative(lookedup, destpath) else: shutil.copy(lookedup, destpath) -- 2.34.1
>From 6f4b37880b220a85735e22106516d721062205c4 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 18:42:31 +0200 Subject: [PATCH 04/16] gnulib-tool.py: Remove most short options. * gnulib-tool.py (main): Reorder the list of options. Remove most short options, for consistency with gnulib-tool. --- ChangeLog | 4 ++ gnulib-tool.py | 134 ++++++++++++++++++++++---------------------- gnulib-tool.py.TODO | 4 +- 3 files changed, 75 insertions(+), 67 deletions(-) diff --git a/ChangeLog b/ChangeLog index 98438a58a4..14db3cc7e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Remove most short options. + * gnulib-tool.py (main): Reorder the list of options. Remove most short + options, for consistency with gnulib-tool. + gnulib-tool.py: Follow gnulib-tool changes, part 19. Follow gnulib-tool changes 2015-12-09 Pavel Raiskup <prais...@redhat.com> diff --git a/gnulib-tool.py b/gnulib-tool.py index 0b2f866920..c7ab100d78 100755 --- a/gnulib-tool.py +++ b/gnulib-tool.py @@ -95,147 +95,149 @@ def main(): prog=constants.APP['name'], usage='gnulib-tool.py --help', add_help=False) - # help - parser.add_argument('-h', '--help', '--hel', '--he', '--h', - dest='help', - default=None, - action='store_true') - # version - parser.add_argument('--version', '--versio', '--versi', '--vers', - dest='version', - default=None, - action='store_true') + + # Here we list the options in the order they are listed in the --help output. + # list - parser.add_argument('-l', '--list', '--lis', + parser.add_argument('--list', dest='mode_list', default=None, action='store_true') # find - parser.add_argument('-f', '--find', '--fin', '--fi', '--f', + parser.add_argument('--find', dest='mode_find', default=None, nargs='*') # import - parser.add_argument('-i', '--import', + parser.add_argument('--import', dest='mode_import', default=None, nargs='*') # add-import - parser.add_argument('-a', '--add-import', + parser.add_argument('--add-import', dest='mode_add_import', default=None, nargs='+') # remove-import - parser.add_argument('-r', '--remove-import', + parser.add_argument('--remove-import', dest='mode_remove_import', default=None, nargs='+') # update - parser.add_argument('-u', '--update', + parser.add_argument('--update', dest='mode_update', default=None, action='store_true') # create-testdir - parser.add_argument('-td', '--create-testdir', + parser.add_argument('--create-testdir', dest='mode_create_testdir', default=None, nargs='*') # create-megatestdir - parser.add_argument('-mtd', '--create-megatestdir', + parser.add_argument('--create-megatestdir', dest='mode_create_megatestdir', default=None, nargs='*') # test - parser.add_argument('-t', '--test', + parser.add_argument('--test', dest='mode_test', default=None, nargs='*') # megatest - parser.add_argument('-mt', '--megatest', '--megates', '--megate', '--megat', - '--mega', '--meg', '--me', '--m', + parser.add_argument('--megatest', dest='mode_megatest', default=None, nargs='*') - # copy-file - parser.add_argument('-c', '--copy-file', - dest='mode_copy_file', - default=None, - nargs='+') # extract-* - parser.add_argument('-xD', '--extract-description', + parser.add_argument('--extract-description', dest='mode_xdescription', default=None, nargs='*') - parser.add_argument('-xc', '--extract-comment', + parser.add_argument('--extract-comment', dest='mode_xcomment', default=None, nargs='*') - parser.add_argument('-xs', '--extract-status', + parser.add_argument('--extract-status', dest='mode_xstatus', default=None, nargs='*') - parser.add_argument('-xn', '--extract-notice', + parser.add_argument('--extract-notice', dest='mode_xnotice', default=None, nargs='*') - parser.add_argument('-xa', '--extract-applicability', + parser.add_argument('--extract-applicability', dest='mode_xapplicability', default=None, nargs='*') - parser.add_argument('-xf', '--extract-filelist', + parser.add_argument('--extract-filelist', dest='mode_xfilelist', default=None, nargs='*') - parser.add_argument('-xd', '--extract-dependencies', + parser.add_argument('--extract-dependencies', dest='mode_xdependencies', default=None, nargs='*') - parser.add_argument('-xac', '--extract-autoconf-snippet', + parser.add_argument('--extract-autoconf-snippet', dest='mode_xautoconf', default=None, nargs='*') - parser.add_argument('-xam', '--extract-automake-snippet', + parser.add_argument('--extract-automake-snippet', dest='mode_xautomake', default=None, nargs='*') - parser.add_argument('-xi', '--extract-include-directive', + parser.add_argument('--extract-include-directive', dest='mode_xinclude', default=None, nargs='*') - parser.add_argument('-xl', '--extract-link-directive', + parser.add_argument('--extract-link-directive', dest='mode_xlink', default=None, nargs='*') - parser.add_argument('-xL', '--extract-license', + parser.add_argument('--extract-license', dest='mode_xlicense', default=None, nargs='*') - parser.add_argument('-xm', '--extract-maintainer', + parser.add_argument('--extract-maintainer', dest='mode_xmaintainer', default=None, nargs='*') + # copy-file + parser.add_argument('--copy-file', + dest='mode_copy_file', + default=None, + nargs='+') + # help + parser.add_argument('--help', '--hel', '--he', '--h', + dest='help', + default=None, + action='store_true') + # version + parser.add_argument('--version', '--versio', '--versi', '--vers', + dest='version', + default=None, + action='store_true') # no-changelog: a no-op for backward compatibility parser.add_argument('--no-changelog', dest='changelog', default=None, action='store_false') # destdir - parser.add_argument('-d', '--dir', + parser.add_argument('--dir', dest='destdir', default=None, nargs=1) # localpath - parser.add_argument('-ld', '--local-dir', + parser.add_argument('--local-dir', action='append', dest='localpath', default=None, nargs='?') # verbose - parser.add_argument('-v', '--verbose', + parser.add_argument('--verbose', default=0, action='count') # quiet - parser.add_argument('-q', '--quiet', + parser.add_argument('--quiet', default=0, action='count') # dryrun @@ -248,11 +250,6 @@ def main(): dest='inctests', default=None, action='store_true') - # makefile - parser.add_argument("--makefile-name", - dest="makefile", - default=None, - type=str) # obsolete parser.add_argument('--with-obsolete', dest='obsolete', @@ -283,57 +280,62 @@ def main(): dest='alltests', default=None, action='store_true') - # auxdir - parser.add_argument('--aux-dir', - dest='auxdir', - default=None, - nargs=1) - # libname - parser.add_argument('--lib', - dest='libname', + # avoids + parser.add_argument('--avoid', + dest='avoids', default=None, - nargs=1) + nargs='+') # libtool parser.add_argument("--libtool", dest=libtool, default=False, action="store_true") + # libname + parser.add_argument('--lib', + dest='libname', + default=None, + nargs=1) # sourcebase - parser.add_argument('-sb', '--source-base', + parser.add_argument('--source-base', dest='sourcebase', default=None, nargs=1) # m4base - parser.add_argument('-mb', '--m4-base', + parser.add_argument('--m4-base', dest='m4base', default=None, nargs=1) # pobase - parser.add_argument('-pb', '--po-base', + parser.add_argument('--po-base', dest='pobase', default=None, nargs=1) # docbase - parser.add_argument('-db', '--doc-base', + parser.add_argument('--doc-base', dest='docbase', default=None, nargs=1) # testsbase - parser.add_argument('-tb', '--tests-base', + parser.add_argument('--tests-base', dest='testsbase', default=None, nargs=1) + # auxdir + parser.add_argument('--aux-dir', + dest='auxdir', + default=None, + nargs=1) # lgpl parser.add_argument('--lgpl', dest='lgpl', default=False, type=int, nargs='?') - # avoids - parser.add_argument('--avoid', - dest='avoids', + # makefile + parser.add_argument("--makefile-name", + dest="makefile", default=None, - nargs='+') + type=str) # Parse the given arguments. cmdargs = parser.parse_args() diff --git a/gnulib-tool.py.TODO b/gnulib-tool.py.TODO index 26c59c5353..eeecd5ed8a 100644 --- a/gnulib-tool.py.TODO +++ b/gnulib-tool.py.TODO @@ -17,6 +17,9 @@ The following commits to gnulib-tool have not yet been reflected in Implement the options: --find + --extract-recursive-dependencies + --extract-recursive-link-directive + --extract-tests-module --without-tests --without-c++-tests --without-longrunning-tests @@ -34,7 +37,6 @@ Implement the options: --witness-c-macro --vc-files --no-vc-files - --no-changelog -s | --symbolic --local-symlink -h | --hardlink -- 2.34.1
>From 622cef78a7dcbd27c426f09848d0abfbb53df843 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 18:44:56 +0200 Subject: [PATCH 05/16] gnulib-tool.py: Emit error message when conflicting modes are specified. * gnulib-tool.py (main): Fix test of conflicting modes. (Some options produce a value of [], and as a condition, [] evaluates to False.) --- ChangeLog | 4 ++++ gnulib-tool.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 14db3cc7e8..3c271bd4de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Emit error message when conflicting modes are specified. + * gnulib-tool.py (main): Fix test of conflicting modes. (Some options + produce a value of [], and as a condition, [] evaluates to False.) + gnulib-tool.py: Remove most short options. * gnulib-tool.py (main): Reorder the list of options. Remove most short options, for consistency with gnulib-tool. diff --git a/gnulib-tool.py b/gnulib-tool.py index c7ab100d78..b16becb1d2 100755 --- a/gnulib-tool.py +++ b/gnulib-tool.py @@ -351,7 +351,6 @@ def main(): cmdargs.mode_create_megatestdir, cmdargs.mode_test, cmdargs.mode_megatest, - cmdargs.mode_copy_file, cmdargs.mode_xdescription, cmdargs.mode_xcomment, cmdargs.mode_xstatus, @@ -365,8 +364,9 @@ def main(): cmdargs.mode_xlink, cmdargs.mode_xlicense, cmdargs.mode_xmaintainer, + cmdargs.mode_copy_file, ] - overflow = [arg for arg in args if arg] + overflow = [arg for arg in args if arg != None] if len(overflow) > 1: message = 'gnulib-tool: Unable to combine different modes of work.\n' message += 'Try \'gnulib-tool --help\' for more information.\n' -- 2.34.1
>From 56a625b004c134b41a92fc658871df2f954fcafe Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 18:48:25 +0200 Subject: [PATCH 06/16] gnulib-tool.py: Improve compliance with GNU standards. * gnulib-tool.py (main): Handle --help and --version before testing for conflicting modes. --- ChangeLog | 4 ++++ gnulib-tool.py | 20 +++++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3c271bd4de..f5b9c4e968 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Improve compliance with GNU standards. + * gnulib-tool.py (main): Handle --help and --version before testing for + conflicting modes. + gnulib-tool.py: Emit error message when conflicting modes are specified. * gnulib-tool.py (main): Fix test of conflicting modes. (Some options produce a value of [], and as a condition, [] evaluates to False.) diff --git a/gnulib-tool.py b/gnulib-tool.py index b16becb1d2..a6d4f6fa75 100755 --- a/gnulib-tool.py +++ b/gnulib-tool.py @@ -340,6 +340,17 @@ def main(): # Parse the given arguments. cmdargs = parser.parse_args() + # Handle --help and --version, ignoring all other options. + if cmdargs.help != None: + print(info.usage()) + sys.exit(0) + if cmdargs.version != None: + message = '''gnulib-tool (%s %s)%s\n%s\n%s\n\nWritten by %s.''' % \ + (info.package(), info.date(), info.version(), info.copyright(), + info.license(), info.authors()) + print(message) + sys.exit(0) + # Determine when user tries to combine modes. args = [ cmdargs.mode_list, @@ -374,15 +385,6 @@ def main(): sys.exit(1) # Determine selected mode. - if cmdargs.help != None: - print(info.usage()) - sys.exit(0) - if cmdargs.version != None: - message = '''gnulib-tool (%s %s)%s\n%s\n%s\n\nWritten by %s.''' % \ - (info.package(), info.date(), info.version(), info.copyright(), - info.license(), info.authors()) - print(message) - sys.exit(0) if cmdargs.mode_list != None: mode = 'list' if cmdargs.mode_import != None: -- 2.34.1
>From 1d41c75835c08eee63692dd0c25062d05a25d538 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 18:51:17 +0200 Subject: [PATCH 07/16] gnulib-tool.py: Make option processing more similar to gnulib-tool. * gnulib-tool.py (main): Allow --add-import and --remove-import with 0 modules. --- ChangeLog | 4 ++++ gnulib-tool.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f5b9c4e968..178b3986b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Make option processing more similar to gnulib-tool. + * gnulib-tool.py (main): Allow --add-import and --remove-import with 0 + modules. + gnulib-tool.py: Improve compliance with GNU standards. * gnulib-tool.py (main): Handle --help and --version before testing for conflicting modes. diff --git a/gnulib-tool.py b/gnulib-tool.py index a6d4f6fa75..166a4ae56d 100755 --- a/gnulib-tool.py +++ b/gnulib-tool.py @@ -117,12 +117,12 @@ def main(): parser.add_argument('--add-import', dest='mode_add_import', default=None, - nargs='+') + nargs='*') # remove-import parser.add_argument('--remove-import', dest='mode_remove_import', default=None, - nargs='+') + nargs='*') # update parser.add_argument('--update', dest='mode_update', -- 2.34.1
>From 591c99e6b9b5ccd4eeb2a067c1102b7164cd2304 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 18:53:24 +0200 Subject: [PATCH 08/16] gnulib-tool: Clarify that --test allows zero module arguments. * gnulib-tool (func_usage): Mark the modules for --test as optional. * pygnulib/GLInfo.py (GLInfo.usage): Likewise. --- ChangeLog | 4 ++++ gnulib-tool | 2 +- pygnulib/GLInfo.py | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 178b3986b1..caf9747ac3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool: Clarify that --test allows zero module arguments. + * gnulib-tool (func_usage): Mark the modules for --test as optional. + * pygnulib/GLInfo.py (GLInfo.usage): Likewise. + gnulib-tool.py: Make option processing more similar to gnulib-tool. * gnulib-tool.py (main): Allow --add-import and --remove-import with 0 modules. diff --git a/gnulib-tool b/gnulib-tool index f1665f4002..6c50b44fbc 100755 --- a/gnulib-tool +++ b/gnulib-tool @@ -155,7 +155,7 @@ Usage: gnulib-tool --list gnulib-tool --update gnulib-tool --create-testdir --dir=directory [module1 ... moduleN] gnulib-tool --create-megatestdir --dir=directory [module1 ... moduleN] - gnulib-tool --test --dir=directory module1 ... moduleN + gnulib-tool --test --dir=directory [module1 ... moduleN] gnulib-tool --megatest --dir=directory [module1 ... moduleN] gnulib-tool --extract-description module gnulib-tool --extract-comment module diff --git a/pygnulib/GLInfo.py b/pygnulib/GLInfo.py index f66e469670..79c1ba0cf1 100644 --- a/pygnulib/GLInfo.py +++ b/pygnulib/GLInfo.py @@ -119,7 +119,7 @@ Usage: gnulib-tool --list gnulib-tool --update gnulib-tool --create-testdir --dir=directory [module1 ... moduleN] gnulib-tool --create-megatestdir --dir=directory [module1 ... moduleN] - gnulib-tool --test --dir=directory module1 ... moduleN + gnulib-tool --test --dir=directory [module1 ... moduleN] gnulib-tool --megatest --dir=directory [module1 ... moduleN] gnulib-tool --extract-description module gnulib-tool --extract-comment module -- 2.34.1
>From cfb5e7537c7725da01f4854eba605006bdff0468 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 18:54:22 +0200 Subject: [PATCH 09/16] gnulib-tool.py: Make --test behaviour more similar to gnulib-tool. * gnulib-tool.py (main) [test]: Remove space from the testdir name. --- ChangeLog | 3 +++ gnulib-tool.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index caf9747ac3..bff168a7a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Make --test behaviour more similar to gnulib-tool. + * gnulib-tool.py (main) [test]: Remove space from the testdir name. + gnulib-tool: Clarify that --test allows zero module arguments. * gnulib-tool (func_usage): Mark the modules for --test as optional. * pygnulib/GLInfo.py (GLInfo.usage): Likewise. diff --git a/gnulib-tool.py b/gnulib-tool.py index 166a4ae56d..a646ae2d38 100755 --- a/gnulib-tool.py +++ b/gnulib-tool.py @@ -702,7 +702,7 @@ def main(): elif mode == 'test': if not destdir: - destdir = 'testdir %04d' % random.randrange(0, 9999) + destdir = 'testdir%04d' % random.randrange(0, 9999) if not auxdir: auxdir = 'build-aux' config.setAuxDir(auxdir) -- 2.34.1
>From f1b0f11bc8a0e18f34b33fbb7955293715b695ee Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 18:56:05 +0200 Subject: [PATCH 10/16] gnulib-tool.py: Allow module arguments to occur at any position. * gnulib-tool.py (main): Collect the non-option arguments in a single list, regardless of their position. Use parse_known_args instead of parse_args, and give an error message about unknown options ourselves. * gnulib-tool: Fix typo in error message. --- ChangeLog | 6 +++ gnulib-tool | 2 +- gnulib-tool.py | 128 ++++++++++++++++++++++++++++++------------------- 3 files changed, 86 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index bff168a7a4..a48f89db6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Allow module arguments to occur at any position. + * gnulib-tool.py (main): Collect the non-option arguments in a single + list, regardless of their position. Use parse_known_args instead of + parse_args, and give an error message about unknown options ourselves. + * gnulib-tool: Fix typo in error message. + gnulib-tool.py: Make --test behaviour more similar to gnulib-tool. * gnulib-tool.py (main) [test]: Remove space from the testdir name. diff --git a/gnulib-tool b/gnulib-tool index 6c50b44fbc..ac53480dbf 100755 --- a/gnulib-tool +++ b/gnulib-tool @@ -1518,7 +1518,7 @@ func_determine_path_separator echo "gnulib-tool: too many arguments in 'update' mode" 1>&2 echo "Try 'gnulib-tool --help' for more information." 1>&2 echo "If you really want to modify the gnulib configuration of your project," 1>&2 - echo "you need to use 'gnulib --import' - at your own risk!" 1>&2 + echo "you need to use 'gnulib-tool --import' - at your own risk!" 1>&2 func_exit 1 fi if test -n "$local_gnulib_path" || test -n "$supplied_libname" \ diff --git a/gnulib-tool.py b/gnulib-tool.py index a646ae2d38..f1cf389c36 100755 --- a/gnulib-tool.py +++ b/gnulib-tool.py @@ -107,22 +107,22 @@ def main(): parser.add_argument('--find', dest='mode_find', default=None, - nargs='*') + action='store_true') # import parser.add_argument('--import', dest='mode_import', default=None, - nargs='*') + action='store_true') # add-import parser.add_argument('--add-import', dest='mode_add_import', default=None, - nargs='*') + action='store_true') # remove-import parser.add_argument('--remove-import', dest='mode_remove_import', default=None, - nargs='*') + action='store_true') # update parser.add_argument('--update', dest='mode_update', @@ -132,80 +132,80 @@ def main(): parser.add_argument('--create-testdir', dest='mode_create_testdir', default=None, - nargs='*') + action='store_true') # create-megatestdir parser.add_argument('--create-megatestdir', dest='mode_create_megatestdir', default=None, - nargs='*') + action='store_true') # test parser.add_argument('--test', dest='mode_test', default=None, - nargs='*') + action='store_true') # megatest parser.add_argument('--megatest', dest='mode_megatest', default=None, - nargs='*') + action='store_true') # extract-* parser.add_argument('--extract-description', dest='mode_xdescription', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-comment', dest='mode_xcomment', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-status', dest='mode_xstatus', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-notice', dest='mode_xnotice', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-applicability', dest='mode_xapplicability', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-filelist', dest='mode_xfilelist', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-dependencies', dest='mode_xdependencies', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-autoconf-snippet', dest='mode_xautoconf', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-automake-snippet', dest='mode_xautomake', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-include-directive', dest='mode_xinclude', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-link-directive', dest='mode_xlink', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-license', dest='mode_xlicense', default=None, - nargs='*') + action='store_true') parser.add_argument('--extract-maintainer', dest='mode_xmaintainer', default=None, - nargs='*') + action='store_true') # copy-file parser.add_argument('--copy-file', dest='mode_copy_file', default=None, - nargs='+') + action='store_true') # help parser.add_argument('--help', '--hel', '--he', '--h', dest='help', @@ -231,7 +231,7 @@ def main(): action='append', dest='localpath', default=None, - nargs='?') + nargs=1) # verbose parser.add_argument('--verbose', default=0, @@ -282,9 +282,10 @@ def main(): action='store_true') # avoids parser.add_argument('--avoid', + action='append', dest='avoids', default=None, - nargs='+') + nargs=1) # libtool parser.add_argument("--libtool", dest=libtool, @@ -336,9 +337,13 @@ def main(): dest="makefile", default=None, type=str) + # All other arguments are collected. + parser.add_argument("non_option_arguments", + nargs='*') - # Parse the given arguments. - cmdargs = parser.parse_args() + # Parse the given arguments. Don't signal an error if non-option arguments + # occur between or after options. + (cmdargs, unhandled) = parser.parse_known_args() # Handle --help and --version, ignoring all other options. if cmdargs.help != None: @@ -351,6 +356,16 @@ def main(): print(message) sys.exit(0) + # Report unhandled arguments. + for arg in unhandled: + if arg.startswith('-'): + message = '%s: Unrecognized option \'%s\'.\n' % (constants.APP['name'], arg) + message += 'Try \'gnulib-tool --help\' for more information.\n' + sys.stderr.write(message) + sys.exit(1) + # By now, all unhandled arguments were non-options. + cmdargs.non_option_arguments += unhandled + # Determine when user tries to combine modes. args = [ cmdargs.mode_list, @@ -379,7 +394,7 @@ def main(): ] overflow = [arg for arg in args if arg != None] if len(overflow) > 1: - message = 'gnulib-tool: Unable to combine different modes of work.\n' + message = '%s: Unable to combine different modes of work.\n' % constants.APP['name'] message += 'Try \'gnulib-tool --help\' for more information.\n' sys.stderr.write(message) sys.exit(1) @@ -389,81 +404,92 @@ def main(): mode = 'list' if cmdargs.mode_import != None: mode = 'import' - modules = list(cmdargs.mode_import) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_add_import != None: mode = 'add-import' - modules = list(cmdargs.mode_add_import) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_remove_import != None: mode = 'remove-import' - modules = list(cmdargs.mode_remove_import) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_update != None: mode = 'update' + if len(cmdargs.non_option_arguments) > 0: + message = '%s: too many arguments in \'update\' mode\n' + message += 'Try \'gnulib-tool --help\' for more information.\n' + message += 'If you really want to modify the gnulib configuration of your project,\n' + message += 'you need to use \'gnulib-tool --import\' - at your own risk!\n' + sys.stderr.write(message) + sys.exit(1) if cmdargs.mode_create_testdir != None: mode = 'create-testdir' - modules = list(cmdargs.mode_create_testdir) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_create_megatestdir != None: mode = 'create-megatestdir' - modules = list(cmdargs.mode_create_megatestdir) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_test != None: mode = 'test' - modules = list(cmdargs.mode_test) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_megatest != None: mode = 'megatest' - modules = list(cmdargs.mode_megatest) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xdescription != None: mode = 'extract-description' - modules = list(cmdargs.mode_xdescription) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xcomment != None: mode = 'extract-comment' - modules = list(cmdargs.mode_xcomment) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xstatus != None: mode = 'extract-status' - modules = list(cmdargs.mode_xstatus) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xnotice != None: mode = 'extract-notice' - modules = list(cmdargs.mode_xnotice) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xapplicability != None: mode = 'extract-applicability' - modules = list(cmdargs.mode_xapplicability) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xfilelist != None: mode = 'extract-filelist' - modules = list(cmdargs.mode_xfilelist) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xautoconf != None: mode = 'extract-autoconf-snippet' - modules = list(cmdargs.mode_xautoconf) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xautomake != None: mode = 'extract-automake-snippet' - modules = list(cmdargs.mode_xautomake) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xdependencies != None: mode = 'extract-dependencies' - modules = list(cmdargs.mode_xdependencies) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xinclude != None: mode = 'extract-include-directive' - modules = list(cmdargs.mode_xinclude) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xlink != None: mode = 'extract-link-directive' - modules = list(cmdargs.mode_xlink) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xlicense != None: mode = 'extract-license' - modules = list(cmdargs.mode_xlicense) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xmaintainer != None: mode = 'extract-maintainer' - modules = list(cmdargs.mode_xmaintainer) + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_copy_file != None: mode = 'copy-file' - if len(cmdargs.mode_copy_file) > 2: + if len(cmdargs.non_option_arguments) < 1 or len(cmdargs.non_option_arguments) > 2: message = '%s: *** ' % constants.APP['name'] message += 'invalid number of arguments for --%s' % mode message += '\n%s: *** Exit.\n' % constants.APP['name'] sys.stderr.write(message) sys.exit(1) - files = list(cmdargs.mode_copy_file) + files = list(cmdargs.non_option_arguments) # Determine specific settings. destdir = cmdargs.destdir if destdir != None: destdir = cmdargs.destdir[0] localpath = cmdargs.localpath + if localpath != None: + localpath = [ dir + for list1 in localpath + for dir in list1 ] libname = cmdargs.libname if libname != None: libname = cmdargs.libname[0] @@ -513,6 +539,10 @@ def main(): if lgpl == None: lgpl = True avoids = cmdargs.avoids + if avoids != None: + avoids = [ module + for list1 in avoids + for module in list1 ] # Create pygnulib configuration. config = classes.GLConfig( -- 2.34.1
>From 96f7bad09085273649f4b26a25e9d8fd51279c32 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 20:02:40 +0200 Subject: [PATCH 11/16] gnulib-tool.py: Make --copy-file work. * gnulib-tool.py (main) [copy-file]: Fix reference to uninitialized variable. Fix error handling of os.makedirs. Pass the destdir to the GLFileAssistant. --- ChangeLog | 5 +++++ gnulib-tool.py | 34 +++++++++++++++------------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index a48f89db6d..59bfec205e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Make --copy-file work. + * gnulib-tool.py (main) [copy-file]: Fix reference to uninitialized + variable. Fix error handling of os.makedirs. Pass the destdir to the + GLFileAssistant. + gnulib-tool.py: Allow module arguments to occur at any position. * gnulib-tool.py (main): Collect the non-option arguments in a single list, regardless of their position. Use parse_known_args instead of diff --git a/gnulib-tool.py b/gnulib-tool.py index f1cf389c36..f20d1157a3 100755 --- a/gnulib-tool.py +++ b/gnulib-tool.py @@ -892,9 +892,11 @@ def main(): elif mode == 'copy-file': srcpath = files[0] + # The second argument is the destination; either a directory ot a file. + # It defaults to the current directory. if len(files) == 2: dest = files[1] - else: # if len(files) != 2 + else: # if len(files) < 2 dest = '.' if not auxdir: auxdir = 'build-aux' @@ -914,53 +916,47 @@ def main(): filesystem = classes.GLFileSystem(config) lookedup, flag = filesystem.lookup(srcpath) if isdir(dest): - destdir = str(dest) + destdir = dest if srcpath.startswith('build-aux/'): - destpath = constants.substart( - 'build-aux/', '%s/' % auxdir, srcpath) + destpath = constants.substart('build-aux/', '%s/' % auxdir, srcpath) elif srcpath.startswith('doc/'): destpath = constants.substart('doc/', '%s/' % docbase, srcpath) elif srcpath.startswith('lib/'): - destpath = constants.substart( - 'lib/', '%s/' % sourcebase, srcpath) + destpath = constants.substart('lib/', '%s/' % sourcebase, srcpath) elif srcpath.startswith('m4/'): destpath = constants.substart('m4/', '%s/' % m4base, srcpath) elif srcpath.startswith('tests/'): - destpath = constants.substart( - 'tests/', '%s/' % testsbase, srcpath) - elif srcpath.startswith('tests=lib/'): - destpath = constants.substart( - 'tests=lib/', '%s/' % testsbase, srcpath) + destpath = constants.substart('tests/', '%s/' % testsbase, srcpath) elif srcpath.startswith('top/'): destpath = constants.substart('top/', '', srcpath) else: # either case destpath = srcpath - else: # if not isdir(destpath) - destdir = os.path.dirname(destpath) - destpath = os.path.basename(destpath) + else: # if not isdir(dest) + destdir = os.path.dirname(dest) + destpath = os.path.basename(dest) # Create the directory for destfile. dirname = os.path.dirname(joinpath(destdir, destpath)) if not config['dryrun']: if dirname and not isdir(dirname): try: # Try to create directories os.makedirs(dirname) - except Exception as error: + except FileExistsError: pass # Copy the file. assistant = classes.GLFileAssistant(config) tmpfile = assistant.tmpfilename(destpath) shutil.copy(lookedup, tmpfile) - already_present = True assistant.setOriginal(srcpath) + assistant.config.setDestDir(destdir) assistant.setRewritten(destpath) if isfile(joinpath(destdir, destpath)): # The file already exists. - assistant.update(lookedup, flag, tmpfile, already_present) + assistant.update(lookedup, flag, tmpfile, True) else: # if not isfile(joinpath(destdir, destpath)) # Install the file. # Don't protest if the file should be there but isn't: it happens - # frequently that developers don't put autogenerated files under version - # control. + # frequently that developers don't put autogenerated files under + # version control. assistant.add(lookedup, flag, tmpfile) if isfile(tmpfile): os.remove(tmpfile) -- 2.34.1
>From ba5620880ac965d1ecd302b77dd90bfd8c7bf682 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 21:08:55 +0200 Subject: [PATCH 12/16] gnulib-tool.py: Implement options --symlink and --local-symlink. * gnulib-tool.py (main): Handle options --symlink and --local-symlink. * pygnulib/constants.py (link_if_changed): Ignore FileNotFoundError from os.remove call. --- ChangeLog | 5 +++++ gnulib-tool.py | 14 ++++++++++++++ pygnulib/constants.py | 5 ++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 59bfec205e..0ba5352039 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Implement options --symlink and --local-symlink. + * gnulib-tool.py (main): Handle options --symlink and --local-symlink. + * pygnulib/constants.py (link_if_changed): Ignore FileNotFoundError from + os.remove call. + gnulib-tool.py: Make --copy-file work. * gnulib-tool.py (main) [copy-file]: Fix reference to uninitialized variable. Fix error handling of os.makedirs. Pass the destdir to the diff --git a/gnulib-tool.py b/gnulib-tool.py index f20d1157a3..f936a92031 100755 --- a/gnulib-tool.py +++ b/gnulib-tool.py @@ -337,6 +337,16 @@ def main(): dest="makefile", default=None, type=str) + # symlink + parser.add_argument('-s', '--symbolic', '--symlink', + dest='symlink', + default=None, + action='store_true') + # local-symlink + parser.add_argument('--local-symlink', + dest='lsymlink', + default=None, + action='store_true') # All other arguments are collected. parser.add_argument("non_option_arguments", nargs='*') @@ -543,6 +553,8 @@ def main(): avoids = [ module for list1 in avoids for module in list1 ] + symlink = cmdargs.symlink == True + lsymlink = cmdargs.lsymlink == True # Create pygnulib configuration. config = classes.GLConfig( @@ -566,6 +578,8 @@ def main(): podomain=podomain, witness_c_macro=witness_c_macro, vc_files=vc_files, + symbolic=symlink, + lsymbolic=lsymlink, modcache=modcache, verbose=verbose, dryrun=dryrun, diff --git a/pygnulib/constants.py b/pygnulib/constants.py index 9ef2e01089..10bd363f5b 100644 --- a/pygnulib/constants.py +++ b/pygnulib/constants.py @@ -330,7 +330,10 @@ def link_if_changed(src, dest): '''Create a symlink, but avoids munging timestamps if the link is correct.''' ln_target = os.path.realpath(src) if not (os.path.islink(dest) and src == ln_target): - os.remove(dest) + try: + os.remove(dest) + except FileNotFoundError: + pass link_relative(src, dest) -- 2.34.1
>From c35a6f89c420c68bd25520360f111067b3d27cd5 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 22:29:15 +0200 Subject: [PATCH 13/16] gnulib-tool.py: Use mainstream coding style. * pygnulib/GLConfig.py: Use 'raise' to re-throw an exception. --- ChangeLog | 3 +++ pygnulib/GLConfig.py | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ba5352039..bc4a09088c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Use mainstream coding style. + * pygnulib/GLConfig.py: Use 'raise' to re-throw an exception. + gnulib-tool.py: Implement options --symlink and --local-symlink. * gnulib-tool.py (main): Handle options --symlink and --local-symlink. * pygnulib/constants.py (link_if_changed): Ignore FileNotFoundError from diff --git a/pygnulib/GLConfig.py b/pygnulib/GLConfig.py index 55b6cd2986..dc0cce3490 100644 --- a/pygnulib/GLConfig.py +++ b/pygnulib/GLConfig.py @@ -579,9 +579,9 @@ class GLConfig(object): except TypeError as error: self.table['modules'] = old_modules raise TypeError('each module must be a string') - except GLError as error: + except GLError: self.table['modules'] = old_modules - raise GLError(error.errno, error.errinfo) + raise else: # if type of modules is not list or tuple raise TypeError('modules must be a list or a tuple, not %s' % type(modules).__name__) @@ -625,9 +625,9 @@ class GLConfig(object): except TypeError as error: self.table['avoids'] = old_avoids raise TypeError('each module must be a string') - except GLError as error: + except GLError: self.table['avoids'] = old_avoids - raise GLError(error.errno, error.errinfo) + raise else: # if type of modules is not list or tuple raise TypeError('modules must be a list or a tuple, not %s' % type(modules).__name__) @@ -670,9 +670,9 @@ class GLConfig(object): except TypeError as error: self.table['files'] = old_files raise TypeError('each file must be a string') - except GLError as error: + except GLError: self.table['files'] = old_files - raise GLError(error.errno, error.errinfo) + raise else: # if type of files is not list or tuple raise TypeError('files must be a list or a tuple, not %s' % type(files).__name__) -- 2.34.1
>From 07de10784c320267fabea1edfd8b3ce1e6b88f62 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 22:35:30 +0200 Subject: [PATCH 14/16] gnulib-tool.py: Write errors to stderr, not stdout. * pygnulib/constants.py: Write error messages to stderr, not stdout. --- ChangeLog | 3 +++ pygnulib/constants.py | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc4a09088c..b7d13bb414 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Write errors to stderr, not stdout. + * pygnulib/constants.py: Write error messages to stderr, not stdout. + gnulib-tool.py: Use mainstream coding style. * pygnulib/GLConfig.py: Use 'raise' to re-throw an exception. diff --git a/pygnulib/constants.py b/pygnulib/constants.py index 10bd363f5b..91a2958eb3 100644 --- a/pygnulib/constants.py +++ b/pygnulib/constants.py @@ -213,7 +213,7 @@ def execute(args, verbose): try: # Try to run retcode = sp.call(args) except Exception as error: - print(error) + sys.stderr.write(str(error) + '\n') sys.exit(1) else: # Commands like automake produce output to stderr even when they succeed. @@ -223,7 +223,7 @@ def execute(args, verbose): try: # Try to run retcode = sp.call(xargs, shell=True) except Exception as error: - print(error) + sys.stderr.write(str(error) + '\n') sys.exit(1) if retcode == 0: os.remove(temp) -- 2.34.1
>From eb6a04f6ef114c801ebd0c212fbb8822c4368f50 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 23:02:58 +0200 Subject: [PATCH 15/16] gnulib-tool.py: Improve some error messages. * gnulib-tool.py (main): Write "*** Stop." instead of "*** Exit.". (__main__): Print an error message for GLError 5, 13, 14, 15, 16, 17, 18. * pygnulib/GLError.py (GLError.__repr__): Compute one error message, not 19. --- ChangeLog | 6 ++++ gnulib-tool.py | 39 +++++++++++--------- pygnulib/GLError.py | 74 ++++++++++++++++++++++---------------- pygnulib/GLModuleSystem.py | 3 +- 4 files changed, 72 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index b7d13bb414..30805d4d73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Improve some error messages. + * gnulib-tool.py (main): Write "*** Stop." instead of "*** Exit.". + (__main__): Print an error message for GLError 5, 13, 14, 15, 16, 17, 18. + * pygnulib/GLError.py (GLError.__repr__): Compute one error message, + not 19. + gnulib-tool.py: Write errors to stderr, not stdout. * pygnulib/constants.py: Write error messages to stderr, not stdout. diff --git a/gnulib-tool.py b/gnulib-tool.py index f936a92031..302aaf3405 100755 --- a/gnulib-tool.py +++ b/gnulib-tool.py @@ -486,7 +486,7 @@ def main(): if len(cmdargs.non_option_arguments) < 1 or len(cmdargs.non_option_arguments) > 2: message = '%s: *** ' % constants.APP['name'] message += 'invalid number of arguments for --%s' % mode - message += '\n%s: *** Exit.\n' % constants.APP['name'] + message += '\n%s: *** Stop.\n' % constants.APP['name'] sys.stderr.write(message) sys.exit(1) files = list(cmdargs.non_option_arguments) @@ -722,7 +722,7 @@ def main(): if not destdir: message = '%s: *** ' % constants.APP['name'] message += 'please specify --dir option' - message += '\n%s: *** Exit.\n' % constants.APP['name'] + message += '\n%s: *** Stop.\n' % constants.APP['name'] sys.stderr.write(message) sys.exit(1) if not auxdir: @@ -735,7 +735,7 @@ def main(): if not destdir: message = '%s: *** ' % constants.APP['name'] message += 'please specify --dir option' - message += '\n%s: *** Exit.\n' % constants.APP['name'] + message += '\n%s: *** Stop.\n' % constants.APP['name'] sys.stderr.write(message) sys.exit(1) if not auxdir: @@ -846,7 +846,7 @@ def main(): if avoids: message = '%s: *** ' % constants.APP['name'] message += 'cannot combine --avoid and --extract-dependencies\n' - message += '%s: *** Exit.\n' % constants.APP['name'] + message += '%s: *** Stop.\n' % constants.APP['name'] sys.stderr.write(message) sys.exit(1) modulesystem = classes.GLModuleSystem(config) @@ -978,7 +978,7 @@ def main(): else: message = '%s: *** ' % constants.APP['name'] message += 'no mode specified' - message += '\n%s: *** Exit.\n' % constants.APP['name'] + message += '\n%s: *** Stop.\n' % constants.APP['name'] sys.stderr.write(message) sys.exit(1) @@ -999,15 +999,13 @@ if __name__ == '__main__': elif errno == 2: message += 'patch file %s didn\'t apply cleanly' % errinfo elif errno == 3: - message += 'cannot find %s - make sure ' % errinfo - message += 'you run gnulib-tool from within your package\'s directory' + message += 'cannot find %s - make sure you run gnulib-tool from within your package\'s directory' % errinfo elif errno == 4: message += 'minimum supported autoconf version is 2.59. Try adding' message += 'AC_PREREQ([%s])' % constants.DEFAULT_AUTOCONF_MINVERSION message += ' to your configure.ac.' elif errno == 5: - "%s is expected to contain gl_M4_BASE([%s])" % \ - (repr(os.path.join(errinfo, 'gnulib-comp.m4')), repr(errinfo)) + message += '%s is expected to contain gl_M4_BASE([%s])' % (repr(os.path.join(errinfo, 'gnulib-comp.m4')), repr(errinfo)) elif errno == 6: message += 'missing --source-base option' elif errno == 7: @@ -1020,8 +1018,7 @@ if __name__ == '__main__': elif errno == 9: message += 'missing --lib option' elif errno == 10: - message = 'gnulib-tool: option --conditional-dependencies is not ' - message += 'supported with --with-tests\n' + message = 'gnulib-tool: option --conditional-dependencies is not supported with --with-tests' elif errno == 11: incompatibilities = '' message += 'incompatible license on modules:%s' % constants.NL @@ -1035,17 +1032,25 @@ if __name__ == '__main__': sed_table = 's,^\\([^ ]*\\) ,\\1' + ' ' * 51 + ',\n' sed_table += 's,^\\(' + '.' * 49 + '[^ ]*\\) *,' + ' ' * 17 + '\\1 ,' args = ['sed', '-e', sed_table, tempname] - incompatibilities = sp.check_output( - args).decode(ENCS['default']) + incompatibilities = sp.check_output(args).decode(ENCS['default']) message += incompatibilities os.remove(tempname) elif errno == 12: message += 'refusing to do nothing' - elif errno in [13, 14, 15, 16, 17]: - message += 'failed' + elif errno == 13: + message += 'could not create directory %s' % errinfo + elif errno == 14: + message += 'could not delete file %s' % errinfo + elif errno == 15: + message += 'could not create file %s' % errinfo + elif errno == 16: + message += 'could not transform file %s' % errinfo + elif errno == 17: + message += 'could not update file %s' % errinfo + elif errno == 18: + message += 'module %s lacks a license' % errinfo elif errno == 19: message += 'could not create destination directory: %s' % errinfo - if errno != 10: - message += '\n%s: *** Exit.\n' % constants.APP['name'] + message += '\n%s: *** Stop.\n' % constants.APP['name'] sys.stderr.write(message) sys.exit(1) diff --git a/pygnulib/GLError.py b/pygnulib/GLError.py index a7cb81afe2..a366da5b1a 100644 --- a/pygnulib/GLError.py +++ b/pygnulib/GLError.py @@ -65,41 +65,53 @@ class GLError(Exception): 17: cannot update the given file: <file> 18: module lacks a license: <module> 19: could not create destination directory: <directory> - errinfo: additional information; - style: 0 or 1, whether old-style''' + errinfo: additional information''' self.errno = errno self.errinfo = errinfo self.args = (self.errno, self.errinfo) def __repr__(self): + errno = self.errno errinfo = self.errinfo - errors = \ - [ # Begin list of errors - "file does not exist in GLFileSystem: %s" % repr(errinfo), - "cannot patch file inside GLFileSystem: %s" % repr(errinfo), - "configure file does not exist: %s" % repr(errinfo), - "minimum supported autoconf version is 2.59, not %s" % repr( - errinfo), - "%s is expected to contain gl_M4_BASE([%s])" % \ - (repr(os.path.join(errinfo, 'gnulib-comp.m4')), repr(errinfo)), - "missing sourcebase argument; cache file doesn't contain it," - + " so you might have to set this argument", - "missing docbase argument; you might have to create GLImport" \ - + " instance with mode 0 and docbase argument", - "missing testsbase argument; cache file doesn't contain it," - + " so you might have to set this argument" - "missing libname argument; cache file doesn't contain it," - + " so you might have to set this argument", - "conddeps are not supported with inctests", - "incompatible licenses on modules: %s" % repr(errinfo), - "cannot process empty filelist", - "cannot create the given directory: %s" % repr(errinfo), - "cannot remove the given file: %s" % repr(errinfo), - "cannot create the given file: %s" % repr(errinfo), - "cannot transform the given file: %s" % repr(errinfo), - "cannot update/replace the given file: %s" % repr(errinfo), - "module lacks a license: %s" % repr(errinfo), - "error when running subprocess: %s" % repr(errinfo), - ] # Complete list of errors - self.message = '[Errno %d] %s' % (self.errno, errors[self.errno - 1]) + if self.message == None: + message = None + if errno == 1: + message = "file does not exist in GLFileSystem: %s" % repr(errinfo) + elif errno == 2: + message = "cannot patch file inside GLFileSystem: %s" % repr(errinfo) + elif errno == 3: + message = "configure file does not exist: %s" % repr(errinfo) + elif errno == 4: + message = "minimum supported autoconf version is 2.59, not %s" % repr(errinfo) + elif errno == 5: + message = "%s is expected to contain gl_M4_BASE([%s])" % (repr(os.path.join(errinfo, 'gnulib-comp.m4')), repr(errinfo)) + elif errno == 6: + message = "missing sourcebase argument; cache file doesn't contain it, so you might have to set this argument" + elif errno == 7: + message = "missing docbase argument; you might have to create GLImport instance with mode 0 and docbase argument" + elif errno == 8: + message = "missing testsbase argument; cache file doesn't contain it, so you might have to set this argument" + elif errno == 9: + message = "missing libname argument; cache file doesn't contain it, so you might have to set this argument" + elif errno == 10: + message = "conddeps are not supported with inctests" + elif errno == 11: + message = "incompatible licenses on modules: %s" % repr(errinfo) + elif errno == 12: + message = "cannot process empty filelist" + elif errno == 13: + message = "cannot create the given directory: %s" % repr(errinfo) + elif errno == 14: + message = "cannot remove the given file: %s" % repr(errinfo) + elif errno == 15: + message = "cannot create the given file: %s" % repr(errinfo) + elif errno == 16: + message = "cannot transform the given file: %s" % repr(errinfo) + elif errno == 17: + message = "cannot update/replace the given file: %s" % repr(errinfo) + elif errno == 18: + message = "module lacks a license: %s" % repr(errinfo) + elif errno == 19: + message = "error when running subprocess: %s" % repr(errinfo) + self.message = '[Errno %d] %s' % (errno, message) return self.message diff --git a/pygnulib/GLModuleSystem.py b/pygnulib/GLModuleSystem.py index 00b2c5f035..319175dee8 100644 --- a/pygnulib/GLModuleSystem.py +++ b/pygnulib/GLModuleSystem.py @@ -802,8 +802,7 @@ Include:|Link:|License:|Maintainer:)' if self.config['errors']: raise GLError(18, str(self)) else: # if not self.config['errors'] - sys.stderr.write('gnulib-tool: warning: ') - sys.stderr.write('module %s lacks a license\n' % str(self)) + sys.stderr.write('gnulib-tool: warning: module %s lacks a license\n' % str(self)) if not license: license = 'GPL' return license -- 2.34.1
>From b299bfa3fb3cf4ab31b88e843cbe16583e98b21e Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 31 Jul 2022 23:28:18 +0200 Subject: [PATCH 16/16] gnulib-tool.py: Fix typo. * pygnulib/GLTestDir.py (GLMegaTestDir.execute): Invoke os.mkdir as intended. --- ChangeLog | 4 ++++ pygnulib/GLTestDir.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 30805d4d73..e60722ff35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2022-07-31 Bruno Haible <br...@clisp.org> + gnulib-tool.py: Fix typo. + * pygnulib/GLTestDir.py (GLMegaTestDir.execute): Invoke os.mkdir as + intended. + gnulib-tool.py: Improve some error messages. * gnulib-tool.py (main): Write "*** Stop." instead of "*** Exit.". (__main__): Print an error message for GLError 5, 13, 14, 15, 16, 17, 18. diff --git a/pygnulib/GLTestDir.py b/pygnulib/GLTestDir.py index 7a7f5c52fb..36aa5d2117 100644 --- a/pygnulib/GLTestDir.py +++ b/pygnulib/GLTestDir.py @@ -961,7 +961,7 @@ class GLMegaTestDir(object): constants.execute(args, verbose) try: # Try to make a directory if not isdir('build-aux'): - os, mkdir('build-aux') + os.mkdir('build-aux') except Exception as error: pass args = [UTILS['autoconf']] -- 2.34.1