"""Organize docs/reports/ files into week folders named --
. Scheme: ShareX-style -- where resolves to the day-of-month (zero-padded) of the week's Monday. Example: files from the week of Mon June 22, 2026 land in docs/reports/2026-06-22/. Only moves files from OLD weeks; the current week's files stay in place so in-flight work isn't buried. Date resolution per file: 1. Parse an 8-digit YYYYMMDD or YYYY-MM-DD substring from the filename (most reports embed one, e.g. TRACK_COMPLETION_..._20260627.md). 2. Fall back to the file's mtime. NOTE: git checkout resets mtime, so undated files may be mis-classified as 'current week' and left in place. Idempotent: subdirectories (existing week folders) are skipped; files already at their computed destination are skipped. Non-recursive: only immediate children of the reports dir are scanned. Subdirectories (existing week folders, category folders like code_path_audit/ + license_cve_audit/) are never entered; their contents are left untouched. Only loose .md (or other) files in the immediate reports dir are candidates for moving. Usage: python scripts/organize_reports.py # dry-run; print plan python scripts/organize_reports.py --apply # actually move files python scripts/organize_reports.py --json # dry-run; JSON output python scripts/organize_reports.py --dir docs/reports """ from __future__ import annotations import argparse import json import re import shutil import sys from datetime import date, timedelta from pathlib import Path _DATE_REGEX = re.compile(r"(\d{4})[-_]?(\d{2})[-_]?(\d{2})") def _week_monday(d: date) -> date: return d - timedelta(days=d.weekday()) def _parse_filename_date(name: str) -> date | None: m = _DATE_REGEX.search(name) if not m: return None y, mo, dy = int(m.group(1)), int(m.group(2)), int(m.group(3)) if not (2000 <= y < 2100 and 1 <= mo <= 12 and 1 <= dy <= 31): return None try: return date(y, mo, dy) except ValueError: return None def _file_week_monday(path: Path) -> date | None: fd = _parse_filename_date(path.name) if fd is not None: return _week_monday(fd) try: mt = path.stat().st_mtime except OSError: return None return _week_monday(date.fromtimestamp(mt)) def main() -> int: parser = argparse.ArgumentParser( description="Organize docs/reports/ files into week folders named --
(Monday of the file's week). Old weeks only; current week's files stay in place." ) parser.add_argument("--apply", action="store_true", help="Actually move files (default: dry-run)") parser.add_argument("--json", action="store_true", help="Emit JSON instead of human-readable output") parser.add_argument("--dir", default="docs/reports", help="Reports directory (default: docs/reports)") args = parser.parse_args() reports = Path(args.dir) if not reports.is_dir(): print(f"error: {reports} is not a directory", file=sys.stderr) return 1 subdirs_skipped = [e.name for e in sorted(reports.iterdir(), key=lambda e: e.name) if e.is_dir()] current_monday = _week_monday(date.today()) moves: list[dict] = [] skipped_current_week: list[str] = [] skipped_no_date: list[str] = [] skipped_already_in_place: list[str] = [] for entry in sorted(reports.iterdir(), key=lambda e: e.name): if entry.is_dir(): continue if not entry.is_file(): continue fm = _file_week_monday(entry) if fm is None: skipped_no_date.append(entry.name) continue if fm >= current_monday: skipped_current_week.append(entry.name) continue dest_dir = reports / fm.isoformat() dest = dest_dir / entry.name if dest.exists(): skipped_already_in_place.append(entry.name) continue moves.append({"src": str(entry), "dest": str(dest), "week": fm.isoformat()}) if args.json: print(json.dumps({ "current_week_monday": current_monday.isoformat(), "reports_dir": str(reports), "moves": moves, "skipped_current_week": skipped_current_week, "skipped_no_date": skipped_no_date, "skipped_already_in_place": skipped_already_in_place, "subdirs_skipped": subdirs_skipped, }, indent=2)) return 0 print(f"Current week Monday: {current_monday.isoformat()} (files from this week stay put)") print(f"Reports dir: {reports}") print() if not moves: print("Nothing to move.") else: tag = "MOVE" if args.apply else "DRY " print(f"{tag}: {len(moves)} file(s)") for mv in moves: print(f" {tag} {mv['src']} -> {mv['dest']}") if skipped_current_week: print(f"\nSkipped (current week): {len(skipped_current_week)}") for n in skipped_current_week: print(f" - {n}") if skipped_already_in_place: print(f"\nSkipped (already in destination): {len(skipped_already_in_place)}") for n in skipped_already_in_place: print(f" - {n}") if skipped_no_date: print(f"\nSkipped (no parseable date): {len(skipped_no_date)}") for n in skipped_no_date: print(f" - {n}") if subdirs_skipped: print(f"\nSubdirectories skipped (non-recursive; left untouched): {len(subdirs_skipped)}") for n in subdirs_skipped: print(f" - {n}") if args.apply and moves: for mv in moves: dest_path = Path(mv["dest"]) dest_path.parent.mkdir(parents=True, exist_ok=True) shutil.move(mv["src"], mv["dest"]) print(f"\nApplied: moved {len(moves)} file(s).") elif moves: print("\nDry run. Pass --apply to move.") return 0 if __name__ == "__main__": sys.exit(main())