Coverage for little_loops / cli / issues / skip.py: 14%

35 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2026-04-11 23:20 -0500

1"""ll-issues skip: Deprioritize an issue by bumping its priority prefix.""" 

2 

3from __future__ import annotations 

4 

5import re 

6import sys 

7from typing import TYPE_CHECKING 

8 

9if TYPE_CHECKING: 

10 import argparse 

11 

12 from little_loops.config import BRConfig 

13 

14 

15def cmd_skip(config: BRConfig, args: argparse.Namespace) -> int: 

16 """Deprioritize an issue by renaming its priority prefix. 

17 

18 Renames the issue file to the given priority (default P5), appends a 

19 ``## Skip Log`` entry with timestamp and optional reason, and prints the 

20 new file path to stdout so callers can confirm the rename. 

21 

22 Args: 

23 config: Project configuration 

24 args: Parsed arguments with .issue_id, .priority, and .reason 

25 

26 Returns: 

27 Exit code (0 = success, 1 = error) 

28 """ 

29 from little_loops.cli.issues.show import _resolve_issue_id 

30 from little_loops.issue_lifecycle import skip_issue 

31 

32 path = _resolve_issue_id(config, args.issue_id) 

33 if path is None: 

34 print(f"Error: Issue '{args.issue_id}' not found.", file=sys.stderr) 

35 return 1 

36 

37 # Only skip active issues 

38 parent_name = path.parent.name 

39 if parent_name in ("completed", "deferred"): 

40 print( 

41 f"Error: Issue '{args.issue_id}' is in {parent_name}/, not an active issue.", 

42 file=sys.stderr, 

43 ) 

44 return 1 

45 

46 new_name = re.sub(r"^P\d-", f"{args.priority}-", path.name) 

47 new_path = path.parent / new_name 

48 

49 if path == new_path: 

50 # Already at target priority — nothing to rename, still print path 

51 try: 

52 rel = str(new_path.relative_to(config.project_root)) 

53 except ValueError: 

54 rel = str(new_path) 

55 print(f"Deprioritized {args.issue_id} to {args.priority}: {rel}") 

56 return 0 

57 

58 try: 

59 skip_issue(path, new_path, args.reason) 

60 except FileExistsError as exc: 

61 print(f"Error: {exc}", file=sys.stderr) 

62 return 1 

63 

64 try: 

65 rel = str(new_path.relative_to(config.project_root)) 

66 except ValueError: 

67 rel = str(new_path) 

68 

69 print(f"Deprioritized {args.issue_id} to {args.priority}: {rel}") 

70 return 0