On 3/25/24 10:27 PM, Collin Funk wrote:
> But that is an easy fix. I just have to figure out how to write it so
> that it isn't ugly. :)

I was not very successful at making it not ugly...

It seems that Python has an index() function to find the first
occurrence of an item in a list, but they don't have one for the last
occurrence [1]. Do other languages have this? Maybe we can define a
new one.

I assume the Python people would expect you to reverse the list with
slicing and then call the function:

    print([1, 2, 3, 4][::-1])
    [4, 3, 2, 1]

We have to find the last occurrence though just incase a project using
Gnulib is in a 'modules' subdirectory. In that case finding the first
would break things.

The other important thing is the unpacking on this line [2]:

    self.name = str(Path(*parts[name_index + 1:]))

This is important because some of the modules, like cryptography ones,
are in subdirectories. Therefore, we have to combine all components
following the last 'modules/' directory.

The 'parts' variable is a list of directory components from
Path().parts. I tried to find an os.path.* function with similar
functionality but there doesn't seem to be any.

But, atleast we are not back to taking 20 seconds to run ./test-all.sh.

$ time env GNULIB_TOOL_IMPL=py ./test-all.sh
real    0m6.378s
user    0m3.555s
sys     0m2.909s

[1] https://docs.python.org/3/tutorial/datastructures.html#more-on-lists
[2] https://docs.python.org/3/tutorial/controlflow.html#tut-unpacking-arguments
[3] https://docs.python.org/3/library/pathlib.html#accessing-individual-parts

Collin
From 4044ac06daa2ae9636057054c6b2e27fdac7f180 Mon Sep 17 00:00:00 2001
From: Collin Funk <collin.fu...@gmail.com>
Date: Mon, 25 Mar 2024 23:26:00 -0700
Subject: [PATCH 2/2] gnulib-tool.py: Store the module name instead of
 computing it.

* pygnulib/GLModuleSystem.py (GLModule.__init__): Locate the module name
and store it.
(GLModule.getName): Return the name that we save instead of using
regular expressions on each call.
---
 ChangeLog                  |  8 ++++++++
 pygnulib/GLModuleSystem.py | 17 ++++++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2ae1c7340e..f4aa2bb200 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2024-03-25  Collin Funk  <collin.fu...@gmail.com>
+
+	gnulib-tool.py: Store the module name instead of computing it.
+	* pygnulib/GLModuleSystem.py (GLModule.__init__): Locate the module name
+	and store it.
+	(GLModule.getName): Return the name that we save instead of using
+	regular expressions on each call.
+
 2024-03-25  Collin Funk  <collin.fu...@gmail.com>
 
 	gnulib-tool.py: Fix sorting of modules when --local-dir is used.
diff --git a/pygnulib/GLModuleSystem.py b/pygnulib/GLModuleSystem.py
index 38379da3d3..27a8037e2f 100644
--- a/pygnulib/GLModuleSystem.py
+++ b/pygnulib/GLModuleSystem.py
@@ -22,6 +22,7 @@ import sys
 import codecs
 import hashlib
 import subprocess as sp
+from pathlib import Path
 from . import constants
 from .GLError import GLError
 from .GLConfig import GLConfig
@@ -207,7 +208,18 @@ class GLModule(object):
         if type(patched) is not bool:
             raise TypeError('patched must be a bool, not %s'
                             % type(patched).__name__)
-        self.path = path
+
+        # Split the path into directory components.
+        parts = list(Path(path).parts)
+
+        # Find the module name after the last 'modules/' directory component.
+        parts.reverse()
+        name_index = len(parts) - parts.index('modules') - 1
+        parts.reverse()
+
+        # Get all directory components after modules/
+        self.name = str(Path(*parts[name_index + 1:]))
+
         self.patched = patched
         self.config = config
         self.filesystem = GLFileSystem(self.config)
@@ -294,8 +306,7 @@ class GLModule(object):
         '''GLModule.getName() -> str
 
         Return the name of the module.'''
-        pattern = re.compile(joinpath('modules', '(.*)$'))
-        result = pattern.findall(self.path)[0]
+        result = self.name
         return result
 
     def isPatched(self):
-- 
2.44.0

Reply via email to