Skip to content

Commit e680232

Browse files
mavamclaude
andauthored
Fix changelog entry ordering in multi-project show command (#6)
* Fix changelog entry ordering in multi-project show command Entries were displayed newest-first instead of oldest-first when showing multiple projects. Changed the sort key in _render_entries_multi_project() from -ts to ts to sort entries ascending by date, ensuring consistency with single-project display and placing the newest entry at the bottom of the table where users expect it. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Ensure consistent entry ordering in multi-project show command The multi-project show command now displays entries in chronological order (oldest first), matching single-project behavior and user expectations. Previously entries were sorted newest-first, creating an inconsistency in the application's sorting behavior. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Format test file Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b546b22 commit e680232

File tree

3 files changed

+78
-2
lines changed

3 files changed

+78
-2
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
title: Consistent entry ordering in multi-project show command
3+
type: bugfix
4+
authors:
5+
- mavam
6+
- claude
7+
pr: 6
8+
created: 2026-01-22T19:32:16.587667Z
9+
---
10+
11+
The multi-project `show` command now displays changelog entries in chronological order, with the newest entry at the bottom of the table where users expect it. Previously, entries were sorted newest-first, which was inconsistent with single-project behavior and user expectations. This brings the multi-project display in line with the rest of the application's sorting behavior.

src/tenzir_ship/cli/_rendering.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -768,11 +768,11 @@ def _render_entries_multi_project(
768768
if "id" in visible_columns:
769769
_add_table_column(table, "ID", "id", column_specs, style="cyan", no_wrap_default=True)
770770

771-
# Sort entries: by project order, then by date descending
771+
# Sort entries: by project order, then by date ascending (oldest first)
772772
def sort_key(multi: MultiProjectEntry) -> tuple[int, float, str]:
773773
proj_idx = project_order.get(multi.project_id, 999)
774774
ts = multi.entry.created_at.timestamp() if multi.entry.created_at else 0
775-
return (proj_idx, -ts, multi.entry.entry_id)
775+
return (proj_idx, ts, multi.entry.entry_id)
776776

777777
sorted_entries = sorted(entries, key=sort_key)
778778

tests/test_modules.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,3 +526,68 @@ def test_show_release_no_modules_no_separator(tmp_path: Path) -> None:
526526
assert "Test Feature" in result.output
527527
# No separator when no modules
528528
assert "---" not in result.output
529+
530+
531+
def create_entry_with_timestamp(
532+
module_root: Path, title: str, timestamp: str, entry_type: str = "feature"
533+
) -> Path:
534+
"""Create a changelog entry with a specific timestamp."""
535+
slug = title.lower().replace(" ", "-")
536+
entry_path = module_root / "unreleased" / f"{slug}.md"
537+
entry_path.write_text(
538+
f"---\ntitle: {title}\ntype: {entry_type}\ncreated: {timestamp}\n---\n\nBody.\n",
539+
encoding="utf-8",
540+
)
541+
return entry_path
542+
543+
544+
def test_cli_show_multi_project_sorts_entries_oldest_first(tmp_path: Path) -> None:
545+
"""Multi-project show command sorts entries oldest-first within each project."""
546+
packages = tmp_path / "packages"
547+
mod_root = create_module(packages, "mymod", "My Module")
548+
549+
# Create module entries with different timestamps (out of order)
550+
create_entry_with_timestamp(mod_root, "Newest Module Entry", "2025-01-03T00:00:00Z")
551+
create_entry_with_timestamp(mod_root, "Oldest Module Entry", "2025-01-01T00:00:00Z")
552+
create_entry_with_timestamp(mod_root, "Middle Module Entry", "2025-01-02T00:00:00Z")
553+
554+
project_dir = tmp_path / "changelog"
555+
project_dir.mkdir()
556+
write_yaml(
557+
project_dir / "config.yaml",
558+
{"id": "parent", "name": "Parent", "modules": "../packages/*/changelog"},
559+
)
560+
(project_dir / "unreleased").mkdir()
561+
562+
# Create parent entries with different timestamps (out of order)
563+
create_entry_with_timestamp(project_dir, "Newest Parent Entry", "2025-01-03T00:00:00Z")
564+
create_entry_with_timestamp(project_dir, "Oldest Parent Entry", "2025-01-01T00:00:00Z")
565+
create_entry_with_timestamp(project_dir, "Middle Parent Entry", "2025-01-02T00:00:00Z")
566+
567+
runner = CliRunner()
568+
result = runner.invoke(cli, ["--root", str(project_dir), "show"])
569+
570+
assert result.exit_code == 0
571+
572+
# Find positions of entries in output to verify ordering
573+
output = result.output
574+
parent_oldest = output.find("Oldest Parent Entry")
575+
parent_middle = output.find("Middle Parent Entry")
576+
parent_newest = output.find("Newest Parent Entry")
577+
module_oldest = output.find("Oldest Module Entry")
578+
module_middle = output.find("Middle Module Entry")
579+
module_newest = output.find("Newest Module Entry")
580+
581+
# Verify all entries are present
582+
assert parent_oldest != -1, "Oldest Parent Entry not found"
583+
assert parent_middle != -1, "Middle Parent Entry not found"
584+
assert parent_newest != -1, "Newest Parent Entry not found"
585+
assert module_oldest != -1, "Oldest Module Entry not found"
586+
assert module_middle != -1, "Middle Module Entry not found"
587+
assert module_newest != -1, "Newest Module Entry not found"
588+
589+
# Within parent project: oldest should appear before middle, middle before newest
590+
assert parent_oldest < parent_middle < parent_newest, "Parent entries not sorted oldest-first"
591+
592+
# Within module project: oldest should appear before middle, middle before newest
593+
assert module_oldest < module_middle < module_newest, "Module entries not sorted oldest-first"

0 commit comments

Comments
 (0)