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

Reply via email to