Skip to content

Commit

Permalink
gnulib-tool.py: Reduce code duplication in file name transformations.
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
collinfunk committed Apr 26, 2024
1 parent 7941742 commit 9af79f6
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 147 deletions.
14 changes: 14 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
2024-04-25 Collin Funk <[email protected]>

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 <[email protected]>

doc: Remove documentation of IRIX as supported platform.
Expand Down
97 changes: 10 additions & 87 deletions pygnulib/GLImport.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
relativize,
rmtree,
)
from .functions import rewrite_file_name
from .GLError import GLError
from .GLConfig import GLConfig
from .GLModuleSystem import GLModuleTable
Expand Down Expand Up @@ -303,80 +304,6 @@ def __repr__(self) -> str:
result = '<pygnulib.GLImport %s>' % 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()
Expand Down Expand Up @@ -943,31 +870,27 @@ def prepare(self) -> tuple[GLFileTable, dict[str, tuple[re.Pattern, str] | None]
# 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])
Expand Down
55 changes: 10 additions & 45 deletions pygnulib/GLTestDir.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
relinverse,
rmtree,
)
from .functions import rewrite_file_name
from .enums import CopyAction
from .GLError import GLError
from .GLConfig import GLConfig
Expand Down Expand Up @@ -122,42 +123,6 @@ def __init__(self, config: GLConfig, testdir: str) -> None:
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']
Expand Down Expand Up @@ -339,24 +304,24 @@ def execute(self) -> None:
# "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)
Expand Down
52 changes: 52 additions & 0 deletions pygnulib/functions.py
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>.

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)
17 changes: 2 additions & 15 deletions pygnulib/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,12 @@
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
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 9af79f6

Please sign in to comment.