Coverage for little_loops / cli / issues / anchor_sweep.py: 92%
26 statements
« prev ^ index » next coverage.py v7.12.0, created at 2026-05-22 16:19 -0500
« prev ^ index » next coverage.py v7.12.0, created at 2026-05-22 16:19 -0500
1"""ll-issues anchor-sweep: rewrite file:line refs in active issue files."""
3from __future__ import annotations
5import argparse
6import sys
7from pathlib import Path
8from typing import TYPE_CHECKING
10if TYPE_CHECKING:
11 from little_loops.config import BRConfig
14def cmd_anchor_sweep(config: BRConfig, args: argparse.Namespace) -> int:
15 """Rewrite file:line references in active issue files to anchor form.
17 Scans bugs/, features/, and enhancements/ under the issues directory for
18 references like ``file.py:42`` outside code fences, resolves each to its
19 enclosing function/class/section, and rewrites in-place.
21 Args:
22 config: Project configuration.
23 args: Parsed arguments with .dry_run and .issues_dir.
25 Returns:
26 0 on success, 1 on error.
27 """
28 from little_loops.issues.anchor_sweep import sweep_issues
30 issues_dir = Path(args.issues_dir)
31 if not issues_dir.is_absolute():
32 issues_dir = config.project_root / issues_dir
34 if not issues_dir.is_dir():
35 print(f"Error: issues directory not found: {issues_dir}", file=sys.stderr)
36 return 1
38 dry_run: bool = args.dry_run
39 result = sweep_issues(issues_dir, dry_run=dry_run)
41 mode = "[dry-run] " if dry_run else ""
42 if result.changes:
43 for change in result.changes:
44 print(f"{mode}{change}")
45 if dry_run:
46 print(
47 f"\n{mode}Would modify {len(result.changes)} file(s). Re-run without --dry-run to apply."
48 )
49 else:
50 print(f"\nModified {len(result.modified_files)} file(s).")
51 else:
52 print(f"{mode}No file:line references found in active issue files.")
54 if result.skipped_refs:
55 print(
56 f"Warning: {result.skipped_refs} reference(s) could not be resolved and were left unchanged.",
57 file=sys.stderr,
58 )
60 return 0