+2024-03-14 Collin Funk <collin.funk1@gmail.com>
+
+ gnulib-tool.py: Follow gnulib-tool changes, part 57.
+ Follow gnulib-tool change
+ 2019-01-04 Bruno Haible <bruno@clisp.org>
+ 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 <bruno@clisp.org>
gnulib-tool: Obey environment variable GNULIB_TOOL_IMPL.
--------------------------------------------------------------------------------
Implement the options:
- --extract-recursive-dependencies
- --extract-recursive-link-directive
-h | --hardlink
--local-hardlink
-S | --more-symlinks
--------------------------------------------------------------------------------
-commit 87e6634b28df65084321fed22f60d114a0931d21
-Author: Bernhard Voelker <mail@bernhard-voelker.de>
-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 <bruno@clisp.org>
Date: Sat Dec 25 14:30:57 2021 +0100
--------------------------------------------------------------------------------
-commit ce8a5edbc49dea0cb859207c2d063dbd3be0f96c
-Author: Bruno Haible <bruno@clisp.org>
-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 <bruno@clisp.org>
Date: Sun Oct 29 16:57:32 2017 +0100
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
--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
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
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,
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,
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)
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:
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: