-
Notifications
You must be signed in to change notification settings - Fork 1
🎨 Palette: Improved CLI feedback with countdown timers and duration formatting #187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -256,6 +256,16 @@ def print_plan_details(plan_entry: Dict[str, Any]) -> None: | |||||||||||||||||||||||||||||||||||
| print("") | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| def format_duration(seconds: float) -> str: | ||||||||||||||||||||||||||||||||||||
| """Formats duration in a human-readable way (e.g., 2m 05s).""" | ||||||||||||||||||||||||||||||||||||
| if seconds < 60: | ||||||||||||||||||||||||||||||||||||
| return f"{seconds:.1f}s" | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| minutes = int(seconds // 60) | ||||||||||||||||||||||||||||||||||||
| rem_seconds = int(seconds % 60) | ||||||||||||||||||||||||||||||||||||
| return f"{minutes}m {rem_seconds:02d}s" | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+259
to
+266
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current implementation of A more consistent and accurate approach would be to round the duration to the nearest second and then format it. This avoids information loss and also handles the transition around 60 seconds more gracefully (e.g., Here is a suggested implementation that addresses this. Note that this change will require updating the corresponding test cases in
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| def countdown_timer(seconds: int, message: str = "Waiting") -> None: | ||||||||||||||||||||||||||||||||||||
| """Shows a countdown timer if strictly in a TTY, otherwise just sleeps.""" | ||||||||||||||||||||||||||||||||||||
| if not USE_COLORS: | ||||||||||||||||||||||||||||||||||||
|
|
@@ -836,7 +846,7 @@ def verify_access_and_get_folders( | |||||||||||||||||||||||||||||||||||
| MAX_RETRIES, | ||||||||||||||||||||||||||||||||||||
| wait_time, | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| time.sleep(wait_time) | ||||||||||||||||||||||||||||||||||||
| countdown_timer(int(wait_time), "Retrying") | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| def get_all_existing_rules( | ||||||||||||||||||||||||||||||||||||
|
|
@@ -1044,7 +1054,7 @@ def create_folder( | |||||||||||||||||||||||||||||||||||
| log.info( | ||||||||||||||||||||||||||||||||||||
| f"Folder '{sanitize_for_log(name)}' not found yet. Retrying in {wait_time}s..." | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| time.sleep(wait_time) | ||||||||||||||||||||||||||||||||||||
| countdown_timer(int(wait_time), "Waiting for folder") | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| log.error( | ||||||||||||||||||||||||||||||||||||
| f"Folder {sanitize_for_log(name)} was not found after creation and retries." | ||||||||||||||||||||||||||||||||||||
|
|
@@ -1651,7 +1661,7 @@ def validate_profile_input(value: str) -> bool: | |||||||||||||||||||||||||||||||||||
| f"{res['profile']:<{profile_col_width}} | " | ||||||||||||||||||||||||||||||||||||
| f"{res['folders']:>10} | " | ||||||||||||||||||||||||||||||||||||
| f"{res['rules']:>10,} | " | ||||||||||||||||||||||||||||||||||||
| f"{res['duration']:>9.1f}s | " | ||||||||||||||||||||||||||||||||||||
| f"{format_duration(res['duration']):>10} | " | ||||||||||||||||||||||||||||||||||||
| f"{status_color}{res['status_label']:<15}{Colors.ENDC}" | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| total_folders += res["folders"] | ||||||||||||||||||||||||||||||||||||
|
|
@@ -1682,7 +1692,7 @@ def validate_profile_input(value: str) -> bool: | |||||||||||||||||||||||||||||||||||
| f"{'TOTAL':<{profile_col_width}} | " | ||||||||||||||||||||||||||||||||||||
| f"{total_folders:>10} | " | ||||||||||||||||||||||||||||||||||||
| f"{total_rules:>10,} | " | ||||||||||||||||||||||||||||||||||||
| f"{total_duration:>9.1f}s | " | ||||||||||||||||||||||||||||||||||||
| f"{format_duration(total_duration):>10} | " | ||||||||||||||||||||||||||||||||||||
| f"{total_status_color}{total_status_text:<15}{Colors.ENDC}" | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| print("=" * table_width + "\n") | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
format_duration()can produce the inconsistent output "60.0s" for inputs just under 60 seconds (e.g., 59.95 rounds to 60.0 with:.1fwhile still taking the< 60branch). Consider truncating (not rounding) sub-minute values, or adding a guard so any value that formats to 60.0s is emitted as "1m 00s" instead.