From d776a13e8b69b5d7e8b155fbc1645e7db8518b9b Mon Sep 17 00:00:00 2001 From: Collin Funk Date: Thu, 14 Mar 2024 18:41:05 -0700 Subject: [PATCH] gnulib-tool.py: Follow gnulib-tool changes, part 57. Follow gnulib-tool change 2019-01-04 Bruno Haible gnulib-tool: New option --extract-recursive-link-directive. * pygnulib/GLModuleSystem.py (GLModule.getDependenciesRecursively): New function. Implements the --extract-recursive-dependencies option. (GLModule.getLinkDirectiveRecursively): New function. Implements the --extract-recursive-link-directive. * pygnulib/main.py (main): Add the --extract-recursive-dependencies and --extract-recursive-link-directive options. * pygnulib/GLInfo.py (GLInfo.usage): Add new options to help message. --- ChangeLog | 14 ++++++++ gnulib-tool.py.TODO | 34 ------------------- pygnulib/GLInfo.py | 8 +++++ pygnulib/GLModuleSystem.py | 69 ++++++++++++++++++++++++++++++++++++++ pygnulib/main.py | 40 ++++++++++++++++++++++ 5 files changed, 131 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index b39f16566e..08a8276629 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2024-03-14 Collin Funk + + gnulib-tool.py: Follow gnulib-tool changes, part 57. + Follow gnulib-tool change + 2019-01-04 Bruno Haible + gnulib-tool: New option --extract-recursive-link-directive. + * pygnulib/GLModuleSystem.py (GLModule.getDependenciesRecursively): New + function. Implements the --extract-recursive-dependencies option. + (GLModule.getLinkDirectiveRecursively): New function. Implements the + --extract-recursive-link-directive. + * pygnulib/main.py (main): Add the --extract-recursive-dependencies and + --extract-recursive-link-directive options. + * pygnulib/GLInfo.py (GLInfo.usage): Add new options to help message. + 2024-03-14 Bruno Haible gnulib-tool: Obey environment variable GNULIB_TOOL_IMPL. diff --git a/gnulib-tool.py.TODO b/gnulib-tool.py.TODO index d4de551976..b5796b24a3 100644 --- a/gnulib-tool.py.TODO +++ b/gnulib-tool.py.TODO @@ -16,8 +16,6 @@ The following commits to gnulib-tool have not yet been reflected in -------------------------------------------------------------------------------- Implement the options: - --extract-recursive-dependencies - --extract-recursive-link-directive -h | --hardlink --local-hardlink -S | --more-symlinks @@ -96,21 +94,6 @@ Date: Sun Jan 9 15:38:51 2022 +0100 -------------------------------------------------------------------------------- -commit 87e6634b28df65084321fed22f60d114a0931d21 -Author: Bernhard Voelker -Date: Tue Jan 4 00:16:50 2022 +0100 - - license: fix GPLv3 texts to use a comma instead of semicolon. - - See: https://www.gnu.org/licenses/gpl-3.0.html#howto - Run: - $ git grep -l 'Foundation; either version 3' \ - | xargs sed -i '/Foundation; either version 3/ s/n; e/n, e/' - - * All files using GPLv3: Adjust via the above command. - --------------------------------------------------------------------------------- - commit 9af17c55629c4cbe2facdc9edb5242136567ebba Author: Bruno Haible Date: Sat Dec 25 14:30:57 2021 +0100 @@ -192,23 +175,6 @@ Date: Mon Nov 18 13:32:46 2019 +0100 -------------------------------------------------------------------------------- -commit ce8a5edbc49dea0cb859207c2d063dbd3be0f96c -Author: Bruno Haible -Date: Fri Jan 4 19:34:19 2019 +0100 - - gnulib-tool: New option --extract-recursive-link-directive. - - * gnulib-tool (func_usage): Document the new options - --extract-recursive-dependencies, --extract-recursive-link-directive. - (func_verify_module): Document output variables. - (func_get_dependencies_recursively): New function. - (func_get_link_directive_recursively): New function. - Use them to implement the new options - --extract-recursive-dependencies, --extract-recursive-link-directive. - * doc/gnulib-tool.texi (Link-time requirements): New section. - --------------------------------------------------------------------------------- - commit cd58dba367a3b8ffbebb23f2099a820106197fae Author: Bruno Haible Date: Sun Oct 29 16:57:32 2017 +0100 diff --git a/pygnulib/GLInfo.py b/pygnulib/GLInfo.py index 11fdfa60e6..cb77c5e923 100644 --- a/pygnulib/GLInfo.py +++ b/pygnulib/GLInfo.py @@ -149,10 +149,12 @@ Usage: gnulib-tool --list gnulib-tool --extract-applicability module gnulib-tool --extract-filelist module gnulib-tool --extract-dependencies module + gnulib-tool --extract-recursive-dependencies module gnulib-tool --extract-autoconf-snippet module gnulib-tool --extract-automake-snippet module gnulib-tool --extract-include-directive module gnulib-tool --extract-link-directive module + gnulib-tool --extract-recursive-link-directive module gnulib-tool --extract-license module gnulib-tool --extract-maintainer module gnulib-tool --extract-tests-module module @@ -185,10 +187,16 @@ Operation modes: --extract-applicability extract the applicability --extract-filelist extract the list of files --extract-dependencies extract the dependencies + --extract-recursive-dependencies extract the dependencies of the module + and its dependencies, recursively, all + together, but without the conditions --extract-autoconf-snippet extract the snippet for configure.ac --extract-automake-snippet extract the snippet for library makefile --extract-include-directive extract the #include directive --extract-link-directive extract the linker directive + --extract-recursive-link-directive extract the linker directive of the + module and its dependencies, + recursively, all together --extract-license report the license terms of the source files under lib/ --extract-maintainer report the maintainer(s) inside gnulib diff --git a/pygnulib/GLModuleSystem.py b/pygnulib/GLModuleSystem.py index 86794cf80e..ce2a60636c 100644 --- a/pygnulib/GLModuleSystem.py +++ b/pygnulib/GLModuleSystem.py @@ -329,6 +329,75 @@ class GLModule(object): result = self.modulesystem.find(self.getTestsName()) return result + def getDependenciesRecursively(self) -> str: + '''Return a list of recursive dependencies of this module separated + by a newline.''' + handledmodules = set() + inmodules = set() + outmodules = set() + + # In order to process every module only once (for speed), process an "input + # list" of modules, producing an "output list" of modules. During each round, + # more modules can be queued in the input list. Once a module on the input + # list has been processed, it is added to the "handled list", so we can avoid + # to process it again. + inmodules.add(self) + while len(inmodules) > 0: + inmodules_this_round = inmodules + inmodules = set() # Accumulator, queue for next round + for module in inmodules_this_round: + outmodules.add(module) + inmodules = inmodules.union(module.getDependenciesWithoutConditions()) + handledmodules = handledmodules.union(inmodules_this_round) + # Remove handledmodules from inmodules. + inmodules = inmodules.difference(handledmodules) + + if len(outmodules) > 0: + module_names = sorted([ str(module) + for module in outmodules ]) + return '\n'.join(module_names) + '\n' + else: + return '' + + def getLinkDirectiveRecursively(self) -> str: + '''Return a list of the link directives of this module separated + by a newline.''' + handledmodules = set() + inmodules = set() + outmodules = set() + + # In order to process every module only once (for speed), process an "input + # list" of modules, producing an "output list" of modules. During each round, + # more modules can be queued in the input list. Once a module on the input + # list has been processed, it is added to the "handled list", so we can avoid + # to process it again. + inmodules.add(self) + while len(inmodules) > 0: + inmodules_this_round = inmodules + inmodules = set() # Accumulator, queue for next round + for module in inmodules_this_round: + if self.getLink() != '': + # The module description has a 'Link:' field. Ignore the dependencies. + outmodules.add(module) + else: + # The module description has no 'Link:' field. Recurse through the dependencies. + inmodules = inmodules.union(module.getDependenciesWithoutConditions()) + handledmodules = handledmodules.union(inmodules_this_round) + # Remove handledmodules from inmodules. + inmodules = inmodules.difference(handledmodules) + + if len(outmodules) > 0: + # Remove whitespace from sections. + link_sections = [ module.getLink().strip() + for module in outmodules ] + # Sort the link directives. + directives = sorted([ line + for section in link_sections + for line in section.splitlines() ]) + return '\n'.join(directives) + '\n' + else: + return '' + def getShellFunc(self): '''GLModule.getShellFunc() -> str diff --git a/pygnulib/main.py b/pygnulib/main.py index b145675f78..5d65a45b25 100644 --- a/pygnulib/main.py +++ b/pygnulib/main.py @@ -176,6 +176,10 @@ def main(): dest='mode_xdependencies', default=None, action='store_true') + parser.add_argument('--extract-recursive-dependencies', + dest='mode_xrecursive_dependencies', + default=None, + action='store_true') parser.add_argument('--extract-autoconf-snippet', dest='mode_xautoconf', default=None, @@ -192,6 +196,10 @@ def main(): dest='mode_xlink', default=None, action='store_true') + parser.add_argument('--extract-recursive-link-directive', + dest='mode_xrecursive_link', + default=None, + action='store_true') parser.add_argument('--extract-license', dest='mode_xlicense', default=None, @@ -572,12 +580,18 @@ def main(): if cmdargs.mode_xdependencies != None: mode = 'extract-dependencies' modules = list(cmdargs.non_option_arguments) + if cmdargs.mode_xrecursive_dependencies != None: + mode = 'extract-recursive-dependencies' + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xinclude != None: mode = 'extract-include-directive' modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xlink != None: mode = 'extract-link-directive' modules = list(cmdargs.non_option_arguments) + if cmdargs.mode_xrecursive_link != None: + mode = 'extract-recursive-link-directive' + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xlicense != None: mode = 'extract-license' modules = list(cmdargs.non_option_arguments) @@ -1101,6 +1115,19 @@ def main(): if module: sys.stdout.write(module.getDependencies()) + elif mode == 'extract-recursive-dependencies': + if avoids: + message = '%s: *** ' % constants.APP['name'] + message += 'cannot combine --avoid and --extract-recursive-dependencies\n' + message += '%s: *** Stop.\n' % constants.APP['name'] + sys.stderr.write(message) + sys.exit(1) + modulesystem = classes.GLModuleSystem(config) + for name in modules: + module = modulesystem.find(name) + if module: + sys.stdout.write(module.getDependenciesRecursively()) + elif mode == 'extract-autoconf-snippet': modulesystem = classes.GLModuleSystem(config) for name in modules: @@ -1129,6 +1156,19 @@ def main(): if module: sys.stdout.write(module.getLink()) + elif mode == 'extract-recursive-link-directive': + if avoids: + message = '%s: *** ' % constants.APP['name'] + message += 'cannot combine --avoid and --extract-recursive-link-directive\n' + message += '%s: *** Stop.\n' % constants.APP['name'] + sys.stderr.write(message) + sys.exit(1) + modulesystem = classes.GLModuleSystem(config) + for name in modules: + module = modulesystem.find(name) + if module: + sys.stdout.write(module.getLinkDirectiveRecursively()) + elif mode == 'extract-license': modulesystem = classes.GLModuleSystem(config) for name in modules: -- 2.39.5