Hello, I have discovered the cause of the --add-import issue. It is simpler than I originally thought. It seems that a code path is taken where the value of 'sourcebase' in the GLConfig is not set. Then in GLImport.rewrite_new_files this line is taken:
path = constants.substart('lib/', '%s/' % sourcebase, file) Since sourcebase is passed to GLConfig as None, it is turned into an empty string by GLConfig.resetSourceBase. This means that that line results in path being '/dummy.c', which should not be writable assuming default permissions for the root directory. The code path is a bit hard to follow, but I will do my best to explain. When --add-import is used, this path is taken. Here is a diff with the important line in main: diff --git a/pygnulib/main.py b/pygnulib/main.py index 7f710a2079..ddd09389b7 100644 --- a/pygnulib/main.py +++ b/pygnulib/main.py @@ -931,6 +931,7 @@ def main(): elif len(m4dirs) == 1: m4base = m4dirs[-1] config.setM4Base(m4base) + config.setSourceBase('lib') # Perform GLImport actions. importer = classes.GLImport(config, mode) filetable, transformers = importer.prepare() To demonstrate the effect of that added line, I have these lines in GLImport.prepare: diff --git a/pygnulib/GLImport.py b/pygnulib/GLImport.py index de2961c55e..ca0c568410 100644 --- a/pygnulib/GLImport.py +++ b/pygnulib/GLImport.py @@ -1017,6 +1017,11 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix filetable['added'] = list() filetable['removed'] = list() + for key in filetable.keys(): + print('===================') + for file in filetable[key]: + print(f'{key}: {file}') + # Return the result. result = tuple([filetable, transformers]) return result Now, the output of gnulib-tool.py --add-import without the added "config.setSourceBase('lib')": $ gnulib-tool.py --add-import Module list with included dependencies (indented): File list: lib/dummy.c m4/00gnulib.m4 m4/gnulib-common.m4 m4/zzgnulib.m4 =================== all: lib/dummy.c all: m4/00gnulib.m4 all: m4/gnulib-common.m4 all: m4/zzgnulib.m4 =================== =================== new: ('/dummy.c', 'lib/dummy.c') ####### missing source base. new: ('m4/00gnulib.m4', 'm4/00gnulib.m4') new: ('m4/gnulib-common.m4', 'm4/gnulib-common.m4') new: ('m4/gnulib-tool.m4', 'm4/gnulib-tool.m4') new: ('m4/zzgnulib.m4', 'm4/zzgnulib.m4') =================== =================== /home/collin/.local/src/gnulib/gnulib-tool.py: *** could not create file /home/collin/.local/src/gnulib/lib/dummy.c /home/collin/.local/src/gnulib/gnulib-tool.py: *** Stop. Now with the line added: $ gnulib-tool.py --add-import Module list with included dependencies (indented): File list: lib/dummy.c m4/00gnulib.m4 m4/gnulib-common.m4 m4/zzgnulib.m4 =================== all: lib/dummy.c all: m4/00gnulib.m4 all: m4/gnulib-common.m4 all: m4/zzgnulib.m4 =================== old: ('lib/dummy.c', 'lib/dummy.c') old: ('m4/00gnulib.m4', 'm4/00gnulib.m4') old: ('m4/gnulib-common.m4', 'm4/gnulib-common.m4') old: ('m4/gnulib-tool.m4', 'm4/gnulib-tool.m4') old: ('m4/zzgnulib.m4', 'm4/zzgnulib.m4') =================== new: ('lib/dummy.c', 'lib/dummy.c') ####### sourcebase is set. new: ('m4/00gnulib.m4', 'm4/00gnulib.m4') new: ('m4/gnulib-common.m4', 'm4/gnulib-common.m4') new: ('m4/gnulib-tool.m4', 'm4/gnulib-tool.m4') new: ('m4/zzgnulib.m4', 'm4/zzgnulib.m4') =================== =================== I find that the main function is a bit hard to follow. Would it be better to use better default values in GLConfig instead? Like this: class GLConfig: def __init__(self, destdir='.', localpath=None, auxdir='build-aux', sourcebase='lib', m4base='m4', ...) for example. I think this solution would be cleaner and more maintainable than trying to handle things separately in every command. Collin