Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2024-05-22 - Helpful CLI Prompts
**Learning:** Even in CLI tools, users often get stuck on authentication steps (Tokens/IDs). Providing direct URLs or location hints in the prompt text significantly reduces friction compared to forcing users to consult external docs.
**Action:** When prompting for credentials in CLI tools, always include a "Where to find this" hint or direct URL.

## 2024-05-23 - CLI Progress Bars
**Learning:** Using clear-line ANSI codes (`\033[K`) is significantly more robust than space-padding for overwriting CLI lines, especially when line lengths vary between updates. Visual progress bars (e.g., `[β–ˆβ–ˆβ–‘β–‘]`) provide better psychological feedback for waiting periods than simple countdowns.
**Action:** Use `\033[K` for dynamic CLI updates and favor visual bars for waits > 5 seconds.
8 changes: 6 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,16 @@
time.sleep(seconds)
return

width = 15
for remaining in range(seconds, 0, -1):
sys.stderr.write(f"\r{Colors.CYAN}⏳ {message}: {remaining}s...{Colors.ENDC}")
progress = (seconds - remaining + 1) / seconds
filled = int(width * progress)
bar = "β–ˆ" * filled + "β–‘" * (width - filled)

Check warning

Code scanning / Prospector (reported by Codacy)

Black listed name "bar" (blacklisted-name) Warning

Black listed name "bar" (blacklisted-name)

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Black listed name "bar" Warning

Black listed name "bar"

Check warning

Code scanning / Pylint (reported by Codacy)

Black listed name "bar" Warning

Black listed name "bar"
sys.stderr.write(f"\r{Colors.CYAN}⏳ {message}: [{bar}] {remaining}s...{Colors.ENDC}")
sys.stderr.flush()
time.sleep(1)

sys.stderr.write(f"\r{Colors.GREEN}βœ… {message}: Done! {Colors.ENDC}\n")
sys.stderr.write(f"\r\033[K{Colors.GREEN}βœ… {message}: Done!{Colors.ENDC}\n")
sys.stderr.flush()


Expand Down
46 changes: 46 additions & 0 deletions tests/test_ux.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing module docstring Warning test

Missing module docstring

Check warning

Code scanning / Pylint (reported by Codacy)

Missing module docstring Warning test

Missing module docstring
import sys
from unittest.mock import MagicMock
import main

def test_countdown_timer_visuals(monkeypatch):
"""Verify that countdown_timer writes a progress bar to stderr."""
# Force colors on
monkeypatch.setattr(main, "USE_COLORS", True)

# Mock stderr
mock_stderr = MagicMock()
monkeypatch.setattr(sys, "stderr", mock_stderr)

# Mock time.sleep to run instantly
monkeypatch.setattr(main.time, "sleep", MagicMock())

main.countdown_timer(3, "Test")

# Check calls
writes = [args[0] for args, _ in mock_stderr.write.call_args_list]
combined_output = "".join(writes)

# Check for progress bar chars
assert "β–‘" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "β–ˆ" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "Test" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
assert "Done!" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

# Check for ANSI clear line code
assert "\033[K" in combined_output

Check notice

Code scanning / Bandit

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

Check notice

Code scanning / Bandit (reported by Codacy)

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. Note test

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.

def test_countdown_timer_no_colors(monkeypatch):
"""Verify that countdown_timer sleeps without writing to stderr if NO_COLOR."""
monkeypatch.setattr(main, "USE_COLORS", False)
mock_stderr = MagicMock()
monkeypatch.setattr(sys, "stderr", mock_stderr)
mock_sleep = MagicMock()
monkeypatch.setattr(main.time, "sleep", mock_sleep)

main.countdown_timer(3, "Test")

# Should not write to stderr
mock_stderr.write.assert_not_called()
# Should call sleep exactly once with full seconds
mock_sleep.assert_called_once_with(3)
Loading