Hi Bruno,

On 3/24/24 5:18 PM, Bruno Haible wrote:
> Thanks, applied, with a tweak: I don't like the variable name 'group'
> here. I know that 'tuple' is not possible either. But a couple of lines
> below we call it a 'row', and that fits better (imagining the ignorelist
> as a matrix).

Yes, that is a better name. I was going to use tuple but couldn't. I
didn't see it was called 'row' below.

> You're right: When ignore-added is empty and ignore-removed is non-empty,
> it can happen that the .gitignore file won't change, thus gnulib-tool.sh
> will advertise a file change and create a backup file when there is no
> need. I'll look into fixing that.

Thanks. I've attached a *very* rough patch that I think works
similarly to gnulib-tool.sh if you would like to take a look at it.
I'm not sure the best way to test it. When using
GNULIB_TOOL_IMPL=sh+py on Inetutils I get only this now:

diff --git a/home/collin/.local/src/inetutils/m4/gnulib-comp.m4 
b/home/collin/.local/src/glpyVG0WNy/m4/gnulib-comp.m4
index 5c38ac18..4fe2c5ce 100644
--- a/home/collin/.local/src/inetutils/m4/gnulib-comp.m4
+++ b/home/collin/.local/src/glpyVG0WNy/m4/gnulib-comp.m4
@@ -42,6 +42,7 @@ AC_DEFUN([gl_EARLY],
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
   AC_REQUIRE([gl_PROG_AR_RANLIB])
 
+  AC_REQUIRE([AM_PROG_CC_C_O])
   # Code from module absolute-header:
   # Code from module alignasof:
   # Code from module alignof:

Before this change I had an extra '.gitignore~'. Also variable names
are probably incorrect. I was more concerned with avoiding collisions
to be honest.

Maybe this will help:

      * original_lines: Unprocessed lines with ending newline removed
        and trailing whitespace preserved.
      * dirs_ignored: All ignored filenames, like "$tmp"/ignore.
      * dirs_added: All added filenames that are not ignored yet, like
        "$tmp"/ignore-added.
      * dirs_removed: All filenames to remove from the .gitignore,
        like "$tmp"/ignore-removed.

I would just use the basename of the files from gnulib-tool.sh but
'ignore' is already used and assigned to '.gitignore' or '.cvsignore'.
:(

Feel free to change it however you like (assuming the patch is correct).

Collin
From 34ce5aefe9bea00253469a1478d733a1e4aefcf6 Mon Sep 17 00:00:00 2001
From: Collin Funk <collin.fu...@gmail.com>
Date: Sun, 24 Mar 2024 22:20:15 -0700
Subject: [PATCH] gnulib-tool.py: Handle removed files in the vc ignore files.

* pygnulib/GLImport.py (GLImport._update_ignorelist_): Handle removed
files. Check whether the original lines should be removed too.
---
 ChangeLog            |  6 ++++++
 pygnulib/GLImport.py | 27 ++++++++++++++++++---------
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2d8a54f1a5..d699b692e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2024-03-24  Collin Funk  <collin.fu...@gmail.com>
+
+	gnulib-tool.py: Handle removed files in the vc ignore files.
+	* pygnulib/GLImport.py (GLImport._update_ignorelist_): Handle removed
+	files. Check whether the original lines should be removed too.
+
 2024-03-24  Collin Funk  <collin.fu...@gmail.com>
 
 	gnulib-tool.py: Fix "Creating directory" output.
diff --git a/pygnulib/GLImport.py b/pygnulib/GLImport.py
index c516491067..5b24d0fb88 100644
--- a/pygnulib/GLImport.py
+++ b/pygnulib/GLImport.py
@@ -803,20 +803,29 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
         if isfile(joinpath(destdir, srcpath)):
             if files_added or files_removed:
                 with codecs.open(joinpath(destdir, srcpath), 'rb', 'UTF-8') as file:
-                    srcdata = file.read()
+                    original_lines = file.readlines()
+                # Clean the newlines but not trailing whitespace.
+                original_lines = [ line if not line.endswith('\n') else line[:-1]
+                                   for line in original_lines ]
                 dirs_ignore = { constants.substart(anchor, '', filename)
-                                for filename in srcdata.split('\n')
+                                for filename in original_lines
                                 if filename.strip() }
-                srcdata = lines_to_multiline(sorted(dirs_ignore))
-                dirs_ignore = [ '%s%s' % (anchor, d)
-                                for d in set(files_added).difference(dirs_ignore) ]
-                destdata = lines_to_multiline(sorted(dirs_ignore))
-                if srcdata != destdata:
+                dirs_added = set(files_added).difference(dirs_ignore)
+                dirs_removed = set(files_removed)
+                if dirs_added or dirs_removed:
                     if not self.config['dryrun']:
                         print('Updating %s (backup in %s)' % (srcpath, backupname))
                         copyfile2(joinpath(destdir, srcpath), joinpath(destdir, backupname))
-                        with codecs.open(joinpath(destdir, srcpath), 'ab', 'UTF-8') as file:
-                            file.write(destdata)
+                        new_lines = original_lines + [ f'{anchor}{filename}'
+                                                       for filename in sorted(dirs_added) ]
+                        if anchor != '':
+                            dirs_removed = dirs_removed.union({ f'{anchor}{filename}'
+                                                                for filename in dirs_removed })
+                        new_lines = [ line
+                                      for line in new_lines
+                                      if line not in dirs_removed ]
+                        with codecs.open(joinpath(destdir, srcpath), 'wb', 'UTF-8') as file:
+                            file.write(lines_to_multiline(new_lines))
                     else:  # if self.config['dryrun']
                         print('Update %s (backup in %s)' % (srcpath, backupname))
         else:  # if not isfile(joinpath(destdir, srcpath))
-- 
2.44.0

Reply via email to