mirror of
https://github.com/borgbackup/borg.git
synced 2026-05-28 04:03:21 -04:00
list --depth=N: list files up to N depth in path hierarchy, fixes #8268
IOW: if there are > N slashes in the path, it is not listed.
This commit is contained in:
parent
98c0f29876
commit
2f8485400a
2 changed files with 83 additions and 1 deletions
|
|
@ -32,7 +32,21 @@ class ListMixIn:
|
|||
def _list_inner(cache):
|
||||
archive = Archive(manifest, archive_info.id, cache=cache)
|
||||
formatter = ItemFormatter(archive, format)
|
||||
for item in archive.iter_items(lambda item: matcher.match(item.path)):
|
||||
|
||||
def item_filter(item):
|
||||
# Check if the item matches the patterns/paths.
|
||||
if not matcher.match(item.path):
|
||||
return False
|
||||
# If depth is specified, also check the depth of the path.
|
||||
if args.depth is not None:
|
||||
# Count path separators to determine depth.
|
||||
# For paths like "dir/subdir/file.txt", the depth is 2.
|
||||
path_depth = item.path.count("/")
|
||||
if path_depth > args.depth:
|
||||
return False
|
||||
return True
|
||||
|
||||
for item in archive.iter_items(item_filter):
|
||||
sys.stdout.write(formatter.format_item(item, args.json_lines, sort=True))
|
||||
|
||||
# Only load the cache if it will be used
|
||||
|
|
@ -117,6 +131,13 @@ class ListMixIn:
|
|||
"but keys used in it are added to the JSON output. "
|
||||
"Some keys are always present. Note: JSON can only represent text.",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--depth",
|
||||
metavar="N",
|
||||
dest="depth",
|
||||
type=int,
|
||||
help="only list files up to the specified directory level depth",
|
||||
)
|
||||
subparser.add_argument("name", metavar="NAME", type=archivename_validator, help="specify the archive name")
|
||||
subparser.add_argument(
|
||||
"paths", metavar="PATH", nargs="*", type=PathSpec, help="paths to list; patterns are supported"
|
||||
|
|
|
|||
|
|
@ -74,3 +74,64 @@ def test_list_json(archivers, request):
|
|||
file1 = items[1]
|
||||
assert file1["path"] == "input/file1"
|
||||
assert file1["sha256"] == "b2915eb69f260d8d3c25249195f2c8f4f716ea82ec760ae929732c0262442b2b"
|
||||
|
||||
|
||||
def test_list_depth(archivers, request):
|
||||
"""Test the --depth option for the list command."""
|
||||
archiver = request.getfixturevalue(archivers)
|
||||
|
||||
# Create repository
|
||||
cmd(archiver, "repo-create", RK_ENCRYPTION)
|
||||
|
||||
# Create files at different directory depths
|
||||
create_regular_file(archiver.input_path, "file_at_depth_1.txt", size=1)
|
||||
create_regular_file(archiver.input_path, "dir1/file_at_depth_2.txt", size=1)
|
||||
create_regular_file(archiver.input_path, "dir1/dir2/file_at_depth_3.txt", size=1)
|
||||
|
||||
# Create archive
|
||||
cmd(archiver, "create", "test", "input")
|
||||
|
||||
# Test with depth=0 (only the root directory)
|
||||
output_depth_0 = cmd(archiver, "list", "test", "--depth=0")
|
||||
assert "input" in output_depth_0
|
||||
assert "input/file_at_depth_1.txt" not in output_depth_0
|
||||
assert "input/dir1" not in output_depth_0
|
||||
assert "input/dir1/file_at_depth_2.txt" not in output_depth_0
|
||||
assert "input/dir1/dir2" not in output_depth_0
|
||||
assert "input/dir1/dir2/file_at_depth_3.txt" not in output_depth_0
|
||||
|
||||
# Test with depth=1 (only input directory and files directly in it)
|
||||
output_depth_1 = cmd(archiver, "list", "test", "--depth=1")
|
||||
assert "input" in output_depth_1
|
||||
assert "input/file_at_depth_1.txt" in output_depth_1
|
||||
assert "input/dir1" in output_depth_1
|
||||
assert "input/dir1/file_at_depth_2.txt" not in output_depth_1
|
||||
assert "input/dir1/dir2" not in output_depth_1
|
||||
assert "input/dir1/dir2/file_at_depth_3.txt" not in output_depth_1
|
||||
|
||||
# Test with depth=2 (files up to one level inside input)
|
||||
output_depth_2 = cmd(archiver, "list", "test", "--depth=2")
|
||||
assert "input" in output_depth_2
|
||||
assert "input/file_at_depth_1.txt" in output_depth_2
|
||||
assert "input/dir1" in output_depth_2
|
||||
assert "input/dir1/file_at_depth_2.txt" in output_depth_2
|
||||
assert "input/dir1/dir2" in output_depth_2
|
||||
assert "input/dir1/dir2/file_at_depth_3.txt" not in output_depth_2
|
||||
|
||||
# Test with depth=3 (files up to two levels inside input)
|
||||
output_depth_3 = cmd(archiver, "list", "test", "--depth=3")
|
||||
assert "input" in output_depth_3
|
||||
assert "input/file_at_depth_1.txt" in output_depth_3
|
||||
assert "input/dir1" in output_depth_3
|
||||
assert "input/dir1/file_at_depth_2.txt" in output_depth_3
|
||||
assert "input/dir1/dir2" in output_depth_3
|
||||
assert "input/dir1/dir2/file_at_depth_3.txt" in output_depth_3
|
||||
|
||||
# Test without depth parameter (should show all files)
|
||||
output_no_depth = cmd(archiver, "list", "test")
|
||||
assert "input" in output_no_depth
|
||||
assert "input/file_at_depth_1.txt" in output_no_depth
|
||||
assert "input/dir1" in output_no_depth
|
||||
assert "input/dir1/file_at_depth_2.txt" in output_no_depth
|
||||
assert "input/dir1/dir2" in output_no_depth
|
||||
assert "input/dir1/dir2/file_at_depth_3.txt" in output_no_depth
|
||||
|
|
|
|||
Loading…
Reference in a new issue