From 8455955e698cd03c064cd4cd3458d9f75e441e02 Mon Sep 17 00:00:00 2001 From: Roland Date: Sat, 14 Mar 2026 13:18:07 -0600 Subject: [PATCH] Fixing bug where similarly named files could not be deleted. --- wrolpi/files/lib.py | 2 +- wrolpi/files/test/test_lib.py | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/wrolpi/files/lib.py b/wrolpi/files/lib.py index 9e8e9b81..25c7d189 100644 --- a/wrolpi/files/lib.py +++ b/wrolpi/files/lib.py @@ -230,7 +230,7 @@ async def delete(*paths: Union[str, pathlib.Path]): for p2 in paths: if p1 == p2: continue - if str(p2).startswith(str(p1)): + if p1 != p2 and p1 in p2.parents: raise InvalidFile(f'Cannot deleted nested paths') with get_db_session() as session: # Search for any files that have been tagged. diff --git a/wrolpi/files/test/test_lib.py b/wrolpi/files/test/test_lib.py index 507e1c18..aeae4ab1 100644 --- a/wrolpi/files/test/test_lib.py +++ b/wrolpi/files/test/test_lib.py @@ -74,6 +74,19 @@ async def test_delete_file_multiple(async_client, test_session, make_files_struc assert not baz.is_file() +@pytest.mark.asyncio +async def test_delete_file_missing(async_client, test_session, make_files_structure, test_directory): + """Deleting a mix of existing and nonexistent files should succeed, deleting only the existing files.""" + foo, bar = make_files_structure([ + 'config/foo.txt', + 'config/bar.txt', + ]) + + await lib.delete('config/foo.txt', 'config/._bar.txt', 'config/._baz.txt') + assert not foo.is_file() + assert bar.is_file() + + @pytest.mark.asyncio async def test_delete_file_names(async_client, test_session, make_files_structure, test_directory, tag_factory): """Will not refuse to delete a file that shares the name of a nearby file when they are in different FileGroups.""" @@ -135,6 +148,19 @@ async def test_delete_nested(test_session, make_files_structure): await lib.delete('foo', 'foo/bar') +@pytest.mark.asyncio +async def test_delete_similar_names(async_client, test_session, make_files_structure): + """Deleting sibling files where one filename is a prefix of another should not be considered nested.""" + make_files_structure([ + 'config/._wrolpi.yaml', + 'config/._wrolpi.yaml.sb-98fa34a1-MG7phT', + 'config/._wrolpi.yaml.sb-98fa34a1-N4k8NB', + ]) + + await lib.delete('config/._wrolpi.yaml', 'config/._wrolpi.yaml.sb-98fa34a1-MG7phT', + 'config/._wrolpi.yaml.sb-98fa34a1-N4k8NB') + + @pytest.mark.parametrize( 'path,full,expected', [