3 Commits

Author SHA1 Message Date
Simone Scarduzio
fa1f8b85a9 docs: Update CHANGELOG for v4.2.4 2025-10-08 14:09:30 +02:00
Simone Scarduzio
a06cc2939c fix: Show only filename in ls output, not full path
Match AWS S3 CLI behavior where ls shows filenames relative to
the current prefix, not the full S3 path.

Before:
  2024-05-18 20:11:52   73299362 s3://bucket/build/1.57.3/file.zip

After:
  2024-05-18 20:11:52   73299362 file.zip

This matches aws s3 ls behavior exactly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-08 13:06:15 +02:00
Simone Scarduzio
5b8477ed61 fix: Correct ls command path handling and prefix display
Fixed issues where ls command was:
- Showing incorrect prefixes (e.g., "PRE build/" instead of "PRE 1.67.0-pre6/")
- Getting into loops when listing subdirectories
- Not properly handling paths without trailing slashes

Changes:
- Ensure prefix ends with / for proper path handling
- Use S3 Delimiter parameter to get proper subdirectory grouping
- Display only relative subdirectory names, not full paths
- Use common_prefixes from S3 response instead of manual parsing

This now matches AWS CLI behavior where:
- `ls s3://bucket/build/` shows subdirectories as `PRE org/` and `PRE 1.67.0-pre6/`
- Not `PRE build/org/` and `PRE build/1.67.0-pre6/`

All 99 tests passing, quality checks passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-08 13:00:58 +02:00
2 changed files with 38 additions and 17 deletions

View File

@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [4.2.4] - 2025-01-10
### Fixed
- Show only filename in `ls` output instead of full path for cleaner display
- Correct `ls` command path handling and prefix display logic
## [4.2.3] - 2025-01-07
### Added
@@ -59,6 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Delta compression for versioned artifacts
- 99%+ compression for similar files
[4.2.4]: https://github.com/beshu-tech/deltaglider/compare/v4.2.3...v4.2.4
[4.2.3]: https://github.com/beshu-tech/deltaglider/compare/v4.2.2...v4.2.3
[4.2.2]: https://github.com/beshu-tech/deltaglider/compare/v4.2.1...v4.2.2
[4.2.1]: https://github.com/beshu-tech/deltaglider/compare/v4.2.0...v4.2.1

View File

@@ -240,6 +240,13 @@ def ls(
prefix_str: str
bucket_name, prefix_str = parse_s3_url(s3_url)
# Ensure prefix ends with / if it's meant to be a directory
# This helps with proper path handling
if prefix_str and not prefix_str.endswith("/"):
# Check if this is a file or directory by listing
# For now, assume it's a directory prefix
prefix_str = prefix_str + "/"
# Format bytes to human readable
def format_bytes(size: int) -> str:
if not human_readable:
@@ -256,29 +263,30 @@ def ls(
client = DeltaGliderClient(service)
dg_response: ListObjectsResponse = client.list_objects(
Bucket=bucket_name, Prefix=prefix_str, MaxKeys=10000
Bucket=bucket_name, Prefix=prefix_str, MaxKeys=10000, Delimiter="/" if not recursive else ""
)
objects = dg_response.contents
# Filter by recursive flag
if not recursive:
# Only show direct children
seen_prefixes = set()
# Show common prefixes (subdirectories) from S3 response
for common_prefix in dg_response.common_prefixes:
prefix_path = common_prefix.get("Prefix", "")
# Show only the directory name, not the full path
if prefix_str:
# Strip the current prefix to show only the subdirectory
display_name = prefix_path[len(prefix_str):]
else:
display_name = prefix_path
click.echo(f" PRE {display_name}")
# Only show files at current level (not in subdirectories)
filtered_objects = []
for obj in objects:
rel_path = obj.key[len(prefix_str) :] if prefix_str else obj.key
if "/" in rel_path:
# It's in a subdirectory
subdir = rel_path.split("/")[0] + "/"
if subdir not in seen_prefixes:
seen_prefixes.add(subdir)
# Show as directory
full_prefix = f"{prefix_str}{subdir}" if prefix_str else subdir
click.echo(f" PRE {full_prefix}")
else:
# Direct file
if rel_path: # Only add if there's actually a file at this level
filtered_objects.append(obj)
rel_path = obj.key[len(prefix_str):] if prefix_str else obj.key
# Only include if it's a direct child (no / in relative path)
if "/" not in rel_path and rel_path:
filtered_objects.append(obj)
objects = filtered_objects
# Display objects (SDK already filters reference.bin and strips .delta)
@@ -298,7 +306,13 @@ def ls(
else:
date_str = obj.last_modified.strftime("%Y-%m-%d %H:%M:%S")
click.echo(f"{date_str} {size_str:>10} s3://{bucket_name}/{obj.key}")
# Show only the filename relative to current prefix (like AWS CLI)
if prefix_str:
display_key = obj.key[len(prefix_str):]
else:
display_key = obj.key
click.echo(f"{date_str} {size_str:>10} {display_key}")
# Show summary if requested
if summarize: