From 9af79f662e6a8a07488ff5ec729b09599500531a Mon Sep 17 00:00:00 2001 From: Collin Funk Date: Thu, 25 Apr 2024 15:30:29 -0700 Subject: [PATCH] gnulib-tool.py: Reduce code duplication in file name transformations. * pygnulib/functions.py: New file for shared functions between modules. Add a function based on functions removed from GLImport and GLTestDir. Accepts a single file name instead of a list. * pygnulib/GLImport.py (GLImport.prepare): Use the new function. (GLImport.rewrite_new_files, GLImport.rewrite_old_files): Remove functions. * pygnulib/GLTestDir.py (GLTestDir.execute): Use the new function. (GLTestDir.rewrite_files): Remove functions. * pygnulib/main.py (main): Remove unused function import. Use the new function. --- ChangeLog | 14 +++++++ pygnulib/GLImport.py | 97 +++++-------------------------------------- pygnulib/GLTestDir.py | 55 +++++------------------- pygnulib/functions.py | 52 +++++++++++++++++++++++ pygnulib/main.py | 17 +------- 5 files changed, 88 insertions(+), 147 deletions(-) create mode 100644 pygnulib/functions.py diff --git a/ChangeLog b/ChangeLog index abefd3bae2..276258b885 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2024-04-25 Collin Funk + + gnulib-tool.py: Reduce code duplication in file name transformations. + * pygnulib/functions.py: New file for shared functions between modules. + Add a function based on functions removed from GLImport and GLTestDir. + Accepts a single file name instead of a list. + * pygnulib/GLImport.py (GLImport.prepare): Use the new function. + (GLImport.rewrite_new_files, GLImport.rewrite_old_files): Remove + functions. + * pygnulib/GLTestDir.py (GLTestDir.execute): Use the new function. + (GLTestDir.rewrite_files): Remove functions. + * pygnulib/main.py (main): Remove unused function import. Use the new + function. + 2024-04-25 Bruno Haible doc: Remove documentation of IRIX as supported platform. diff --git a/pygnulib/GLImport.py b/pygnulib/GLImport.py index cf1ebd10ec..47c0e83555 100644 --- a/pygnulib/GLImport.py +++ b/pygnulib/GLImport.py @@ -38,6 +38,7 @@ from .constants import ( relativize, rmtree, ) +from .functions import rewrite_file_name from .GLError import GLError from .GLConfig import GLConfig from .GLModuleSystem import GLModuleTable @@ -303,80 +304,6 @@ class GLImport: result = '' % hex(id(self)) return result - def rewrite_old_files(self, files: list[str]) -> list[str]: - '''Replace auxdir, docbase, sourcebase, m4base and testsbase from default - to their version from cached config.''' - if type(files) is not list: - raise TypeError('files argument must has list type, not %s' - % type(files).__name__) - for file in files: - if type(file) is not str: - raise TypeError('each file must be a string instance') - files = sorted(set(files)) - files = [ '%s%s' % (file, os.path.sep) - for file in files ] - auxdir = self.cache['auxdir'] - docbase = self.cache['docbase'] - sourcebase = self.cache['sourcebase'] - m4base = self.cache['m4base'] - testsbase = self.cache['testsbase'] - result = [] - for file in files: - if file.startswith('build-aux/'): - path = substart('build-aux/', '%s/' % auxdir, file) - elif file.startswith('doc/'): - path = substart('doc/', '%s/' % docbase, file) - elif file.startswith('lib/'): - path = substart('lib/', '%s/' % sourcebase, file) - elif file.startswith('m4/'): - path = substart('m4/', '%s/' % m4base, file) - elif file.startswith('tests/'): - path = substart('tests/', '%s/' % testsbase, file) - elif file.startswith('tests=lib/'): - path = substart('tests=lib/', '%s/' % testsbase, file) - elif file.startswith('top/'): - path = substart('top/', '', file) - else: # file is not a special file - path = file - result.append(os.path.normpath(path)) - return sorted(set(result)) - - def rewrite_new_files(self, files: list[str]) -> list[str]: - '''Replace auxdir, docbase, sourcebase, m4base and testsbase from - default to their version from config.''' - if type(files) is not list: - raise TypeError('files argument must has list type, not %s' - % type(files).__name__) - for file in files: - if type(file) is not str: - raise TypeError('each file must be a string instance') - files = sorted(set(files)) - auxdir = self.config['auxdir'] - docbase = self.config['docbase'] - sourcebase = self.config['sourcebase'] - m4base = self.config['m4base'] - testsbase = self.config['testsbase'] - result = [] - for file in files: - if file.startswith('build-aux/'): - path = substart('build-aux/', '%s/' % auxdir, file) - elif file.startswith('doc/'): - path = substart('doc/', '%s/' % docbase, file) - elif file.startswith('lib/'): - path = substart('lib/', '%s/' % sourcebase, file) - elif file.startswith('m4/'): - path = substart('m4/', '%s/' % m4base, file) - elif file.startswith('tests/'): - path = substart('tests/', '%s/' % testsbase, file) - elif file.startswith('tests=lib/'): - path = substart('tests=lib/', '%s/' % testsbase, file) - elif file.startswith('top/'): - path = substart('top/', '', file) - else: # file is not a special file - path = file - result.append(os.path.normpath(path)) - return sorted(set(result)) - def actioncmd(self) -> str: '''Return command-line invocation comment.''' modules = self.config.getModules() @@ -943,31 +870,27 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix # old_files is the list of files according to the last gnulib-tool invocation. # new_files is the list of files after this gnulib-tool invocation. - # Construct tables and transformers. + # Construct the transformers. transformers = dict() transformers['lib'] = sed_transform_lib_file transformers['aux'] = sed_transform_build_aux_file transformers['main'] = sed_transform_main_lib_file transformers['tests'] = sed_transform_testsrelated_lib_file - old_table = [] - new_table = [] - for src in old_files: - dest = self.rewrite_old_files([src])[-1] - old_table.append(tuple([dest, src])) - for src in new_files: - dest = self.rewrite_new_files([src])[-1] - new_table.append(tuple([dest, src])) - old_table = sorted(set(old_table)) - new_table = sorted(set(new_table)) + # old_table is a table with two columns: (rewritten-file-name original-file-name), # representing the files according to the last gnulib-tool invocation. + old_table = { (rewrite_file_name(file_name, self.cache, True), file_name) + for file_name in old_files } + # new_table is a table with two columns: (rewritten-file-name original-file-name), # representing the files after this gnulib-tool invocation. + new_table = { (rewrite_file_name(file_name, self.config, True), file_name) + for file_name in new_files } # Prepare the filetable. filetable = GLFileTable(sorted(set(filelist))) - filetable.old_files = sorted(set(old_table), key=lambda pair: pair[0]) - filetable.new_files = sorted(set(new_table), key=lambda pair: pair[0]) + filetable.old_files = sorted(old_table, key=lambda pair: pair[0]) + filetable.new_files = sorted(new_table, key=lambda pair: pair[0]) # Return the result. result = tuple([filetable, transformers]) diff --git a/pygnulib/GLTestDir.py b/pygnulib/GLTestDir.py index 0ac2f32f69..8534e19254 100644 --- a/pygnulib/GLTestDir.py +++ b/pygnulib/GLTestDir.py @@ -42,6 +42,7 @@ from .constants import ( relinverse, rmtree, ) +from .functions import rewrite_file_name from .enums import CopyAction from .GLError import GLError from .GLConfig import GLConfig @@ -122,42 +123,6 @@ class GLTestDir: self.config.resetWitnessCMacro() self.config.resetVCFiles() - def rewrite_files(self, files: list[str]) -> list[str]: - '''Replace auxdir, docbase, sourcebase, m4base and testsbase from - default to their version from config.''' - if type(files) is not list: - raise TypeError('files argument must have list type, not %s' - % type(files).__name__) - for file in files: - if type(file) is not str: - raise TypeError('each file must be a string instance') - files = sorted(set(files)) - auxdir = self.config['auxdir'] - docbase = self.config['docbase'] - sourcebase = self.config['sourcebase'] - m4base = self.config['m4base'] - testsbase = self.config['testsbase'] - result = [] - for file in files: - if file.startswith('build-aux/'): - path = substart('build-aux/', '%s/' % auxdir, file) - elif file.startswith('doc/'): - path = substart('doc/', '%s/' % docbase, file) - elif file.startswith('lib/'): - path = substart('lib/', '%s/' % sourcebase, file) - elif file.startswith('m4/'): - path = substart('m4/', '%s/' % m4base, file) - elif file.startswith('tests/'): - path = substart('tests/', '%s/' % testsbase, file) - elif file.startswith('tests=lib/'): - path = substart('tests=lib/', '%s/' % testsbase, file) - elif file.startswith('top/'): - path = substart('top/', '', file) - else: # file is not a special file - path = file - result.append(os.path.normpath(path)) - return sorted(set(result)) - def execute(self) -> None: '''Create a scratch package with the given modules.''' auxdir = self.config['auxdir'] @@ -339,24 +304,24 @@ class GLTestDir: # "automake --add-missing --copy" would provide. filelist = sorted(set(filelist + ['build-aux/config.guess', 'build-aux/config.sub'])) + # new_table is a table with two columns: (rewritten-file-name original-file-name), + # representing the files after this gnulib-tool invocation. + new_table = { (rewrite_file_name(file_name, self.config, True), file_name) + for file_name in filelist } + # Setup the file table. filetable = GLFileTable(filelist) + filetable.new_files = sorted(new_table, key=lambda pair: pair[0]) # Create directories. - directories = [ joinpath(self.testdir, os.path.dirname(file)) - for file in self.rewrite_files(filetable.all_files) ] - directories = sorted(set(directories)) + directories = sorted({ joinpath(self.testdir, os.path.dirname(pair[0])) + for pair in filetable.new_files }) for directory in directories: if not os.path.isdir(directory): os.makedirs(directory) # Copy files or make symbolic links or hard links. - for src in filetable.all_files: - dest = self.rewrite_files([src])[-1] - filetable.new_files.append(tuple([dest, src])) - for row in filetable.new_files: - src = row[1] - dest = row[0] + for (dest, src) in filetable.new_files: destpath = joinpath(self.testdir, dest) if src.startswith('tests=lib/'): src = substart('tests=lib/', 'lib/', src) diff --git a/pygnulib/functions.py b/pygnulib/functions.py new file mode 100644 index 0000000000..9459d9c1f8 --- /dev/null +++ b/pygnulib/functions.py @@ -0,0 +1,52 @@ +# Copyright (C) 2002-2024 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import annotations + +import os.path +from .constants import substart +from .GLConfig import GLConfig + + +def rewrite_file_name(file_name: str, config: GLConfig, also_tests_lib: bool = False) -> str: + '''Replace auxdir, docbase, sourcebase, m4base and testsbase from their + default to the ones specified in a GLConfig object. + - file_name, the file name to transform, + - config, the GLConfig storing directory names, + - also_tests_lib, True if 'tests=lib/' should be replaced.''' + if type(file_name) is not str: + raise TypeError(f'file_name must be a str type, not {type(file_name).__name__}') + auxdir = config['auxdir'] + docbase = config['docbase'] + sourcebase = config['sourcebase'] + m4base = config['m4base'] + testsbase = config['testsbase'] + if file_name.startswith('build-aux/'): + result = substart('build-aux/', '%s/' % auxdir, file_name) + elif file_name.startswith('doc/'): + result = substart('doc/', '%s/' % docbase, file_name) + elif file_name.startswith('lib/'): + result = substart('lib/', '%s/' % sourcebase, file_name) + elif file_name.startswith('m4/'): + result = substart('m4/', '%s/' % m4base, file_name) + elif file_name.startswith('tests/'): + result = substart('tests/', '%s/' % testsbase, file_name) + elif also_tests_lib and file_name.startswith('tests=lib/'): + result = substart('tests=lib/', '%s/' % testsbase, file_name) + elif file_name.startswith('top/'): + result = substart('top/', '', file_name) + else: # file is not a special file + result = file_name + return os.path.normpath(result) diff --git a/pygnulib/main.py b/pygnulib/main.py index ea781f5a97..3230c45a31 100644 --- a/pygnulib/main.py +++ b/pygnulib/main.py @@ -96,12 +96,12 @@ from pygnulib.constants import ( lines_to_multiline, ensure_writable, copyfile, - substart, force_output, init_DIRS, rmtree, DEFAULT_AUTOCONF_MINVERSION, ) +from pygnulib.functions import rewrite_file_name from pygnulib.enums import CopyAction from pygnulib.GLConfig import GLConfig from pygnulib.GLError import GLError @@ -1309,20 +1309,7 @@ def main() -> None: lookedup, flag = filesystem.lookup(srcpath) if os.path.isdir(dest): destdir = dest - if srcpath.startswith('build-aux/'): - destpath = substart('build-aux/', '%s/' % auxdir, srcpath) - elif srcpath.startswith('doc/'): - destpath = substart('doc/', '%s/' % docbase, srcpath) - elif srcpath.startswith('lib/'): - destpath = substart('lib/', '%s/' % sourcebase, srcpath) - elif srcpath.startswith('m4/'): - destpath = substart('m4/', '%s/' % m4base, srcpath) - elif srcpath.startswith('tests/'): - destpath = substart('tests/', '%s/' % testsbase, srcpath) - elif srcpath.startswith('top/'): - destpath = substart('top/', '', srcpath) - else: # either case - destpath = srcpath + destpath = rewrite_file_name(srcpath, config) else: # if not os.path.isdir(dest) destdir = os.path.dirname(dest) destpath = os.path.basename(dest) -- 2.39.5