[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
gnulib-tool.py: Refactor directory tree removals
From: |
Bruno Haible |
Subject: |
gnulib-tool.py: Refactor directory tree removals |
Date: |
Sat, 13 Apr 2024 12:17:58 +0200 |
There are two ways to remove a directory tree: via 'rm -rf' and through
shutil.rmtree. The former is ca. 10% faster on average. Also, it is more
likely to include platform-specific optimizations. So, let's use it.
2024-04-13 Bruno Haible <bruno@clisp.org>
gnulib-tool.py: Refactor directory tree removals.
* pygnulib/constants.py (rmtree): New function.
* pygnulib/GLImport.py (GLImport.execute): Use it instead of calling
'rm -rf' directly or shutil.rmtree.
* pygnulib/GLTestDir.py (GLTestDir.execute, GLMegaTestDir.execute):
Likewise.
* pygnulib/main.py (main): Likewise.
diff --git a/gnulib-tool.py.TODO b/gnulib-tool.py.TODO
index 368c0addac..1eada15429 100644
--- a/gnulib-tool.py.TODO
+++ b/gnulib-tool.py.TODO
@@ -10,7 +10,6 @@ Optimize:
Various other refactorings, as deemed useful:
- Use an enum for 'all', 'old', 'new', 'added', 'removed' in GLImport.py.
- - sp.call(['rm', '-rf' ...]) versus shutil.rmtree ?
- go through all the open() and codecs.open() calls and turn them into
with open(file_name, 'r', newline='\n', encoding='utf-8') as file:
or
diff --git a/pygnulib/GLImport.py b/pygnulib/GLImport.py
index d45cf6b3ba..3d694a7919 100644
--- a/pygnulib/GLImport.py
+++ b/pygnulib/GLImport.py
@@ -1466,4 +1466,4 @@ in <library>_a_LDFLAGS or <library>_la_LDFLAGS when
linking a library.''')
position_early_after = 'AC_PROG_CC'
print(' - invoke %s_EARLY in %s, right after %s,' % (macro_prefix,
configure_ac, position_early_after))
print(' - invoke %s_INIT in %s.' % (macro_prefix, configure_ac))
- sp.call(['rm', '-rf', self.config['tempdir']], shell=False)
+ constants.rmtree(self.config['tempdir'])
diff --git a/pygnulib/GLTestDir.py b/pygnulib/GLTestDir.py
index 5fd4197e52..be61d58b52 100644
--- a/pygnulib/GLTestDir.py
+++ b/pygnulib/GLTestDir.py
@@ -23,7 +23,6 @@ import re
import sys
import codecs
import subprocess as sp
-import shutil
from pathlib import Path
from . import constants
from .enums import CopyAction
@@ -709,7 +708,7 @@ class GLTestDir:
# automake
args = [UTILS['automake'], '--add-missing', '--copy']
constants.execute(args, verbose)
- shutil.rmtree('autom4te.cache')
+ constants.rmtree('autom4te.cache')
os.chdir(DIRS['cwd'])
if inctests and not single_configure:
# Do not use "${AUTORECONF} --force --install", because it may
invoke
@@ -744,7 +743,7 @@ class GLTestDir:
# automake
args = [UTILS['automake'], '--add-missing', '--copy']
constants.execute(args, verbose)
- shutil.rmtree('autom4te.cache')
+ constants.rmtree('autom4te.cache')
os.chdir(DIRS['cwd'])
# Need to run configure and make once, to create built files that are
to be
@@ -879,7 +878,7 @@ class GLTestDir:
if isfile(joinpath('build-aux', 'test-driver')):
_patch_test_driver()
os.chdir(DIRS['cwd'])
- sp.call(['rm', '-rf', self.config['tempdir']], shell=False)
+ constants.rmtree(self.config['tempdir'])
#===============================================================================
@@ -1036,8 +1035,8 @@ class GLMegaTestDir:
constants.execute(args, verbose)
args = [UTILS['automake'], '--add-missing', '--copy']
constants.execute(args, verbose)
- shutil.rmtree('autom4te.cache')
+ constants.rmtree('autom4te.cache')
if isfile(joinpath('build-aux', 'test-driver')):
_patch_test_driver()
os.chdir(DIRS['cwd'])
- sp.call(['rm', '-rf', self.config['tempdir']], shell=False)
+ constants.rmtree(self.config['tempdir'])
diff --git a/pygnulib/constants.py b/pygnulib/constants.py
index dc1297d529..f307ffa6b1 100644
--- a/pygnulib/constants.py
+++ b/pygnulib/constants.py
@@ -454,6 +454,20 @@ def hardlink(src: str, dest: str) -> None:
ensure_writable(dest)
+def rmtree(dest: str) -> None:
+ '''Removes the file or directory tree at dest, if it exists.'''
+ # These two implementations are nearly equivalent.
+ # Speed: 'rm -rf' can be a little faster.
+ # Exceptions: shutil.rmtree raises Python exceptions, e.g. PermissionError.
+ if True:
+ sp.run(['rm', '-rf', dest], shell=False)
+ else:
+ try:
+ shutil.rmtree(dest)
+ except FileNotFoundError:
+ pass
+
+
def filter_filelist(separator: str, filelist: str, prefix: str, suffix: str,
removed_prefix: str, removed_suffix: str,
added_prefix: str = '', added_suffix: str = '') -> str:
diff --git a/pygnulib/main.py b/pygnulib/main.py
index 4b64305049..471f4b9fb9 100644
--- a/pygnulib/main.py
+++ b/pygnulib/main.py
@@ -1120,7 +1120,7 @@ def main() -> None:
sys.stderr.write(message)
sys.exit(1)
os.chdir('../..')
- sp.call(['rm', '-rf', destdir], shell=False)
+ constants.rmtree(destdir)
elif mode == 'megatest':
if not destdir:
@@ -1150,7 +1150,7 @@ def main() -> None:
sys.stderr.write(message)
sys.exit(1)
os.chdir('../..')
- sp.call(['rm', '-rf', destdir], shell=False)
+ constants.rmtree(destdir)
elif mode == 'extract-description':
modulesystem = GLModuleSystem(config)
- gnulib-tool.py: Refactor directory tree removals,
Bruno Haible <=